summaryrefslogtreecommitdiffstats
path: root/gfx/thebes/DeviceManagerDx.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'gfx/thebes/DeviceManagerDx.cpp')
-rw-r--r--gfx/thebes/DeviceManagerDx.cpp123
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();