Bug 1561178 - Use Endpoints for VideoBridge construction, and support the possibility that there are multiple at the same time. r=jya

In the future we're going to want VideoBridge connections from the RDD process into both the parent process and the GPU process.
This does the preparation work for unifying the way we create VideoBridges (using Endpoints, required for cross-process connections),
and detects which one to use based on where the video will be composited.

Differential Revision: https://phabricator.services.mozilla.com/D35968

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Matt Woodrow 2019-06-27 01:29:15 +00:00
Родитель 99b0d9c73f
Коммит 9c0b625ec4
8 изменённых файлов: 93 добавлений и 25 удалений

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

@ -114,8 +114,9 @@ bool RemoteDecoderManagerParent::StartupThreads() {
#endif
if (XRE_IsGPUProcess()) {
sRemoteDecoderManagerParentThread->Dispatch(
NS_NewRunnableFunction("RemoteDecoderManagerParent::StartupThreads",
[]() { layers::VideoBridgeChild::Startup(); }),
NS_NewRunnableFunction(
"RemoteDecoderManagerParent::StartupThreads",
[]() { layers::VideoBridgeChild::StartupForGPUProcess(); }),
NS_DISPATCH_NORMAL);
}

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

@ -6,6 +6,7 @@
#ifndef include_dom_media_ipc_RemoteDecoderManagerParent_h
#define include_dom_media_ipc_RemoteDecoderManagerParent_h
#include "mozilla/PRemoteDecoderManagerParent.h"
#include "mozilla/layers/VideoBridgeChild.h"
namespace mozilla {

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

@ -36,13 +36,31 @@ class KnowsCompositorVideo : public layers::KnowsCompositor {
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(KnowsCompositorVideo, override)
layers::TextureForwarder* GetTextureForwarder() override {
return VideoBridgeChild::GetSingleton();
return mTextureFactoryIdentifier.mParentProcessType == GeckoProcessType_GPU
? VideoBridgeChild::GetSingletonToGPUProcess()
: VideoBridgeChild::GetSingletonToParentProcess();
}
layers::LayersIPCActor* GetLayersIPCActor() override {
return VideoBridgeChild::GetSingleton();
return GetTextureForwarder();
}
static already_AddRefed<KnowsCompositorVideo> TryCreateForIdentifier(
const layers::TextureFactoryIdentifier& aIdentifier) {
VideoBridgeChild* child =
(aIdentifier.mParentProcessType == GeckoProcessType_GPU)
? VideoBridgeChild::GetSingletonToGPUProcess()
: VideoBridgeChild::GetSingletonToParentProcess();
if (!child) {
return nullptr;
}
RefPtr<KnowsCompositorVideo> knowsCompositor = new KnowsCompositorVideo();
knowsCompositor->IdentifyTextureHost(aIdentifier);
return knowsCompositor.forget();
}
private:
KnowsCompositorVideo() = default;
virtual ~KnowsCompositorVideo() = default;
};
@ -260,9 +278,14 @@ RemoteVideoDecoderParent::RemoteVideoDecoderParent(
nsCString* aErrorDescription)
: RemoteDecoderParent(aParent, aManagerTaskQueue, aDecodeTaskQueue),
mVideoInfo(aVideoInfo) {
if (XRE_IsGPUProcess() && aIdentifier) {
mKnowsCompositor = new KnowsCompositorVideo();
mKnowsCompositor->IdentifyTextureHost(aIdentifier.value());
if (aIdentifier) {
// Check to see if we have a direct PVideoBridge connection to the destination
// process specified in aIdentifier, and create a KnowsCompositor representing
// that connection if so.
// If this fails, then we fall back to returning the decoded frames directly
// via Output().
mKnowsCompositor =
KnowsCompositorVideo::TryCreateForIdentifier(*aIdentifier);
}
CreateDecoderParams params(mVideoInfo);

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

@ -24,6 +24,10 @@ GPUVideoTextureHost::~GPUVideoTextureHost() {
GPUVideoTextureHost* GPUVideoTextureHost::CreateFromDescriptor(
TextureFlags aFlags, const SurfaceDescriptorGPUVideo& aDescriptor) {
// In the future when the RDD process has a PVideoBridge connection,
// then there might be two VideoBridgeParents (one within the GPU process,
// one from RDD). We'll need to flag which one to use to lookup our
// descriptor, or just try both.
TextureHost* wrappedTextureHost =
VideoBridgeParent::GetSingleton()->LookupTexture(aDescriptor.handle());
if (!wrappedTextureHost) {

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

@ -11,36 +11,61 @@
namespace mozilla {
namespace layers {
StaticRefPtr<VideoBridgeChild> sVideoBridgeChildSingleton;
StaticRefPtr<VideoBridgeChild> sVideoBridgeToParentProcess;
StaticRefPtr<VideoBridgeChild> sVideoBridgeToGPUProcess;
/* static */
void VideoBridgeChild::Startup() {
sVideoBridgeChildSingleton = new VideoBridgeChild();
RefPtr<VideoBridgeParent> parent = new VideoBridgeParent();
void VideoBridgeChild::StartupForGPUProcess() {
ipc::Endpoint<PVideoBridgeParent> parentPipe;
ipc::Endpoint<PVideoBridgeChild> childPipe;
MessageLoop* loop = CompositorThreadHolder::Loop();
PVideoBridge::CreateEndpoints(base::GetCurrentProcId(),
base::GetCurrentProcId(), &parentPipe,
&childPipe);
sVideoBridgeChildSingleton->Open(parent->GetIPCChannel(), loop,
ipc::ChildSide);
sVideoBridgeChildSingleton->mIPDLSelfRef = sVideoBridgeChildSingleton;
parent->SetOtherProcessId(base::GetCurrentProcId());
VideoBridgeChild::OpenToGPUProcess(std::move(childPipe));
CompositorThreadHolder::Loop()->PostTask(
NewRunnableFunction("gfx::VideoBridgeParent::Open",
&VideoBridgeParent::Open, std::move(parentPipe)));
}
void VideoBridgeChild::OpenToGPUProcess(
Endpoint<PVideoBridgeChild>&& aEndpoint) {
sVideoBridgeToGPUProcess = new VideoBridgeChild();
if (!aEndpoint.Bind(sVideoBridgeToGPUProcess)) {
// We can't recover from this.
MOZ_CRASH("Failed to bind RemoteDecoderManagerParent to endpoint");
}
}
/* static */
void VideoBridgeChild::Shutdown() {
if (sVideoBridgeChildSingleton) {
sVideoBridgeChildSingleton->Close();
sVideoBridgeChildSingleton = nullptr;
if (sVideoBridgeToParentProcess) {
sVideoBridgeToParentProcess->Close();
sVideoBridgeToParentProcess = nullptr;
}
if (sVideoBridgeToGPUProcess) {
sVideoBridgeToGPUProcess->Close();
sVideoBridgeToGPUProcess = nullptr;
}
}
VideoBridgeChild::VideoBridgeChild()
: mMessageLoop(MessageLoop::current()), mCanSend(true) {}
: mIPDLSelfRef(this),
mMessageLoop(MessageLoop::current()),
mCanSend(true) {}
VideoBridgeChild::~VideoBridgeChild() {}
VideoBridgeChild* VideoBridgeChild::GetSingleton() {
return sVideoBridgeChildSingleton;
VideoBridgeChild* VideoBridgeChild::GetSingletonToParentProcess() {
return sVideoBridgeToParentProcess;
}
VideoBridgeChild* VideoBridgeChild::GetSingletonToGPUProcess() {
return sVideoBridgeToGPUProcess;
}
bool VideoBridgeChild::AllocUnsafeShmem(

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

@ -19,10 +19,11 @@ class VideoBridgeChild final : public PVideoBridgeChild,
public:
NS_INLINE_DECL_THREADSAFE_REFCOUNTING(VideoBridgeChild, override);
static void Startup();
static void StartupForGPUProcess();
static void Shutdown();
static VideoBridgeChild* GetSingleton();
static VideoBridgeChild* GetSingletonToParentProcess();
static VideoBridgeChild* GetSingletonToGPUProcess();
// PVideoBridgeChild
PTextureChild* AllocPTextureChild(const SurfaceDescriptor& aSharedData,
@ -64,6 +65,8 @@ class VideoBridgeChild final : public PVideoBridgeChild,
bool CanSend() { return mCanSend; }
static void OpenToGPUProcess(Endpoint<PVideoBridgeChild>&& aEndpoint);
private:
VideoBridgeChild();
virtual ~VideoBridgeChild();

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

@ -24,6 +24,14 @@ VideoBridgeParent::VideoBridgeParent() : mClosed(false) {
VideoBridgeParent::~VideoBridgeParent() { sVideoBridgeSingleton = nullptr; }
void VideoBridgeParent::Open(Endpoint<PVideoBridgeParent>&& aEndpoint) {
RefPtr<VideoBridgeParent> parent = new VideoBridgeParent();
if (!aEndpoint.Bind(parent)) {
// We can't recover from this.
MOZ_CRASH("Failed to bind RemoteDecoderManagerParent to endpoint");
}
}
/* static */
VideoBridgeParent* VideoBridgeParent::GetSingleton() {
return sVideoBridgeSingleton;

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

@ -19,7 +19,6 @@ class VideoBridgeParent final : public PVideoBridgeParent,
public HostIPCAllocator,
public ShmemAllocator {
public:
VideoBridgeParent();
~VideoBridgeParent();
static VideoBridgeParent* GetSingleton();
@ -55,7 +54,11 @@ class VideoBridgeParent final : public PVideoBridgeParent,
void DeallocShmem(ipc::Shmem& aShmem) override;
static void Open(Endpoint<PVideoBridgeParent>&& aEndpoint);
private:
VideoBridgeParent();
void ActorDealloc() override;
// This keeps us alive until ActorDestroy(), at which point we do a