Refactor cross-process acceleration controls. (bug 1294988 part 4, r=mattwoodrow)

This commit is contained in:
David Anderson 2016-08-20 20:59:11 -07:00
parent 7df82d4b70
commit 396d5d1191
14 changed files with 240 additions and 182 deletions

View File

@ -5174,9 +5174,9 @@ ContentParent::RecvProfile(const nsCString& aProfile)
}
bool
ContentParent::RecvGetGraphicsDeviceInitData(DeviceInitData* aOut)
ContentParent::RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut)
{
gfxPlatform::GetPlatform()->GetDeviceInitData(aOut);
gfxPlatform::GetPlatform()->BuildContentDeviceData(aOut);
return true;
}

View File

@ -1107,7 +1107,7 @@ private:
virtual bool RecvProfile(const nsCString& aProfile) override;
virtual bool RecvGetGraphicsDeviceInitData(DeviceInitData* aOut) override;
virtual bool RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut) override;
void StartProfiler(nsIProfilerStartParams* aParams);

View File

@ -1141,7 +1141,7 @@ parent:
* Request graphics initialization information from the parent.
*/
sync GetGraphicsDeviceInitData()
returns (DeviceInitData aData);
returns (ContentDeviceData aData);
sync CreateWindow(nullable PBrowser aThisTab,
PBrowser aNewTab,

View File

@ -146,6 +146,8 @@ gfxConfig::Inherit(Feature aFeature, FeatureStatus aStatus)
{
FeatureState& state = sConfig->GetState(aFeature);
state.Reset();
switch (aStatus) {
case FeatureStatus::Unused:
break;

View File

@ -263,12 +263,24 @@ FeatureState::GetFailureId() const
return mFailureId;
}
void
FeatureState::Reset()
{
mDefault.Set(FeatureStatus::Unused);
mUser.Set(FeatureStatus::Unused);
mEnvironment.Set(FeatureStatus::Unused);
mRuntime.Set(FeatureStatus::Unused);
mFailureId = nsCString();
}
void
FeatureState::Instance::Set(FeatureStatus aStatus, const char* aMessage /* = nullptr */)
{
mStatus = aStatus;
if (aMessage) {
SprintfLiteral(mMessage, "%s", aMessage);
} else {
mMessage[0] = '\0';
}
}

View File

@ -85,6 +85,9 @@ class FeatureState
MOZ_ASSERT(IsInitialized());
}
// Clear all state.
void Reset();
private:
void SetFailureId(const nsACString& aFailureId);

View File

@ -13,14 +13,10 @@ using mozilla::gfx::IntSize from "mozilla/gfx/Point.h";
namespace mozilla {
namespace gfx {
struct DeviceInitData
struct D3D11DeviceStatus
{
bool useHwCompositing;
// Windows only.
bool useD3D11;
bool d3d11TextureSharingWorks;
bool useD2D1;
bool isWARP;
bool textureSharingWorks;
DxgiAdapterDesc adapter;
};
@ -33,6 +29,12 @@ struct DevicePrefs
FeatureStatus useD2D1;
};
struct ContentDeviceData
{
DevicePrefs prefs;
D3D11DeviceStatus d3d11;
};
union GfxVarValue
{
BackendType;

View File

@ -43,8 +43,6 @@ DeviceManagerD3D11::Shutdown()
DeviceManagerD3D11::DeviceManagerD3D11()
: mDeviceLock("gfxWindowsPlatform.mDeviceLock"),
mIsWARP(false),
mTextureSharingWorks(false),
mCompositorDeviceSupportsVideo(false)
{
// Set up the D3D11 feature levels we can ask for.
@ -97,10 +95,17 @@ DeviceManagerD3D11::ReleaseD3D11()
sD3D11CreateDeviceFn = nullptr;
}
static inline bool
ProcessOwnsCompositor()
{
return XRE_GetProcessType() == GeckoProcessType_GPU ||
(XRE_IsParentProcess() && !gfxConfig::IsEnabled(Feature::GPU_PROCESS));
}
bool
DeviceManagerD3D11::CreateCompositorDevices()
{
MOZ_ASSERT(XRE_IsParentProcess() || XRE_GetProcessType() == GeckoProcessType_GPU);
MOZ_ASSERT(ProcessOwnsCompositor());
FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
MOZ_ASSERT(d3d11.IsEnabled());
@ -127,13 +132,22 @@ DeviceManagerD3D11::CreateCompositorDevices()
}
void
DeviceManagerD3D11::InheritDeviceInfo(const DeviceInitData& aDeviceInfo)
DeviceManagerD3D11::ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus)
{
MOZ_ASSERT_IF(!XRE_IsContentProcess(),
XRE_IsParentProcess() && gfxPrefs::GPUProcessDevEnabled());
MOZ_ASSERT(!ProcessOwnsCompositor());
mIsWARP = gfxPrefs::LayersD3D11ForceWARP();
mTextureSharingWorks = aDeviceInfo.d3d11TextureSharingWorks();
mDeviceStatus = Some(aDeviceStatus);
}
void
DeviceManagerD3D11::ExportDeviceInfo(D3D11DeviceStatus* aOut)
{
MOZ_ASSERT(ProcessOwnsCompositor());
MOZ_ASSERT(!!mCompositorDevice == !!mDeviceStatus);
if (mDeviceStatus) {
*aOut = mDeviceStatus.value();
}
}
void
@ -145,6 +159,10 @@ DeviceManagerD3D11::CreateContentDevices()
return;
}
// We should have been assigned a DeviceStatus from the parent process,
// GPU process, or the same process if using in-process compositing.
MOZ_ASSERT(mDeviceStatus);
if (CreateContentDevice() == FeatureStatus::CrashedInHandler) {
DisableD3D11AfterCrash();
}
@ -176,14 +194,21 @@ DeviceManagerD3D11::GetDXGIAdapter()
return nullptr;
}
if (!XRE_IsContentProcess()) {
// In the parent process, we pick the first adapter.
if (!mDeviceStatus) {
// If we haven't created a device yet, and have no existing device status,
// then this must be the compositor device. Pick the first adapter we can.
MOZ_ASSERT(ProcessOwnsCompositor());
if (FAILED(factory1->EnumAdapters1(0, getter_AddRefs(mAdapter)))) {
return nullptr;
}
} else {
const DxgiAdapterDesc& parent =
gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
// In the UI and GPU process, we clear mDeviceStatus on device reset, so we
// 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());
// In the child process, we search for the adapter that matches the parent
// process. The first adapter can be mismatched on dual-GPU systems.
@ -193,12 +218,14 @@ DeviceManagerD3D11::GetDXGIAdapter()
break;
}
const DxgiAdapterDesc& preferred = mDeviceStatus->adapter();
DXGI_ADAPTER_DESC desc;
if (SUCCEEDED(adapter->GetDesc(&desc)) &&
desc.AdapterLuid.HighPart == parent.AdapterLuid.HighPart &&
desc.AdapterLuid.LowPart == parent.AdapterLuid.LowPart &&
desc.VendorId == parent.VendorId &&
desc.DeviceId == parent.DeviceId)
desc.AdapterLuid.HighPart == preferred.AdapterLuid.HighPart &&
desc.AdapterLuid.LowPart == preferred.AdapterLuid.LowPart &&
desc.VendorId == preferred.VendorId &&
desc.DeviceId == preferred.DeviceId)
{
mAdapter = adapter.forget();
break;
@ -290,34 +317,38 @@ DeviceManagerD3D11::CreateCompositorDevice(FeatureState& d3d11)
mCompositorDeviceSupportsVideo = true;
}
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
}
// Only test this when not using WARP since it can fail and cause
// GetDeviceRemovedReason to return weird values.
mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
bool textureSharingWorks = D3D11Checks::DoesTextureSharingWork(device);
if (!mTextureSharingWorks) {
DXGI_ADAPTER_DESC desc;
PodZero(&desc);
adapter->GetDesc(&desc);
if (!textureSharingWorks) {
gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
FeatureStatus::Broken,
"Texture sharing doesn't work");
}
if (D3D11Checks::DoesRenderTargetViewNeedRecreating(mCompositorDevice)) {
if (D3D11Checks::DoesRenderTargetViewNeedRecreating(device)) {
gfxConfig::SetFailed(Feature::D3D11_HW_ANGLE,
FeatureStatus::Broken,
"RenderTargetViews need recreating");
}
if (XRE_IsParentProcess()) {
// It seems like this may only happen when we're using the NVIDIA gpu
D3D11Checks::WarnOnAdapterMismatch(mCompositorDevice);
D3D11Checks::WarnOnAdapterMismatch(device);
}
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
mDeviceStatus = Some(D3D11DeviceStatus(
false,
textureSharingWorks,
DxgiAdapterDesc::From(desc)));
}
mCompositorDevice->SetExceptionMode(0);
mIsWARP = false;
}
bool
@ -365,28 +396,37 @@ DeviceManagerD3D11::CreateWARPCompositorDevice()
return;
}
// Only test for texture sharing on Windows 8 since it puts the device into
// an unusable state if used on Windows 7
bool textureSharingWorks = false;
if (IsWin8OrLater()) {
textureSharingWorks = D3D11Checks::DoesTextureSharingWork(device);
}
DxgiAdapterDesc nullAdapter;
PodZero(&nullAdapter);
{
MutexAutoLock lock(mDeviceLock);
mCompositorDevice = device;
}
reporterWARP.SetSuccessful();
// Only test for texture sharing on Windows 8 since it puts the device into
// an unusable state if used on Windows 7
if (IsWin8OrLater()) {
mTextureSharingWorks = D3D11Checks::DoesTextureSharingWork(mCompositorDevice);
mDeviceStatus = Some(D3D11DeviceStatus(
true,
textureSharingWorks,
nullAdapter));
}
mCompositorDevice->SetExceptionMode(0);
mIsWARP = true;
reporterWARP.SetSuccessful();
}
FeatureStatus
DeviceManagerD3D11::CreateContentDevice()
{
RefPtr<IDXGIAdapter1> adapter;
if (!mIsWARP) {
if (!mDeviceStatus->isWARP()) {
adapter = GetDXGIAdapter();
if (!adapter) {
gfxCriticalNote << "Could not get a DXGI adapter";
return FeatureStatus::Unavailable;
}
}
@ -395,7 +435,9 @@ DeviceManagerD3D11::CreateContentDevice()
RefPtr<ID3D11Device> device;
UINT flags = D3D11_CREATE_DEVICE_BGRA_SUPPORT;
D3D_DRIVER_TYPE type = mIsWARP ? D3D_DRIVER_TYPE_WARP : D3D_DRIVER_TYPE_UNKNOWN;
D3D_DRIVER_TYPE type = mDeviceStatus->isWARP()
? D3D_DRIVER_TYPE_WARP
: D3D_DRIVER_TYPE_UNKNOWN;
if (!CreateDevice(adapter, type, flags, hr, device)) {
gfxCriticalNote << "Recovered from crash while creating a D3D11 content device";
gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode::Content);
@ -408,11 +450,6 @@ DeviceManagerD3D11::CreateContentDevice()
return FeatureStatus::Failed;
}
{
MutexAutoLock lock(mDeviceLock);
mContentDevice = device;
}
// InitializeD2D() will abort early if the compositor device did not support
// texture sharing. If we're in the content process, we can't rely on the
// parent device alone: some systems have dual GPUs that are capable of
@ -420,18 +457,18 @@ DeviceManagerD3D11::CreateContentDevice()
// we re-check texture sharing against the newly created D3D11 content device.
// If it fails, we won't use Direct2D.
if (XRE_IsContentProcess()) {
if (!D3D11Checks::DoesTextureSharingWork(mContentDevice)) {
{
MutexAutoLock lock(mDeviceLock);
mContentDevice = nullptr;
}
if (!D3D11Checks::DoesTextureSharingWork(device)) {
return FeatureStatus::Failed;
}
DebugOnly<bool> ok = ContentAdapterIsParentAdapter(mContentDevice);
DebugOnly<bool> ok = ContentAdapterIsParentAdapter(device);
MOZ_ASSERT(ok);
}
{
MutexAutoLock lock(mDeviceLock);
mContentDevice = device;
}
mContentDevice->SetExceptionMode(0);
RefPtr<ID3D10Multithread> multi;
@ -498,6 +535,7 @@ DeviceManagerD3D11::ResetDevices()
mCompositorDevice = nullptr;
mContentDevice = nullptr;
mDeviceStatus = Nothing();
Factory::SetDirect3D11Device(nullptr);
}
@ -510,15 +548,18 @@ DeviceManagerD3D11::ContentAdapterIsParentAdapter(ID3D11Device* device)
return false;
}
const DxgiAdapterDesc& parent =
gfxPlatform::GetPlatform()->GetParentDevicePrefs().adapter();
if (desc.VendorId != parent.VendorId ||
desc.DeviceId != parent.DeviceId ||
desc.SubSysId != parent.SubSysId ||
desc.AdapterLuid.HighPart != parent.AdapterLuid.HighPart ||
desc.AdapterLuid.LowPart != parent.AdapterLuid.LowPart)
const DxgiAdapterDesc& preferred = mDeviceStatus->adapter();
if (desc.VendorId != preferred.VendorId ||
desc.DeviceId != preferred.DeviceId ||
desc.SubSysId != preferred.SubSysId ||
desc.AdapterLuid.HighPart != preferred.AdapterLuid.HighPart ||
desc.AdapterLuid.LowPart != preferred.AdapterLuid.LowPart)
{
gfxCriticalNote << "VendorIDMismatch P " << hexa(parent.VendorId) << " " << hexa(desc.VendorId);
gfxCriticalNote <<
"VendorIDMismatch P " <<
hexa(preferred.VendorId) << " " <<
hexa(desc.VendorId);
return false;
}
@ -599,7 +640,7 @@ DeviceManagerD3D11::GetContentDevice()
}
unsigned
DeviceManagerD3D11::GetD3D11Version() const
DeviceManagerD3D11::GetFeatureLevel() const
{
MOZ_ASSERT(NS_IsMainThread());
if (!mCompositorDevice) {
@ -609,15 +650,23 @@ DeviceManagerD3D11::GetD3D11Version() const
}
bool
DeviceManagerD3D11::TextureSharingWorks() const
DeviceManagerD3D11::TextureSharingWorks()
{
return mTextureSharingWorks;
MutexAutoLock lock(mDeviceLock);
if (!mDeviceStatus) {
return false;
}
return mDeviceStatus->textureSharingWorks();
}
bool
DeviceManagerD3D11::IsWARP() const
DeviceManagerD3D11::IsWARP()
{
return mIsWARP;
MutexAutoLock lock(mDeviceLock);
if (!mDeviceStatus) {
return false;
}
return mDeviceStatus->isWARP();
}
} // namespace gfx

