Skip to content

Commit

Permalink
Bug 1400317 - Use gfxVars to mirror DWM status to content processes r…
Browse files Browse the repository at this point in the history
…=jrmuizel

The only caveat here is that gfxVars are not atomic, but multiple threads can
query DWM status. To solve this, changes to the var are mirrored into an atomic
and that is read instead.

DWM status changes are indicated by Windows via a window message. We use that
window message to cause the update to propagate

Differential Revision: https://phabricator.services.mozilla.com/D73743
  • Loading branch information
Chris Martin committed May 6, 2020
1 parent 1093edd commit 06d9dd2
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 8 deletions.
3 changes: 2 additions & 1 deletion gfx/config/gfxVars.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,8 @@ class gfxVarReceiver;
_(RemoteCanvasEnabled, bool, false) \
_(UseDoubleBufferingWithCompositor, bool, false) \
_(UseGLSwizzle, bool, true) \
_(AllowSacrificingSubpixelAA, bool, false)
_(AllowSacrificingSubpixelAA, bool, false) \
_(DwmCompositionEnabled, bool, true)

/* Add new entries above this line. */

Expand Down
33 changes: 26 additions & 7 deletions gfx/thebes/gfxWindowsPlatform.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,9 @@ class D3DSharedTexturesReporter final : public nsIMemoryReporter {

NS_IMPL_ISUPPORTS(D3DSharedTexturesReporter, nsIMemoryReporter)

gfxWindowsPlatform::gfxWindowsPlatform() : mRenderMode(RENDER_GDI) {
gfxWindowsPlatform::gfxWindowsPlatform()
: mRenderMode(RENDER_GDI),
mDwmCompositionStatus(DwmCompositionStatus::Unknown) {
/*
* Initialize COM
*/
Expand Down Expand Up @@ -335,6 +337,27 @@ void gfxWindowsPlatform::InitAcceleration() {
gfxVars::SetSystemTextQualityListener(
gfxDWriteFont::SystemTextQualityChanged);

if (XRE_IsParentProcess()) {
BOOL dwmEnabled = FALSE;
if (FAILED(::DwmIsCompositionEnabled(&dwmEnabled)) || !dwmEnabled) {
gfxVars::SetDwmCompositionEnabled(false);
} else {
gfxVars::SetDwmCompositionEnabled(true);
}
}

// gfxVars are not atomic, but multiple threads can query DWM status
// Therefore, mirror value into an atomic
mDwmCompositionStatus = gfxVars::DwmCompositionEnabled()
? DwmCompositionStatus::Enabled
: DwmCompositionStatus::Disabled;

gfxVars::SetDwmCompositionEnabledListener([this] {
this->mDwmCompositionStatus = gfxVars::DwmCompositionEnabled()
? DwmCompositionStatus::Enabled
: DwmCompositionStatus::Disabled;
});

// CanUseHardwareVideoDecoding depends on DeviceManagerDx state,
// so update the cached value now.
UpdateCanUseHardwareVideoDecoding();
Expand Down Expand Up @@ -1610,13 +1633,9 @@ bool gfxWindowsPlatform::InitGPUProcessSupport() {
}

bool gfxWindowsPlatform::DwmCompositionEnabled() {
BOOL dwmEnabled = false;

if (FAILED(DwmIsCompositionEnabled(&dwmEnabled))) {
return false;
}
MOZ_RELEASE_ASSERT(mDwmCompositionStatus != DwmCompositionStatus::Unknown);

return dwmEnabled;
return mDwmCompositionStatus == DwmCompositionStatus::Enabled;
}

class D3DVsyncSource final : public VsyncSource {
Expand Down
9 changes: 9 additions & 0 deletions gfx/thebes/gfxWindowsPlatform.h
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,12 @@ class gfxWindowsPlatform final : public gfxPlatform {
RenderMode mRenderMode;

private:
enum class DwmCompositionStatus : uint32_t {
Unknown,
Disabled,
Enabled,
};

void Init();
void InitAcceleration() override;
void InitWebRenderConfig() override;
Expand Down Expand Up @@ -254,6 +260,9 @@ class gfxWindowsPlatform final : public gfxPlatform {
RefPtr<mozilla::layers::ReadbackManagerD3D11> mD3D11ReadbackManager;
bool mInitializedDevices = false;

mozilla::Atomic<DwmCompositionStatus, mozilla::ReleaseAcquire>
mDwmCompositionStatus;

// Cached contents of the output color profile file
nsTArray<uint8_t> mCachedOutputColorProfile;
};
Expand Down
11 changes: 11 additions & 0 deletions widget/windows/nsWindow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5994,6 +5994,17 @@ bool nsWindow::ProcessMessage(UINT msg, WPARAM& wParam, LPARAM& lParam,
} break;

case WM_DWMCOMPOSITIONCHANGED:
// Every window will get this message, but gfxVars only broadcasts
// updates when the value actually changes
if (XRE_IsParentProcess()) {
BOOL dwmEnabled = FALSE;
if (FAILED(::DwmIsCompositionEnabled(&dwmEnabled)) || !dwmEnabled) {
gfxVars::SetDwmCompositionEnabled(false);
} else {
gfxVars::SetDwmCompositionEnabled(true);
}
}

UpdateNonClientMargins();
BroadcastMsg(mWnd, WM_DWMCOMPOSITIONCHANGED);
NotifyThemeChanged();
Expand Down

0 comments on commit 06d9dd2

Please sign in to comment.