Bug 1650996 - P3. Have RemoteDecoderManagerChild use a TaskQueue over a media threadpool. r=mjf

Differential Revision: https://phabricator.services.mozilla.com/D82503
This commit is contained in:
Jean-Yves Avenard 2020-07-09 06:00:53 +00:00
Родитель a3e2ecf7c4
Коммит 8c4180fca5
7 изменённых файлов: 67 добавлений и 76 удалений

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

@ -65,7 +65,6 @@ ProxyResolution
RemoteLzyStream
RWLockTester
RacingServMan
RemVidChild
Sandbox Testing
SaveScripts
Socket Thread

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

@ -5,13 +5,11 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "GpuDecoderModule.h"
#include "base/thread.h"
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/StaticPrefs_media.h"
#include "RemoteVideoDecoder.h"
#include "RemoteDecoderManagerChild.h"
#include "RemoteMediaDataDecoder.h"
#include "RemoteVideoDecoder.h"
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/SyncRunnable.h"
namespace mozilla {
@ -50,19 +48,20 @@ already_AddRefed<MediaDataDecoder> GpuDecoderModule::CreateVideoDecoder(
}
RefPtr<GpuRemoteVideoDecoderChild> child = new GpuRemoteVideoDecoderChild();
SynchronousTask task("InitIPDL");
MediaResult result(NS_OK);
RemoteDecoderManagerChild::GetManagerThread()->Dispatch(
NS_NewRunnableFunction(
"dom::GpuDecoderModule::CreateVideoDecoder",
[&, child]() {
AutoCompleteTask complete(&task);
result = child->InitIPDL(
aParams.VideoConfig(), aParams.mRate.mValue, aParams.mOptions,
aParams.mKnowsCompositor->GetTextureFactoryIdentifier());
}),
NS_DISPATCH_NORMAL);
task.Wait();
RefPtr<Runnable> task = NS_NewRunnableFunction(
"dom::GpuDecoderModule::CreateVideoDecoder", [&]() {
result = child->InitIPDL(
aParams.VideoConfig(), aParams.mRate.mValue, aParams.mOptions,
aParams.mKnowsCompositor->GetTextureFactoryIdentifier());
if (NS_FAILED(result)) {
// Release GpuRemoteVideoDecoderChild here, while we're on
// manager thread. Don't just let the RefPtr go out of scope.
child = nullptr;
}
});
SyncRunnable::DispatchToThread(RemoteDecoderManagerChild::GetManagerThread(),
task);
if (NS_FAILED(result)) {
if (aParams.mError) {

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

@ -254,7 +254,7 @@ MediaDataDecoder::ConversionRequired RemoteDecoderChild::NeedsConversion()
}
void RemoteDecoderChild::AssertOnManagerThread() const {
MOZ_ASSERT(NS_GetCurrentThread() == mThread);
MOZ_ASSERT(mThread->IsOnCurrentThread());
}
RemoteDecoderManagerChild* RemoteDecoderChild::GetManager() {

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

@ -55,7 +55,7 @@ class RemoteDecoderChild : public PRemoteDecoderChild,
MediaDataDecoder::DecodedData mDecodedData;
private:
const RefPtr<nsIThread> mThread;
const nsCOMPtr<nsISerialEventTarget> mThread;
MozPromiseHolder<MediaDataDecoder::InitPromise> mInitPromise;
MozPromiseRequestHolder<PRemoteDecoderChild::InitPromise> mInitPromiseRequest;

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

@ -5,15 +5,14 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteDecoderManagerChild.h"
#include "base/task.h"
#include "RemoteDecoderChild.h"
#include "VideoUtils.h"
#include "mozilla/dom/ContentChild.h"
#include "mozilla/gfx/2D.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/gfx/DataSurfaceHelpers.h"
#include "mozilla/ipc/ProtocolUtils.h"
#include "mozilla/layers/ISurfaceAllocator.h"
#include "mozilla/layers/SynchronousTask.h"
namespace mozilla {
@ -21,7 +20,7 @@ using namespace layers;
using namespace gfx;
// Only modified on the main-thread
StaticRefPtr<nsIThread> sRemoteDecoderManagerChildThread;
StaticRefPtr<TaskQueue> sRemoteDecoderManagerChildThread;
// Only accessed from sRemoteDecoderManagerChildThread
static StaticRefPtr<RemoteDecoderManagerChild>
@ -36,10 +35,12 @@ void RemoteDecoderManagerChild::InitializeThread() {
MOZ_ASSERT(NS_IsMainThread());
if (!sRemoteDecoderManagerChildThread) {
RefPtr<nsIThread> childThread;
nsresult rv = NS_NewNamedThread("RemVidChild", getter_AddRefs(childThread));
NS_ENSURE_SUCCESS_VOID(rv);
sRemoteDecoderManagerChildThread = childThread;
// We can't use a MediaThreadType::PLAYBACK as the GpuDecoderModule and
// RemoteDecoderModule runs on it and dispatch synchronous tasks to the
// manager thread, should more than 4 concurrent videos being instantiated
// at the same time, we could end up in a deadlock.
sRemoteDecoderManagerChildThread = new TaskQueue(
GetMediaThreadPool(MediaThreadType::PLATFORM_DECODER), "RemVidChild");
sRecreateTasks = MakeUnique<nsTArray<RefPtr<Runnable>>>();
}
@ -49,20 +50,18 @@ void RemoteDecoderManagerChild::InitializeThread() {
void RemoteDecoderManagerChild::InitForRDDProcess(
Endpoint<PRemoteDecoderManagerChild>&& aVideoManager) {
InitializeThread();
sRemoteDecoderManagerChildThread->Dispatch(
MOZ_ALWAYS_SUCCEEDS(sRemoteDecoderManagerChildThread->Dispatch(
NewRunnableFunction("InitForContentRunnable", &OpenForRDDProcess,
std::move(aVideoManager)),
NS_DISPATCH_NORMAL);
std::move(aVideoManager))));
}
/* static */
void RemoteDecoderManagerChild::InitForGPUProcess(
Endpoint<PRemoteDecoderManagerChild>&& aVideoManager) {
InitializeThread();
sRemoteDecoderManagerChildThread->Dispatch(
MOZ_ALWAYS_SUCCEEDS(sRemoteDecoderManagerChildThread->Dispatch(
NewRunnableFunction("InitForContentRunnable", &OpenForGPUProcess,
std::move(aVideoManager)),
NS_DISPATCH_NORMAL);
std::move(aVideoManager))));
}
/* static */
@ -70,24 +69,23 @@ void RemoteDecoderManagerChild::Shutdown() {
MOZ_ASSERT(NS_IsMainThread());
if (sRemoteDecoderManagerChildThread) {
sRemoteDecoderManagerChildThread->Dispatch(
NS_NewRunnableFunction(
"dom::RemoteDecoderManagerChild::Shutdown",
[]() {
MOZ_ALWAYS_SUCCEEDS(
sRemoteDecoderManagerChildThread->Dispatch(NS_NewRunnableFunction(
"dom::RemoteDecoderManagerChild::Shutdown", []() {
if (sRemoteDecoderManagerChildForRDDProcess &&
sRemoteDecoderManagerChildForRDDProcess->CanSend()) {
sRemoteDecoderManagerChildForRDDProcess->Close();
sRemoteDecoderManagerChildForRDDProcess = nullptr;
}
sRemoteDecoderManagerChildForRDDProcess = nullptr;
if (sRemoteDecoderManagerChildForGPUProcess &&
sRemoteDecoderManagerChildForGPUProcess->CanSend()) {
sRemoteDecoderManagerChildForGPUProcess->Close();
sRemoteDecoderManagerChildForGPUProcess = nullptr;
}
}),
NS_DISPATCH_NORMAL);
sRemoteDecoderManagerChildForGPUProcess = nullptr;
})));
sRemoteDecoderManagerChildThread->Shutdown();
sRemoteDecoderManagerChildThread->BeginShutdown();
sRemoteDecoderManagerChildThread->AwaitShutdownAndIdle();
sRemoteDecoderManagerChildThread = nullptr;
sRecreateTasks = nullptr;
@ -96,7 +94,7 @@ void RemoteDecoderManagerChild::Shutdown() {
void RemoteDecoderManagerChild::RunWhenGPUProcessRecreated(
already_AddRefed<Runnable> aTask) {
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
MOZ_ASSERT(GetManagerThread() && GetManagerThread()->IsOnCurrentThread());
// If we've already been recreated, then run the task immediately.
if (GetGPUProcessSingleton() && GetGPUProcessSingleton() != this &&
@ -110,18 +108,18 @@ void RemoteDecoderManagerChild::RunWhenGPUProcessRecreated(
/* static */
RemoteDecoderManagerChild* RemoteDecoderManagerChild::GetRDDProcessSingleton() {
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
MOZ_ASSERT(GetManagerThread() && GetManagerThread()->IsOnCurrentThread());
return sRemoteDecoderManagerChildForRDDProcess;
}
/* static */
RemoteDecoderManagerChild* RemoteDecoderManagerChild::GetGPUProcessSingleton() {
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
MOZ_ASSERT(GetManagerThread() && GetManagerThread()->IsOnCurrentThread());
return sRemoteDecoderManagerChildForGPUProcess;
}
/* static */
nsIThread* RemoteDecoderManagerChild::GetManagerThread() {
nsISerialEventTarget* RemoteDecoderManagerChild::GetManagerThread() {
return sRemoteDecoderManagerChildThread;
}
@ -151,7 +149,7 @@ RemoteDecoderManagerChild::RemoteDecoderManagerChild(
void RemoteDecoderManagerChild::OpenForRDDProcess(
Endpoint<PRemoteDecoderManagerChild>&& aEndpoint) {
MOZ_ASSERT(NS_GetCurrentThread() == GetManagerThread());
MOZ_ASSERT(GetManagerThread() && GetManagerThread()->IsOnCurrentThread());
// Only create RemoteDecoderManagerChild, bind new endpoint and init
// ipdl if:
// 1) haven't init'd sRemoteDecoderManagerChild
@ -199,18 +197,17 @@ void RemoteDecoderManagerChild::InitIPDL() {
void RemoteDecoderManagerChild::ActorDealloc() { mIPDLSelfRef = nullptr; }
bool RemoteDecoderManagerChild::DeallocShmem(mozilla::ipc::Shmem& aShmem) {
if (NS_GetCurrentThread() != sRemoteDecoderManagerChildThread) {
if (!sRemoteDecoderManagerChildThread->IsOnCurrentThread()) {
RefPtr<RemoteDecoderManagerChild> self = this;
mozilla::ipc::Shmem shmem = aShmem;
sRemoteDecoderManagerChildThread->Dispatch(
NS_NewRunnableFunction("RemoteDecoderManagerChild::DeallocShmem",
[self, shmem]() {
if (self->CanSend()) {
mozilla::ipc::Shmem shmemCopy = shmem;
self->DeallocShmem(shmemCopy);
}
}),
NS_DISPATCH_NORMAL);
MOZ_ALWAYS_SUCCEEDS(
sRemoteDecoderManagerChildThread->Dispatch(NS_NewRunnableFunction(
"RemoteDecoderManagerChild::DeallocShmem", [self, shmem]() {
if (self->CanSend()) {
mozilla::ipc::Shmem shmemCopy = shmem;
self->DeallocShmem(shmemCopy);
}
})));
return true;
}
return PRemoteDecoderManagerChild::DeallocShmem(aShmem);
@ -242,14 +239,12 @@ already_AddRefed<SourceSurface> RemoteDecoderManagerChild::Readback(
RefPtr<RemoteDecoderManagerChild> ref = this;
SurfaceDescriptor sd;
if (NS_FAILED(sRemoteDecoderManagerChildThread->Dispatch(
NS_NewRunnableFunction("RemoteDecoderManagerChild::Readback",
[&]() {
AutoCompleteTask complete(&task);
if (ref->CanSend()) {
ref->SendReadback(aSD, &sd);
}
}),
NS_DISPATCH_NORMAL))) {
NS_NewRunnableFunction("RemoteDecoderManagerChild::Readback", [&]() {
AutoCompleteTask complete(&task);
if (ref->CanSend()) {
ref->SendReadback(aSD, &sd);
}
})))) {
return nullptr;
}
@ -278,15 +273,14 @@ void RemoteDecoderManagerChild::DeallocateSurfaceDescriptor(
const SurfaceDescriptorGPUVideo& aSD) {
RefPtr<RemoteDecoderManagerChild> ref = this;
SurfaceDescriptorGPUVideo sd = std::move(aSD);
sRemoteDecoderManagerChildThread->Dispatch(
NS_NewRunnableFunction(
MOZ_ALWAYS_SUCCEEDS(
sRemoteDecoderManagerChildThread->Dispatch(NS_NewRunnableFunction(
"RemoteDecoderManagerChild::DeallocateSurfaceDescriptor",
[ref, sd]() {
if (ref->CanSend()) {
ref->SendDeallocateSurfaceDescriptorGPUVideo(sd);
}
}),
NS_DISPATCH_NORMAL);
})));
}
void RemoteDecoderManagerChild::HandleFatalError(const char* aMsg) const {

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

@ -25,7 +25,7 @@ class RemoteDecoderManagerChild final
static RemoteDecoderManagerChild* GetGPUProcessSingleton();
// Can be called from any thread.
static nsIThread* GetManagerThread();
static nsISerialEventTarget* GetManagerThread();
// Can be called from any thread, dispatches the request to the IPDL thread
// internally and will be ignored if the IPDL actor has been destroyed.

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

@ -5,20 +5,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "RemoteDecoderModule.h"
#include "base/thread.h"
#include "mozilla/dom/ContentChild.h" // for launching RDD w/ ContentChild
#include "mozilla/layers/SynchronousTask.h"
#include "mozilla/StaticPrefs_media.h"
#include "mozilla/SyncRunnable.h"
#include "mozilla/dom/ContentChild.h" // for launching RDD w/ ContentChild
#include "mozilla/layers/SynchronousTask.h"
#ifdef MOZ_AV1
# include "AOMDecoder.h"
#endif
#include "OpusDecoder.h"
#include "RemoteAudioDecoder.h"
#include "RemoteDecoderManagerChild.h"
#include "RemoteMediaDataDecoder.h"
#include "RemoteVideoDecoder.h"
#include "OpusDecoder.h"
#include "VideoUtils.h"
#include "VorbisDecoder.h"
#include "WAVDecoder.h"