View File

@ -8,9 +8,11 @@
#include "gfxPlatform.h"
#include "gfxTelemetry.h"
#include "mozilla/Maybe.h"
#include "mozilla/Mutex.h"
#include "mozilla/RefPtr.h"
#include "mozilla/StaticPtr.h"
#include "mozilla/gfx/GraphicsMessages.h"
#include "nsTArray.h"
#include "nsWindowsHelpers.h"
@ -52,14 +54,16 @@ public:
RefPtr<ID3D11Device> GetContentDevice();
RefPtr<ID3D11Device> CreateDecoderDevice();
unsigned GetD3D11Version() const;
bool TextureSharingWorks() const;
bool IsWARP() const;
unsigned GetFeatureLevel() const;
bool TextureSharingWorks();
bool IsWARP();
bool CreateCompositorDevices();
void CreateContentDevices();
void InheritDeviceInfo(const DeviceInitData& aDeviceInfo);
void ImportDeviceInfo(const D3D11DeviceStatus& aDeviceStatus);
void ExportDeviceInfo(D3D11DeviceStatus* aOut);
void ResetDevices();
// Call GetDeviceRemovedReason on each device until one returns
@ -107,9 +111,9 @@ private:
RefPtr<ID3D11Device> mCompositorDevice;
RefPtr<ID3D11Device> mContentDevice;
RefPtr<ID3D11Device> mDecoderDevice;
mozilla::Atomic<bool> mIsWARP;
mozilla::Atomic<bool> mTextureSharingWorks;
bool mCompositorDeviceSupportsVideo;
Maybe<D3D11DeviceStatus> mDeviceStatus;
};
} // namespace gfx

