Bug 1595994 - PD: Allow WMF decoding inside RDD process. r=mattwoodrow

This assumes that access to Windows WMF and DirectX is allowed from RDD process.

Depends on D91699

Differential Revision: https://phabricator.services.mozilla.com/D54883
This commit is contained in:
Dan Glastonbury 2020-10-20 23:26:52 +00:00
parent 9c5439655a
commit 7ab5253afe
12 changed files with 112 additions and 11 deletions

View File

@ -44,7 +44,8 @@ parent:
async UpdateVar(GfxVarUpdate var);
async InitVideoBridge(Endpoint<PVideoBridgeChild> endpoint);
async InitVideoBridge(Endpoint<PVideoBridgeChild> endpoint,
ContentDeviceData contentDeviceData);
async GetUntrustedModulesData() returns (UntrustedModulesData? data);

View File

@ -6,6 +6,8 @@
#include "RDDParent.h"
#if defined(XP_WIN)
# include "mozilla/gfx/DeviceManagerDx.h"
# include "WMF.h"
# include <process.h>
# include <dwrite.h>
# include "mozilla/WinDllServices.h"
@ -22,6 +24,7 @@
#include "mozilla/ipc/CrashReporterClient.h"
#include "mozilla/ipc/ProcessChild.h"
#include "mozilla/gfx/gfxVars.h"
#include "gfxConfig.h"
#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
# include "mozilla/Sandbox.h"
@ -90,7 +93,12 @@ bool RDDParent::Init(base::ProcessId aParentPid, const char* aParentBuildID,
return false;
}
gfxConfig::Init();
gfxVars::Initialize();
#ifdef XP_WIN
DeviceManagerDx::Init();
wmf::MFStartup();
#endif
mozilla::ipc::SetThisProcessName("RDD Process");
@ -157,11 +165,33 @@ mozilla::ipc::IPCResult RDDParent::RecvNewContentRemoteDecoderManager(
}
mozilla::ipc::IPCResult RDDParent::RecvInitVideoBridge(
Endpoint<PVideoBridgeChild>&& aEndpoint) {
Endpoint<PVideoBridgeChild>&& aEndpoint,
const ContentDeviceData& aContentDeviceData) {
if (!RemoteDecoderManagerParent::CreateVideoBridgeToOtherProcess(
std::move(aEndpoint))) {
return IPC_FAIL_NO_REASON(this);
}
gfxConfig::Inherit(
{
Feature::HW_COMPOSITING,
Feature::D3D11_COMPOSITING,
Feature::OPENGL_COMPOSITING,
Feature::ADVANCED_LAYERS,
Feature::DIRECT2D,
Feature::WEBGPU,
},
aContentDeviceData.prefs());
#ifdef XP_WIN
if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
auto* devmgr = DeviceManagerDx::Get();
if (devmgr) {
devmgr->ImportDeviceInfo(aContentDeviceData.d3d11());
devmgr->CreateContentDevices();
}
}
#endif
return IPC_OK();
}
@ -208,6 +238,9 @@ void RDDParent::ActorDestroy(ActorDestroyReason aWhy) {
}
#ifndef NS_FREE_PERMANENT_DATA
# ifdef XP_WIN
wmf::MFShutdown();
# endif
// No point in going through XPCOM shutdown because we don't keep persistent
// state.
ProcessChild::QuickExit();
@ -217,6 +250,10 @@ void RDDParent::ActorDestroy(ActorDestroyReason aWhy) {
mShutdownBlockers.WaitUntilClear(10 * 1000 /* 10s timeout*/)
->Then(GetCurrentSerialEventTarget(), __func__, [this]() {
#ifdef XP_WIN
wmf::MFShutdown();
#endif
#if defined(XP_WIN)
RefPtr<DllServices> dllSvc(DllServices::Get());
dllSvc->DisableFull();
@ -231,7 +268,11 @@ void RDDParent::ActorDestroy(ActorDestroyReason aWhy) {
RemoteDecoderManagerParent::ShutdownVideoBridge();
#ifdef XP_WIN
DeviceManagerDx::Shutdown();
#endif
gfxVars::Shutdown();
gfxConfig::Shutdown();
CrashReporterClient::DestroySingleton();
XRE_ShutdownChildProcess();
});

View File

@ -36,7 +36,8 @@ class RDDParent final : public PRDDParent {
mozilla::ipc::IPCResult RecvNewContentRemoteDecoderManager(
Endpoint<PRemoteDecoderManagerParent>&& aEndpoint);
mozilla::ipc::IPCResult RecvInitVideoBridge(
Endpoint<PVideoBridgeChild>&& aEndpoint);
Endpoint<PVideoBridgeChild>&& aEndpoint,
const ContentDeviceData& aContentDeviceData);
mozilla::ipc::IPCResult RecvRequestMemoryReport(
const uint32_t& generation, const bool& anonymize,
const bool& minimizeMemoryUsage,

View File

@ -255,7 +255,10 @@ bool RDDProcessManager::CreateVideoBridge() {
return false;
}
mRDDChild->SendInitVideoBridge(std::move(childPipe));
ContentDeviceData contentDeviceData;
gfxPlatform::GetPlatform()->BuildContentDeviceData(&contentDeviceData);
mRDDChild->SendInitVideoBridge(std::move(childPipe), contentDeviceData);
if (gpuProcessPid != -1) {
gpuManager->InitVideoBridge(std::move(parentPipe));
} else {

View File

@ -356,6 +356,12 @@ void PDMFactory::CreateGpuPDMs() {
void PDMFactory::CreateRddPDMs() {
MOZ_ASSERT(XRE_IsRDDProcess());
#ifdef XP_WIN
if (StaticPrefs::media_wmf_enabled() &&
StaticPrefs::media_rdd_wmf_enabled()) {
CreateAndStartupPDM<WMFDecoderModule>();
}
#endif
CreateAndStartupPDM<AgnosticDecoderModule>();
}

View File

@ -104,8 +104,8 @@ void WMFDecoderModule::Init() {
// directly calls WMFDecoderModule::Supports in the content process.
// This unnecessary requirement will be fixed in bug 1534815.
testForVPx = true;
} else if (XRE_IsGPUProcess()) {
// Always allow DXVA in the GPU process.
} else if (XRE_IsGPUProcess() || XRE_IsRDDProcess()) {
// Always allow DXVA in the GPU or RDD process.
testForVPx = sDXVAEnabled = true;
} else {
// Only allow DXVA in the UI process if we aren't in e10s Firefox

View File

@ -925,7 +925,7 @@ WMFVideoMFTManager::CreateBasicVideoFrame(IMFSample* aSample,
!mKnowsCompositor->SupportsD3D11() || !mIMFUsable) {
RefPtr<VideoData> v = VideoData::CreateAndCopyData(
mVideoInfo, mImageContainer, aStreamOffset, pts, duration, b, false,
TimeUnit::FromMicroseconds(-1), pictureRegion);
TimeUnit::FromMicroseconds(-1), pictureRegion, mKnowsCompositor);
if (twoDBuffer) {
twoDBuffer->Unlock2D();
} else {

View File

@ -152,6 +152,37 @@ void gfxConfig::Inherit(Feature aFeature, FeatureStatus aStatus) {
}
}
/* static */
void gfxConfig::Inherit(EnumSet<Feature> aFeatures,
const DevicePrefs& aDevicePrefs) {
for (Feature feature : aFeatures) {
FeatureStatus status = FeatureStatus::Unused;
switch (feature) {
case Feature::HW_COMPOSITING:
status = aDevicePrefs.hwCompositing();
break;
case Feature::D3D11_COMPOSITING:
status = aDevicePrefs.d3d11Compositing();
break;
case Feature::OPENGL_COMPOSITING:
status = aDevicePrefs.oglCompositing();
break;
case Feature::ADVANCED_LAYERS:
status = aDevicePrefs.advancedLayers();
break;
case Feature::DIRECT2D:
status = aDevicePrefs.useD2D1();
break;
case Feature::WEBGPU:
status = aDevicePrefs.webGPU();
break;
default:
break;
}
gfxConfig::Inherit(feature, status);
}
}
/* static */
bool gfxConfig::UseFallback(Fallback aFallback) {
return sConfig->UseFallbackImpl(aFallback);

View File

@ -10,12 +10,14 @@
#include "gfxFeature.h"
#include "gfxFallback.h"
#include "mozilla/Assertions.h"
#include "mozilla/EnumSet.h"
#include "mozilla/Maybe.h"
namespace mozilla {
namespace gfx {
// Defined in GraphicsMessages.ipdlh.
class DevicePrefs;
class FeatureFailure;
// Manages the history and state of a graphics feature. The flow of a feature
@ -78,6 +80,10 @@ class gfxConfig {
// Inherit a computed value from another process.
static void Inherit(Feature aFeature, FeatureStatus aStatus);
// Inherit a set of computed values from another process.
static void Inherit(EnumSet<Feature> aFeatures,
const DevicePrefs& aDevicePrefs);
// Set a environment status that overrides both the default and user
// statuses; this should be used to disable features based on system
// or hardware problems that can be determined up-front. The only

View File

@ -59,9 +59,9 @@ void DriverCrashGuard::InitializeIfNeeded() {
}
static inline bool AreCrashGuardsEnabled(CrashGuardType aType) {
// Crash guard isn't supported in the GPU process since the entire
// Crash guard isn't supported in the GPU or RDD process since the entire
// process is basically a crash guard.
if (XRE_IsGPUProcess()) {
if (XRE_IsGPUProcess() || XRE_IsRDDProcess()) {
return false;
}
#ifdef NIGHTLY_BUILD

View File

@ -509,8 +509,9 @@ IDXGIAdapter1* DeviceManagerDx::GetDXGIAdapter() {
// should never reach here. Furthermore, the UI process does not create
// devices when using a GPU process.
//
// So, this should only ever get called on the content process.
MOZ_ASSERT(XRE_IsContentProcess());
// So, this should only ever get called on the content process or RDD
// process
MOZ_ASSERT(XRE_IsContentProcess() || XRE_IsRDDProcess());
// In the child process, we search for the adapter that matches the parent
// process. The first adapter can be mismatched on dual-GPU systems.

View File

@ -7069,6 +7069,17 @@
value: 5000
mirror: always
#ifdef MOZ_WMF
- name: media.rdd-wmf.enabled
type: RelaxedAtomicBool
#if defined(XP_WIN) && !defined(_ARM64_)
value: true
#else
value: false
#endif
mirror: always
#endif
- name: media.rdd-vorbis.enabled
type: RelaxedAtomicBool
#if defined(XP_LINUX) && !defined(ANDROID)