зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1365927 - Part 5. Make PCompositorManager the manager protocol of PCompositorBridge. r=dvander
This commit is contained in:
Родитель
c17a8c1ea1
Коммит
7dc8c4cc9f
|
@ -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);
|
||||
mCanSend = true;
|
||||
mIdNamespace = aNamespace;
|
||||
sCompositorBridge = this;
|
||||
}
|
||||
|
||||
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,
|
||||
void
|
||||
CompositorBridgeChild::InitForWidget(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;
|
||||
}
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(aProcessToken);
|
||||
MOZ_ASSERT(aLayerManager);
|
||||
MOZ_ASSERT(aNamespace);
|
||||
|
||||
void
|
||||
CompositorBridgeChild::InitIPDL()
|
||||
{
|
||||
mCanSend = true;
|
||||
AddRef();
|
||||
}
|
||||
|
||||
void
|
||||
CompositorBridgeChild::DeallocPCompositorBridgeChild()
|
||||
{
|
||||
Release();
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
|
Загрузка…
Ссылка в новой задаче