View File

@ -10,6 +10,7 @@
#include "mozilla/layers/ISurfaceAllocator.h" // for GfxMemoryImageReporter
#include "mozilla/gfx/gfxVars.h"
#include "mozilla/gfx/GPUProcessManager.h"
#include "mozilla/gfx/GraphicsMessages.h"
#include "mozilla/ClearOnShutdown.h"
#include "mozilla/Telemetry.h"
#include "mozilla/TimeStamp.h"
@ -174,10 +175,6 @@ static qcms_transform *gCMSRGBATransform = nullptr;
static bool gCMSInitialized = false;
static eCMSMode gCMSMode = eCMSMode_Off;
// Device init data should only be used on child processes, so we protect it
// behind a getter here.
static DeviceInitData sDeviceInitDataDoNotUseDirectly;
static void ShutdownCMS();
#include "mozilla/gfx/2D.h"
@ -2246,13 +2243,6 @@ gfxPlatform::GetScaledFontForFontWithCairoSkia(DrawTarget* aTarget, gfxFont* aFo
return nullptr;
}
/* static */ DeviceInitData&
gfxPlatform::GetParentDevicePrefs()
{
MOZ_ASSERT(XRE_IsContentProcess());
return sDeviceInitDataDoNotUseDirectly;
}
/* static */ bool
gfxPlatform::UsesOffMainThreadCompositing()
{
@ -2431,32 +2421,34 @@ gfxPlatform::NotifyCompositorCreated(LayersBackend aBackend)
}
void
gfxPlatform::GetDeviceInitData(mozilla::gfx::DeviceInitData* aOut)
gfxPlatform::FetchAndImportContentDeviceData()
{
MOZ_ASSERT(XRE_IsParentProcess());
aOut->useHwCompositing() = gfxConfig::IsEnabled(Feature::HW_COMPOSITING);
MOZ_ASSERT(XRE_IsContentProcess());
mozilla::dom::ContentChild* cc = mozilla::dom::ContentChild::GetSingleton();
mozilla::gfx::ContentDeviceData data;
cc->SendGetGraphicsDeviceInitData(&data);
ImportContentDeviceData(data);
}
bool
gfxPlatform::UpdateDeviceInitData()
void
gfxPlatform::ImportContentDeviceData(const mozilla::gfx::ContentDeviceData& aData)
{
if (XRE_IsParentProcess()) {
// The parent process figures out device initialization on its own.
return false;
}
MOZ_ASSERT(XRE_IsContentProcess());
mozilla::gfx::DeviceInitData data;
mozilla::dom::ContentChild::GetSingleton()->SendGetGraphicsDeviceInitData(&data);
const DevicePrefs& prefs = aData.prefs();
gfxConfig::Inherit(Feature::HW_COMPOSITING, prefs.hwCompositing());
gfxConfig::Inherit(Feature::OPENGL_COMPOSITING, prefs.oglCompositing());
}
sDeviceInitDataDoNotUseDirectly = data;
// Ensure that child processes have inherited the HW_COMPOSITING pref.
gfxConfig::InitOrUpdate(
Feature::HW_COMPOSITING,
GetParentDevicePrefs().useHwCompositing(),
FeatureStatus::Blocked,
"Hardware-accelerated compositing disabled in parent process");
return true;
void
gfxPlatform::BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut)
{
MOZ_ASSERT(XRE_IsParentProcess());
aOut->prefs().hwCompositing() = gfxConfig::GetValue(Feature::HW_COMPOSITING);
aOut->prefs().oglCompositing() = gfxConfig::GetValue(Feature::OPENGL_COMPOSITING);
}
bool

