diff options
Diffstat (limited to 'gfx/thebes/DeviceManagerDx.cpp')
-rw-r--r-- | gfx/thebes/DeviceManagerDx.cpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/gfx/thebes/DeviceManagerDx.cpp b/gfx/thebes/DeviceManagerDx.cpp index 18c5cea7db..ba473e0d1e 100644 --- a/gfx/thebes/DeviceManagerDx.cpp +++ b/gfx/thebes/DeviceManagerDx.cpp @@ -206,6 +206,129 @@ bool DeviceManagerDx::GetOutputFromMonitor(HMONITOR monitor, return false; } +void DeviceManagerDx::PostUpdateMonitorInfo() { + MOZ_ASSERT(XRE_IsGPUProcess()); + MOZ_ASSERT(NS_IsMainThread()); + + MutexAutoLock lock(mDeviceLock); + // Reduce frequency of UpdateMonitorInfo() call. + if (mUpdateMonitorInfoRunnable) { + return; + } + + auto* holder = CompositorThreadHolder::GetSingleton(); + if (!holder) { + return; + } + + mUpdateMonitorInfoRunnable = NS_NewRunnableFunction( + "DeviceManagerDx::PostUpdateMonitorInfo::Runnable", []() -> void { + auto* dm = gfx::DeviceManagerDx::Get(); + if (dm) { + dm->UpdateMonitorInfo(); + } + }); + + const uint32_t kDelayMS = 100; + RefPtr<Runnable> runnable = mUpdateMonitorInfoRunnable; + holder->GetCompositorThread()->DelayedDispatch(runnable.forget(), kDelayMS); +} + +void DeviceManagerDx::UpdateMonitorInfo() { + bool systemHdrEnabled = false; + + for (const auto& desc : GetOutputDescs()) { + if (desc.ColorSpace == DXGI_COLOR_SPACE_RGB_FULL_G2084_NONE_P2020) { + systemHdrEnabled = true; + } + } + { + MutexAutoLock lock(mDeviceLock); + mSystemHdrEnabled = Some(systemHdrEnabled); + mUpdateMonitorInfoRunnable = nullptr; + } +} + +std::vector<DXGI_OUTPUT_DESC1> DeviceManagerDx::GetOutputDescs() { + std::vector<DXGI_OUTPUT_DESC1> outputDescs; + + nsModuleHandle dxgiModule(LoadLibrarySystem32(L"dxgi.dll")); + decltype(CreateDXGIFactory1)* createDXGIFactory1 = + (decltype(CreateDXGIFactory1)*)GetProcAddress(dxgiModule, + "CreateDXGIFactory1"); + if (!createDXGIFactory1) { + return outputDescs; + } + + RefPtr<IDXGIFactory1> dxgiFactory; + HRESULT hr = + createDXGIFactory1(__uuidof(IDXGIFactory1), getter_AddRefs(dxgiFactory)); + if (FAILED(hr)) { + gfxCriticalNoteOnce << "Failed to create DXGI factory: " << gfx::hexa(hr); + return outputDescs; + } + + for (UINT adapterIndex = 0;; adapterIndex++) { + RefPtr<IDXGIAdapter> adapter; + hr = dxgiFactory->EnumAdapters(adapterIndex, getter_AddRefs(adapter)); + if (hr == DXGI_ERROR_NOT_FOUND) { + break; + } + if (FAILED(hr)) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + gfxCriticalNoteOnce << "Failed to enumerate DXGI adapter: " + << gfx::hexa(hr); + break; + } + + for (UINT outputIndex = 0;; ++outputIndex) { + RefPtr<IDXGIOutput> output; + hr = adapter->EnumOutputs(outputIndex, getter_AddRefs(output)); + if (hr == DXGI_ERROR_NOT_FOUND) { + break; + } + if (FAILED(hr)) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + gfxCriticalNoteOnce << "Failed to enumulate DXGI output: " + << gfx::hexa(hr); + break; + } + + RefPtr<IDXGIOutput6> output6; + hr = output->QueryInterface(__uuidof(IDXGIOutput6), + getter_AddRefs(output6)); + if (FAILED(hr)) { + continue; + } + + DXGI_OUTPUT_DESC1 desc; + if (FAILED(output6->GetDesc1(&desc))) { + MOZ_ASSERT_UNREACHABLE("unexpected to be called"); + gfxCriticalNoteOnce << "Failed to get DXGI output descriptor"; + continue; + } + + outputDescs.push_back(std::move(desc)); + } + } + + return outputDescs; +} + +bool DeviceManagerDx::SystemHDREnabled() { + { + MutexAutoLock lock(mDeviceLock); + if (mSystemHdrEnabled.isSome()) { + return mSystemHdrEnabled.ref(); + } + } + + UpdateMonitorInfo(); + + MutexAutoLock lock(mDeviceLock); + return mSystemHdrEnabled.ref(); +} + void DeviceManagerDx::CheckHardwareStretchingSupport(HwStretchingSupport& aRv) { RefPtr<IDXGIAdapter> adapter = GetDXGIAdapter(); |