зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1672072 - P9. Make EnsureRDDProcessAndCreateBridge an async API. r=mattwoodrow,bryce,mjf,padenot,ipc-reviewers,mccr8
We can now chaincreation of the decoder to the launch of the RDD process as needed and setting up the PRemoteDecoderManager Differential Revision: https://phabricator.services.mozilla.com/D96365
This commit is contained in:
Родитель
7a6315ba80
Коммит
8ffdd4eaef
|
@ -26,8 +26,9 @@ using namespace layers;
|
|||
using namespace gfx;
|
||||
|
||||
// Used so that we only ever attempt to check if the RDD process should be
|
||||
// launched serially.
|
||||
// launched serially. Protects sLaunchPromise
|
||||
StaticMutex sLaunchMutex;
|
||||
static StaticRefPtr<GenericNonExclusivePromise> sLaunchRDDPromise;
|
||||
|
||||
// Only modified on the main-thread, read on any thread. While it could be read
|
||||
// on the main thread directly, for clarity we force access via the DataMutex
|
||||
|
@ -202,9 +203,9 @@ RemoteDecoderManagerChild::CreateAudioDecoder(
|
|||
return PlatformDecoderModule::CreateDecoderPromise::CreateAndReject(
|
||||
NS_ERROR_DOM_MEDIA_CANCELED, __func__);
|
||||
}
|
||||
return InvokeAsync(
|
||||
return LaunchRDDProcessIfNeeded()->Then(
|
||||
managerThread, __func__,
|
||||
[params = CreateDecoderParamsForAsync(aParams)]() {
|
||||
[params = CreateDecoderParamsForAsync(aParams)](bool) {
|
||||
auto child = MakeRefPtr<RemoteAudioDecoderChild>();
|
||||
MediaResult result =
|
||||
child->InitIPDL(params.AudioConfig(), params.mOptions);
|
||||
|
@ -213,6 +214,10 @@ RemoteDecoderManagerChild::CreateAudioDecoder(
|
|||
result, __func__);
|
||||
}
|
||||
return Construct(std::move(child));
|
||||
},
|
||||
[](nsresult aResult) {
|
||||
return PlatformDecoderModule::CreateDecoderPromise::CreateAndReject(
|
||||
MediaResult(aResult, "Couldn't start RDD process"), __func__);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -235,10 +240,15 @@ RemoteDecoderManagerChild::CreateVideoDecoder(
|
|||
}
|
||||
|
||||
MOZ_ASSERT(aLocation != RemoteDecodeIn::Unspecified);
|
||||
return InvokeAsync(
|
||||
|
||||
RefPtr<GenericNonExclusivePromise> p =
|
||||
aLocation == RemoteDecodeIn::GpuProcess
|
||||
? GenericNonExclusivePromise::CreateAndResolve(true, __func__)
|
||||
: LaunchRDDProcessIfNeeded();
|
||||
|
||||
return p->Then(
|
||||
managerThread, __func__,
|
||||
[aLocation, params = CreateDecoderParamsForAsync(aParams)]()
|
||||
-> RefPtr<PlatformDecoderModule::CreateDecoderPromise> {
|
||||
[aLocation, params = CreateDecoderParamsForAsync(aParams)](bool) {
|
||||
auto child = MakeRefPtr<RemoteVideoDecoderChild>(aLocation);
|
||||
MediaResult result = child->InitIPDL(
|
||||
params.VideoConfig(), params.mRate.mValue, params.mOptions,
|
||||
|
@ -250,6 +260,10 @@ RemoteDecoderManagerChild::CreateVideoDecoder(
|
|||
result, __func__);
|
||||
}
|
||||
return Construct(std::move(child));
|
||||
},
|
||||
[](nsresult aResult) {
|
||||
return PlatformDecoderModule::CreateDecoderPromise::CreateAndReject(
|
||||
MediaResult(aResult, "Couldn't start RDD process"), __func__);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -287,24 +301,24 @@ RemoteDecoderManagerChild::Construct(RefPtr<RemoteDecoderChild>&& aChild) {
|
|||
}
|
||||
|
||||
/* static */
|
||||
void RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(
|
||||
RemoteDecodeIn aLocation) {
|
||||
RefPtr<GenericNonExclusivePromise>
|
||||
RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded() {
|
||||
MOZ_DIAGNOSTIC_ASSERT(XRE_IsContentProcess(),
|
||||
"Only supported from a content process.");
|
||||
|
||||
if (aLocation != RemoteDecodeIn::RddProcess) {
|
||||
// Not targeting RDD process? No need to launch RDD.
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISerialEventTarget> managerThread = GetManagerThread();
|
||||
if (!managerThread) {
|
||||
// We got shutdown.
|
||||
return;
|
||||
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_FAILURE,
|
||||
__func__);
|
||||
}
|
||||
|
||||
StaticMutexAutoLock lock(sLaunchMutex);
|
||||
|
||||
if (sLaunchRDDPromise) {
|
||||
return sLaunchRDDPromise;
|
||||
}
|
||||
|
||||
// We have a couple possible states here. We are in a content process
|
||||
// and:
|
||||
// 1) the RDD process has never been launched. RDD should be launched
|
||||
|
@ -319,33 +333,51 @@ void RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(
|
|||
// LaunchRDDProcess which will launch RDD if necessary, and setup the
|
||||
// IPC connections between *this* content process and the RDD process.
|
||||
|
||||
bool needsLaunch = true;
|
||||
RefPtr<Runnable> task = NS_NewRunnableFunction(
|
||||
"RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded-CheckSend", [&]() {
|
||||
RefPtr<GenericNonExclusivePromise> p = InvokeAsync(
|
||||
managerThread, __func__, []() -> RefPtr<GenericNonExclusivePromise> {
|
||||
auto* rps = GetSingleton(RemoteDecodeIn::RddProcess);
|
||||
needsLaunch = rps ? !rps->CanSend() : true;
|
||||
});
|
||||
if (NS_FAILED(SyncRunnable::DispatchToThread(managerThread, task))) {
|
||||
return;
|
||||
};
|
||||
if (rps && rps->CanSend()) {
|
||||
return GenericNonExclusivePromise::CreateAndResolve(true, __func__);
|
||||
}
|
||||
nsCOMPtr<nsISerialEventTarget> managerThread = GetManagerThread();
|
||||
ipc::PBackgroundChild* bgActor =
|
||||
ipc::BackgroundChild::GetForCurrentThread();
|
||||
if (!managerThread || NS_WARN_IF(!bgActor)) {
|
||||
return GenericNonExclusivePromise::CreateAndReject(NS_ERROR_FAILURE,
|
||||
__func__);
|
||||
}
|
||||
|
||||
if (needsLaunch) {
|
||||
managerThread->Dispatch(NS_NewRunnableFunction(
|
||||
"RemoteDecoderManagerChild::EnsureRDDProcessAndCreateBridge", [&]() {
|
||||
ipc::PBackgroundChild* bgActor =
|
||||
ipc::BackgroundChild::GetForCurrentThread();
|
||||
if (NS_WARN_IF(!bgActor)) {
|
||||
return;
|
||||
}
|
||||
nsresult rv;
|
||||
Endpoint<PRemoteDecoderManagerChild> endpoint;
|
||||
Unused << bgActor->SendEnsureRDDProcessAndCreateBridge(&rv,
|
||||
&endpoint);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
OpenForRDDProcess(std::move(endpoint));
|
||||
}
|
||||
}));
|
||||
}
|
||||
return bgActor->SendEnsureRDDProcessAndCreateBridge()->Then(
|
||||
managerThread, __func__,
|
||||
[](ipc::PBackgroundChild::EnsureRDDProcessAndCreateBridgePromise::
|
||||
ResolveOrRejectValue&& aResult) {
|
||||
nsCOMPtr<nsISerialEventTarget> managerThread = GetManagerThread();
|
||||
if (!managerThread || aResult.IsReject()) {
|
||||
// The parent process died or we got shutdown
|
||||
return GenericNonExclusivePromise::CreateAndReject(
|
||||
NS_ERROR_FAILURE, __func__);
|
||||
}
|
||||
nsresult rv = Get<0>(aResult.ResolveValue());
|
||||
if (NS_FAILED(rv)) {
|
||||
return GenericNonExclusivePromise::CreateAndReject(rv,
|
||||
__func__);
|
||||
}
|
||||
OpenForRDDProcess(Get<1>(std::move(aResult.ResolveValue())));
|
||||
return GenericNonExclusivePromise::CreateAndResolve(true,
|
||||
__func__);
|
||||
});
|
||||
});
|
||||
|
||||
p = p->Then(
|
||||
GetCurrentSerialEventTarget(), __func__,
|
||||
[](const GenericNonExclusivePromise::ResolveOrRejectValue& aResult) {
|
||||
StaticMutexAutoLock lock(sLaunchMutex);
|
||||
sLaunchRDDPromise = nullptr;
|
||||
return GenericNonExclusivePromise::CreateAndResolveOrReject(aResult,
|
||||
__func__);
|
||||
});
|
||||
sLaunchRDDPromise = p;
|
||||
return sLaunchRDDPromise;
|
||||
}
|
||||
|
||||
PRemoteDecoderChild* RemoteDecoderManagerChild::AllocPRemoteDecoderChild(
|
||||
|
|
|
@ -44,7 +44,6 @@ class RemoteDecoderManagerChild final
|
|||
|
||||
// Can be called from any thread.
|
||||
static nsISerialEventTarget* GetManagerThread();
|
||||
static void LaunchRDDProcessIfNeeded(RemoteDecodeIn aLocation);
|
||||
|
||||
// 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.
|
||||
|
@ -106,6 +105,7 @@ class RemoteDecoderManagerChild final
|
|||
Endpoint<PRemoteDecoderManagerChild>&& aEndpoint);
|
||||
static void OpenForGPUProcess(
|
||||
Endpoint<PRemoteDecoderManagerChild>&& aEndpoint);
|
||||
static RefPtr<GenericNonExclusivePromise> LaunchRDDProcessIfNeeded();
|
||||
|
||||
RefPtr<RemoteDecoderManagerChild> mIPDLSelfRef;
|
||||
// The location for decoding, Rdd or Gpu process.
|
||||
|
|
|
@ -5,11 +5,6 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
#include "RemoteDecoderModule.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
|
||||
|
@ -63,8 +58,6 @@ bool RemoteDecoderModule::Supports(
|
|||
|
||||
RefPtr<RemoteDecoderModule::CreateDecoderPromise>
|
||||
RemoteDecoderModule::AsyncCreateDecoder(const CreateDecoderParams& aParams) {
|
||||
RemoteDecoderManagerChild::LaunchRDDProcessIfNeeded(mLocation);
|
||||
|
||||
if (aParams.mConfig.IsAudio()) {
|
||||
// OpusDataDecoder will check this option to provide the same info
|
||||
// that IsDefaultPlaybackDeviceMono provides. We want to avoid calls
|
||||
|
|
|
@ -1314,13 +1314,16 @@ mozilla::ipc::IPCResult BackgroundParentImpl::RecvPEndpointForReportConstructor(
|
|||
|
||||
mozilla::ipc::IPCResult
|
||||
BackgroundParentImpl::RecvEnsureRDDProcessAndCreateBridge(
|
||||
nsresult* aRv, Endpoint<PRemoteDecoderManagerChild>* aEndpoint) {
|
||||
EnsureRDDProcessAndCreateBridgeResolver&& aResolver) {
|
||||
RDDProcessManager* rdd = RDDProcessManager::Get();
|
||||
if (rdd && rdd->EnsureRDDProcessAndCreateBridge(OtherPid(), aEndpoint)) {
|
||||
*aRv = NS_OK;
|
||||
} else {
|
||||
*aRv = NS_ERROR_NOT_AVAILABLE;
|
||||
}
|
||||
Endpoint<PRemoteDecoderManagerChild> endpoint;
|
||||
nsresult rv =
|
||||
rdd && rdd->EnsureRDDProcessAndCreateBridge(OtherPid(), &endpoint)
|
||||
? NS_OK
|
||||
: NS_ERROR_NOT_AVAILABLE;
|
||||
aResolver(
|
||||
Tuple<const nsresult&, Endpoint<mozilla::PRemoteDecoderManagerChild>&&>(
|
||||
rv, std::move(endpoint)));
|
||||
|
||||
return IPC_OK();
|
||||
}
|
||||
|
|
|
@ -392,7 +392,7 @@ class BackgroundParentImpl : public PBackgroundParent,
|
|||
const PrincipalInfo& aPrincipalInfo) override;
|
||||
|
||||
mozilla::ipc::IPCResult RecvEnsureRDDProcessAndCreateBridge(
|
||||
nsresult* aRv, Endpoint<PRemoteDecoderManagerChild>* aEndpoint) override;
|
||||
EnsureRDDProcessAndCreateBridgeResolver&& aResolver) override;
|
||||
|
||||
bool DeallocPEndpointForReportParent(
|
||||
PEndpointForReportParent* aActor) override;
|
||||
|
|
|
@ -263,8 +263,7 @@ parent:
|
|||
uint32_t aProviderFlags,
|
||||
uint32_t aCertVerifierFlags);
|
||||
|
||||
// See Bug 1518344 - Investigate using async for PBackground::EnsureRDDProcessAndCreateBridge
|
||||
sync EnsureRDDProcessAndCreateBridge()
|
||||
async EnsureRDDProcessAndCreateBridge()
|
||||
returns (nsresult rv, Endpoint<PRemoteDecoderManagerChild> aEndpoint);
|
||||
|
||||
child:
|
||||
|
|
|
@ -884,8 +884,6 @@ description = legacy sync IPC - please add detailed description
|
|||
description = legacy sync IPC - please add detailed description
|
||||
[PRemoteDecoderManager::Readback]
|
||||
description = legacy sync IPC - please add detailed description
|
||||
[PBackground::EnsureRDDProcessAndCreateBridge]
|
||||
description = See Bug 1518344 - investigate using async for PBackground::EnsureRDDProcessAndCreateBridge
|
||||
[PBackgroundStorage::Preload]
|
||||
description = legacy sync IPC - please add detailed description
|
||||
[PBackgroundLSDatabase::PBackgroundLSSnapshot]
|
||||
|
|
Загрузка…
Ссылка в новой задаче