View File

@ -51,7 +51,7 @@ class DataSourceSurface;
class ScaledFont;
class DrawEventRecorder;
class VsyncSource;
class DeviceInitData;
class ContentDeviceData;
inline uint32_t
BackendTypeBit(BackendType b)
@ -644,10 +644,6 @@ public:
virtual void CompositorUpdated() {}
// Return information on how child processes should initialize graphics
// devices. Currently this is only used on Windows.
virtual void GetDeviceInitData(mozilla::gfx::DeviceInitData* aOut);
// Plugin async drawing support.
virtual bool SupportsPluginDirectBitmapDrawing() {
return false;
@ -672,6 +668,12 @@ public:
const gfxSkipChars& EmptySkipChars() const { return kEmptySkipChars; }
/**
* Return information on how child processes should initialize graphics
* devices.
*/
virtual void BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut);
protected:
gfxPlatform();
virtual ~gfxPlatform();
@ -704,10 +706,11 @@ protected:
uint32_t aContentBitmask, mozilla::gfx::BackendType aContentDefault);
/**
* If in a child process, triggers a refresh of device preferences, then returns true.
* In a parent process, nothing happens and false is returned.
* Content-process only. Requests device preferences from the parent process
* and updates any cached settings.
*/
virtual bool UpdateDeviceInitData();
void FetchAndImportContentDeviceData();
virtual void ImportContentDeviceData(const mozilla::gfx::ContentDeviceData& aData);
/**
* Increase the global device counter after a device has been removed/reset.
@ -742,8 +745,6 @@ protected:
static already_AddRefed<mozilla::gfx::ScaledFont>
GetScaledFontForFontWithCairoSkia(mozilla::gfx::DrawTarget* aTarget, gfxFont* aFont);
static mozilla::gfx::DeviceInitData& GetParentDevicePrefs();
int8_t mAllowDownloadableFonts;
int8_t mGraphiteShapingEnabled;
int8_t mOpenTypeSVGEnabled;

View File

@ -472,6 +472,12 @@ gfxWindowsPlatform::HandleDeviceReset()
imgLoader::PrivateBrowsingLoader()->ClearCache(false);
gfxAlphaBoxBlur::ShutdownBlurCache();
if (XRE_IsContentProcess()) {
// Fetch updated device parameters.
FetchAndImportContentDeviceData();
UpdateANGLEConfig();
}
InitializeDevices();
UpdateANGLEConfig();
BumpDeviceCounter();
@ -1437,15 +1443,17 @@ InitializeANGLEConfig()
void
gfxWindowsPlatform::InitializeConfig()
{
if (!XRE_IsParentProcess()) {
// Child processes init their configuration via UpdateDeviceInitData().
return;
if (XRE_IsParentProcess()) {
// The parent process first determines which features can be attempted.
// This information is relayed to content processes and the GPU process.
InitializeD3D9Config();
InitializeD3D11Config();
InitializeANGLEConfig();
InitializeD2DConfig();
} else {
FetchAndImportContentDeviceData();
InitializeANGLEConfig();
}
InitializeD3D9Config();
InitializeD3D11Config();
InitializeANGLEConfig();
InitializeD2DConfig();
}
void
@ -1521,29 +1529,6 @@ gfxWindowsPlatform::InitializeD3D11Config()
}
}
bool
gfxWindowsPlatform::UpdateDeviceInitData()
{
if (!gfxPlatform::UpdateDeviceInitData()) {
return false;
}
gfxConfig::InitOrUpdate(
Feature::D3D11_COMPOSITING,
GetParentDevicePrefs().useD3D11(),
FeatureStatus::Disabled,
"Disabled by parent process");
gfxConfig::InitOrUpdate(
Feature::DIRECT2D,
GetParentDevicePrefs().useD2D1(),
FeatureStatus::Disabled,
"Disabled by parent process");
InitializeANGLEConfig();
return true;
}
/* static */ void
gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode aDevice)
{
@ -1561,9 +1546,6 @@ gfxWindowsPlatform::RecordContentDeviceFailure(TelemetryDeviceCode aDevice)
void
gfxWindowsPlatform::InitializeDevices()
{
// Ask the parent process for an updated list of which devices to create.
UpdateDeviceInitData();
// If acceleration is disabled, we refuse to initialize anything.
if (!gfxConfig::IsEnabled(Feature::HW_COMPOSITING)) {
return;
@ -1594,14 +1576,17 @@ gfxWindowsPlatform::InitializeDevices()
return;
}
bool shouldUseD2D = gfxConfig::IsEnabled(Feature::DIRECT2D);
// First, initialize D3D11. If this succeeds we attempt to use Direct2D.
InitializeD3D11();
InitializeD2D();
if (!gfxConfig::IsEnabled(Feature::DIRECT2D)) {
if (XRE_IsContentProcess() && GetParentDevicePrefs().useD2D1()) {
RecordContentDeviceFailure(TelemetryDeviceCode::D2D1);
}
if (!gfxConfig::IsEnabled(Feature::DIRECT2D) &&
XRE_IsContentProcess() &&
shouldUseD2D)
{
RecordContentDeviceFailure(TelemetryDeviceCode::D2D1);
}
}
@ -1623,9 +1608,8 @@ gfxWindowsPlatform::InitializeD3D11()
if (!dm->CreateCompositorDevices()) {
return;
}
} else if (XRE_IsContentProcess()) {
dm->InheritDeviceInfo(GetParentDevicePrefs());
}
dm->CreateContentDevices();
}
@ -2046,30 +2030,39 @@ gfxWindowsPlatform::GetAcceleratedCompositorBackends(nsTArray<LayersBackend>& aB
}
void
gfxWindowsPlatform::GetDeviceInitData(DeviceInitData* aOut)
gfxWindowsPlatform::ImportContentDeviceData(const mozilla::gfx::ContentDeviceData& aData)
{
MOZ_ASSERT(XRE_IsContentProcess());
gfxPlatform::ImportContentDeviceData(aData);
const DevicePrefs& prefs = aData.prefs();
gfxConfig::Inherit(Feature::D3D11_COMPOSITING, prefs.d3d11Compositing());
gfxConfig::Inherit(Feature::D3D9_COMPOSITING, prefs.d3d9Compositing());
gfxConfig::Inherit(Feature::DIRECT2D, prefs.useD2D1());
if (gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
dm->ImportDeviceInfo(aData.d3d11());
}
}
void
gfxWindowsPlatform::BuildContentDeviceData(ContentDeviceData* aOut)
{
// Check for device resets before giving back new graphics information.
UpdateRenderMode();
gfxPlatform::GetDeviceInitData(aOut);
gfxPlatform::BuildContentDeviceData(aOut);
// IPDL initializes each field to false for us so we can early return.
if (!gfxConfig::IsEnabled(Feature::D3D11_COMPOSITING)) {
return;
}
const FeatureState& d3d11 = gfxConfig::GetFeature(Feature::D3D11_COMPOSITING);
aOut->prefs().d3d11Compositing() = d3d11.GetValue();
aOut->prefs().d3d9Compositing() = gfxConfig::GetValue(Feature::D3D9_COMPOSITING);
aOut->prefs().useD2D1() = gfxConfig::GetValue(Feature::DIRECT2D);
DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
aOut->useD3D11() = true;
aOut->d3d11TextureSharingWorks() = dm->TextureSharingWorks();
aOut->useD2D1() = gfxConfig::IsEnabled(Feature::DIRECT2D);
if (RefPtr<ID3D11Device> device = dm->GetCompositorDevice()) {
DXGI_ADAPTER_DESC desc;
if (!D3D11Checks::GetDxgiDesc(device, &desc)) {
return;
}
aOut->adapter() = DxgiAdapterDesc::From(desc);
if (d3d11.IsEnabled()) {
DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
dm->ExportDeviceInfo(&aOut->d3d11());
}
}

View File

@ -238,8 +238,6 @@ public:
static mozilla::Atomic<size_t> sD3D11SharedTextures;
static mozilla::Atomic<size_t> sD3D9SharedTextures;
void GetDeviceInitData(mozilla::gfx::DeviceInitData* aOut) override;
bool SupportsPluginDirectBitmapDrawing() override {
return true;
}
@ -253,7 +251,9 @@ protected:
}
void GetAcceleratedCompositorBackends(nsTArray<mozilla::layers::LayersBackend>& aBackends) override;
virtual void GetPlatformCMSOutputProfile(void* &mem, size_t &size) override;
bool UpdateDeviceInitData() override;
void ImportContentDeviceData(const mozilla::gfx::ContentDeviceData& aData) override;
void BuildContentDeviceData(mozilla::gfx::ContentDeviceData* aOut) override;
protected:
RenderMode mRenderMode;

View File

@ -1354,7 +1354,7 @@ GfxInfo::DescribeFeatures(JSContext* aCx, JS::Handle<JSObject*> aObj)
}
if (d3d11 == gfx::FeatureStatus::Available) {
DeviceManagerD3D11* dm = DeviceManagerD3D11::Get();
JS::Rooted<JS::Value> val(aCx, JS::Int32Value(dm->GetD3D11Version()));
JS::Rooted<JS::Value> val(aCx, JS::Int32Value(dm->GetFeatureLevel()));
JS_SetProperty(aCx, obj, "version", val);
val = JS::BooleanValue(dm->IsWARP());