Bug 821474 - Add memory reporting for Shmem and Memory texture clients. r=BenWa
This commit is contained in:
@@ -231,14 +231,16 @@ CompositableClient::RemoveTextureClient(TextureClient* aClient)
|
|||||||
MOZ_ASSERT(aClient);
|
MOZ_ASSERT(aClient);
|
||||||
mTexturesToRemove.AppendElement(TextureIDAndFlags(aClient->GetID(),
|
mTexturesToRemove.AppendElement(TextureIDAndFlags(aClient->GetID(),
|
||||||
aClient->GetFlags()));
|
aClient->GetFlags()));
|
||||||
if (!(aClient->GetFlags() & TEXTURE_DEALLOCATE_HOST)) {
|
TextureClientData* data = aClient->DropTextureData();
|
||||||
TextureClientData* data = aClient->DropTextureData();
|
if (data) {
|
||||||
if (data) {
|
if (!(aClient->GetFlags() & TEXTURE_DEALLOCATE_HOST)) {
|
||||||
mTexturesToRemoveCallbacks[aClient->GetID()] = data;
|
mTexturesToRemoveCallbacks[aClient->GetID()] = data;
|
||||||
|
} else {
|
||||||
|
data->ForgetSharedData();
|
||||||
|
delete data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
aClient->ClearID();
|
aClient->ClearID();
|
||||||
aClient->MarkInvalid();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
#include "mozilla/layers/YCbCrImageDataSerializer.h"
|
||||||
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
|
#include "nsDebug.h" // for NS_ASSERTION, NS_WARNING, etc
|
||||||
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
#include "nsTraceRefcnt.h" // for MOZ_COUNT_CTOR, etc
|
||||||
|
#include "nsIMemoryReporter.h"
|
||||||
|
|
||||||
#ifdef MOZ_ANDROID_OMTC
|
#ifdef MOZ_ANDROID_OMTC
|
||||||
# include "gfxReusableImageSurfaceWrapper.h"
|
# include "gfxReusableImageSurfaceWrapper.h"
|
||||||
@@ -35,6 +36,72 @@ using namespace mozilla::gl;
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds some memory reporting for the shared data.
|
||||||
|
*
|
||||||
|
* Due to the memory model of texture client/host we count memory only on the
|
||||||
|
* client side because:
|
||||||
|
* - If we count it also on the host side it would mean counting it twice since
|
||||||
|
* TextureClient/Host do not transfer ownership. They actually do share the data.
|
||||||
|
* - Counting on the client side means we get per app reports on B2G which is nice.
|
||||||
|
*
|
||||||
|
* When a texture client allocates its memory, we add the amount of bytes
|
||||||
|
* allocated (no suprise here).
|
||||||
|
* When we destroy the texture client there are two possibilities:
|
||||||
|
* - eiter the shared memory will be deallocated on the client-side in which
|
||||||
|
* case we basically count the deallocation where we deallocate the memory.
|
||||||
|
* - or the shared memory will be deallocated on the host process, but we still
|
||||||
|
* need to count it in the client process, since the memory reports are per
|
||||||
|
* process and we added the amount allocated in the client process. In this
|
||||||
|
* case we count the deallocation in TextureClientData::ForgetSharedData which
|
||||||
|
* is always called when the client gives up its references to the shared data
|
||||||
|
* to let the host deallocate it.
|
||||||
|
*
|
||||||
|
* More info about the lifetime of shared texture data here:
|
||||||
|
* https://wiki.mozilla.org/Platform/GFX/textures#Deallocating_the_shared_data
|
||||||
|
*/
|
||||||
|
class TextureClientReporter : public MemoryUniReporter
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TextureClientReporter(const char* name, uint32_t aKind)
|
||||||
|
: MemoryUniReporter(name, aKind, UNITS_BYTES,
|
||||||
|
"Texture data that is shared between the content process and the compositor process.")
|
||||||
|
, mAmount(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
int64_t Amount() MOZ_OVERRIDE { return mAmount; }
|
||||||
|
|
||||||
|
void Add(uint64_t val) { mAmount += val; }
|
||||||
|
|
||||||
|
void Remove(uint64_t val) { mAmount -= val; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
int64_t mAmount;
|
||||||
|
};
|
||||||
|
|
||||||
|
static TextureClientReporter* sMemoryTextureClientReporter = nullptr;
|
||||||
|
static TextureClientReporter* sShmemTextureClientReporter = nullptr;
|
||||||
|
|
||||||
|
TextureClientReporter* GetMemoryTextureReporter()
|
||||||
|
{
|
||||||
|
if (!sMemoryTextureClientReporter) {
|
||||||
|
sMemoryTextureClientReporter
|
||||||
|
= new TextureClientReporter("gfx-MemoryTexture", nsIMemoryReporter::KIND_HEAP);
|
||||||
|
NS_RegisterMemoryReporter(sMemoryTextureClientReporter);
|
||||||
|
}
|
||||||
|
return sMemoryTextureClientReporter;
|
||||||
|
}
|
||||||
|
|
||||||
|
TextureClientReporter* GetShmemTextureReporter()
|
||||||
|
{
|
||||||
|
if (!sShmemTextureClientReporter) {
|
||||||
|
sShmemTextureClientReporter
|
||||||
|
= new TextureClientReporter("gfx-ShmemTexture", nsIMemoryReporter::KIND_OTHER);
|
||||||
|
NS_RegisterMemoryReporter(sShmemTextureClientReporter);
|
||||||
|
}
|
||||||
|
return sShmemTextureClientReporter;
|
||||||
|
}
|
||||||
|
|
||||||
class ShmemTextureClientData : public TextureClientData
|
class ShmemTextureClientData : public TextureClientData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -49,12 +116,23 @@ public:
|
|||||||
MOZ_COUNT_CTOR(ShmemTextureClientData);
|
MOZ_COUNT_CTOR(ShmemTextureClientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DeallocateSharedData(ISurfaceAllocator* allocator)
|
virtual void DeallocateSharedData(ISurfaceAllocator* allocator) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mShmem.IsReadable());
|
||||||
|
GetShmemTextureReporter()->Remove(mShmem.Size<uint8_t>());
|
||||||
allocator->DeallocShmem(mShmem);
|
allocator->DeallocShmem(mShmem);
|
||||||
mShmem = ipc::Shmem();
|
mShmem = ipc::Shmem();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void ForgetSharedData() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mShmem.IsReadable());
|
||||||
|
// This is called when the shmem is about to be deallocated on the host
|
||||||
|
// side, but we must always count memory on the client side.
|
||||||
|
GetShmemTextureReporter()->Remove(mShmem.Size<uint8_t>());
|
||||||
|
mShmem = ipc::Shmem();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ipc::Shmem mShmem;
|
ipc::Shmem mShmem;
|
||||||
};
|
};
|
||||||
@@ -62,8 +140,9 @@ private:
|
|||||||
class MemoryTextureClientData : public TextureClientData
|
class MemoryTextureClientData : public TextureClientData
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
MemoryTextureClientData(uint8_t* aBuffer)
|
MemoryTextureClientData(uint8_t* aBuffer, uint64_t aBufferSize)
|
||||||
: mBuffer(aBuffer)
|
: mBuffer(aBuffer)
|
||||||
|
, mBufferSize(aBufferSize)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(MemoryTextureClientData);
|
MOZ_COUNT_CTOR(MemoryTextureClientData);
|
||||||
}
|
}
|
||||||
@@ -74,22 +153,35 @@ public:
|
|||||||
MOZ_COUNT_CTOR(MemoryTextureClientData);
|
MOZ_COUNT_CTOR(MemoryTextureClientData);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void DeallocateSharedData(ISurfaceAllocator*)
|
virtual void DeallocateSharedData(ISurfaceAllocator*) MOZ_OVERRIDE
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(mBuffer);
|
||||||
|
GetMemoryTextureReporter()->Remove(mBufferSize);
|
||||||
delete[] mBuffer;
|
delete[] mBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void ForgetSharedData() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
MOZ_ASSERT(mBuffer);
|
||||||
|
// This is called when the buffer is about to be deallocated on the host
|
||||||
|
// side, but we must always count memory on the client side.
|
||||||
|
GetMemoryTextureReporter()->Remove(mBufferSize);
|
||||||
|
mBuffer = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint8_t* mBuffer;
|
uint8_t* mBuffer;
|
||||||
|
uint64_t mBufferSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
TextureClientData*
|
TextureClientData*
|
||||||
MemoryTextureClient::DropTextureData()
|
MemoryTextureClient::DropTextureData()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IsValid());
|
||||||
if (!mBuffer) {
|
if (!mBuffer) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
TextureClientData* result = new MemoryTextureClientData(mBuffer);
|
TextureClientData* result = new MemoryTextureClientData(mBuffer, mBufSize);
|
||||||
MarkInvalid();
|
MarkInvalid();
|
||||||
mBuffer = nullptr;
|
mBuffer = nullptr;
|
||||||
return result;
|
return result;
|
||||||
@@ -98,6 +190,7 @@ MemoryTextureClient::DropTextureData()
|
|||||||
TextureClientData*
|
TextureClientData*
|
||||||
ShmemTextureClient::DropTextureData()
|
ShmemTextureClient::DropTextureData()
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(IsValid());
|
||||||
if (!mShmem.IsReadable()) {
|
if (!mShmem.IsReadable()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -155,6 +248,7 @@ ShmemTextureClient::Allocate(uint32_t aSize)
|
|||||||
MOZ_ASSERT(IsValid());
|
MOZ_ASSERT(IsValid());
|
||||||
ipc::SharedMemory::SharedMemoryType memType = OptimalShmemType();
|
ipc::SharedMemory::SharedMemoryType memType = OptimalShmemType();
|
||||||
mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
|
mAllocated = GetAllocator()->AllocUnsafeShmem(aSize, memType, &mShmem);
|
||||||
|
GetShmemTextureReporter()->Add(aSize);
|
||||||
return mAllocated;
|
return mAllocated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -187,9 +281,10 @@ ShmemTextureClient::ShmemTextureClient(CompositableClient* aCompositable,
|
|||||||
ShmemTextureClient::~ShmemTextureClient()
|
ShmemTextureClient::~ShmemTextureClient()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(ShmemTextureClient);
|
MOZ_COUNT_DTOR(ShmemTextureClient);
|
||||||
if (ShouldDeallocateInDestructor()) {
|
if (mShmem.IsReadable() && ShouldDeallocateInDestructor()) {
|
||||||
// if the buffer has never been shared we must deallocate it or ir would
|
// if the buffer has never been shared we must deallocate it or ir would
|
||||||
// leak.
|
// leak.
|
||||||
|
GetShmemTextureReporter()->Remove(mShmem.Size<uint8_t>());
|
||||||
mCompositable->GetForwarder()->DeallocShmem(mShmem);
|
mCompositable->GetForwarder()->DeallocShmem(mShmem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -212,6 +307,7 @@ MemoryTextureClient::Allocate(uint32_t aSize)
|
|||||||
MOZ_ASSERT(!mBuffer);
|
MOZ_ASSERT(!mBuffer);
|
||||||
mBuffer = new uint8_t[aSize];
|
mBuffer = new uint8_t[aSize];
|
||||||
mBufSize = aSize;
|
mBufSize = aSize;
|
||||||
|
GetMemoryTextureReporter()->Add(aSize);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,9 +324,10 @@ MemoryTextureClient::MemoryTextureClient(CompositableClient* aCompositable,
|
|||||||
MemoryTextureClient::~MemoryTextureClient()
|
MemoryTextureClient::~MemoryTextureClient()
|
||||||
{
|
{
|
||||||
MOZ_COUNT_DTOR(MemoryTextureClient);
|
MOZ_COUNT_DTOR(MemoryTextureClient);
|
||||||
if (ShouldDeallocateInDestructor()) {
|
if (mBuffer && ShouldDeallocateInDestructor()) {
|
||||||
// if the buffer has never been shared we must deallocate it or ir would
|
// if the buffer has never been shared we must deallocate it or ir would
|
||||||
// leak.
|
// leak.
|
||||||
|
GetMemoryTextureReporter()->Remove(mBufSize);
|
||||||
delete mBuffer;
|
delete mBuffer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -89,6 +89,18 @@ public:
|
|||||||
class TextureClientData {
|
class TextureClientData {
|
||||||
public:
|
public:
|
||||||
virtual void DeallocateSharedData(ISurfaceAllocator* allocator) = 0;
|
virtual void DeallocateSharedData(ISurfaceAllocator* allocator) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called just before telling the host side to deallocate the data.
|
||||||
|
*
|
||||||
|
* The reference to the shared data must be dropped without doing the deallocation
|
||||||
|
* because it is the host side that will deallocate the data.
|
||||||
|
* If there is a memory reproting mechanism in place for this type of data,
|
||||||
|
* the memory should be reported as deallocated. After this call, nothing on
|
||||||
|
* the client process should still have a reference to the shared data.
|
||||||
|
*/
|
||||||
|
virtual void ForgetSharedData() = 0;
|
||||||
|
|
||||||
virtual ~TextureClientData() {}
|
virtual ~TextureClientData() {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,11 @@ public:
|
|||||||
mBufferLocked = nullptr;
|
mBufferLocked = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void ForgetSharedData() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
mBufferLocked = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RefPtr<GraphicBufferLocked> mBufferLocked;
|
RefPtr<GraphicBufferLocked> mBufferLocked;
|
||||||
};
|
};
|
||||||
@@ -66,6 +71,11 @@ public:
|
|||||||
mGrallocActor = nullptr;
|
mGrallocActor = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void ForgetSharedData() MOZ_OVERRIDE
|
||||||
|
{
|
||||||
|
mGrallocActor = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
GrallocBufferActor* mGrallocActor;
|
GrallocBufferActor* mGrallocActor;
|
||||||
};
|
};
|
||||||
@@ -73,6 +83,7 @@ private:
|
|||||||
TextureClientData*
|
TextureClientData*
|
||||||
GrallocTextureClientOGL::DropTextureData()
|
GrallocTextureClientOGL::DropTextureData()
|
||||||
{
|
{
|
||||||
|
MarkInvalid();
|
||||||
if (mBufferLocked) {
|
if (mBufferLocked) {
|
||||||
TextureClientData* result = new GraphicBufferLockedTextureClientData(mBufferLocked);
|
TextureClientData* result = new GraphicBufferLockedTextureClientData(mBufferLocked);
|
||||||
mBufferLocked = nullptr;
|
mBufferLocked = nullptr;
|
||||||
|
|||||||
Reference in New Issue
Block a user