author | Bas Schouten <bschouten@mozilla.com> |
Wed, 20 Jun 2012 23:41:16 +0200 | |
changeset 97207 | e7b9f828d4c1e233eed96a3ca898992a77abddc5 |
parent 97206 | b35294da2c4bc65d3838a3108c616a5ef93c8e2e |
child 97208 | f328118d86b910aa5bb06571a2a55f949aaf7058 |
push id | 22962 |
push user | emorley@mozilla.com |
push date | Thu, 21 Jun 2012 10:59:14 +0000 |
treeherder | mozilla-central@10e019421e6b [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | jrmuizel |
bugs | 738189 |
milestone | 16.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/gfx/2d/2D.h +++ b/gfx/2d/2D.h @@ -847,16 +847,19 @@ public: SurfaceFormat aFormat); static void SetDirect3D10Device(ID3D10Device1 *aDevice); static ID3D10Device1 *GetDirect3D10Device(); static TemporaryRef<GlyphRenderingOptions> CreateDWriteGlyphRenderingOptions(IDWriteRenderingParams *aParams); + static uint64_t GetD2DVRAMUsageDrawTarget(); + static uint64_t GetD2DVRAMUsageSourceSurface(); + private: static ID3D10Device1 *mD3D10Device; #endif }; } }
--- a/gfx/2d/DrawTargetD2D.cpp +++ b/gfx/2d/DrawTargetD2D.cpp @@ -50,16 +50,18 @@ namespace gfx { struct Vertex { float x; float y; }; ID2D1Factory *DrawTargetD2D::mFactory; IDWriteFactory *DrawTargetD2D::mDWriteFactory; +uint64_t DrawTargetD2D::mVRAMUsageDT; +uint64_t DrawTargetD2D::mVRAMUsageSS; // Helper class to restore surface contents that was clipped out but may have // been altered by a drawing call. class AutoSaveRestoreClippedOut { public: AutoSaveRestoreClippedOut(DrawTargetD2D *aDT) : mDT(aDT) @@ -156,30 +158,34 @@ DrawTargetD2D::DrawTargetD2D() } DrawTargetD2D::~DrawTargetD2D() { if (mRT) { PopAllClips(); mRT->EndDraw(); + + mVRAMUsageDT -= GetByteSize(); } if (mTempRT) { mTempRT->EndDraw(); + + mVRAMUsageDT -= GetByteSize(); } if (mSnapshot) { // We may hold the only reference. MarkIndependent will clear mSnapshot; - // keep the snapshot object alive so it doesn't get destroyed while - // MarkIndependent is running. + // keep the snapshot object alive so it doesn't get destroyed while + // MarkIndependent is running. RefPtr<SourceSurfaceD2DTarget> deathGrip = mSnapshot; - // mSnapshot can be treated as independent of this DrawTarget since we know - // this DrawTarget won't change again. - deathGrip->MarkIndependent(); - // mSnapshot will be cleared now. + // mSnapshot can be treated as independent of this DrawTarget since we know + // this DrawTarget won't change again. + deathGrip->MarkIndependent(); + // mSnapshot will be cleared now. } // Targets depending on us can break that dependency, since we're obviously not going to // be modified in the future. for (TargetSet::iterator iter = mDependentTargets.begin(); iter != mDependentTargets.end(); iter++) { (*iter)->mDependingOnTargets.erase(this); } @@ -1269,16 +1275,22 @@ DrawTargetD2D::InitD3D10Data() } return true; } /* * Private helpers */ +uint32_t +DrawTargetD2D::GetByteSize() const +{ + return mSize.width * mSize.height * BytesPerPixel(mFormat); +} + bool DrawTargetD2D::InitD2DRenderTarget() { if (!factory()) { return false; } mRT = CreateRTForTexture(mTexture, mFormat); @@ -1288,16 +1300,18 @@ DrawTargetD2D::InitD2DRenderTarget() } mRT->BeginDraw(); if (mFormat == FORMAT_B8G8R8X8) { mRT->SetTextAntialiasMode(D2D1_TEXT_ANTIALIAS_MODE_CLEARTYPE); } + mVRAMUsageDT += GetByteSize(); + return InitD3D10Data(); } void DrawTargetD2D::PrepareForDrawing(ID2D1RenderTarget *aRT) { if (!mClipsArePushed || aRT == mTempRT) { if (mPushedClips.size()) { @@ -1436,16 +1450,18 @@ DrawTargetD2D::GetRTForOperation(Composi } mTempRT = CreateRTForTexture(mTempTexture, FORMAT_B8G8R8A8); if (!mTempRT) { return mRT; } + mVRAMUsageDT += GetByteSize(); + mTempRT->BeginDraw(); mTempRT->Clear(D2D1::ColorF(0, 0)); return mTempRT; } /* This function blends back the content of a drawing operation (drawn to an
--- a/gfx/2d/DrawTargetD2D.h +++ b/gfx/2d/DrawTargetD2D.h @@ -116,26 +116,31 @@ public: uint32_t aNumStops, ExtendMode aExtendMode = EXTEND_CLAMP) const; virtual void *GetNativeSurface(NativeSurfaceType aType); bool Init(const IntSize &aSize, SurfaceFormat aFormat); bool Init(ID3D10Texture2D *aTexture, SurfaceFormat aFormat); bool InitD3D10Data(); + uint32_t GetByteSize() const; static ID2D1Factory *factory(); static TemporaryRef<ID2D1StrokeStyle> CreateStrokeStyleForOptions(const StrokeOptions &aStrokeOptions); static IDWriteFactory *GetDWriteFactory(); operator std::string() const { std::stringstream stream; stream << "DrawTargetD2D(" << this << ")"; return stream.str(); } + + static uint64_t mVRAMUsageDT; + static uint64_t mVRAMUsageSS; + private: friend class AutoSaveRestoreClippedOut; friend class SourceSurfaceD2DTarget; #ifdef _MSC_VER typedef stdext::hash_set<DrawTargetD2D*> TargetSet; #else typedef std::unordered_set<DrawTargetD2D*> TargetSet;
--- a/gfx/2d/Factory.cpp +++ b/gfx/2d/Factory.cpp @@ -376,10 +376,22 @@ Factory::CreateWrappingDataSourceSurface if (newSurf->InitWrappingData(aData, aSize, aStride, aFormat, false)) { return newSurf; } return NULL; } +uint64_t +Factory::GetD2DVRAMUsageDrawTarget() +{ + return DrawTargetD2D::mVRAMUsageDT; +} + +uint64_t +Factory::GetD2DVRAMUsageSourceSurface() +{ + return DrawTargetD2D::mVRAMUsageSS; +} + } }
--- a/gfx/2d/SourceSurfaceD2D.cpp +++ b/gfx/2d/SourceSurfaceD2D.cpp @@ -1,25 +1,30 @@ /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SourceSurfaceD2D.h" +#include "DrawTargetD2D.h" #include "Logging.h" +#include "Tools.h" namespace mozilla { namespace gfx { SourceSurfaceD2D::SourceSurfaceD2D() { } SourceSurfaceD2D::~SourceSurfaceD2D() { + if (mBitmap) { + DrawTargetD2D::mVRAMUsageSS -= GetByteSize(); + } } IntSize SourceSurfaceD2D::GetSize() const { return mSize; } @@ -57,16 +62,18 @@ SourceSurfaceD2D::InitFromData(unsigned D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat))); hr = aRT->CreateBitmap(D2DIntSize(aSize), aData, aStride, props, byRef(mBitmap)); if (FAILED(hr)) { gfxWarning() << "Failed to create D2D Bitmap for data. Code: " << hr; return false; } + DrawTargetD2D::mVRAMUsageSS += GetByteSize(); + return true; } bool SourceSurfaceD2D::InitFromTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat, ID2D1RenderTarget *aRT) { @@ -91,13 +98,21 @@ SourceSurfaceD2D::InitFromTexture(ID3D10 D2D1::BitmapProperties(D2D1::PixelFormat(DXGIFormat(aFormat), AlphaMode(aFormat))); hr = aRT->CreateSharedBitmap(IID_IDXGISurface, surf, &props, byRef(mBitmap)); if (FAILED(hr)) { gfxWarning() << "Failed to create SharedBitmap. Code: " << hr; return false; } + DrawTargetD2D::mVRAMUsageSS += GetByteSize(); + return true; } +uint32_t +SourceSurfaceD2D::GetByteSize() const +{ + return mSize.width * mSize.height * BytesPerPixel(mFormat); +} + } }
--- a/gfx/2d/SourceSurfaceD2D.h +++ b/gfx/2d/SourceSurfaceD2D.h @@ -33,16 +33,18 @@ public: ID2D1RenderTarget *aRT); bool InitFromTexture(ID3D10Texture2D *aTexture, SurfaceFormat aFormat, ID2D1RenderTarget *aRT); private: friend class DrawTargetD2D; + uint32_t GetByteSize() const; + RefPtr<ID2D1Bitmap> mBitmap; SurfaceFormat mFormat; IntSize mSize; }; } }
--- a/gfx/2d/SourceSurfaceD2DTarget.cpp +++ b/gfx/2d/SourceSurfaceD2DTarget.cpp @@ -1,36 +1,43 @@ /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "SourceSurfaceD2DTarget.h" #include "Logging.h" #include "DrawTargetD2D.h" +#include "Tools.h" #include <algorithm> namespace mozilla { namespace gfx { SourceSurfaceD2DTarget::SourceSurfaceD2DTarget(DrawTargetD2D* aDrawTarget, ID3D10Texture2D* aTexture, SurfaceFormat aFormat) : mDrawTarget(aDrawTarget) , mTexture(aTexture) , mFormat(aFormat) + , mOwnsCopy(false) { } SourceSurfaceD2DTarget::~SourceSurfaceD2DTarget() { // We don't need to do anything special here to notify our mDrawTarget. It must // already have cleared its mSnapshot field, otherwise this object would // be kept alive. + if (mOwnsCopy) { + IntSize size = GetSize(); + + DrawTargetD2D::mVRAMUsageSS -= size.width * size.height * BytesPerPixel(mFormat); + } } IntSize SourceSurfaceD2DTarget::GetSize() const { D3D10_TEXTURE2D_DESC desc; mTexture->GetDesc(&desc); @@ -93,16 +100,19 @@ SourceSurfaceD2DTarget::DrawTargetWillCh mTexture->GetDesc(&desc); // Get a copy of the surface data so the content at snapshot time was saved. Factory::GetDirect3D10Device()->CreateTexture2D(&desc, NULL, byRef(mTexture)); Factory::GetDirect3D10Device()->CopyResource(mTexture, oldTexture); mBitmap = NULL; + DrawTargetD2D::mVRAMUsageSS += desc.Width * desc.Height * BytesPerPixel(mFormat); + mOwnsCopy = true; + // We now no longer depend on the source surface content remaining the same. MarkIndependent(); } ID2D1Bitmap* SourceSurfaceD2DTarget::GetBitmap(ID2D1RenderTarget *aRT) { if (mBitmap) {
--- a/gfx/2d/SourceSurfaceD2DTarget.h +++ b/gfx/2d/SourceSurfaceD2DTarget.h @@ -47,16 +47,17 @@ private: RefPtr<ID2D1Bitmap> mBitmap; // Non-null if this is a "lazy copy" of the given draw target. // Null if we've made a copy. The target is not kept alive, otherwise we'd // have leaks since it might keep us alive. If the target is destroyed, it // will notify us. DrawTargetD2D* mDrawTarget; mutable RefPtr<ID3D10Texture2D> mTexture; SurfaceFormat mFormat; + bool mOwnsCopy; }; class DataSourceSurfaceD2DTarget : public DataSourceSurface { public: DataSourceSurfaceD2DTarget(); ~DataSourceSurfaceD2DTarget();
--- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -113,16 +113,45 @@ NS_MEMORY_REPORTER_IMPLEMENT( "gfx-d2d-surfacevram", KIND_OTHER, UNITS_BYTES, GetD2DSurfaceVramUsage, "Video memory used by D2D surfaces.") #endif +namespace +{ + +PRInt64 GetD2DVRAMUsageDrawTarget() { + return mozilla::gfx::Factory::GetD2DVRAMUsageDrawTarget(); +} + +PRInt64 GetD2DVRAMUsageSourceSurface() { + return mozilla::gfx::Factory::GetD2DVRAMUsageSourceSurface(); +} + +} // anonymous namespace + +NS_MEMORY_REPORTER_IMPLEMENT( + D2DVRAMDT, + "gfx-d2d-vram-drawtarget", + KIND_OTHER, + UNITS_BYTES, + GetD2DVRAMUsageDrawTarget, + "Video memory used by D2D DrawTargets.") + +NS_MEMORY_REPORTER_IMPLEMENT( + D2DVRAMSS, + "gfx-d2d-vram-sourcesurface", + KIND_OTHER, + UNITS_BYTES, + GetD2DVRAMUsageSourceSurface, + "Video memory used by D2D SourceSurfaces.") + #define GFX_USE_CLEARTYPE_ALWAYS "gfx.font_rendering.cleartype.always_use_for_content" #define GFX_DOWNLOADABLE_FONTS_USE_CLEARTYPE "gfx.font_rendering.cleartype.use_for_downloadable_fonts" #define GFX_CLEARTYPE_PARAMS "gfx.font_rendering.cleartype_params." #define GFX_CLEARTYPE_PARAMS_GAMMA "gfx.font_rendering.cleartype_params.gamma" #define GFX_CLEARTYPE_PARAMS_CONTRAST "gfx.font_rendering.cleartype_params.enhanced_contrast" #define GFX_CLEARTYPE_PARAMS_LEVEL "gfx.font_rendering.cleartype_params.cleartype_level" #define GFX_CLEARTYPE_PARAMS_STRUCTURE "gfx.font_rendering.cleartype_params.pixel_structure" @@ -325,16 +354,18 @@ gfxWindowsPlatform::gfxWindowsPlatform() mScreenDC = GetDC(NULL); #ifdef CAIRO_HAS_D2D_SURFACE NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(D2DCache)); NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(D2DVram)); mD2DDevice = nsnull; #endif + NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(D2DVRAMDT)); + NS_RegisterMemoryReporter(new NS_MEMORY_REPORTER_NAME(D2DVRAMSS)); UpdateRenderMode(); #ifdef ENABLE_GPU_MEM_REPORTER mGPUAdapterMultiReporter = new GPUAdapterMultiReporter(); NS_RegisterMemoryMultiReporter(mGPUAdapterMultiReporter); #endif }