Bug 1365927 - Part 5. Make PCompositorManager the manager protocol of PCompositorBridge. r=dvander

This commit is contained in:
Andrew Osmond 2017-06-13 15:20:00 -04:00
Родитель c17a8c1ea1
Коммит 7dc8c4cc9f
12 изменённых файлов: 294 добавлений и 181 удалений

Просмотреть файл

@ -13,6 +13,7 @@
#include "base/task.h" // for NewRunnableMethod, etc
#include "gfxPrefs.h"
#include "mozilla/dom/TabGroup.h"
#include "mozilla/layers/CompositorManagerChild.h"
#include "mozilla/layers/ImageBridgeChild.h"
#include "mozilla/layers/APZChild.h"
#include "mozilla/layers/IAPZCTreeManager.h"
@ -77,17 +78,18 @@ static StaticRefPtr<CompositorBridgeChild> sCompositorBridge;
Atomic<int32_t> KnowsCompositor::sSerialCounter(0);
CompositorBridgeChild::CompositorBridgeChild(LayerManager *aLayerManager, uint32_t aNamespace)
: mLayerManager(aLayerManager)
, mIdNamespace(aNamespace)
CompositorBridgeChild::CompositorBridgeChild(CompositorManagerChild *aManager)
: mCompositorManager(aManager)
, mIdNamespace(0)
, mResourceId(0)
, mCanSend(false)
, mActorDestroyed(false)
, mFwdTransactionId(0)
, mDeviceResetSequenceNumber(0)
, mMessageLoop(MessageLoop::current())
, mProcessToken(0)
, mSectionAllocator(nullptr)
{
MOZ_ASSERT(mIdNamespace);
MOZ_ASSERT(NS_IsMainThread());
}
@ -104,12 +106,18 @@ CompositorBridgeChild::IsSameProcess() const
return OtherPid() == base::GetCurrentProcId();
}
static void DeferredDestroyCompositor(RefPtr<CompositorBridgeParent> aCompositorBridgeParent,
RefPtr<CompositorBridgeChild> aCompositorBridgeChild)
void
CompositorBridgeChild::AfterDestroy()
{
aCompositorBridgeChild->Close();
// Note that we cannot rely upon mCanSend here because we already set that to
// false to prevent normal IPDL calls from being made after SendWillClose.
// The only time we should not issue Send__delete__ is if the actor is already
// destroyed, e.g. the compositor process crashed.
if (!mActorDestroyed) {
Send__delete__(this);
}
if (sCompositorBridge == aCompositorBridgeChild) {
if (sCompositorBridge == this) {
sCompositorBridge = nullptr;
}
}
@ -183,8 +191,9 @@ CompositorBridgeChild::Destroy()
// handle compositor desctruction.
// From now on we can't send any message message.
MessageLoop::current()->PostTask(
NewRunnableFunction(DeferredDestroyCompositor, mCompositorBridgeParent, selfRef));
MessageLoop::current()->PostTask(NewRunnableMethod(
"CompositorBridgeChild::AfterDestroy",
selfRef, &CompositorBridgeChild::AfterDestroy));
}
// static
@ -209,28 +218,11 @@ CompositorBridgeChild::LookupCompositorFrameMetrics(const FrameMetrics::ViewID a
return false;
}
/* static */ bool
CompositorBridgeChild::InitForContent(Endpoint<PCompositorBridgeChild>&& aEndpoint, uint32_t aNamespace)
{
// There's only one compositor per child process.
MOZ_ASSERT(!sCompositorBridge);
RefPtr<CompositorBridgeChild> child(new CompositorBridgeChild(nullptr, aNamespace));
if (!aEndpoint.Bind(child)) {
NS_RUNTIMEABORT("Couldn't Open() Compositor channel.");
return false;
}
child->InitIPDL();
// We release this ref in DeferredDestroyCompositor.
sCompositorBridge = child;
return true;
}
/* static */ bool
CompositorBridgeChild::ReinitForContent(Endpoint<PCompositorBridgeChild>&& aEndpoint, uint32_t aNamespace)
void
CompositorBridgeChild::InitForContent(uint32_t aNamespace)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aNamespace);
if (RefPtr<CompositorBridgeChild> old = sCompositorBridge.forget()) {
// Note that at this point, ActorDestroy may not have been called yet,
@ -240,59 +232,25 @@ CompositorBridgeChild::ReinitForContent(Endpoint<PCompositorBridgeChild>&& aEndp
old->Destroy();
}
return InitForContent(Move(aEndpoint), aNamespace);
}
CompositorBridgeParent*
CompositorBridgeChild::InitSameProcess(widget::CompositorWidget* aWidget,
const uint64_t& aLayerTreeId,
CSSToLayoutDeviceScale aScale,
const CompositorOptions& aOptions,
bool aUseExternalSurface,
const gfx::IntSize& aSurfaceSize)
{
TimeDuration vsyncRate =
gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
mCompositorBridgeParent =
new CompositorBridgeParent(aScale, vsyncRate, aOptions, aUseExternalSurface, aSurfaceSize);
bool ok = Open(mCompositorBridgeParent->GetIPCChannel(),
CompositorThreadHolder::Loop(),
ipc::ChildSide);
MOZ_RELEASE_ASSERT(ok);
InitIPDL();
mCompositorBridgeParent->InitSameProcess(aWidget, aLayerTreeId);
return mCompositorBridgeParent;
}
/* static */ RefPtr<CompositorBridgeChild>
CompositorBridgeChild::CreateRemote(const uint64_t& aProcessToken,
LayerManager* aLayerManager,
Endpoint<PCompositorBridgeChild>&& aEndpoint,
uint32_t aNamespace)
{
RefPtr<CompositorBridgeChild> child = new CompositorBridgeChild(aLayerManager, aNamespace);
if (!aEndpoint.Bind(child)) {
return nullptr;
}
child->InitIPDL();
child->mProcessToken = aProcessToken;
return child;
}
void
CompositorBridgeChild::InitIPDL()
{
mCanSend = true;
AddRef();
mIdNamespace = aNamespace;
sCompositorBridge = this;
}
void
CompositorBridgeChild::DeallocPCompositorBridgeChild()
CompositorBridgeChild::InitForWidget(uint64_t aProcessToken,
LayerManager* aLayerManager,
uint32_t aNamespace)
{
Release();
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aProcessToken);
MOZ_ASSERT(aLayerManager);
MOZ_ASSERT(aNamespace);
mCanSend = true;
mProcessToken = aProcessToken;
mLayerManager = aLayerManager;
mIdNamespace = aNamespace;
}
/*static*/ CompositorBridgeChild*
@ -584,6 +542,7 @@ CompositorBridgeChild::ActorDestroy(ActorDestroyReason aWhy)
}
mCanSend = false;
mActorDestroyed = true;
if (mProcessToken && XRE_IsParentProcess()) {
GPUProcessManager::Get()->NotifyRemoteActorDestroyed(mProcessToken);

Просмотреть файл

@ -39,6 +39,7 @@ class IAPZCTreeManager;
class APZCTreeManagerChild;
class ClientLayerManager;
class CompositorBridgeParent;
class CompositorManagerChild;
class CompositorOptions;
class TextureClient;
class TextureClientPool;
@ -52,7 +53,16 @@ class CompositorBridgeChild final : public PCompositorBridgeChild,
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(CompositorBridgeChild, override);
explicit CompositorBridgeChild(LayerManager *aLayerManager, uint32_t aNamespace);
explicit CompositorBridgeChild(CompositorManagerChild* aManager);
/**
* Initialize the singleton compositor bridge for a content process.
*/
void InitForContent(uint32_t aNamespace);
void InitForWidget(uint64_t aProcessToken,
LayerManager* aLayerManager,
uint32_t aNamespace);
void Destroy();
@ -63,30 +73,6 @@ public:
*/
bool LookupCompositorFrameMetrics(const FrameMetrics::ViewID aId, FrameMetrics&);
/**
* Initialize the singleton compositor bridge for a content process.
*/
static bool InitForContent(Endpoint<PCompositorBridgeChild>&& aEndpoint, uint32_t aNamespace);
static bool ReinitForContent(Endpoint<PCompositorBridgeChild>&& aEndpoint, uint32_t aNamespace);
static RefPtr<CompositorBridgeChild> CreateRemote(
const uint64_t& aProcessToken,
LayerManager* aLayerManager,
Endpoint<PCompositorBridgeChild>&& aEndpoint,
uint32_t aNamespace);
/**
* Initialize the CompositorBridgeChild, create CompositorBridgeParent, and
* open a same-process connection.
*/
CompositorBridgeParent* InitSameProcess(
widget::CompositorWidget* aWidget,
const uint64_t& aLayerTreeId,
CSSToLayoutDeviceScale aScale,
const CompositorOptions& aOptions,
bool aUseExternalSurface,
const gfx::IntSize& aSurfaceSize);
static CompositorBridgeChild* Get();
static bool ChildProcessHasCompositorBridge();
@ -237,8 +223,7 @@ private:
// Private destructor, to discourage deletion outside of Release():
virtual ~CompositorBridgeChild();
void InitIPDL();
void DeallocPCompositorBridgeChild() override;
void AfterDestroy();
virtual PLayerTransactionChild*
AllocPLayerTransactionChild(const nsTArray<LayersBackend>& aBackendHints,
@ -291,6 +276,8 @@ private:
uint32_t mAPZCId;
};
RefPtr<CompositorManagerChild> mCompositorManager;
RefPtr<LayerManager> mLayerManager;
uint32_t mIdNamespace;
@ -313,6 +300,9 @@ private:
// True until the beginning of the two-step shutdown sequence of this actor.
bool mCanSend;
// False until the actor is destroyed.
bool mActorDestroyed;
/**
* Transaction id of ShadowLayerForwarder.
* It is incrementaed by UpdateFwdTransactionId() in each BeginTransaction() call.

Просмотреть файл

@ -42,6 +42,7 @@
#include "mozilla/layers/AsyncCompositionManager.h"
#include "mozilla/layers/BasicCompositor.h" // for BasicCompositor
#include "mozilla/layers/Compositor.h" // for Compositor
#include "mozilla/layers/CompositorManagerParent.h" // for CompositorManagerParent
#include "mozilla/layers/CompositorOGL.h" // for CompositorOGL
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/CompositorTypes.h"
@ -106,6 +107,16 @@ using namespace std;
using base::ProcessId;
using base::Thread;
CompositorBridgeParentBase::CompositorBridgeParentBase(CompositorManagerParent* aManager)
: mCanSend(true)
, mCompositorManager(aManager)
{
}
CompositorBridgeParentBase::~CompositorBridgeParentBase()
{
}
ProcessId
CompositorBridgeParentBase::GetChildProcessId()
{
@ -169,6 +180,9 @@ CompositorBridgeParentBase::StartSharingMetrics(ipc::SharedMemoryBasic::Handle a
uint64_t aLayersId,
uint32_t aApzcId)
{
if (!mCanSend) {
return false;
}
return PCompositorBridgeParent::SendSharedCompositorFrameMetrics(
aHandle, aMutexHandle, aLayersId, aApzcId);
}
@ -177,6 +191,9 @@ bool
CompositorBridgeParentBase::StopSharingMetrics(FrameMetrics::ViewID aScrollId,
uint32_t aApzcId)
{
if (!mCanSend) {
return false;
}
return PCompositorBridgeParent::SendReleaseSharedCompositorFrameMetrics(
aScrollId, aApzcId);
}
@ -298,12 +315,14 @@ CompositorLoop()
return CompositorThreadHolder::Loop();
}
CompositorBridgeParent::CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
CompositorBridgeParent::CompositorBridgeParent(CompositorManagerParent* aManager,
CSSToLayoutDeviceScale aScale,
const TimeDuration& aVsyncRate,
const CompositorOptions& aOptions,
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize)
: mWidget(nullptr)
: CompositorBridgeParentBase(aManager)
, mWidget(nullptr)
, mScale(aScale)
, mVsyncRate(aVsyncRate)
, mIsTesting(false)
@ -327,37 +346,24 @@ CompositorBridgeParent::CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
, mPluginWindowsHidden(false)
#endif
{
// Always run destructor on the main thread
MOZ_ASSERT(NS_IsMainThread());
}
void
CompositorBridgeParent::InitSameProcess(widget::CompositorWidget* aWidget,
const uint64_t& aLayerTreeId)
{
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
mWidget = aWidget;
mRootLayerTreeID = aLayerTreeId;
if (mOptions.UseAPZ()) {
mApzcTreeManager = new APZCTreeManager();
}
// IPDL initialization. mSelfRef is cleared in DeferredDestroy.
SetOtherProcessId(base::GetCurrentProcId());
mSelfRef = this;
Initialize();
}
bool
CompositorBridgeParent::Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint)
{
if (!aEndpoint.Bind(this)) {
return false;
}
mSelfRef = this;
return true;
}
mozilla::ipc::IPCResult
CompositorBridgeParent::RecvInitialize(const uint64_t& aRootLayerTreeId)
{
@ -640,6 +646,8 @@ CompositorBridgeParent::RecvNotifyApproximatelyVisibleRegion(const ScrollableLay
void
CompositorBridgeParent::ActorDestroy(ActorDestroyReason why)
{
mCanSend = false;
StopAndClearResources();
RemoveCompositor(mCompositorID);
@ -1936,25 +1944,6 @@ CompositorBridgeParent::InvalidateRemoteLayers()
});
}
static void
OpenCompositor(RefPtr<CrossProcessCompositorBridgeParent> aCompositor,
Endpoint<PCompositorBridgeParent>&& aEndpoint)
{
aCompositor->Bind(Move(aEndpoint));
}
/* static */ bool
CompositorBridgeParent::CreateForContent(Endpoint<PCompositorBridgeParent>&& aEndpoint)
{
gfxPlatform::InitLayersIPC();
RefPtr<CrossProcessCompositorBridgeParent> cpcp =
new CrossProcessCompositorBridgeParent();
CompositorLoop()->PostTask(NewRunnableFunction(OpenCompositor, cpcp, Move(aEndpoint)));
return true;
}
void
UpdateIndirectTree(uint64_t aId, Layer* aRoot, const TargetConfig& aTargetConfig)
{

Просмотреть файл

@ -67,6 +67,7 @@ class AsyncCompositionManager;
class Compositor;
class CompositorAnimationStorage;
class CompositorBridgeParent;
class CompositorManagerParent;
class CompositorVsyncScheduler;
class HostLayerManager;
class LayerTransactionParent;
@ -94,6 +95,8 @@ class CompositorBridgeParentBase : public PCompositorBridgeParent,
public MetricsSharingController
{
public:
explicit CompositorBridgeParentBase(CompositorManagerParent* aManager);
virtual void ShadowLayersUpdated(LayerTransactionParent* aLayerTree,
const TransactionInfo& aInfo,
bool aHitTestUpdate) = 0;
@ -122,6 +125,8 @@ public:
virtual mozilla::ipc::IPCResult RecvSyncWithCompositor() override { return IPC_OK(); }
mozilla::ipc::IPCResult Recv__delete__() override { return IPC_OK(); }
virtual void ObserveLayerUpdate(uint64_t aLayersId, uint64_t aEpoch, bool aActive) = 0;
virtual void NotifyDidCompositeToPipeline(const wr::PipelineId& aPipelineId, const wr::Epoch& aEpoch, TimeStamp& aCompositeStart, TimeStamp& aCompositeEnd) {}
@ -154,6 +159,14 @@ public:
virtual bool IsRemote() const {
return false;
}
protected:
~CompositorBridgeParentBase() override;
bool mCanSend;
private:
RefPtr<CompositorManagerParent> mCompositorManager;
};
class CompositorBridgeParent final : public CompositorBridgeParentBase
@ -169,22 +182,14 @@ public:
NS_IMETHOD_(MozExternalRefCountType) AddRef() override { return CompositorBridgeParentBase::AddRef(); }
NS_IMETHOD_(MozExternalRefCountType) Release() override { return CompositorBridgeParentBase::Release(); }
explicit CompositorBridgeParent(CSSToLayoutDeviceScale aScale,
explicit CompositorBridgeParent(CompositorManagerParent* aManager,
CSSToLayoutDeviceScale aScale,
const TimeDuration& aVsyncRate,
const CompositorOptions& aOptions,
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize);
// Must only be called by CompositorBridgeChild. After invoking this, the
// IPC channel is active and RecvWillStop/ActorDestroy must be called to
// free the compositor.
void InitSameProcess(widget::CompositorWidget* aWidget,
const uint64_t& aLayerTreeId);
// Must only be called by GPUParent. After invoking this, the IPC channel
// is active and RecvWillStop/ActorDestroy must be called to free the
// compositor.
bool Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint);
void InitSameProcess(widget::CompositorWidget* aWidget, const uint64_t& aLayerTreeId);
virtual mozilla::ipc::IPCResult RecvInitialize(const uint64_t& aRootLayerTreeId) override;
virtual mozilla::ipc::IPCResult RecvGetFrameUniformity(FrameUniformityData* aOutData) override;
@ -344,13 +349,6 @@ public:
static void SetControllerForLayerTree(uint64_t aLayersId,
GeckoContentController* aController);
/**
* A new child process has been configured to push transactions
* directly to us. Transport is to its thread context.
*/
static bool
CreateForContent(Endpoint<PCompositorBridgeParent>&& aEndpoint);
struct LayerTreeState {
LayerTreeState();
~LayerTreeState();

Просмотреть файл

@ -10,6 +10,7 @@
#include "mozilla/dom/ContentChild.h" // for ContentChild
#include "mozilla/dom/TabChild.h" // for TabChild
#include "mozilla/dom/TabGroup.h" // for TabGroup
#include "VsyncSource.h"
namespace mozilla {
namespace layers {
@ -69,7 +70,21 @@ CompositorManagerChild::Shutdown()
/* static */ bool
CompositorManagerChild::CreateContentCompositorBridge(uint32_t aNamespace)
{
return false;
MOZ_ASSERT(NS_IsMainThread());
if (NS_WARN_IF(!sInstance)) {
return false;
}
CompositorBridgeOptions options = ContentCompositorOptions();
PCompositorBridgeChild* pbridge =
sInstance->SendPCompositorBridgeConstructor(options);
if (NS_WARN_IF(!pbridge)) {
return true;
}
auto bridge = static_cast<CompositorBridgeChild*>(pbridge);
bridge->InitForContent(aNamespace);
return true;
}
/* static */ already_AddRefed<CompositorBridgeChild>
@ -81,14 +96,51 @@ CompositorManagerChild::CreateWidgetCompositorBridge(uint64_t aProcessToken,
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize)
{
return nullptr;
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
if (NS_WARN_IF(!sInstance)) {
return nullptr;
}
TimeDuration vsyncRate =
gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
CompositorBridgeOptions options =
WidgetCompositorOptions(aScale, vsyncRate, aOptions,
aUseExternalSurfaceSize, aSurfaceSize);
PCompositorBridgeChild* pbridge =
sInstance->SendPCompositorBridgeConstructor(options);
if (NS_WARN_IF(!pbridge)) {
return nullptr;
}
RefPtr<CompositorBridgeChild> bridge =
static_cast<CompositorBridgeChild*>(pbridge);
bridge->InitForWidget(aProcessToken, aLayerManager, aNamespace);
return bridge.forget();
}
/* static */ already_AddRefed<CompositorBridgeChild>
CompositorManagerChild::CreateSameProcessWidgetCompositorBridge(LayerManager* aLayerManager,
uint32_t aNamespace)
{
return nullptr;
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
if (NS_WARN_IF(!sInstance)) {
return nullptr;
}
CompositorBridgeOptions options = SameProcessWidgetCompositorOptions();
PCompositorBridgeChild* pbridge =
sInstance->SendPCompositorBridgeConstructor(options);
if (NS_WARN_IF(!pbridge)) {
return nullptr;
}
RefPtr<CompositorBridgeChild> bridge =
static_cast<CompositorBridgeChild*>(pbridge);
bridge->InitForWidget(1, aLayerManager, aNamespace);
return bridge.forget();
}
CompositorManagerChild::CompositorManagerChild(CompositorManagerParent* aParent,
@ -137,6 +189,21 @@ CompositorManagerChild::ActorDestroy(ActorDestroyReason aReason)
mCanSend = false;
}
PCompositorBridgeChild*
CompositorManagerChild::AllocPCompositorBridgeChild(const CompositorBridgeOptions& aOptions)
{
CompositorBridgeChild* child = new CompositorBridgeChild(this);
child->AddRef();
return child;
}
bool
CompositorManagerChild::DeallocPCompositorBridgeChild(PCompositorBridgeChild* aActor)
{
static_cast<CompositorBridgeChild*>(aActor)->Release();
return true;
}
void
CompositorManagerChild::HandleFatalError(const char* aName, const char* aMsg) const
{

Просмотреть файл

@ -62,6 +62,10 @@ public:
void ProcessingError(Result aCode, const char* aReason) override;
PCompositorBridgeChild* AllocPCompositorBridgeChild(const CompositorBridgeOptions& aOptions) override;
bool DeallocPCompositorBridgeChild(PCompositorBridgeChild* aActor) override;
private:
static StaticRefPtr<CompositorManagerChild> sInstance;

Просмотреть файл

@ -5,8 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozilla/layers/CompositorManagerParent.h"
#include "mozilla/gfx/GPUParent.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CrossProcessCompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#include "VsyncSource.h"
namespace mozilla {
namespace layers {
@ -66,7 +69,38 @@ CompositorManagerParent::CreateSameProcessWidgetCompositorBridge(CSSToLayoutDevi
bool aUseExternalSurfaceSize,
const gfx::IntSize& aSurfaceSize)
{
return nullptr;
MOZ_ASSERT(XRE_IsParentProcess());
MOZ_ASSERT(NS_IsMainThread());
// When we are in a combined UI / GPU process, InProcessCompositorSession
// requires both the parent and child PCompositorBridge actors for its own
// construction, which is done on the main thread. Normally
// CompositorBridgeParent is created on the compositor thread via the IPDL
// plumbing (CompositorManagerParent::AllocPCompositorBridgeParent). Thus to
// actually get a reference to the parent, we would need to block on the
// compositor thread until it handles our constructor message. Because only
// one one IPDL constructor is permitted per parent and child protocol, we
// cannot make the normal case async and this case sync. Instead what we do
// is leave the constructor async (a boon to the content process setup) and
// create the parent ahead of time. It will pull the preinitialized parent
// from the queue when it receives the message and give that to IPDL.
// Note that the static mutex not only is used to protect sInstance, but also
// mPendingCompositorBridges.
StaticMutexAutoLock lock(sMutex);
if (NS_WARN_IF(!sInstance)) {
return nullptr;
}
TimeDuration vsyncRate =
gfxPlatform::GetPlatform()->GetHardwareVsync()->GetGlobalDisplay().GetVsyncRate();
RefPtr<CompositorBridgeParent> bridge =
new CompositorBridgeParent(sInstance, aScale, vsyncRate, aOptions,
aUseExternalSurfaceSize, aSurfaceSize);
sInstance->mPendingCompositorBridges.AppendElement(bridge);
return bridge.forget();
}
CompositorManagerParent::CompositorManagerParent()
@ -106,5 +140,66 @@ CompositorManagerParent::DeallocPCompositorManagerParent()
Release();
}
PCompositorBridgeParent*
CompositorManagerParent::AllocPCompositorBridgeParent(const CompositorBridgeOptions& aOpt)
{
switch (aOpt.type()) {
case CompositorBridgeOptions::TContentCompositorOptions: {
CrossProcessCompositorBridgeParent* bridge =
new CrossProcessCompositorBridgeParent(this);
bridge->AddRef();
return bridge;
}
case CompositorBridgeOptions::TWidgetCompositorOptions: {
// Only the UI process is allowed to create widget compositors in the
// compositor process.
gfx::GPUParent* gpu = gfx::GPUParent::GetSingleton();
if (NS_WARN_IF(!gpu || OtherPid() != gpu->OtherPid())) {
MOZ_ASSERT_UNREACHABLE("Child cannot create widget compositor!");
break;
}
const WidgetCompositorOptions& opt = aOpt.get_WidgetCompositorOptions();
CompositorBridgeParent* bridge =
new CompositorBridgeParent(this, opt.scale(), opt.vsyncRate(),
opt.options(), opt.useExternalSurfaceSize(),
opt.surfaceSize());
bridge->AddRef();
return bridge;
}
case CompositorBridgeOptions::TSameProcessWidgetCompositorOptions: {
// If the GPU and UI process are combined, we actually already created the
// CompositorBridgeParent, so we need to reuse that to inject it into the
// IPDL framework.
if (NS_WARN_IF(OtherPid() != base::GetCurrentProcId())) {
MOZ_ASSERT_UNREACHABLE("Child cannot create same process compositor!");
break;
}
// Note that the static mutex not only is used to protect sInstance, but
// also mPendingCompositorBridges.
StaticMutexAutoLock lock(sMutex);
MOZ_ASSERT(sInstance == this);
MOZ_ASSERT(!mPendingCompositorBridges.IsEmpty());
CompositorBridgeParent* bridge = mPendingCompositorBridges[0];
bridge->AddRef();
mPendingCompositorBridges.RemoveElementAt(0);
return bridge;
}
default:
break;
}
return nullptr;
}
bool
CompositorManagerParent::DeallocPCompositorBridgeParent(PCompositorBridgeParent* aActor)
{
static_cast<CompositorBridgeParentBase*>(aActor)->Release();
return true;
}
} // namespace layers
} // namespace mozilla

Просмотреть файл

@ -36,7 +36,8 @@ public:
void ActorDestroy(ActorDestroyReason aReason) override;
ipc::IPCResult RecvIgnoreTemporarySkeletonMessage() override { return IPC_OK(); }
bool DeallocPCompositorBridgeParent(PCompositorBridgeParent* aActor) override;
PCompositorBridgeParent* AllocPCompositorBridgeParent(const CompositorBridgeOptions& aOpt) override;
private:
static StaticRefPtr<CompositorManagerParent> sInstance;
@ -50,6 +51,8 @@ private:
void DeallocPCompositorManagerParent() override;
RefPtr<CompositorThreadHolder> mCompositorThreadHolder;
AutoTArray<RefPtr<CompositorBridgeParent>, 1> mPendingCompositorBridges;
};
} // namespace layers

Просмотреть файл

@ -54,6 +54,8 @@ CrossProcessCompositorBridgeParent::RecvRequestNotifyAfterRemotePaint()
void
CrossProcessCompositorBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
{
mCanSend = false;
// We must keep this object alive untill the code handling message
// reception is finished on this thread.
MessageLoop::current()->PostTask(NewRunnableMethod(this, &CrossProcessCompositorBridgeParent::DeferredDestroy));
@ -485,7 +487,6 @@ CrossProcessCompositorBridgeParent::DeferredDestroy()
CrossProcessCompositorBridgeParent::~CrossProcessCompositorBridgeParent()
{
MOZ_ASSERT(XRE_GetIOMessageLoop());
MOZ_ASSERT(IToplevelProtocol::GetTransport());
}
PTextureParent*

Просмотреть файл

@ -28,18 +28,11 @@ class CrossProcessCompositorBridgeParent final : public CompositorBridgeParentBa
friend class CompositorBridgeParent;
public:
explicit CrossProcessCompositorBridgeParent()
: mNotifyAfterRemotePaint(false)
explicit CrossProcessCompositorBridgeParent(CompositorManagerParent* aManager)
: CompositorBridgeParentBase(aManager)
, mNotifyAfterRemotePaint(false)
, mDestroyCalled(false)
{
MOZ_ASSERT(NS_IsMainThread());
}
void Bind(Endpoint<PCompositorBridgeParent>&& aEndpoint) {
if (!aEndpoint.Bind(this)) {
return;
}
mSelfRef = this;
}
virtual void ActorDestroy(ActorDestroyReason aWhy) override;
@ -158,10 +151,6 @@ public:
return true;
}
protected:
void OnChannelConnected(int32_t pid) override {
mCompositorThreadHolder = CompositorThreadHolder::GetSingleton();
}
private:
// Private destructor, to discourage deletion outside of Release():
virtual ~CrossProcessCompositorBridgeParent();

Просмотреть файл

@ -11,6 +11,7 @@ include PlatformWidgetTypes;
include protocol PAPZ;
include protocol PAPZCTreeManager;
include protocol PBrowser;
include protocol PCompositorManager;
include protocol PCompositorWidget;
include protocol PLayerTransaction;
include protocol PTexture;
@ -72,6 +73,8 @@ namespace layers {
*/
sync protocol PCompositorBridge
{
manager PCompositorManager;
manages PAPZ;
manages PAPZCTreeManager;
// A Compositor manages a single Layer Manager (PLayerTransaction)
@ -130,6 +133,8 @@ child:
async ObserveLayerUpdate(uint64_t aLayersId, uint64_t aEpoch, bool aActive);
parent:
async __delete__();
// Must be called before Initialize().
async PCompositorWidget(CompositorWidgetInitData aInitData);

Просмотреть файл

@ -52,8 +52,21 @@ union CompositorBridgeOptions {
*/
sync protocol PCompositorManager
{
manages PCompositorBridge;
parent:
async IgnoreTemporarySkeletonMessage();
/**
* There are three variants of a PCompositorBridge protocol, each of which can
* only be created by certain processes and configurations:
* - A "content" PCompositorBridge is requested by each content process,
* representing the drawable area for Web content.
* - A "widget" PCompositorBridge is requested by the UI process for each
* "top level browser window" for chrome and such.
* - A "same process widget" PCompositorBridge is requested by the combined
* GPU/UI process for each "top level browser window" as above.
* See gfx/layers/ipc/PCompositorBridge.ipdl for more details.
*/
async PCompositorBridge(CompositorBridgeOptions options);
};
} // layers