Bug 1513308 - Lazily initialize DirectX devices for WebRender r=mattwoodrow

This commit is contained in:
sotaro 2018-12-18 14:54:28 +09:00
Родитель f1762a3667
Коммит 757062cdf2
9 изменённых файлов: 70 добавлений и 4 удалений

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

@ -102,6 +102,11 @@ UniquePtr<GLScreenBuffer> GLScreenBuffer::Create(GLContext* gl,
#endif
} else if (useD3D) {
#ifdef XP_WIN
// Ensure devices initialization. SharedSurfaceANGLE and
// SharedSurfaceD3D11Interop use them. The devices are lazily initialized
// with WebRender to reduce memory usage.
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
// Enable surface sharing only if ANGLE and compositing devices
// are both WARP or both not WARP
gfx::DeviceManagerDx* dm = gfx::DeviceManagerDx::Get();

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

@ -1615,7 +1615,8 @@ bool SyncObjectD3D11Host::Synchronize(bool aFallible) {
SyncObjectD3D11Client::SyncObjectD3D11Client(SyncHandle aSyncHandle,
ID3D11Device* aDevice)
: mSyncHandle(aSyncHandle), mSyncLock("SyncObjectD3D11") {
if (!aDevice) {
if (!aDevice && !XRE_IsGPUProcess() &&
gfxPlatform::GetPlatform()->DevicesInitialized()) {
mDevice = DeviceManagerDx::Get()->GetContentDevice();
return;
}
@ -1664,7 +1665,17 @@ void SyncObjectD3D11Client::RegisterTexture(ID3D11Texture2D* aTexture) {
}
bool SyncObjectD3D11Client::IsSyncObjectValid() {
RefPtr<ID3D11Device> dev = DeviceManagerDx::Get()->GetContentDevice();
RefPtr<ID3D11Device> dev;
// There is a case that devices are not initialized yet with WebRender.
if (gfxPlatform::GetPlatform()->DevicesInitialized()) {
dev = DeviceManagerDx::Get()->GetContentDevice();
}
// Update mDevice if the ContentDevice initialization is detected.
if (!mDevice && dev && NS_IsMainThread() && gfxVars::UseWebRender()) {
mDevice = dev;
}
if (!dev || (NS_IsMainThread() && dev != mDevice)) {
return false;
}

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

@ -546,6 +546,11 @@ ipc::IShmemAllocator* WebRenderBridgeChild::GetShmemAllocator() {
RefPtr<KnowsCompositor> WebRenderBridgeChild::GetForMedia() {
MOZ_ASSERT(NS_IsMainThread());
// Ensure devices initialization for video playback. The devices are lazily
// initialized with WebRender to reduce memory usage.
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
return MakeAndAddRef<KnowsCompositorMediaProxy>(
GetTextureFactoryIdentifier());
}

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

@ -665,6 +665,11 @@ void WebRenderLayerManager::SetRoot(Layer* aLayer) {
already_AddRefed<PersistentBufferProvider>
WebRenderLayerManager::CreatePersistentBufferProvider(
const gfx::IntSize& aSize, gfx::SurfaceFormat aFormat) {
// Ensure devices initialization for canvas 2d. The devices are lazily
// initialized with WebRender to reduce memory usage.
gfxPlatform::GetPlatform()->EnsureDevicesInitialized();
if (gfxPrefs::PersistentBufferProviderSharedEnabled()) {
RefPtr<PersistentBufferProvider> provider =
PersistentBufferProviderShared::Create(aSize, aFormat,

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

@ -991,6 +991,9 @@ RefPtr<ID3D11Device> DeviceManagerDx::GetCompositorDevice() {
}
RefPtr<ID3D11Device> DeviceManagerDx::GetContentDevice() {
MOZ_ASSERT(XRE_IsGPUProcess() ||
gfxPlatform::GetPlatform()->DevicesInitialized());
MutexAutoLock lock(mDeviceLock);
return mContentDevice;
}

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

@ -913,6 +913,13 @@ void gfxPlatform::Init() {
#endif
gPlatform->InitAcceleration();
gPlatform->InitWebRenderConfig();
// When using WebRender, we defer initialization of the D3D11 devices until
// the (rare) cases where they're used. Note that the GPU process where WebRender
// runs doesn't initialize gfxPlatform and performs explicit initialization of
// the bits it needs.
if (!gfxVars::UseWebRender()) {
gPlatform->EnsureDevicesInitialized();
}
gPlatform->InitOMTPConfig();
if (gfxConfig::IsEnabled(Feature::GPU_PROCESS)) {

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

@ -752,6 +752,9 @@ class gfxPlatform : public mozilla::layers::MemoryPressureListener {
virtual void OnMemoryPressure(
mozilla::layers::MemoryPressureReason aWhy) override;
virtual void EnsureDevicesInitialized() {};
virtual bool DevicesInitialized() { return true; };
protected:
gfxPlatform();
virtual ~gfxPlatform();

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

@ -424,7 +424,6 @@ void gfxWindowsPlatform::InitAcceleration() {
DeviceManagerDx::Init();
InitializeConfig();
InitializeDevices();
UpdateANGLEConfig();
UpdateRenderMode();
@ -497,7 +496,9 @@ bool gfxWindowsPlatform::HandleDeviceReset() {
gfxConfig::Reset(Feature::DIRECT2D);
InitializeConfig();
InitializeDevices();
if (mInitializedDevices) {
InitializeDevices();
}
UpdateANGLEConfig();
return true;
}
@ -1470,7 +1471,25 @@ void gfxWindowsPlatform::InitializeD3D11Config() {
uint32_t(aDevice));
}
// Supports lazy device initialization on Windows, so that WebRender can avoid
// initializing GPU state and allocating swap chains for most non-GPU processes.
void gfxWindowsPlatform::EnsureDevicesInitialized() {
if (!mInitializedDevices) {
mInitializedDevices = true;
InitializeDevices();
UpdateBackendPrefs();
}
}
bool
gfxWindowsPlatform::DevicesInitialized() {
return mInitializedDevices;
}
void gfxWindowsPlatform::InitializeDevices() {
MOZ_ASSERT(NS_IsMainThread());
if (XRE_IsParentProcess()) {
// If we're the UI process, and the GPU process is enabled, then we don't
// initialize any DirectX devices. We do leave them enabled in gfxConfig
@ -2032,6 +2051,10 @@ void gfxWindowsPlatform::BuildContentDeviceData(ContentDeviceData* aOut) {
}
bool gfxWindowsPlatform::SupportsPluginDirectDXGIDrawing() {
// Ensure devices initialization for plugin's DXGISurface. The devices are
// lazily initialized with WebRender to reduce memory usage.
EnsureDevicesInitialized();
DeviceManagerDx* dm = DeviceManagerDx::Get();
if (!dm->GetContentDevice() || !dm->TextureSharingWorks()) {
return false;

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

@ -105,6 +105,9 @@ class gfxWindowsPlatform : public gfxPlatform {
return (gfxWindowsPlatform*)gfxPlatform::GetPlatform();
}
virtual void EnsureDevicesInitialized() override;
virtual bool DevicesInitialized() override;
virtual gfxPlatformFontList* CreatePlatformFontList() override;
virtual already_AddRefed<gfxASurface> CreateOffscreenSurface(
@ -259,6 +262,7 @@ class gfxWindowsPlatform : public gfxPlatform {
DWRITE_MEASURING_MODE mMeasuringMode;
RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
bool mInitializedDevices = false;
};
#endif /* GFX_WINDOWS_PLATFORM_H */