mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 14:52:16 +00:00
Refactor cross-process acceleration controls. (bug 1294988 part 4, r=mattwoodrow)
This commit is contained in:
parent
7df82d4b70
commit
396d5d1191
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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,
|
||||
|
@ -146,6 +146,8 @@ gfxConfig::Inherit(Feature aFeature, FeatureStatus aStatus)
|
||||
{
|
||||
FeatureState& state = sConfig->GetState(aFeature);
|
||||
|
||||
state.Reset();
|
||||
|
||||
switch (aStatus) {
|
||||
case FeatureStatus::Unused:
|
||||
break;
|
||||
|
@ -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';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,6 +85,9 @@ class FeatureState
|
||||
MOZ_ASSERT(IsInitialized());
|
||||
}
|
||||
|
||||
// Clear all state.
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
void SetFailureId(const nsACString& aFailureId);
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user