From a6633f839610eb0cad743cd0b3144c8c44784a67 Mon Sep 17 00:00:00 2001 From: Nicholas Cameron Date: Tue, 24 Sep 2013 10:59:26 +1200 Subject: [PATCH] Bug 915940. Memory reporter for memory image surfaces. r=njn,mattwoodrow --- gfx/layers/client/TextureClient.cpp | 4 +++- gfx/layers/composite/TextureHost.cpp | 3 +++ gfx/layers/ipc/ISurfaceAllocator.cpp | 6 ++++- gfx/layers/ipc/ISurfaceAllocator.h | 36 ++++++++++++++++++++++++++++ gfx/thebes/gfxPlatform.cpp | 3 +++ 5 files changed, 50 insertions(+), 2 deletions(-) diff --git a/gfx/layers/client/TextureClient.cpp b/gfx/layers/client/TextureClient.cpp index 4c2c0e56972f..16dbcbaf5603 100644 --- a/gfx/layers/client/TextureClient.cpp +++ b/gfx/layers/client/TextureClient.cpp @@ -211,6 +211,7 @@ MemoryTextureClient::Allocate(uint32_t aSize) { MOZ_ASSERT(!mBuffer); mBuffer = new uint8_t[aSize]; + GfxHeapTexturesReporter::OnAlloc(mBuffer); mBufSize = aSize; return true; } @@ -228,9 +229,10 @@ MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable, MemoryTextureClient::~MemoryTextureClient() { MOZ_COUNT_DTOR(MemoryTextureClient); - if (ShouldDeallocateInDestructor()) { + if (ShouldDeallocateInDestructor() && mBuffer) { // if the buffer has never been shared we must deallocate it or ir would // leak. + GfxHeapTexturesReporter::OnFree(mBuffer); delete mBuffer; } } diff --git a/gfx/layers/composite/TextureHost.cpp b/gfx/layers/composite/TextureHost.cpp index b2358ab71e0f..1ddf229fe6ed 100644 --- a/gfx/layers/composite/TextureHost.cpp +++ b/gfx/layers/composite/TextureHost.cpp @@ -537,6 +537,9 @@ MemoryTextureHost::~MemoryTextureHost() void MemoryTextureHost::DeallocateSharedData() { + if (mBuffer) { + GfxHeapTexturesReporter::OnFree(mBuffer); + } delete[] mBuffer; } diff --git a/gfx/layers/ipc/ISurfaceAllocator.cpp b/gfx/layers/ipc/ISurfaceAllocator.cpp index b54ec9fe6dcd..4113fd6cd447 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.cpp +++ b/gfx/layers/ipc/ISurfaceAllocator.cpp @@ -27,6 +27,8 @@ using namespace mozilla::ipc; namespace mozilla { namespace layers { +mozilla::Atomic GfxHeapTexturesReporter::sAmount; + SharedMemory::SharedMemoryType OptimalShmemType() { return SharedMemory::TYPE_BASIC; @@ -88,6 +90,7 @@ ISurfaceAllocator::AllocSurfaceDescriptorWithCaps(const gfxIntSize& aSize, if (!data) { return false; } + GfxHeapTexturesReporter::OnAlloc(data); #ifdef XP_MACOSX // Workaround a bug in Quartz where drawing an a8 surface to another a8 // surface with OPERATOR_SOURCE still requires the destination to be clear. @@ -135,7 +138,8 @@ ISurfaceAllocator::DestroySharedSurface(SurfaceDescriptor* aSurface) case SurfaceDescriptor::TSurfaceDescriptorD3D10: break; case SurfaceDescriptor::TMemoryImage: - delete [] (unsigned char *)aSurface->get_MemoryImage().data(); + GfxHeapTexturesReporter::OnFree((uint8_t*)aSurface->get_MemoryImage().data()); + delete [] (uint8_t*)aSurface->get_MemoryImage().data(); break; case SurfaceDescriptor::Tnull_t: case SurfaceDescriptor::T__None: diff --git a/gfx/layers/ipc/ISurfaceAllocator.h b/gfx/layers/ipc/ISurfaceAllocator.h index df11d5c4570f..2679dfe0bfc7 100644 --- a/gfx/layers/ipc/ISurfaceAllocator.h +++ b/gfx/layers/ipc/ISurfaceAllocator.h @@ -11,6 +11,8 @@ #include "gfxTypes.h" #include "gfxPoint.h" // for gfxIntSize #include "mozilla/ipc/SharedMemory.h" // for SharedMemory, etc +#include "nsIMemoryReporter.h" // for MemoryUniReporter +#include "mozilla/Atomics.h" // for Atomic /* * FIXME [bjacob] *** PURE CRAZYNESS WARNING *** @@ -24,6 +26,8 @@ #endif class gfxSharedImageSurface; +class MemoryTextureClient; +class MemoryTextureHost; namespace base { class Thread; @@ -132,6 +136,38 @@ protected: ~ISurfaceAllocator() {} }; +class GfxHeapTexturesReporter MOZ_FINAL : public mozilla::MemoryUniReporter +{ +public: + GfxHeapTexturesReporter() + : MemoryUniReporter("explicit/gfx/heap-textures", KIND_HEAP, UNITS_BYTES, + "Heap memory shared between threads by texture clients and hosts.") + { +#ifdef DEBUG + // There must be only one instance of this class, due to |sAmount| + // being static. + static bool hasRun = false; + MOZ_ASSERT(!hasRun); + hasRun = true; +#endif + } + + static void OnAlloc(void* aPointer) + { + sAmount += MallocSizeOfOnAlloc(aPointer); + } + + static void OnFree(void* aPointer) + { + sAmount -= MallocSizeOfOnFree(aPointer); + } + +private: + int64_t Amount() MOZ_OVERRIDE { return sAmount; } + + static mozilla::Atomic sAmount; +}; + } // namespace } // namespace diff --git a/gfx/thebes/gfxPlatform.cpp b/gfx/thebes/gfxPlatform.cpp index 27527f05d235..05d4553d5dba 100644 --- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -10,6 +10,7 @@ #include "mozilla/layers/CompositorChild.h" #include "mozilla/layers/CompositorParent.h" #include "mozilla/layers/ImageBridgeChild.h" +#include "mozilla/layers/ISurfaceAllocator.h" // for GfxHeapTexturesReporter #include "prlog.h" #include "prenv.h" @@ -441,6 +442,8 @@ gfxPlatform::Init() false); CreateCMSOutputProfile(); + + NS_RegisterMemoryReporter(new GfxHeapTexturesReporter()); } void