зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1492930 - Part 1. Expose composition of shared surfaces cache to allow memory reporting. r=nical
This exposes methods to capture a snapshot of the SharedSurfacesParent cache for memory reporting purposes. It yields the identifiers, image properties and references to images mapped in the cache. This will be used by the compositor process to list everything it has mapped into its memory space. It will also be used by the content processes / main process to list images that specific process had mapped into the compositor process. This will allow us to easily identify what images remain in the compositor process, but are missing from the surface cache.
This commit is contained in:
Родитель
e65c479846
Коммит
3aedcdc649
|
@ -43,6 +43,7 @@ public:
|
|||
, mConsumers(0)
|
||||
, mFormat(SurfaceFormat::UNKNOWN)
|
||||
, mCreatorPid(0)
|
||||
, mCreatorRef(true)
|
||||
{ }
|
||||
|
||||
bool Init(const IntSize& aSize,
|
||||
|
@ -79,12 +80,30 @@ public:
|
|||
return ++mConsumers == 1;
|
||||
}
|
||||
|
||||
bool RemoveConsumer()
|
||||
bool RemoveConsumer(bool aForCreator)
|
||||
{
|
||||
MOZ_ASSERT(mConsumers > 0);
|
||||
if (aForCreator) {
|
||||
if (!mCreatorRef) {
|
||||
MOZ_ASSERT_UNREACHABLE("Already released creator reference!");
|
||||
return false;
|
||||
}
|
||||
mCreatorRef = false;
|
||||
}
|
||||
return --mConsumers == 0;
|
||||
}
|
||||
|
||||
uint32_t GetConsumers() const
|
||||
{
|
||||
MOZ_ASSERT(mConsumers > 0);
|
||||
return mConsumers;
|
||||
}
|
||||
|
||||
bool HasCreatorRef() const
|
||||
{
|
||||
return mCreatorRef;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t GetDataLength() const
|
||||
{
|
||||
|
@ -102,6 +121,7 @@ private:
|
|||
RefPtr<SharedMemoryBasic> mBuf;
|
||||
SurfaceFormat mFormat;
|
||||
base::ProcessId mCreatorPid;
|
||||
bool mCreatorRef;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -289,6 +289,15 @@ CompositorManagerParent::RecvRemoveSharedSurface(const wr::ExternalImageId& aId)
|
|||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
CompositorManagerParent::RecvReportSharedSurfacesMemory(ReportSharedSurfacesMemoryResolver&& aResolver)
|
||||
{
|
||||
SharedSurfacesMemoryReport report;
|
||||
SharedSurfacesParent::AccumulateMemoryReport(OtherPid(), report);
|
||||
aResolver(std::move(report));
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult
|
||||
CompositorManagerParent::RecvNotifyMemoryPressure()
|
||||
{
|
||||
|
|
|
@ -43,6 +43,7 @@ public:
|
|||
mozilla::ipc::IPCResult RecvAddSharedSurface(const wr::ExternalImageId& aId,
|
||||
const SurfaceDescriptorShared& aDesc) override;
|
||||
mozilla::ipc::IPCResult RecvRemoveSharedSurface(const wr::ExternalImageId& aId) override;
|
||||
mozilla::ipc::IPCResult RecvReportSharedSurfacesMemory(ReportSharedSurfacesMemoryResolver&&) override;
|
||||
|
||||
virtual mozilla::ipc::IPCResult RecvNotifyMemoryPressure() override;
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ using mozilla::ipc::SharedMemoryBasic::Handle from "mozilla/ipc/SharedMemoryBasi
|
|||
using mozilla::layers::CompositorOptions from "mozilla/layers/CompositorOptions.h";
|
||||
using mozilla::wr::ExternalImageId from "mozilla/webrender/WebRenderTypes.h";
|
||||
using mozilla::wr::MemoryReport from "mozilla/webrender/WebRenderTypes.h";
|
||||
using mozilla::layers::SharedSurfacesMemoryReport from "mozilla/layers/SharedSurfacesMemoryReport.h";
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
@ -76,6 +77,7 @@ parent:
|
|||
|
||||
async AddSharedSurface(ExternalImageId aId, SurfaceDescriptorShared aDesc);
|
||||
async RemoveSharedSurface(ExternalImageId aId);
|
||||
async ReportSharedSurfacesMemory() returns (SharedSurfacesMemoryReport aReport);
|
||||
|
||||
async NotifyMemoryPressure();
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@ namespace layers {
|
|||
|
||||
using namespace mozilla::gfx;
|
||||
|
||||
/* static */ UserDataKey SharedSurfacesChild::sSharedKey;
|
||||
|
||||
class SharedSurfacesChild::ImageKeyData final
|
||||
{
|
||||
public:
|
||||
|
@ -224,7 +226,6 @@ SharedSurfacesChild::ShareInternal(SourceSurfaceSharedData* aSurface,
|
|||
return NS_ERROR_NOT_INITIALIZED;
|
||||
}
|
||||
|
||||
static UserDataKey sSharedKey;
|
||||
SharedUserData* data =
|
||||
static_cast<SharedUserData*>(aSurface->GetUserData(&sSharedKey));
|
||||
if (!data) {
|
||||
|
@ -455,5 +456,20 @@ SharedSurfacesChild::Unshare(const wr::ExternalImageId& aId,
|
|||
}
|
||||
}
|
||||
|
||||
/* static */ Maybe<wr::ExternalImageId>
|
||||
SharedSurfacesChild::GetExternalId(const SourceSurfaceSharedData* aSurface)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aSurface);
|
||||
|
||||
SharedUserData* data =
|
||||
static_cast<SharedUserData*>(aSurface->GetUserData(&sSharedKey));
|
||||
if (!data || !data->IsShared()) {
|
||||
return Nothing();
|
||||
}
|
||||
|
||||
return Some(data->Id());
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
#include <stddef.h> // for size_t
|
||||
#include <stdint.h> // for uint32_t, uint64_t
|
||||
#include "mozilla/Attributes.h" // for override
|
||||
#include "mozilla/Maybe.h" // for Maybe
|
||||
#include "mozilla/RefPtr.h" // for already_AddRefed
|
||||
#include "mozilla/StaticPtr.h" // for StaticRefPtr
|
||||
#include "mozilla/gfx/UserData.h" // for UserDataKey
|
||||
#include "mozilla/webrender/WebRenderTypes.h" // for wr::ImageKey
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -71,6 +73,13 @@ public:
|
|||
wr::IpcResourceUpdateQueue& aResources,
|
||||
wr::ImageKey& aKey);
|
||||
|
||||
/**
|
||||
* Get the external ID, if any, bound to the shared surface. Used for memory
|
||||
* reporting purposes.
|
||||
*/
|
||||
static Maybe<wr::ExternalImageId>
|
||||
GetExternalId(const gfx::SourceSurfaceSharedData* aSurface);
|
||||
|
||||
private:
|
||||
SharedSurfacesChild() = delete;
|
||||
~SharedSurfacesChild() = delete;
|
||||
|
@ -83,6 +92,8 @@ private:
|
|||
|
||||
static void Unshare(const wr::ExternalImageId& aId, nsTArray<ImageKeyData>& aKeys);
|
||||
static void DestroySharedUserData(void* aClosure);
|
||||
|
||||
static gfx::UserDataKey sSharedKey;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
|
|
|
@ -0,0 +1,93 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef MOZILLA_GFX_SHAREDSURFACESMEMORYREPORT_H
|
||||
#define MOZILLA_GFX_SHAREDSURFACESMEMORYREPORT_H
|
||||
|
||||
#include <cstdint> // for uint32_t
|
||||
#include <unordered_map>
|
||||
#include "ipc/IPCMessageUtils.h"
|
||||
#include "mozilla/gfx/Point.h" // for IntSize
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
|
||||
class SharedSurfacesMemoryReport final
|
||||
{
|
||||
public:
|
||||
class SurfaceEntry final {
|
||||
public:
|
||||
base::ProcessId mCreatorPid;
|
||||
gfx::IntSize mSize;
|
||||
int32_t mStride;
|
||||
uint32_t mConsumers;
|
||||
bool mCreatorRef;
|
||||
};
|
||||
|
||||
std::unordered_map<uint64_t, SurfaceEntry> mSurfaces;
|
||||
};
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
||||
namespace IPC {
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::layers::SharedSurfacesMemoryReport>
|
||||
{
|
||||
typedef mozilla::layers::SharedSurfacesMemoryReport paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam) {
|
||||
WriteParam(aMsg, aParam.mSurfaces);
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
return ReadParam(aMsg, aIter, &aResult->mSurfaces);
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::layers::SharedSurfacesMemoryReport::SurfaceEntry>
|
||||
: public PlainOldDataSerializer<mozilla::layers::SharedSurfacesMemoryReport::SurfaceEntry>
|
||||
{
|
||||
};
|
||||
|
||||
template<class KeyType, class DataType>
|
||||
struct ParamTraits<std::unordered_map<KeyType, DataType>>
|
||||
{
|
||||
typedef std::unordered_map<KeyType, DataType> paramType;
|
||||
|
||||
static void Write(Message* aMsg, const paramType& aParam) {
|
||||
WriteParam(aMsg, aParam.size());
|
||||
for (auto i = aParam.begin(); i != aParam.end(); ++i) {
|
||||
WriteParam(aMsg, i->first);
|
||||
WriteParam(aMsg, i->second);
|
||||
}
|
||||
}
|
||||
|
||||
static bool Read(const Message* aMsg, PickleIterator* aIter, paramType* aResult)
|
||||
{
|
||||
size_t count;
|
||||
if (!ReadParam(aMsg, aIter, &count)) {
|
||||
return false;
|
||||
}
|
||||
for (; count > 0; --count) {
|
||||
KeyType k;
|
||||
DataType v;
|
||||
if (!ReadParam(aMsg, aIter, &k) ||
|
||||
!ReadParam(aMsg, aIter, &v)) {
|
||||
return false;
|
||||
}
|
||||
aResult->insert(std::make_pair(std::move(k), std::move(v)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace IPC
|
||||
|
||||
#endif
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
#include "SharedSurfacesParent.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/gfx/GPUProcessManager.h"
|
||||
#include "mozilla/layers/SharedSurfacesMemoryReport.h"
|
||||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/webrender/RenderSharedSurfaceTextureHost.h"
|
||||
|
@ -85,7 +87,7 @@ SharedSurfacesParent::Acquire(const wr::ExternalImageId& aId)
|
|||
}
|
||||
|
||||
/* static */ bool
|
||||
SharedSurfacesParent::Release(const wr::ExternalImageId& aId)
|
||||
SharedSurfacesParent::Release(const wr::ExternalImageId& aId, bool aForCreator)
|
||||
{
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (!sInstance) {
|
||||
|
@ -99,7 +101,7 @@ SharedSurfacesParent::Release(const wr::ExternalImageId& aId)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (surface->RemoveConsumer()) {
|
||||
if (surface->RemoveConsumer(aForCreator)) {
|
||||
wr::RenderThread::Get()->UnregisterExternalImage(id);
|
||||
sInstance->mSurfaces.Remove(id);
|
||||
}
|
||||
|
@ -143,7 +145,7 @@ SharedSurfacesParent::RemoveSameProcess(const wr::ExternalImageId& aId)
|
|||
{
|
||||
MOZ_ASSERT(XRE_IsParentProcess());
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
Release(aId);
|
||||
Release(aId, /* aForCreator */ true);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
@ -158,7 +160,9 @@ SharedSurfacesParent::DestroyProcess(base::ProcessId aPid)
|
|||
// lot of surfaces still bound that require unmapping.
|
||||
for (auto i = sInstance->mSurfaces.Iter(); !i.Done(); i.Next()) {
|
||||
SourceSurfaceSharedDataWrapper* surface = i.Data();
|
||||
if (surface->GetCreatorPid() == aPid && surface->RemoveConsumer()) {
|
||||
if (surface->GetCreatorPid() == aPid &&
|
||||
surface->HasCreatorRef() &&
|
||||
surface->RemoveConsumer(/* aForCreator */ true)) {
|
||||
wr::RenderThread::Get()->UnregisterExternalImage(i.Key());
|
||||
i.Remove();
|
||||
}
|
||||
|
@ -200,9 +204,57 @@ SharedSurfacesParent::Add(const wr::ExternalImageId& aId,
|
|||
/* static */ void
|
||||
SharedSurfacesParent::Remove(const wr::ExternalImageId& aId)
|
||||
{
|
||||
DebugOnly<bool> rv = Release(aId);
|
||||
DebugOnly<bool> rv = Release(aId, /* aForCreator */ true);
|
||||
MOZ_ASSERT(rv);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
SharedSurfacesParent::AccumulateMemoryReport(base::ProcessId aPid,
|
||||
SharedSurfacesMemoryReport& aReport)
|
||||
{
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (!sInstance) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto i = sInstance->mSurfaces.ConstIter(); !i.Done(); i.Next()) {
|
||||
SourceSurfaceSharedDataWrapper* surface = i.Data();
|
||||
if (surface->GetCreatorPid() == aPid) {
|
||||
aReport.mSurfaces.insert(std::make_pair(i.Key(),
|
||||
SharedSurfacesMemoryReport::SurfaceEntry {
|
||||
aPid, surface->GetSize(), surface->Stride(),
|
||||
surface->GetConsumers(), surface->HasCreatorRef() }));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ bool
|
||||
SharedSurfacesParent::AccumulateMemoryReport(SharedSurfacesMemoryReport& aReport)
|
||||
{
|
||||
if (XRE_IsParentProcess()) {
|
||||
GPUProcessManager* gpm = GPUProcessManager::Get();
|
||||
if (!gpm || gpm->GPUProcessPid() != -1) {
|
||||
return false;
|
||||
}
|
||||
} else if (!XRE_IsGPUProcess()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
StaticMutexAutoLock lock(sMutex);
|
||||
if (!sInstance) {
|
||||
return true;
|
||||
}
|
||||
|
||||
for (auto i = sInstance->mSurfaces.ConstIter(); !i.Done(); i.Next()) {
|
||||
SourceSurfaceSharedDataWrapper* surface = i.Data();
|
||||
aReport.mSurfaces.insert(std::make_pair(i.Key(),
|
||||
SharedSurfacesMemoryReport::SurfaceEntry {
|
||||
surface->GetCreatorPid(), surface->GetSize(), surface->Stride(),
|
||||
surface->GetConsumers(), surface->HasCreatorRef() }));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace layers
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -29,6 +29,7 @@ class SourceSurfaceSharedDataWrapper;
|
|||
namespace layers {
|
||||
|
||||
class SharedSurfacesChild;
|
||||
class SharedSurfacesMemoryReport;
|
||||
|
||||
class SharedSurfacesParent final
|
||||
{
|
||||
|
@ -44,7 +45,8 @@ public:
|
|||
static already_AddRefed<gfx::DataSourceSurface>
|
||||
Acquire(const wr::ExternalImageId& aId);
|
||||
|
||||
static bool Release(const wr::ExternalImageId& aId);
|
||||
static bool Release(const wr::ExternalImageId& aId,
|
||||
bool aForCreator = false);
|
||||
|
||||
static void Add(const wr::ExternalImageId& aId,
|
||||
const SurfaceDescriptorShared& aDesc,
|
||||
|
@ -54,6 +56,11 @@ public:
|
|||
|
||||
static void DestroyProcess(base::ProcessId aPid);
|
||||
|
||||
static void AccumulateMemoryReport(base::ProcessId aPid,
|
||||
SharedSurfacesMemoryReport& aReport);
|
||||
|
||||
static bool AccumulateMemoryReport(SharedSurfacesMemoryReport& aReport);
|
||||
|
||||
~SharedSurfacesParent();
|
||||
|
||||
private:
|
||||
|
|
|
@ -196,6 +196,7 @@ EXPORTS.mozilla.layers += [
|
|||
'ipc/SharedPlanarYCbCrImage.h',
|
||||
'ipc/SharedRGBImage.h',
|
||||
'ipc/SharedSurfacesChild.h',
|
||||
'ipc/SharedSurfacesMemoryReport.h',
|
||||
'ipc/SharedSurfacesParent.h',
|
||||
'ipc/SynchronousTask.h',
|
||||
'ipc/TextureForwarder.h',
|
||||
|
|
Загрузка…
Ссылка в новой задаче