mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-17 06:09:19 +00:00
Bug 1880926 - Check if system enables HDR on Windows r=gfx-reviewers,lsalzman
By using IDXGIOutput6, we could check if system enables HDR on Windows. DeviceManagerDx::SystemHDREnabled() is expected to be called in GPU process. Differential Revision: https://phabricator.services.mozilla.com/D202186
This commit is contained in:
parent
0842486b73
commit
85c155ff51
@ -571,6 +571,13 @@ mozilla::ipc::IPCResult GPUParent::RecvPreferenceUpdate(const Pref& aPref) {
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
mozilla::ipc::IPCResult GPUParent::RecvScreenInformationChanged() {
|
||||
#if defined(XP_WIN)
|
||||
DeviceManagerDx::Get()->PostUpdateMonitorInfo();
|
||||
#endif
|
||||
return IPC_OK();
|
||||
}
|
||||
|
||||
static void CopyFeatureChange(Feature aFeature, Maybe<FeatureFailure>* aOut) {
|
||||
FeatureState& feature = gfxConfig::GetFeature(aFeature);
|
||||
if (feature.DisabledByDefault() || feature.IsEnabled()) {
|
||||
|
@ -74,6 +74,7 @@ class GPUParent final : public PGPUParent {
|
||||
Endpoint<PProfilerChild>&& aEndpoint);
|
||||
mozilla::ipc::IPCResult RecvUpdateVar(const GfxVarUpdate& pref);
|
||||
mozilla::ipc::IPCResult RecvPreferenceUpdate(const Pref& pref);
|
||||
mozilla::ipc::IPCResult RecvScreenInformationChanged();
|
||||
mozilla::ipc::IPCResult RecvNewContentCompositorManager(
|
||||
Endpoint<PCompositorManagerParent>&& aEndpoint,
|
||||
const ContentParentId& aChildId, uint32_t aNamespace);
|
||||
|
@ -136,6 +136,8 @@ GPUProcessManager::Observer::Observe(nsISupports* aSubject, const char* aTopic,
|
||||
}
|
||||
} else if (!strcmp(aTopic, "application-background")) {
|
||||
mManager->mAppInForeground = false;
|
||||
} else if (!strcmp(aTopic, "screen-information-changed")) {
|
||||
mManager->ScreenInformationChanged();
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -148,6 +150,7 @@ void GPUProcessManager::OnXPCOMShutdown() {
|
||||
if (obsServ) {
|
||||
obsServ->RemoveObserver(mObserver, "application-foreground");
|
||||
obsServ->RemoveObserver(mObserver, "application-background");
|
||||
obsServ->RemoveObserver(mObserver, "screen-information-changed");
|
||||
}
|
||||
mObserver = nullptr;
|
||||
}
|
||||
@ -172,6 +175,14 @@ void GPUProcessManager::OnPreferenceChange(const char16_t* aData) {
|
||||
}
|
||||
}
|
||||
|
||||
void GPUProcessManager::ScreenInformationChanged() {
|
||||
#if defined(XP_WIN)
|
||||
if (!!mGPUChild) {
|
||||
mGPUChild->SendScreenInformationChanged();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void GPUProcessManager::ResetProcessStable() {
|
||||
mTotalProcessAttempts++;
|
||||
mProcessStable = false;
|
||||
@ -207,6 +218,7 @@ bool GPUProcessManager::LaunchGPUProcess() {
|
||||
if (obsServ) {
|
||||
obsServ->AddObserver(mObserver, "application-foreground", false);
|
||||
obsServ->AddObserver(mObserver, "application-background", false);
|
||||
obsServ->AddObserver(mObserver, "screen-information-changed", false);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,6 +214,7 @@ class GPUProcessManager final : public GPUProcessHost::Listener {
|
||||
// Called from our xpcom-shutdown observer.
|
||||
void OnXPCOMShutdown();
|
||||
void OnPreferenceChange(const char16_t* aData);
|
||||
void ScreenInformationChanged();
|
||||
|
||||
bool CreateContentCompositorManager(
|
||||
base::ProcessId aOtherProcess, dom::ContentParentId aChildId,
|
||||
|
@ -79,6 +79,7 @@ parent:
|
||||
async UpdateVar(GfxVarUpdate var);
|
||||
|
||||
async PreferenceUpdate(Pref pref);
|
||||
async ScreenInformationChanged();
|
||||
|
||||
// Create a new content-process compositor bridge.
|
||||
async NewContentCompositorManager(Endpoint<PCompositorManagerParent> endpoint, ContentParentId childId, uint32_t aNamespace);
|
||||
|
@ -206,6 +206,126 @@ 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() {
|
||||
HRESULT hr;
|
||||
std::vector<DXGI_OUTPUT_DESC1> outputDescs;
|
||||
|
||||
#ifdef __MINGW32__
|
||||
return outputDescs;
|
||||
#else
|
||||
RefPtr<IDXGIFactory1> dxgiFactory;
|
||||
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;
|
||||
#endif // __MINGW32__
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
|
@ -6,6 +6,8 @@
|
||||
#ifndef mozilla_gfx_thebes_DeviceManagerDx_h
|
||||
#define mozilla_gfx_thebes_DeviceManagerDx_h
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "gfxPlatform.h"
|
||||
#include "gfxTelemetry.h"
|
||||
#include "gfxTypes.h"
|
||||
@ -88,6 +90,9 @@ class DeviceManagerDx final {
|
||||
// 'monitor'; returns false if not found or some error occurred.
|
||||
bool GetOutputFromMonitor(HMONITOR monitor, RefPtr<IDXGIOutput>* aOutOutput);
|
||||
|
||||
void PostUpdateMonitorInfo();
|
||||
bool SystemHDREnabled();
|
||||
|
||||
// Check if the current adapter supports hardware stretching
|
||||
void CheckHardwareStretchingSupport(HwStretchingSupport& aRv);
|
||||
|
||||
@ -172,6 +177,9 @@ class DeviceManagerDx final {
|
||||
bool GetAnyDeviceRemovedReason(DeviceResetReason* aOutReason)
|
||||
MOZ_REQUIRES(mDeviceLock);
|
||||
|
||||
void UpdateMonitorInfo();
|
||||
std::vector<DXGI_OUTPUT_DESC1> GetOutputDescs();
|
||||
|
||||
private:
|
||||
static StaticAutoPtr<DeviceManagerDx> sInstance;
|
||||
|
||||
@ -198,6 +206,8 @@ class DeviceManagerDx final {
|
||||
bool mCompositorDeviceSupportsVideo MOZ_GUARDED_BY(mDeviceLock);
|
||||
Maybe<D3D11DeviceStatus> mDeviceStatus MOZ_GUARDED_BY(mDeviceLock);
|
||||
Maybe<DeviceResetReason> mDeviceResetReason MOZ_GUARDED_BY(mDeviceLock);
|
||||
RefPtr<Runnable> mUpdateMonitorInfoRunnable MOZ_GUARDED_BY(mDeviceLock);
|
||||
Maybe<bool> mSystemHdrEnabled MOZ_GUARDED_BY(mDeviceLock);
|
||||
|
||||
nsModuleHandle mDirectDrawDLL;
|
||||
RefPtr<IDirectDraw7> mDirectDraw;
|
||||
|
Loading…
x
Reference in New Issue
Block a user