Implement ImageBridge support for the GPU process. (bug 1287366 part 3, r=mattwoodrow,billm)

--HG--
extra : rebase_source : 0fc5f5bab52e6f49ed2c607e63c9a14d0509dd9a
This commit is contained in:
David Anderson 2016-07-20 00:19:27 -07:00
Родитель 6aca1d9865
Коммит 471ed8630a
8 изменённых файлов: 107 добавлений и 18 удалений

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

@ -13,6 +13,7 @@
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/layers/CompositorBridgeParent.h"
#include "mozilla/layers/CompositorThread.h"
#include "mozilla/layers/ImageBridgeParent.h"
namespace mozilla {
namespace gfx {
@ -61,6 +62,13 @@ GPUParent::RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint)
return true;
}
bool
GPUParent::RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint)
{
ImageBridgeParent::CreateForGPUProcess(Move(aEndpoint));
return true;
}
bool
GPUParent::RecvUpdatePref(const GfxPrefSetting& setting)
{
@ -98,6 +106,12 @@ GPUParent::RecvNewContentCompositorBridge(Endpoint<PCompositorBridgeParent>&& aE
return CompositorBridgeParent::CreateForContent(Move(aEndpoint));
}
bool
GPUParent::RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint)
{
return ImageBridgeParent::CreateForContent(Move(aEndpoint));
}
void
GPUParent::ActorDestroy(ActorDestroyReason aWhy)
{

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

@ -26,6 +26,7 @@ public:
bool RecvInit(nsTArray<GfxPrefSetting>&& prefs) override;
bool RecvInitVsyncBridge(Endpoint<PVsyncBridgeParent>&& aVsyncEndpoint) override;
bool RecvInitImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
bool RecvUpdatePref(const GfxPrefSetting& pref) override;
bool RecvNewWidgetCompositor(
Endpoint<PCompositorBridgeParent>&& aEndpoint,
@ -33,6 +34,7 @@ public:
const bool& aUseExternalSurface,
const IntSize& aSurfaceSize) override;
bool RecvNewContentCompositorBridge(Endpoint<PCompositorBridgeParent>&& aEndpoint) override;
bool RecvNewContentImageBridge(Endpoint<PImageBridgeParent>&& aEndpoint) override;
void ActorDestroy(ActorDestroyReason aWhy) override;

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

@ -136,9 +136,29 @@ GPUProcessManager::EnsureGPUReady()
void
GPUProcessManager::EnsureImageBridgeChild()
{
if (!ImageBridgeChild::IsCreated()) {
ImageBridgeChild::InitSameProcess();
if (ImageBridgeChild::IsCreated()) {
return;
}
if (!mGPUChild) {
ImageBridgeChild::InitSameProcess();
return;
}
ipc::Endpoint<PImageBridgeParent> parentPipe;
ipc::Endpoint<PImageBridgeChild> childPipe;
nsresult rv = PImageBridge::CreateEndpoints(
mGPUChild->OtherPid(),
base::GetCurrentProcId(),
&parentPipe,
&childPipe);
if (NS_FAILED(rv)) {
DisableGPUProcess("Failed to create PImageBridge endpoints");
return;
}
mGPUChild->SendInitImageBridge(Move(parentPipe));
ImageBridgeChild::InitWithGPUProcess(Move(childPipe));
}
void
@ -306,18 +326,21 @@ GPUProcessManager::CreateRemoteSession(nsBaseWidget* aWidget,
aScale,
aUseExternalSurfaceSize,
aSurfaceSize);
if (!ok)
if (!ok) {
return nullptr;
}
RefPtr<CompositorVsyncDispatcher> dispatcher = aWidget->GetCompositorVsyncDispatcher();
RefPtr<CompositorWidgetVsyncObserver> observer =
new CompositorWidgetVsyncObserver(mVsyncBridge, aRootLayerTreeId);
CompositorWidgetChild* widget = new CompositorWidgetChild(dispatcher, observer);
if (!child->SendPCompositorWidgetConstructor(widget, initData))
if (!child->SendPCompositorWidgetConstructor(widget, initData)) {
return nullptr;
if (!child->SendInitialize(aRootLayerTreeId))
}
if (!child->SendInitialize(aRootLayerTreeId)) {
return nullptr;
}
RefPtr<RemoteCompositorSession> session =
new RemoteCompositorSession(child, widget, aRootLayerTreeId);
@ -352,8 +375,9 @@ GPUProcessManager::CreateContentCompositorBridge(base::ProcessId aOtherProcess,
if (mGPUChild) {
mGPUChild->SendNewContentCompositorBridge(Move(parentPipe));
} else {
if (!CompositorBridgeParent::CreateForContent(Move(parentPipe)))
if (!CompositorBridgeParent::CreateForContent(Move(parentPipe))) {
return false;
}
}
*aOutEndpoint = Move(childPipe);
@ -366,7 +390,9 @@ GPUProcessManager::CreateContentImageBridge(base::ProcessId aOtherProcess,
{
EnsureImageBridgeChild();
base::ProcessId gpuPid = base::GetCurrentProcId();
base::ProcessId gpuPid = mGPUChild
? mGPUChild->OtherPid()
: base::GetCurrentProcId();
ipc::Endpoint<PImageBridgeParent> parentPipe;
ipc::Endpoint<PImageBridgeChild> childPipe;
@ -380,8 +406,13 @@ GPUProcessManager::CreateContentImageBridge(base::ProcessId aOtherProcess,
return false;
}
if (!ImageBridgeParent::CreateForContent(Move(parentPipe)))
return false;
if (mGPUChild) {
mGPUChild->SendNewContentImageBridge(Move(parentPipe));
} else {
if (!ImageBridgeParent::CreateForContent(Move(parentPipe))) {
return false;
}
}
*aOutEndpoint = Move(childPipe);
return true;

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

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
include protocol PCompositorBridge;
include protocol PImageBridge;
include protocol PVsyncBridge;
using mozilla::CSSToLayoutDeviceScale from "Units.h";
@ -30,7 +31,8 @@ parent:
// Sent by the UI process to initiate core settings.
async Init(GfxPrefSetting[] prefs);
async InitVsyncBridge(Endpoint<PVsyncBridgeParent> vsyncEndpoint);
async InitVsyncBridge(Endpoint<PVsyncBridgeParent> endpoint);
async InitImageBridge(Endpoint<PImageBridgeParent> endpoint);
// Called to update a gfx preference.
async UpdatePref(GfxPrefSetting pref);
@ -43,6 +45,7 @@ parent:
// Create a new content-process compositor bridge.
async NewContentCompositorBridge(Endpoint<PCompositorBridgeParent> endpoint);
async NewContentImageBridge(Endpoint<PImageBridgeParent> endpoint);
};
} // namespace gfx

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

@ -391,13 +391,8 @@ ImageBridgeChild::CancelWaitForRecycle(uint64_t aTextureId)
// Singleton
static StaticRefPtr<ImageBridgeChild> sImageBridgeChildSingleton;
static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
static Thread *sImageBridgeChildThread = nullptr;
void ReleaseImageBridgeParentSingleton() {
sImageBridgeParentSingleton = nullptr;
}
void
ImageBridgeChild::FallbackDestroyActors() {
if (mTxn && !mTxn->mDestroyedActors.IsEmpty()) {
@ -981,13 +976,33 @@ ImageBridgeChild::InitSameProcess()
}
sImageBridgeChildSingleton = new ImageBridgeChild();
sImageBridgeParentSingleton = ImageBridgeParent::CreateSameProcess();
sImageBridgeChildSingleton->ConnectAsync(sImageBridgeParentSingleton);
RefPtr<ImageBridgeParent> parent = ImageBridgeParent::CreateSameProcess();
sImageBridgeChildSingleton->ConnectAsync(parent);
sImageBridgeChildSingleton->GetMessageLoop()->PostTask(
NewRunnableFunction(CallSendImageBridgeThreadId,
sImageBridgeChildSingleton.get()));
}
/* static */ void
ImageBridgeChild::InitWithGPUProcess(Endpoint<PImageBridgeChild>&& aEndpoint)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!sImageBridgeChildSingleton);
MOZ_ASSERT(!sImageBridgeChildThread);
sImageBridgeChildThread = new ImageBridgeThread();
if (!sImageBridgeChildThread->IsRunning()) {
sImageBridgeChildThread->Start();
}
sImageBridgeChildSingleton = new ImageBridgeChild();
MessageLoop* loop = sImageBridgeChildSingleton->GetMessageLoop();
loop->PostTask(NewRunnableMethod<Endpoint<PImageBridgeChild>&&>(
sImageBridgeChildSingleton, &ImageBridgeChild::Bind, Move(aEndpoint)));
}
bool InImageBridgeChildThread()
{
return ImageBridgeChild::IsCreated() &&

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

@ -121,6 +121,7 @@ public:
*/
static void InitSameProcess();
static void InitWithGPUProcess(Endpoint<PImageBridgeChild>&& aEndpoint);
static bool InitForContent(Endpoint<PImageBridgeChild>&& aEndpoint);
/**

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

@ -76,15 +76,38 @@ ImageBridgeParent::~ImageBridgeParent()
sImageBridges.erase(OtherPid());
}
static StaticRefPtr<ImageBridgeParent> sImageBridgeParentSingleton;
void ReleaseImageBridgeParentSingleton() {
sImageBridgeParentSingleton = nullptr;
}
/* static */ ImageBridgeParent*
ImageBridgeParent::CreateSameProcess()
{
RefPtr<ImageBridgeParent> parent =
new ImageBridgeParent(CompositorThreadHolder::Loop(), base::GetCurrentProcId());
parent->mSelfRef = parent;
sImageBridgeParentSingleton = parent;
return parent;
}
/* static */ bool
ImageBridgeParent::CreateForGPUProcess(Endpoint<PImageBridgeParent>&& aEndpoint)
{
MOZ_ASSERT(XRE_GetProcessType() == GeckoProcessType_GPU);
MessageLoop* loop = CompositorThreadHolder::Loop();
RefPtr<ImageBridgeParent> parent = new ImageBridgeParent(loop, aEndpoint.OtherPid());
loop->PostTask(NewRunnableMethod<Endpoint<PImageBridgeParent>&&>(
parent, &ImageBridgeParent::Bind, Move(aEndpoint)));
sImageBridgeParentSingleton = parent;
return true;
}
void
ImageBridgeParent::ActorDestroy(ActorDestroyReason aWhy)
{

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

@ -53,7 +53,7 @@ public:
~ImageBridgeParent();
static ImageBridgeParent* CreateSameProcess();
static bool CreateForGPUProcess(Endpoint<PImageBridgeParent>&& aEndpoint);
static bool CreateForContent(Endpoint<PImageBridgeParent>&& aEndpoint);
virtual ShmemAllocator* AsShmemAllocator() override { return this; }