зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1315510 - Automatically recreate VideoDecoderManager if the GPU process crashes. r=dvander
This commit is contained in:
Родитель
3445ad743b
Коммит
f880884b57
|
@ -25,6 +25,7 @@
|
|||
#include "mozilla/docshell/OfflineCacheUpdateChild.h"
|
||||
#include "mozilla/dom/ContentBridgeChild.h"
|
||||
#include "mozilla/dom/ContentBridgeParent.h"
|
||||
#include "mozilla/dom/VideoDecoderManagerChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/DataTransfer.h"
|
||||
#include "mozilla/dom/DOMStorageIPC.h"
|
||||
|
@ -1181,7 +1182,8 @@ ContentChild::RecvGMPsChanged(nsTArray<GMPCapabilityData>&& capabilities)
|
|||
bool
|
||||
ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
|
||||
Endpoint<PImageBridgeChild>&& aImageBridge,
|
||||
Endpoint<PVRManagerChild>&& aVRBridge)
|
||||
Endpoint<PVRManagerChild>&& aVRBridge,
|
||||
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
|
||||
{
|
||||
if (!CompositorBridgeChild::InitForContent(Move(aCompositor))) {
|
||||
return false;
|
||||
|
@ -1192,13 +1194,15 @@ ContentChild::RecvInitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
|
|||
if (!gfx::VRManagerChild::InitForContent(Move(aVRBridge))) {
|
||||
return false;
|
||||
}
|
||||
VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor,
|
||||
Endpoint<PImageBridgeChild>&& aImageBridge,
|
||||
Endpoint<PVRManagerChild>&& aVRBridge)
|
||||
Endpoint<PVRManagerChild>&& aVRBridge,
|
||||
Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
|
||||
{
|
||||
nsTArray<RefPtr<TabChild>> tabs = TabChild::GetAll();
|
||||
|
||||
|
@ -1226,6 +1230,8 @@ ContentChild::RecvReinitRendering(Endpoint<PCompositorBridgeChild>&& aCompositor
|
|||
tabChild->ReinitRendering();
|
||||
}
|
||||
}
|
||||
|
||||
VideoDecoderManagerChild::InitForContent(Move(aVideoManager));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -169,13 +169,15 @@ public:
|
|||
RecvInitRendering(
|
||||
Endpoint<PCompositorBridgeChild>&& aCompositor,
|
||||
Endpoint<PImageBridgeChild>&& aImageBridge,
|
||||
Endpoint<PVRManagerChild>&& aVRBridge) override;
|
||||
Endpoint<PVRManagerChild>&& aVRBridge,
|
||||
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
|
||||
|
||||
bool
|
||||
RecvReinitRendering(
|
||||
Endpoint<PCompositorBridgeChild>&& aCompositor,
|
||||
Endpoint<PImageBridgeChild>&& aImageBridge,
|
||||
Endpoint<PVRManagerChild>&& aVRBridge) override;
|
||||
Endpoint<PVRManagerChild>&& aVRBridge,
|
||||
Endpoint<PVideoDecoderManagerChild>&& aVideoManager) override;
|
||||
|
||||
PProcessHangMonitorChild*
|
||||
AllocPProcessHangMonitorChild(Transport* aTransport,
|
||||
|
|
|
@ -1027,13 +1027,6 @@ ContentParent::RecvFindPlugins(const uint32_t& aPluginEpoch,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::RecvInitVideoDecoderManager(Endpoint<PVideoDecoderManagerChild>* aEndpoint)
|
||||
{
|
||||
GPUProcessManager::Get()->CreateContentVideoDecoderManager(OtherPid(), aEndpoint);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*static*/ TabParent*
|
||||
ContentParent::CreateBrowserOrApp(const TabContext& aContext,
|
||||
Element* aFrameElement,
|
||||
|
@ -2227,18 +2220,21 @@ ContentParent::InitInternal(ProcessPriority aInitialPriority,
|
|||
Endpoint<PCompositorBridgeChild> compositor;
|
||||
Endpoint<PImageBridgeChild> imageBridge;
|
||||
Endpoint<PVRManagerChild> vrBridge;
|
||||
Endpoint<PVideoDecoderManagerChild> videoManager;
|
||||
|
||||
DebugOnly<bool> opened = gpm->CreateContentBridges(
|
||||
OtherPid(),
|
||||
&compositor,
|
||||
&imageBridge,
|
||||
&vrBridge);
|
||||
&vrBridge,
|
||||
&videoManager);
|
||||
MOZ_ASSERT(opened);
|
||||
|
||||
Unused << SendInitRendering(
|
||||
Move(compositor),
|
||||
Move(imageBridge),
|
||||
Move(vrBridge));
|
||||
Move(vrBridge),
|
||||
Move(videoManager));
|
||||
|
||||
gpm->AddListener(this);
|
||||
}
|
||||
|
@ -2383,18 +2379,21 @@ ContentParent::OnCompositorUnexpectedShutdown()
|
|||
Endpoint<PCompositorBridgeChild> compositor;
|
||||
Endpoint<PImageBridgeChild> imageBridge;
|
||||
Endpoint<PVRManagerChild> vrBridge;
|
||||
Endpoint<PVideoDecoderManagerChild> videoManager;
|
||||
|
||||
DebugOnly<bool> opened = gpm->CreateContentBridges(
|
||||
OtherPid(),
|
||||
&compositor,
|
||||
&imageBridge,
|
||||
&vrBridge);
|
||||
&vrBridge,
|
||||
&videoManager);
|
||||
MOZ_ASSERT(opened);
|
||||
|
||||
Unused << SendReinitRendering(
|
||||
Move(compositor),
|
||||
Move(imageBridge),
|
||||
Move(vrBridge));
|
||||
Move(vrBridge),
|
||||
Move(videoManager));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -262,8 +262,6 @@ public:
|
|||
nsTArray<PluginTag>* aPlugins,
|
||||
uint32_t* aNewPluginEpoch) override;
|
||||
|
||||
virtual bool RecvInitVideoDecoderManager(Endpoint<PVideoDecoderManagerChild>* endpoint) override;
|
||||
|
||||
virtual bool RecvUngrabPointer(const uint32_t& aTime) override;
|
||||
|
||||
virtual bool RecvRemovePermission(const IPC::Principal& aPrincipal,
|
||||
|
|
|
@ -429,7 +429,8 @@ child:
|
|||
async InitRendering(
|
||||
Endpoint<PCompositorBridgeChild> compositor,
|
||||
Endpoint<PImageBridgeChild> imageBridge,
|
||||
Endpoint<PVRManagerChild> vr);
|
||||
Endpoint<PVRManagerChild> vr,
|
||||
Endpoint<PVideoDecoderManagerChild> video);
|
||||
|
||||
// Re-create the rendering stack using the given endpoints. This is sent
|
||||
// after the compositor process has crashed. The new endpoints may be to a
|
||||
|
@ -437,7 +438,8 @@ child:
|
|||
async ReinitRendering(
|
||||
Endpoint<PCompositorBridgeChild> compositor,
|
||||
Endpoint<PImageBridgeChild> bridge,
|
||||
Endpoint<PVRManagerChild> vr);
|
||||
Endpoint<PVRManagerChild> vr,
|
||||
Endpoint<PVideoDecoderManagerChild> video);
|
||||
|
||||
/**
|
||||
* Enable system-level sandboxing features, if available. Can
|
||||
|
@ -742,8 +744,6 @@ parent:
|
|||
|
||||
sync PCrashReporter(NativeThreadId tid, uint32_t processType);
|
||||
|
||||
sync InitVideoDecoderManager() returns (Endpoint<PVideoDecoderManagerChild> endpoint);
|
||||
|
||||
/**
|
||||
* Is this token compatible with the provided version?
|
||||
*
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#include "mozilla/layers/TextureClient.h"
|
||||
#include "base/thread.h"
|
||||
#include "MediaInfo.h"
|
||||
#include "MediaPrefs.h"
|
||||
#include "ImageContainer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -147,7 +148,8 @@ RemoteDecoderModule::DecoderNeedsConversion(const TrackInfo& aConfig) const
|
|||
already_AddRefed<MediaDataDecoder>
|
||||
RemoteDecoderModule::CreateVideoDecoder(const CreateDecoderParams& aParams)
|
||||
{
|
||||
if (!aParams.mKnowsCompositor ||
|
||||
if (!MediaPrefs::PDMUseGPUDecoder() ||
|
||||
!aParams.mKnowsCompositor ||
|
||||
aParams.mKnowsCompositor->GetTextureFactoryIdentifier().mParentProcessType != GeckoProcessType_GPU) {
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -103,11 +103,16 @@ void
|
|||
VideoDecoderChild::ActorDestroy(ActorDestroyReason aWhy)
|
||||
{
|
||||
if (aWhy == AbnormalShutdown) {
|
||||
if (mInitialized) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
} else {
|
||||
mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
|
||||
}
|
||||
// Defer reporting an error until we've recreated the manager so that
|
||||
// it'll be safe for MediaFormatReader to recreate decoders
|
||||
RefPtr<VideoDecoderChild> ref = this;
|
||||
GetManager()->RunWhenRecreated(NS_NewRunnableFunction([=]() {
|
||||
if (ref->mInitialized) {
|
||||
ref->mCallback->Error(NS_ERROR_DOM_MEDIA_DECODE_ERR);
|
||||
} else {
|
||||
ref->mInitPromise.RejectIfExists(NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
|
||||
}
|
||||
}));
|
||||
}
|
||||
mCanSend = false;
|
||||
}
|
||||
|
@ -118,9 +123,15 @@ VideoDecoderChild::InitIPDL(MediaDataDecoderCallback* aCallback,
|
|||
layers::KnowsCompositor* aKnowsCompositor)
|
||||
{
|
||||
RefPtr<VideoDecoderManagerChild> manager = VideoDecoderManagerChild::GetSingleton();
|
||||
if (!manager) {
|
||||
// If the manager isn't available, then don't initialize mIPDLSelfRef and leave
|
||||
// us in an error state. We'll then immediately reject the promise when Init()
|
||||
// is called and the caller can try again. Hopefully by then the new manager is
|
||||
// ready, or we've notified the caller of it being no longer available.
|
||||
// If not, then the cycle repeats until we're ready.
|
||||
if (!manager || !manager->CanSend()) {
|
||||
return;
|
||||
}
|
||||
|
||||
mIPDLSelfRef = this;
|
||||
mCallback = aCallback;
|
||||
mVideoInfo = aVideoInfo;
|
||||
|
@ -150,9 +161,15 @@ RefPtr<MediaDataDecoder::InitPromise>
|
|||
VideoDecoderChild::Init()
|
||||
{
|
||||
AssertOnManagerThread();
|
||||
if (!mCanSend || !SendInit(mVideoInfo, mKnowsCompositor->GetTextureFactoryIdentifier())) {
|
||||
|
||||
if (!mIPDLSelfRef) {
|
||||
return MediaDataDecoder::InitPromise::CreateAndReject(
|
||||
NS_ERROR_DOM_MEDIA_FATAL_ERR, __func__);
|
||||
NS_ERROR_DOM_MEDIA_DECODE_ERR, __func__);
|
||||
}
|
||||
// If we failed to send this, then we'll still resolve the Init promise
|
||||
// as ActorDestroy handles it.
|
||||
if (mCanSend) {
|
||||
SendInit(mVideoInfo, mKnowsCompositor->GetTextureFactoryIdentifier());
|
||||
}
|
||||
return mInitPromise.Ensure(__func__);
|
||||
}
|
||||
|
@ -162,7 +179,6 @@ VideoDecoderChild::Input(MediaRawData* aSample)
|
|||
{
|
||||
AssertOnManagerThread();
|
||||
if (!mCanSend) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -171,7 +187,7 @@ VideoDecoderChild::Input(MediaRawData* aSample)
|
|||
// into shmem rather than requiring a copy here.
|
||||
Shmem buffer;
|
||||
if (!AllocShmem(aSample->Size(), Shmem::SharedMemory::TYPE_BASIC, &buffer)) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_DECODE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -184,17 +200,15 @@ VideoDecoderChild::Input(MediaRawData* aSample)
|
|||
aSample->mFrames,
|
||||
aSample->mKeyframe),
|
||||
buffer);
|
||||
if (!SendInput(sample)) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
}
|
||||
SendInput(sample);
|
||||
}
|
||||
|
||||
void
|
||||
VideoDecoderChild::Flush()
|
||||
{
|
||||
AssertOnManagerThread();
|
||||
if (!mCanSend || !SendFlush()) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
if (mCanSend) {
|
||||
SendFlush();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -202,8 +216,8 @@ void
|
|||
VideoDecoderChild::Drain()
|
||||
{
|
||||
AssertOnManagerThread();
|
||||
if (!mCanSend || !SendDrain()) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
if (mCanSend) {
|
||||
SendDrain();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,8 +225,8 @@ void
|
|||
VideoDecoderChild::Shutdown()
|
||||
{
|
||||
AssertOnManagerThread();
|
||||
if (!mCanSend || !SendShutdown()) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
if (mCanSend) {
|
||||
SendShutdown();
|
||||
}
|
||||
mInitialized = false;
|
||||
}
|
||||
|
@ -228,8 +242,8 @@ void
|
|||
VideoDecoderChild::SetSeekThreshold(const media::TimeUnit& aTime)
|
||||
{
|
||||
AssertOnManagerThread();
|
||||
if (!mCanSend || !SendSetSeekThreshold(aTime.ToMicroseconds())) {
|
||||
mCallback->Error(NS_ERROR_DOM_MEDIA_FATAL_ERR);
|
||||
if (mCanSend) {
|
||||
SendSetSeekThreshold(aTime.ToMicroseconds());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "mozilla/layers/SynchronousTask.h"
|
||||
#include "mozilla/gfx/DataSurfaceHelpers.h"
|
||||
#include "mozilla/layers/ISurfaceAllocator.h"
|
||||
#include "base/task.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
@ -27,24 +28,13 @@ StaticRefPtr<AbstractThread> sVideoDecoderChildAbstractThread;
|
|||
|
||||
// Only accessed from sVideoDecoderChildThread
|
||||
static StaticRefPtr<VideoDecoderManagerChild> sDecoderManager;
|
||||
static UniquePtr<nsTArray<RefPtr<Runnable>>> sRecreateTasks;
|
||||
|
||||
/* static */ void
|
||||
VideoDecoderManagerChild::Initialize()
|
||||
VideoDecoderManagerChild::InitializeThread()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MediaPrefs::GetSingleton();
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (!MediaPrefs::PDMUseGPUDecoder()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Can't run remote video decoding in the parent process.
|
||||
if (!ContentChild::GetSingleton()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sVideoDecoderChildThread) {
|
||||
RefPtr<nsIThread> childThread;
|
||||
nsresult rv = NS_NewNamedThread("VideoChild", getter_AddRefs(childThread));
|
||||
|
@ -53,11 +43,16 @@ VideoDecoderManagerChild::Initialize()
|
|||
|
||||
sVideoDecoderChildAbstractThread =
|
||||
AbstractThread::CreateXPCOMThreadWrapper(childThread, false);
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
|
||||
sRecreateTasks = MakeUnique<nsTArray<RefPtr<Runnable>>>();
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
VideoDecoderManagerChild::InitForContent(Endpoint<PVideoDecoderManagerChild>&& aVideoManager)
|
||||
{
|
||||
InitializeThread();
|
||||
sVideoDecoderChildThread->Dispatch(NewRunnableFunction(&Open, Move(aVideoManager)), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
|
@ -67,7 +62,7 @@ VideoDecoderManagerChild::Shutdown()
|
|||
|
||||
if (sVideoDecoderChildThread) {
|
||||
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([]() {
|
||||
if (sDecoderManager) {
|
||||
if (sDecoderManager && sDecoderManager->CanSend()) {
|
||||
sDecoderManager->Close();
|
||||
sDecoderManager = nullptr;
|
||||
}
|
||||
|
@ -76,36 +71,30 @@ VideoDecoderManagerChild::Shutdown()
|
|||
sVideoDecoderChildAbstractThread = nullptr;
|
||||
sVideoDecoderChildThread->Shutdown();
|
||||
sVideoDecoderChildThread = nullptr;
|
||||
|
||||
sRecreateTasks = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
VideoDecoderManagerChild::RunWhenRecreated(already_AddRefed<Runnable> aTask)
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
|
||||
|
||||
// If we've already been recreated, then run the task immediately.
|
||||
if (sDecoderManager && sDecoderManager != this && sDecoderManager->CanSend()) {
|
||||
RefPtr<Runnable> task = aTask;
|
||||
task->Run();
|
||||
} else {
|
||||
sRecreateTasks->AppendElement(aTask);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* static */ VideoDecoderManagerChild*
|
||||
VideoDecoderManagerChild::GetSingleton()
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
|
||||
|
||||
if (!sDecoderManager || !sDecoderManager->mCanSend) {
|
||||
RefPtr<VideoDecoderManagerChild> manager;
|
||||
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction([&]() {
|
||||
Endpoint<PVideoDecoderManagerChild> endpoint;
|
||||
if (!ContentChild::GetSingleton()->SendInitVideoDecoderManager(&endpoint)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!endpoint.IsValid()) {
|
||||
return;
|
||||
}
|
||||
|
||||
manager = new VideoDecoderManagerChild();
|
||||
|
||||
RefPtr<Runnable> task = NewRunnableMethod<Endpoint<PVideoDecoderManagerChild>&&>(
|
||||
manager, &VideoDecoderManagerChild::Open, Move(endpoint));
|
||||
sVideoDecoderChildThread->Dispatch(task.forget(), NS_DISPATCH_NORMAL);
|
||||
}), NS_DISPATCH_SYNC);
|
||||
|
||||
sDecoderManager = manager;
|
||||
}
|
||||
return sDecoderManager;
|
||||
}
|
||||
|
||||
|
@ -138,11 +127,27 @@ VideoDecoderManagerChild::DeallocPVideoDecoderChild(PVideoDecoderChild* actor)
|
|||
void
|
||||
VideoDecoderManagerChild::Open(Endpoint<PVideoDecoderManagerChild>&& aEndpoint)
|
||||
{
|
||||
if (!aEndpoint.Bind(this)) {
|
||||
return;
|
||||
// Make sure we always dispatch everything in sRecreateTasks, even if we
|
||||
// fail since this is as close to being recreated as we will ever be.
|
||||
sDecoderManager = nullptr;
|
||||
if (aEndpoint.IsValid()) {
|
||||
RefPtr<VideoDecoderManagerChild> manager = new VideoDecoderManagerChild();
|
||||
if (aEndpoint.Bind(manager)) {
|
||||
sDecoderManager = manager;
|
||||
manager->InitIPDL();
|
||||
}
|
||||
}
|
||||
AddRef();
|
||||
for (Runnable* task : *sRecreateTasks) {
|
||||
task->Run();
|
||||
}
|
||||
sRecreateTasks->Clear();
|
||||
}
|
||||
|
||||
void
|
||||
VideoDecoderManagerChild::InitIPDL()
|
||||
{
|
||||
mCanSend = true;
|
||||
mIPDLSelfRef = this;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -154,7 +159,14 @@ VideoDecoderManagerChild::ActorDestroy(ActorDestroyReason aWhy)
|
|||
void
|
||||
VideoDecoderManagerChild::DeallocPVideoDecoderManagerChild()
|
||||
{
|
||||
Release();
|
||||
mIPDLSelfRef = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
VideoDecoderManagerChild::CanSend()
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
|
||||
return mCanSend;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -164,7 +176,7 @@ VideoDecoderManagerChild::DeallocShmem(mozilla::ipc::Shmem& aShmem)
|
|||
RefPtr<VideoDecoderManagerChild> self = this;
|
||||
mozilla::ipc::Shmem shmem = aShmem;
|
||||
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([self, shmem]() {
|
||||
if (self->mCanSend) {
|
||||
if (self->CanSend()) {
|
||||
mozilla::ipc::Shmem shmemCopy = shmem;
|
||||
self->DeallocShmem(shmemCopy);
|
||||
}
|
||||
|
@ -207,7 +219,7 @@ VideoDecoderManagerChild::Readback(const SurfaceDescriptorGPUVideo& aSD)
|
|||
SurfaceDescriptor sd;
|
||||
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([&]() {
|
||||
AutoCompleteTask complete(&task);
|
||||
if (ref->mCanSend) {
|
||||
if (ref->CanSend()) {
|
||||
ref->SendReadback(aSD, &sd);
|
||||
}
|
||||
}), NS_DISPATCH_NORMAL);
|
||||
|
@ -239,7 +251,7 @@ VideoDecoderManagerChild::DeallocateSurfaceDescriptorGPUVideo(const SurfaceDescr
|
|||
RefPtr<VideoDecoderManagerChild> ref = this;
|
||||
SurfaceDescriptorGPUVideo sd = Move(aSD);
|
||||
sVideoDecoderChildThread->Dispatch(NS_NewRunnableFunction([ref, sd]() {
|
||||
if (ref->mCanSend) {
|
||||
if (ref->CanSend()) {
|
||||
ref->SendDeallocateSurfaceDescriptorGPUVideo(sd);
|
||||
}
|
||||
}), NS_DISPATCH_NORMAL);
|
||||
|
|
|
@ -51,10 +51,20 @@ public:
|
|||
bool DeallocShmem(mozilla::ipc::Shmem& aShmem) override;
|
||||
|
||||
// Main thread only
|
||||
static void Initialize();
|
||||
static void InitForContent(Endpoint<PVideoDecoderManagerChild>&& aVideoManager);
|
||||
static void Shutdown();
|
||||
|
||||
// Run aTask (on the manager thread) when we next attempt to create a new manager
|
||||
// (even if creation fails). Intended to be called from ActorDestroy when we get
|
||||
// notified that the old manager is being destroyed.
|
||||
// Can only be called from the manager thread.
|
||||
void RunWhenRecreated(already_AddRefed<Runnable> aTask);
|
||||
|
||||
bool CanSend();
|
||||
|
||||
protected:
|
||||
void InitIPDL();
|
||||
|
||||
void ActorDestroy(ActorDestroyReason aWhy) override;
|
||||
void DeallocPVideoDecoderManagerChild() override;
|
||||
|
||||
|
@ -64,12 +74,17 @@ protected:
|
|||
bool DeallocPVideoDecoderChild(PVideoDecoderChild* actor) override;
|
||||
|
||||
private:
|
||||
// Main thread only
|
||||
static void InitializeThread();
|
||||
|
||||
VideoDecoderManagerChild()
|
||||
: mCanSend(false)
|
||||
{}
|
||||
~VideoDecoderManagerChild() {}
|
||||
|
||||
void Open(Endpoint<PVideoDecoderManagerChild>&& aEndpoint);
|
||||
static void Open(Endpoint<PVideoDecoderManagerChild>&& aEndpoint);
|
||||
|
||||
RefPtr<VideoDecoderManagerChild> mIPDLSelfRef;
|
||||
|
||||
// Should only ever be accessed on the manager thread.
|
||||
bool mCanSend;
|
||||
|
|
|
@ -29,6 +29,7 @@
|
|||
#include "VsyncSource.h"
|
||||
#include "mozilla/dom/VideoDecoderManagerChild.h"
|
||||
#include "mozilla/dom/VideoDecoderManagerParent.h"
|
||||
#include "MediaPrefs.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
|
@ -544,7 +545,8 @@ bool
|
|||
GPUProcessManager::CreateContentBridges(base::ProcessId aOtherProcess,
|
||||
ipc::Endpoint<PCompositorBridgeChild>* aOutCompositor,
|
||||
ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
|
||||
ipc::Endpoint<PVRManagerChild>* aOutVRBridge)
|
||||
ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
|
||||
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager)
|
||||
{
|
||||
if (!CreateContentCompositorBridge(aOtherProcess, aOutCompositor) ||
|
||||
!CreateContentImageBridge(aOtherProcess, aOutImageBridge) ||
|
||||
|
@ -552,6 +554,9 @@ GPUProcessManager::CreateContentBridges(base::ProcessId aOtherProcess,
|
|||
{
|
||||
return false;
|
||||
}
|
||||
// VideoDeocderManager is only supported in the GPU process, so we allow this to be
|
||||
// fallible.
|
||||
CreateContentVideoDecoderManager(aOtherProcess, aOutVideoManager);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -667,12 +672,12 @@ GPUProcessManager::CreateContentVRManager(base::ProcessId aOtherProcess,
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
GPUProcessManager::CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
|
||||
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndpoint)
|
||||
{
|
||||
if (!mGPUChild) {
|
||||
return false;
|
||||
if (!mGPUChild || !MediaPrefs::PDMUseGPUDecoder()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ipc::Endpoint<dom::PVideoDecoderManagerParent> parentPipe;
|
||||
|
@ -685,13 +690,13 @@ GPUProcessManager::CreateContentVideoDecoderManager(base::ProcessId aOtherProces
|
|||
&childPipe);
|
||||
if (NS_FAILED(rv)) {
|
||||
gfxCriticalNote << "Could not create content video decoder: " << hexa(int(rv));
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
mGPUChild->SendNewContentVideoDecoderManager(Move(parentPipe));
|
||||
|
||||
*aOutEndpoint = Move(childPipe);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
already_AddRefed<IAPZCTreeManager>
|
||||
|
|
|
@ -92,9 +92,8 @@ public:
|
|||
base::ProcessId aOtherProcess,
|
||||
ipc::Endpoint<PCompositorBridgeChild>* aOutCompositor,
|
||||
ipc::Endpoint<PImageBridgeChild>* aOutImageBridge,
|
||||
ipc::Endpoint<PVRManagerChild>* aOutVRBridge);
|
||||
bool CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
|
||||
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint);
|
||||
ipc::Endpoint<PVRManagerChild>* aOutVRBridge,
|
||||
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutVideoManager);
|
||||
|
||||
// This returns a reference to the APZCTreeManager to which
|
||||
// pan/zoom-related events can be sent.
|
||||
|
@ -160,6 +159,8 @@ private:
|
|||
ipc::Endpoint<PImageBridgeChild>* aOutEndpoint);
|
||||
bool CreateContentVRManager(base::ProcessId aOtherProcess,
|
||||
ipc::Endpoint<PVRManagerChild>* aOutEndpoint);
|
||||
void CreateContentVideoDecoderManager(base::ProcessId aOtherProcess,
|
||||
ipc::Endpoint<dom::PVideoDecoderManagerChild>* aOutEndPoint);
|
||||
|
||||
// Called from RemoteCompositorSession. We track remote sessions so we can
|
||||
// notify their owning widgets that the session must be restarted.
|
||||
|
|
|
@ -67,7 +67,6 @@
|
|||
#include "FrameLayerBuilder.h"
|
||||
#include "AnimationCommon.h"
|
||||
#include "LayerAnimationInfo.h"
|
||||
#include "mozilla/dom/VideoDecoderManagerChild.h"
|
||||
|
||||
#include "AudioChannelService.h"
|
||||
#include "mozilla/dom/PromiseDebugging.h"
|
||||
|
@ -302,8 +301,6 @@ nsLayoutStatics::Initialize()
|
|||
|
||||
MediaDecoder::InitStatics();
|
||||
|
||||
VideoDecoderManagerChild::Initialize();
|
||||
|
||||
PromiseDebugging::Init();
|
||||
|
||||
mozilla::dom::devicestorage::DeviceStorageStatics::Initialize();
|
||||
|
|
Загрузка…
Ссылка в новой задаче