diff --git a/gfx/layers/d3d11/TextureD3D11.cpp b/gfx/layers/d3d11/TextureD3D11.cpp index c7be1fe8f687..57db2dcd1759 100644 --- a/gfx/layers/d3d11/TextureD3D11.cpp +++ b/gfx/layers/d3d11/TextureD3D11.cpp @@ -364,6 +364,54 @@ TextureClientD3D11::BorrowDrawTarget() return mDrawTarget; } +static const GUID sD3D11TextureUsage = +{ 0xd89275b0, 0x6c7d, 0x4038, { 0xb5, 0xfa, 0x4d, 0x87, 0x16, 0xd5, 0xcc, 0x4e } }; + +/* This class get's it's lifetime tied to a D3D texture + * and increments memory usage on construction and decrements + * on destruction */ +class TextureMemoryMeasurer : public IUnknown +{ +public: + TextureMemoryMeasurer(size_t aMemoryUsed) + { + mMemoryUsed = aMemoryUsed; + gfxWindowsPlatform::sD3D11MemoryUsed += mMemoryUsed; + mRefCnt = 0; + } + STDMETHODIMP_(ULONG) AddRef() { + mRefCnt++; + return mRefCnt; + } + STDMETHODIMP QueryInterface(REFIID riid, + void **ppvObject) + { + IUnknown *punk = nullptr; + if (riid == IID_IUnknown) { + punk = this; + } + *ppvObject = punk; + if (punk) { + punk->AddRef(); + return S_OK; + } else { + return E_NOINTERFACE; + } + } + + STDMETHODIMP_(ULONG) Release() { + int refCnt = --mRefCnt; + if (refCnt == 0) { + gfxWindowsPlatform::sD3D11MemoryUsed -= mMemoryUsed; + delete this; + } + return refCnt; + } +private: + int mRefCnt; + int mMemoryUsed; +}; + bool TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlags aFlags) { @@ -386,6 +434,14 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag newDesc.MiscFlags = D3D11_RESOURCE_MISC_SHARED; hr = d3d11device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture)); + if (FAILED(hr)) { + gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr); + return false; + } + mTexture->SetPrivateDataInterface(sD3D11TextureUsage, + new TextureMemoryMeasurer(newDesc.Width * newDesc.Height * + (mFormat == SurfaceFormat::A8 ? + 1 : 4))); } else { ID3D10Device* device = gfxWindowsPlatform::GetPlatform()->GetD3D10Device(); @@ -397,11 +453,15 @@ TextureClientD3D11::AllocateForSurface(gfx::IntSize aSize, TextureAllocationFlag newDesc.MiscFlags = D3D10_RESOURCE_MISC_SHARED; hr = device->CreateTexture2D(&newDesc, nullptr, byRef(mTexture10)); - } + if (FAILED(hr)) { + gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D10] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr); + return false; + } + mTexture10->SetPrivateDataInterface(sD3D11TextureUsage, + new TextureMemoryMeasurer(newDesc.Width * newDesc.Height * + (mFormat == SurfaceFormat::A8 ? + 1 : 4))); - if (FAILED(hr)) { - gfxCriticalError(CriticalLog::DefaultOptions(Factory::ReasonableSurfaceSize(aSize))) << "[D3D11] 2 CreateTexture2D failure " << aSize << " Code: " << gfx::hexa(hr); - return false; } // Defer clearing to the next time we lock to avoid an extra (expensive) lock. diff --git a/gfx/thebes/gfxWindowsPlatform.cpp b/gfx/thebes/gfxWindowsPlatform.cpp index 317cc3d5b98c..d3c6871795c7 100644 --- a/gfx/thebes/gfxWindowsPlatform.cpp +++ b/gfx/thebes/gfxWindowsPlatform.cpp @@ -325,6 +325,25 @@ public: NS_IMPL_ISUPPORTS(GPUAdapterReporter, nsIMemoryReporter) + +Atomic gfxWindowsPlatform::sD3D11MemoryUsed; + +class D3D11TextureReporter MOZ_FINAL : public nsIMemoryReporter +{ +public: + NS_DECL_ISUPPORTS + + NS_IMETHOD CollectReports(nsIHandleReportCallback *aHandleReport, + nsISupports* aData, bool aAnonymize) MOZ_OVERRIDE + { + return MOZ_COLLECT_REPORT("d3d11-shared-textures", KIND_OTHER, UNITS_BYTES, + gfxWindowsPlatform::sD3D11MemoryUsed, + "Memory used for D3D11 shared textures"); + } +}; + +NS_IMPL_ISUPPORTS(D3D11TextureReporter, nsIMemoryReporter) + gfxWindowsPlatform::gfxWindowsPlatform() : mD3D11DeviceInitialized(false) , mIsWARP(false) @@ -352,6 +371,7 @@ gfxWindowsPlatform::gfxWindowsPlatform() UpdateRenderMode(); RegisterStrongMemoryReporter(new GPUAdapterReporter()); + RegisterStrongMemoryReporter(new D3D11TextureReporter()); } gfxWindowsPlatform::~gfxWindowsPlatform() diff --git a/gfx/thebes/gfxWindowsPlatform.h b/gfx/thebes/gfxWindowsPlatform.h index 3ded93a6c180..b5d07b818450 100644 --- a/gfx/thebes/gfxWindowsPlatform.h +++ b/gfx/thebes/gfxWindowsPlatform.h @@ -22,6 +22,7 @@ #include "gfxPlatform.h" #include "gfxTypes.h" #include "mozilla/Attributes.h" +#include "mozilla/Atomics.h" #include "nsTArray.h" #include "nsDataHashtable.h" @@ -252,6 +253,8 @@ public: bool IsWARP() { return mIsWARP; } + static mozilla::Atomic sD3D11MemoryUsed; + protected: RenderMode mRenderMode;