Bug 1570879 - Fix high contrast theme handling with DirectComposition and WebRender r=nical a=lizzard
authorDaniel Varga <dvarga@mozilla.com>
Thu, 10 Oct 2019 12:13:37 +0300
changeset 555612 3617fc291cc4087cb65f1f921cd63a5fe294439d
parent 555611 ace2e979811f1a196a79e0d90bbe9183a6321155
child 555613 cab0c8004cbc0d94429957ef1675d3677bc56583
push id2165
push userffxbld-merge
push dateMon, 14 Oct 2019 16:30:58 +0000
treeherdermozilla-release@0eae18af659f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical, lizzard
bugs1570879
milestone70.0
Bug 1570879 - Fix high contrast theme handling with DirectComposition and WebRender r=nical a=lizzard
gfx/layers/CompositorTypes.h
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/MLGDeviceD3D11.cpp
gfx/layers/d3d11/MLGDeviceD3D11.h
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/KnowsCompositor.h
gfx/layers/ipc/LayersMessageUtils.h
gfx/layers/mlgpu/LayerManagerMLGPU.cpp
gfx/layers/mlgpu/MLGDevice.h
gfx/layers/wr/AsyncImagePipelineManager.cpp
gfx/layers/wr/AsyncImagePipelineManager.h
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/webrender_bindings/RenderCompositorANGLE.cpp
gfx/webrender_bindings/RenderCompositorANGLE.h
widget/windows/WinCompositorWidget.cpp
widget/windows/WinCompositorWidget.h
widget/windows/nsWindow.cpp
widget/windows/nsWindowGfx.cpp
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -171,51 +171,54 @@ typedef uintptr_t SyncHandle;
  */
 struct TextureFactoryIdentifier {
   LayersBackend mParentBackend;
   GeckoProcessType mParentProcessType;
   int32_t mMaxTextureSize;
   bool mSupportsTextureDirectMapping;
   bool mCompositorUseANGLE;
   bool mCompositorUseDComp;
+  bool mUseCompositorWnd;
   bool mSupportsTextureBlitting;
   bool mSupportsPartialUploads;
   bool mSupportsComponentAlpha;
   bool mUsingAdvancedLayers;
   SyncHandle mSyncHandle;
 
   explicit TextureFactoryIdentifier(
       LayersBackend aLayersBackend = LayersBackend::LAYERS_NONE,
       GeckoProcessType aParentProcessType = GeckoProcessType_Default,
       int32_t aMaxTextureSize = 4096,
       bool aSupportsTextureDirectMapping = false,
       bool aCompositorUseANGLE = false, bool aCompositorUseDComp = false,
-      bool aSupportsTextureBlitting = false,
+      bool aUseCompositorWnd = false, bool aSupportsTextureBlitting = false,
       bool aSupportsPartialUploads = false, bool aSupportsComponentAlpha = true,
       SyncHandle aSyncHandle = 0)
       : mParentBackend(aLayersBackend),
         mParentProcessType(aParentProcessType),
         mMaxTextureSize(aMaxTextureSize),
         mSupportsTextureDirectMapping(aSupportsTextureDirectMapping),
         mCompositorUseANGLE(aCompositorUseANGLE),
         mCompositorUseDComp(aCompositorUseDComp),
+        mUseCompositorWnd(aUseCompositorWnd),
         mSupportsTextureBlitting(aSupportsTextureBlitting),
         mSupportsPartialUploads(aSupportsPartialUploads),
         mSupportsComponentAlpha(aSupportsComponentAlpha),
         mUsingAdvancedLayers(false),
         mSyncHandle(aSyncHandle) {}
 
   bool operator==(const TextureFactoryIdentifier& aOther) const {
     return mParentBackend == aOther.mParentBackend &&
            mParentProcessType == aOther.mParentProcessType &&
            mMaxTextureSize == aOther.mMaxTextureSize &&
            mSupportsTextureDirectMapping ==
                aOther.mSupportsTextureDirectMapping &&
            mCompositorUseANGLE == aOther.mCompositorUseANGLE &&
            mCompositorUseDComp == aOther.mCompositorUseDComp &&
+           mUseCompositorWnd == aOther.mUseCompositorWnd &&
            mSupportsTextureBlitting == aOther.mSupportsTextureBlitting &&
            mSupportsPartialUploads == aOther.mSupportsPartialUploads &&
            mSupportsComponentAlpha == aOther.mSupportsComponentAlpha &&
            mUsingAdvancedLayers == aOther.mUsingAdvancedLayers &&
            mSyncHandle == aOther.mSyncHandle;
   }
 };
 
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -323,16 +323,19 @@ already_AddRefed<DataTextureSource> Comp
   return result.forget();
 }
 
 TextureFactoryIdentifier CompositorD3D11::GetTextureFactoryIdentifier() {
   TextureFactoryIdentifier ident;
   ident.mMaxTextureSize = GetMaxTextureSize();
   ident.mParentProcessType = XRE_GetProcessType();
   ident.mParentBackend = LayersBackend::LAYERS_D3D11;
+  if (mWidget) {
+    ident.mUseCompositorWnd = !!mWidget->AsWindows()->GetCompositorHwnd();
+  }
   if (mAttachments->mSyncObject) {
     ident.mSyncHandle = mAttachments->mSyncObject->GetSyncHandle();
   }
   return ident;
 }
 
 bool CompositorD3D11::CanUseCanvasLayerForSize(const gfx::IntSize& aSize) {
   int32_t maxTextureSize = GetMaxTextureSize();
--- a/gfx/layers/d3d11/MLGDeviceD3D11.cpp
+++ b/gfx/layers/d3d11/MLGDeviceD3D11.cpp
@@ -1267,20 +1267,23 @@ bool MLGDeviceD3D11::InitInputLayout(D3D
   if (FAILED(hr)) {
     gfxCriticalNote << "Could not create input layout for shader "
                     << hexa(unsigned(aShaderID)) << ": " << hexa(hr);
     return false;
   }
   return true;
 }
 
-TextureFactoryIdentifier MLGDeviceD3D11::GetTextureFactoryIdentifier() const {
+TextureFactoryIdentifier MLGDeviceD3D11::GetTextureFactoryIdentifier(
+    widget::CompositorWidget* aWidget) const {
   TextureFactoryIdentifier ident(GetLayersBackend(), XRE_GetProcessType(),
                                  GetMaxTextureSize());
-
+  if (aWidget) {
+    ident.mUseCompositorWnd = !!aWidget->AsWindows()->GetCompositorHwnd();
+  }
   if (mSyncObject) {
     ident.mSyncHandle = mSyncObject->GetSyncHandle();
   }
 
   return ident;
 }
 
 inline uint32_t GetMaxTextureSizeForFeatureLevel1(
--- a/gfx/layers/d3d11/MLGDeviceD3D11.h
+++ b/gfx/layers/d3d11/MLGDeviceD3D11.h
@@ -148,17 +148,18 @@ class MLGDeviceD3D11 final : public MLGD
 
   bool Initialize() override;
 
   void StartDiagnostics(uint32_t aInvalidPixels) override;
   void EndDiagnostics() override;
   void GetDiagnostics(GPUStats* aStats) override;
 
   MLGDeviceD3D11* AsD3D11() override { return this; }
-  TextureFactoryIdentifier GetTextureFactoryIdentifier() const override;
+  TextureFactoryIdentifier GetTextureFactoryIdentifier(
+      widget::CompositorWidget* aWidget) const override;
 
   RefPtr<MLGSwapChain> CreateSwapChainForWidget(
       widget::CompositorWidget* aWidget) override;
 
   int32_t GetMaxTextureSize() const override;
   LayersBackend GetLayersBackend() const override;
 
   void EndFrame() override;
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -1828,17 +1828,22 @@ PWebRenderBridgeParent* CompositorBridge
   nsTArray<RefPtr<wr::WebRenderAPI>> clonedApis;
   for (auto& api : apis) {
     wr::TransactionBuilder txn;
     txn.SetRootPipeline(aPipelineId);
     api->SendTransaction(txn);
     clonedApis.AppendElement(api->Clone());
   }
 
-  mAsyncImageManager = new AsyncImagePipelineManager(std::move(clonedApis));
+  bool useCompositorWnd = false;
+#ifdef XP_WIN
+  useCompositorWnd = !!mWidget->AsWindows()->GetCompositorHwnd();
+#endif
+  mAsyncImageManager =
+      new AsyncImagePipelineManager(std::move(clonedApis), useCompositorWnd);
   RefPtr<AsyncImagePipelineManager> asyncMgr = mAsyncImageManager;
   RefPtr<CompositorAnimationStorage> animStorage = GetAnimationStorage();
   mWrBridge = new WebRenderBridgeParent(this, aPipelineId, mWidget, nullptr,
                                         std::move(apis), std::move(asyncMgr),
                                         std::move(animStorage), mVsyncRate);
   mWrBridge.get()->AddRef();  // IPDL reference
 
   mCompositorScheduler = mWrBridge->CompositorScheduler();
--- a/gfx/layers/ipc/KnowsCompositor.h
+++ b/gfx/layers/ipc/KnowsCompositor.h
@@ -108,16 +108,20 @@ class KnowsCompositor {
   bool GetCompositorUseANGLE() const {
     return mTextureFactoryIdentifier.mCompositorUseANGLE;
   }
 
   bool GetCompositorUseDComp() const {
     return mTextureFactoryIdentifier.mCompositorUseDComp;
   }
 
+  bool GetUseCompositorWnd() const {
+    return mTextureFactoryIdentifier.mUseCompositorWnd;
+  }
+
   const TextureFactoryIdentifier& GetTextureFactoryIdentifier() const {
     return mTextureFactoryIdentifier;
   }
 
   bool DeviceCanReset() const {
     return GetCompositorBackendType() != LayersBackend::LAYERS_BASIC;
   }
 
--- a/gfx/layers/ipc/LayersMessageUtils.h
+++ b/gfx/layers/ipc/LayersMessageUtils.h
@@ -450,32 +450,34 @@ struct ParamTraits<mozilla::layers::Text
 
   static void Write(Message* aMsg, const paramType& aParam) {
     WriteParam(aMsg, aParam.mParentBackend);
     WriteParam(aMsg, aParam.mParentProcessType);
     WriteParam(aMsg, aParam.mMaxTextureSize);
     WriteParam(aMsg, aParam.mSupportsTextureDirectMapping);
     WriteParam(aMsg, aParam.mCompositorUseANGLE);
     WriteParam(aMsg, aParam.mCompositorUseDComp);
+    WriteParam(aMsg, aParam.mUseCompositorWnd);
     WriteParam(aMsg, aParam.mSupportsTextureBlitting);
     WriteParam(aMsg, aParam.mSupportsPartialUploads);
     WriteParam(aMsg, aParam.mSupportsComponentAlpha);
     WriteParam(aMsg, aParam.mUsingAdvancedLayers);
     WriteParam(aMsg, aParam.mSyncHandle);
   }
 
   static bool Read(const Message* aMsg, PickleIterator* aIter,
                    paramType* aResult) {
     bool result =
         ReadParam(aMsg, aIter, &aResult->mParentBackend) &&
         ReadParam(aMsg, aIter, &aResult->mParentProcessType) &&
         ReadParam(aMsg, aIter, &aResult->mMaxTextureSize) &&
         ReadParam(aMsg, aIter, &aResult->mSupportsTextureDirectMapping) &&
         ReadParam(aMsg, aIter, &aResult->mCompositorUseANGLE) &&
         ReadParam(aMsg, aIter, &aResult->mCompositorUseDComp) &&
+        ReadParam(aMsg, aIter, &aResult->mUseCompositorWnd) &&
         ReadParam(aMsg, aIter, &aResult->mSupportsTextureBlitting) &&
         ReadParam(aMsg, aIter, &aResult->mSupportsPartialUploads) &&
         ReadParam(aMsg, aIter, &aResult->mSupportsComponentAlpha) &&
         ReadParam(aMsg, aIter, &aResult->mUsingAdvancedLayers) &&
         ReadParam(aMsg, aIter, &aResult->mSyncHandle);
     return result;
   }
 };
--- a/gfx/layers/mlgpu/LayerManagerMLGPU.cpp
+++ b/gfx/layers/mlgpu/LayerManagerMLGPU.cpp
@@ -188,17 +188,17 @@ already_AddRefed<ImageLayer> LayerManage
 
 already_AddRefed<CanvasLayer> LayerManagerMLGPU::CreateCanvasLayer() {
   return MakeAndAddRef<CanvasLayerMLGPU>(this);
 }
 
 TextureFactoryIdentifier LayerManagerMLGPU::GetTextureFactoryIdentifier() {
   TextureFactoryIdentifier ident;
   if (mDevice) {
-    ident = mDevice->GetTextureFactoryIdentifier();
+    ident = mDevice->GetTextureFactoryIdentifier(mWidget);
   }
   ident.mUsingAdvancedLayers = true;
   return ident;
 }
 
 LayersBackend LayerManagerMLGPU::GetBackendType() {
   return mDevice ? mDevice->GetLayersBackend() : LayersBackend::LAYERS_NONE;
 }
--- a/gfx/layers/mlgpu/MLGDevice.h
+++ b/gfx/layers/mlgpu/MLGDevice.h
@@ -217,17 +217,18 @@ enum class PixelShaderID {
 class MLGDevice {
  public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(MLGDevice)
 
   MLGDevice();
 
   virtual bool Initialize();
 
-  virtual TextureFactoryIdentifier GetTextureFactoryIdentifier() const = 0;
+  virtual TextureFactoryIdentifier GetTextureFactoryIdentifier(
+      widget::CompositorWidget* aWidget) const = 0;
   virtual int32_t GetMaxTextureSize() const = 0;
   virtual LayersBackend GetLayersBackend() const = 0;
 
   virtual RefPtr<MLGSwapChain> CreateSwapChainForWidget(
       widget::CompositorWidget* aWidget) = 0;
 
   // Markers for when we start and finish issuing "normal" (i.e., non-
   // diagnostic) draw commands for the frame.
--- a/gfx/layers/wr/AsyncImagePipelineManager.cpp
+++ b/gfx/layers/wr/AsyncImagePipelineManager.cpp
@@ -36,18 +36,19 @@ AsyncImagePipelineManager::AsyncImagePip
 AsyncImagePipelineManager::PipelineUpdates::PipelineUpdates(
     RefPtr<wr::WebRenderPipelineInfo> aPipelineInfo,
     const uint64_t aUpdatesCount, const bool aRendered)
     : mPipelineInfo(aPipelineInfo),
       mUpdatesCount(aUpdatesCount),
       mRendered(aRendered) {}
 
 AsyncImagePipelineManager::AsyncImagePipelineManager(
-    nsTArray<RefPtr<wr::WebRenderAPI>>&& aApis)
+    nsTArray<RefPtr<wr::WebRenderAPI>>&& aApis, bool aUseCompositorWnd)
     : mApis(aApis),
+      mUseCompositorWnd(aUseCompositorWnd),
       mIdNamespace(mApis[0]->GetNamespace()),
       mUseTripleBuffering(mApis[0]->GetUseTripleBuffering()),
       mResourceId(0),
       mAsyncImageEpoch{0},
       mWillGenerateFrame{},
       mDestroyed(false),
       mUpdatesLock("UpdatesLock"),
       mUpdatesCount(0) {
--- a/gfx/layers/wr/AsyncImagePipelineManager.h
+++ b/gfx/layers/wr/AsyncImagePipelineManager.h
@@ -31,25 +31,27 @@ class CompositableHost;
 class CompositorVsyncScheduler;
 class WebRenderImageHost;
 class WebRenderTextureHost;
 
 class AsyncImagePipelineManager final {
  public:
   NS_INLINE_DECL_THREADSAFE_REFCOUNTING(AsyncImagePipelineManager)
 
-  explicit AsyncImagePipelineManager(
-      nsTArray<RefPtr<wr::WebRenderAPI>>&& aApis);
+  explicit AsyncImagePipelineManager(nsTArray<RefPtr<wr::WebRenderAPI>>&& aApis,
+                                     bool aUseCompositorWnd);
 
  protected:
   ~AsyncImagePipelineManager();
 
  public:
   void Destroy();
 
+  bool UseCompositorWnd() const { return mUseCompositorWnd; }
+
   void AddPipeline(const wr::PipelineId& aPipelineId,
                    WebRenderBridgeParent* aWrBridge);
   void RemovePipeline(const wr::PipelineId& aPipelineId,
                       const wr::Epoch& aEpoch);
   WebRenderBridgeParent* GetWrBridge(const wr::PipelineId& aPipelineId);
 
   void HoldExternalImage(const wr::PipelineId& aPipelineId,
                          const wr::Epoch& aEpoch, TextureHost* aTexture);
@@ -208,16 +210,18 @@ class AsyncImagePipelineManager final {
       wr::TransactionBuilder& aTxn);
 
   // If texture is direct binding texture, keep it until it is not used by GPU.
   void HoldUntilNotUsedByGPU(const CompositableTextureHostRef& aTextureHost,
                              uint64_t aUpdatesCount);
   void CheckForTextureHostsNotUsedByGPU();
 
   nsTArray<RefPtr<wr::WebRenderAPI>> mApis;
+  bool mUseCompositorWnd;
+
   const wr::IdNamespace mIdNamespace;
   const bool mUseTripleBuffering;
   uint32_t mResourceId;
 
   nsClassHashtable<nsUint64HashKey, PipelineTexturesHolder>
       mPipelineTexturesHolders;
   nsClassHashtable<nsUint64HashKey, AsyncImagePipeline> mAsyncImagePipelines;
   wr::Epoch mAsyncImageEpoch;
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -32,16 +32,20 @@
 #include "mozilla/layers/WebRenderImageHost.h"
 #include "mozilla/layers/WebRenderTextureHost.h"
 #include "mozilla/Telemetry.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Unused.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/widget/CompositorWidget.h"
 
+#ifdef XP_WIN
+#  include "mozilla/widget/WinCompositorWidget.h"
+#endif
+
 #ifdef MOZ_GECKO_PROFILER
 #  include "ProfilerMarkerPayload.h"
 #endif
 
 bool is_in_main_thread() { return NS_IsMainThread(); }
 
 bool is_in_compositor_thread() {
   return mozilla::layers::CompositorThreadHolder::IsInCompositorThread();
@@ -2691,17 +2695,18 @@ mozilla::ipc::IPCResult WebRenderBridgeP
 
 TextureFactoryIdentifier WebRenderBridgeParent::GetTextureFactoryIdentifier() {
   MOZ_ASSERT(!!mApis[wr::RenderRoot::Default]);
 
   return TextureFactoryIdentifier(
       LayersBackend::LAYERS_WR, XRE_GetProcessType(),
       mApis[wr::RenderRoot::Default]->GetMaxTextureSize(), false,
       mApis[wr::RenderRoot::Default]->GetUseANGLE(),
-      mApis[wr::RenderRoot::Default]->GetUseDComp(), false, false, false,
+      mApis[wr::RenderRoot::Default]->GetUseDComp(),
+      mAsyncImageManager->UseCompositorWnd(), false, false, false,
       mApis[wr::RenderRoot::Default]->GetSyncHandle());
 }
 
 wr::Epoch WebRenderBridgeParent::GetNextWrEpoch() {
   MOZ_RELEASE_ASSERT(mWrEpoch.mHandle != UINT32_MAX);
   mWrEpoch.mHandle++;
   return mWrEpoch;
 }
--- a/gfx/webrender_bindings/RenderCompositorANGLE.cpp
+++ b/gfx/webrender_bindings/RenderCompositorANGLE.cpp
@@ -46,17 +46,18 @@ UniquePtr<RenderCompositor> RenderCompos
   return compositor;
 }
 
 RenderCompositorANGLE::RenderCompositorANGLE(
     RefPtr<widget::CompositorWidget>&& aWidget)
     : RenderCompositor(std::move(aWidget)),
       mEGLConfig(nullptr),
       mEGLSurface(nullptr),
-      mUseTripleBuffering(false) {}
+      mUseTripleBuffering(false),
+      mUseAlpha(false) {}
 
 RenderCompositorANGLE::~RenderCompositorANGLE() {
   DestroyEGLSurface();
   MOZ_ASSERT(!mEGLSurface);
 }
 
 ID3D11Device* RenderCompositorANGLE::GetDeviceOfEGLDisplay() {
   auto* egl = gl::GLLibraryEGL::Get();
@@ -290,58 +291,120 @@ void RenderCompositorANGLE::CreateSwapCh
 
   hr = dCompDevice->CreateVisual(getter_AddRefs(mVisual));
   if (FAILED(hr)) {
     gfxCriticalNote << "Could not create DCompositionVisualt: "
                     << gfx::hexa(hr);
     return;
   }
 
+  bool useTripleBuffering = gfx::gfxVars::UseWebRenderTripleBufferingWin();
+  bool useAlpha = mUseAlpha;
+  RefPtr<IDXGISwapChain1> swapChain1 =
+      CreateSwapChainForDComp(useTripleBuffering, useAlpha);
+  if (swapChain1) {
+    mSwapChain = swapChain1;
+    mVisual->SetContent(swapChain1);
+    mCompositionTarget->SetRoot(mVisual);
+    mCompositionDevice = dCompDevice;
+    mUseTripleBuffering = useTripleBuffering;
+    mUseAlpha = useAlpha;
+  } else {
+    // Clear on failure
+    mVisual = nullptr;
+    mCompositionTarget = nullptr;
+  }
+}
+
+RefPtr<IDXGISwapChain1> RenderCompositorANGLE::CreateSwapChainForDComp(
+    bool aUseTripleBuffering, bool aUseAlpha) {
+  HRESULT hr;
+  RefPtr<IDXGIDevice> dxgiDevice;
+  mDevice->QueryInterface((IDXGIDevice**)getter_AddRefs(dxgiDevice));
+
+  RefPtr<IDXGIFactory> dxgiFactory;
+  {
+    RefPtr<IDXGIAdapter> adapter;
+    dxgiDevice->GetAdapter(getter_AddRefs(adapter));
+
+    adapter->GetParent(
+        IID_PPV_ARGS((IDXGIFactory**)getter_AddRefs(dxgiFactory)));
+  }
+
+  RefPtr<IDXGIFactory2> dxgiFactory2;
+  hr = dxgiFactory->QueryInterface(
+      (IDXGIFactory2**)getter_AddRefs(dxgiFactory2));
+  if (FAILED(hr)) {
+    return nullptr;
+  }
+
   RefPtr<IDXGISwapChain1> swapChain1;
-  bool useTripleBuffering = gfx::gfxVars::UseWebRenderTripleBufferingWin();
-
   DXGI_SWAP_CHAIN_DESC1 desc{};
   // DXGI does not like 0x0 swapchains. Swap chain creation failed when 0x0 was
   // set.
   desc.Width = 1;
   desc.Height = 1;
   desc.Format = DXGI_FORMAT_B8G8R8A8_UNORM;
   desc.SampleDesc.Count = 1;
   desc.SampleDesc.Quality = 0;
   // DXGI_USAGE_SHADER_INPUT is set for improving performanc of copying from
   // framebuffer to texture on intel gpu.
   desc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT | DXGI_USAGE_SHADER_INPUT;
-  if (useTripleBuffering) {
+  if (aUseTripleBuffering) {
     desc.BufferCount = 3;
   } else {
     desc.BufferCount = 2;
   }
   // DXGI_SCALING_NONE caused swap chain creation failure.
   desc.Scaling = DXGI_SCALING_STRETCH;
   desc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL;
-  desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+  if (aUseAlpha) {
+    // This could degrade performance. Use it only when it is necessary.
+    desc.AlphaMode = DXGI_ALPHA_MODE_PREMULTIPLIED;
+  } else {
+    desc.AlphaMode = DXGI_ALPHA_MODE_IGNORE;
+  }
   desc.Flags = 0;
 
-  hr = aDXGIFactory2->CreateSwapChainForComposition(mDevice, &desc, nullptr,
-                                                    getter_AddRefs(swapChain1));
+  hr = dxgiFactory2->CreateSwapChainForComposition(mDevice, &desc, nullptr,
+                                                   getter_AddRefs(swapChain1));
   if (SUCCEEDED(hr) && swapChain1) {
     DXGI_RGBA color = {1.0f, 1.0f, 1.0f, 1.0f};
     swapChain1->SetBackgroundColor(&color);
-    mSwapChain = swapChain1;
-    mVisual->SetContent(swapChain1);
-    mCompositionTarget->SetRoot(mVisual);
-    mCompositionDevice = dCompDevice;
-    mUseTripleBuffering = useTripleBuffering;
+    return swapChain1;
   }
+
+  return nullptr;
 }
 
 bool RenderCompositorANGLE::BeginFrame(layers::NativeLayer* aNativeLayer) {
   MOZ_RELEASE_ASSERT(!aNativeLayer, "Unexpected native layer on this platform");
   mWidget->AsWindows()->UpdateCompositorWndSizeIfNecessary();
 
+  if (mCompositionDevice) {
+    bool useAlpha = mWidget->AsWindows()->HasGlass();
+    // When Alpha usage is changed, SwapChain needs to be recreatd.
+    if (useAlpha != mUseAlpha) {
+      DestroyEGLSurface();
+      mBufferSize.reset();
+
+      RefPtr<IDXGISwapChain1> swapChain1 =
+          CreateSwapChainForDComp(mUseTripleBuffering, useAlpha);
+      if (swapChain1) {
+        mSwapChain = swapChain1;
+        mUseAlpha = useAlpha;
+        mVisual->SetContent(swapChain1);
+      } else {
+        gfxCriticalNote << "Failed to re-create SwapChain";
+        RenderThread::Get()->HandleWebRenderError(WebRenderError::NEW_SURFACE);
+        return false;
+      }
+    }
+  }
+
   if (!ResizeBufferIfNeeded()) {
     return false;
   }
 
   if (!MakeCurrent()) {
     gfxCriticalNote << "Failed to make render context current, can't draw.";
     return false;
   }
--- a/gfx/webrender_bindings/RenderCompositorANGLE.h
+++ b/gfx/webrender_bindings/RenderCompositorANGLE.h
@@ -17,16 +17,17 @@
 struct ID3D11DeviceContext;
 struct ID3D11Device;
 struct ID3D11Query;
 struct IDCompositionDevice;
 struct IDCompositionTarget;
 struct IDCompositionVisual;
 struct IDXGIFactory2;
 struct IDXGISwapChain;
+struct IDXGISwapChain1;
 
 namespace mozilla {
 namespace gl {
 class GLLibraryEGL;
 }  // namespace gl
 
 namespace wr {
 
@@ -61,23 +62,26 @@ class RenderCompositorANGLE : public Ren
 
  protected:
   void InsertPresentWaitQuery();
   bool WaitForPreviousPresentQuery();
   bool ResizeBufferIfNeeded();
   void DestroyEGLSurface();
   ID3D11Device* GetDeviceOfEGLDisplay();
   void CreateSwapChainForDCompIfPossible(IDXGIFactory2* aDXGIFactory2);
+  RefPtr<IDXGISwapChain1> CreateSwapChainForDComp(bool aUseTripleBuffering,
+                                                  bool aUseAlpha);
   bool SutdownEGLLibraryIfNecessary();
   RefPtr<ID3D11Query> GetD3D11Query();
 
   EGLConfig mEGLConfig;
   EGLSurface mEGLSurface;
 
   int mUseTripleBuffering;
+  bool mUseAlpha;
 
   RefPtr<ID3D11Device> mDevice;
   RefPtr<ID3D11DeviceContext> mCtx;
   RefPtr<IDXGISwapChain> mSwapChain;
 
   RefPtr<IDCompositionDevice> mCompositionDevice;
   RefPtr<IDCompositionTarget> mCompositionTarget;
   RefPtr<IDCompositionVisual> mVisual;
--- a/widget/windows/WinCompositorWidget.cpp
+++ b/widget/windows/WinCompositorWidget.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WinCompositorWidget.h"
 
 #include "mozilla/StaticPrefs_layers.h"
 #include "mozilla/gfx/DeviceManagerDx.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/layers/Compositor.h"
+#include "mozilla/layers/CompositorThread.h"
+#include "mozilla/webrender/RenderThread.h"
 #include "mozilla/widget/PlatformWidgetTypes.h"
 #include "nsWindow.h"
 #include "VsyncDispatcher.h"
 #include "WinCompositorWindowThread.h"
 
 #include <ddraw.h>
 
 namespace mozilla {
@@ -242,16 +244,25 @@ void WinCompositorWidget::UpdateTranspar
   mTransparentSurface = nullptr;
   mMemoryDC = nullptr;
 
   if (mTransparencyMode == eTransparencyTransparent) {
     EnsureTransparentSurface();
   }
 }
 
+bool WinCompositorWidget::HasGlass() const {
+  MOZ_ASSERT(layers::CompositorThreadHolder::IsInCompositorThread() ||
+             wr::RenderThread::IsInRenderThread());
+
+  nsTransparencyMode transparencyMode = mTransparencyMode;
+  return transparencyMode == eTransparencyGlass ||
+         transparencyMode == eTransparencyBorderlessGlass;
+}
+
 void WinCompositorWidget::ClearTransparentWindow() {
   MutexAutoLock lock(mTransparentSurfaceLock);
   if (!mTransparentSurface) {
     return;
   }
 
   EnsureTransparentSurface();
 
--- a/widget/windows/WinCompositorWidget.h
+++ b/widget/windows/WinCompositorWidget.h
@@ -3,16 +3,17 @@
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef widget_windows_WinCompositorWidget_h
 #define widget_windows_WinCompositorWidget_h
 
 #include "CompositorWidget.h"
 #include "gfxASurface.h"
+#include "mozilla/Atomics.h"
 #include "mozilla/gfx/CriticalSection.h"
 #include "mozilla/gfx/Point.h"
 #include "mozilla/Mutex.h"
 #include "mozilla/widget/WinCompositorWindowThread.h"
 #include "nsIWidget.h"
 
 class nsWindow;
 
@@ -99,16 +100,18 @@ class WinCompositorWidget : public Compo
   void EnsureCompositorWindow();
   void DestroyCompositorWindow();
   void UpdateCompositorWndSizeIfNecessary();
 
   mozilla::Mutex& GetTransparentSurfaceLock() {
     return mTransparentSurfaceLock;
   }
 
+  bool HasGlass() const;
+
  protected:
  private:
   HDC GetWindowSurface();
   void FreeWindowSurface(HDC dc);
 
   void CreateTransparentSurface(const gfx::IntSize& aSize);
 
  private:
@@ -117,17 +120,18 @@ class WinCompositorWidget : public Compo
 
   WinCompositorWnds mCompositorWnds;
   LayoutDeviceIntSize mLastCompositorWndSize;
 
   gfx::CriticalSection mPresentLock;
 
   // Transparency handling.
   mozilla::Mutex mTransparentSurfaceLock;
-  nsTransparencyMode mTransparencyMode;
+  mozilla::Atomic<nsTransparencyMode, MemoryOrdering::Relaxed>
+      mTransparencyMode;
   RefPtr<gfxASurface> mTransparentSurface;
   HDC mMemoryDC;
   HDC mCompositeDC;
 
   // Locked back buffer of BasicCompositor
   uint8_t* mLockedBackBufferData;
 
   bool mNotDeferEndRemoteDrawing;
--- a/widget/windows/nsWindow.cpp
+++ b/widget/windows/nsWindow.cpp
@@ -7412,16 +7412,31 @@ void nsWindow::SetWindowTranslucencyInne
 
   if (HasGlass()) memset(&mGlassMargins, 0, sizeof mGlassMargins);
   mTransparencyMode = aMode;
 
   if (mCompositorWidgetDelegate) {
     mCompositorWidgetDelegate->UpdateTransparency(aMode);
   }
   UpdateGlass();
+
+  // Clear window by transparent black when compositor window is used in GPU
+  // process and non-client area rendering by DWM is enabled.
+  // It is for showing non-client area rendering. See nsWindow::UpdateGlass().
+  if (HasGlass() && GetLayerManager()->AsKnowsCompositor() &&
+      GetLayerManager()->AsKnowsCompositor()->GetUseCompositorWnd()) {
+    HDC hdc;
+    RECT rect;
+    hdc = ::GetWindowDC(mWnd);
+    ::GetWindowRect(mWnd, &rect);
+    ::MapWindowPoints(nullptr, mWnd, (LPPOINT)&rect, 2);
+    ::FillRect(hdc, &rect,
+               reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
+    ReleaseDC(mWnd, hdc);
+  }
 }
 
 #endif  // MOZ_XUL
 
 /**************************************************************
  **************************************************************
  **
  ** BLOCK: Popup rollup hooks
--- a/widget/windows/nsWindowGfx.cpp
+++ b/widget/windows/nsWindowGfx.cpp
@@ -199,16 +199,31 @@ bool nsWindow::OnPaint(HDC aDC, uint32_t
   // Avoid starting the GPU process for the initial navigator:blank window.
   if (mIsEarlyBlankWindow) {
     // Call BeginPaint/EndPaint or Windows will keep sending us messages.
     ::BeginPaint(mWnd, &ps);
     ::EndPaint(mWnd, &ps);
     return true;
   }
 
+  // Clear window by transparent black when compositor window is used in GPU
+  // process and non-client area rendering by DWM is enabled.
+  // It is for showing non-client area rendering. See nsWindow::UpdateGlass().
+  if (HasGlass() && GetLayerManager()->AsKnowsCompositor() &&
+      GetLayerManager()->AsKnowsCompositor()->GetUseCompositorWnd()) {
+    HDC hdc;
+    RECT rect;
+    hdc = ::GetWindowDC(mWnd);
+    ::GetWindowRect(mWnd, &rect);
+    ::MapWindowPoints(nullptr, mWnd, (LPPOINT)&rect, 2);
+    ::FillRect(hdc, &rect,
+               reinterpret_cast<HBRUSH>(GetStockObject(BLACK_BRUSH)));
+    ReleaseDC(mWnd, hdc);
+  }
+
   if (GetLayerManager()->AsKnowsCompositor() &&
       !mBounds.IsEqualEdges(mLastPaintBounds)) {
     // Do an early async composite so that we at least have something on the
     // screen in the right place, even if the content is out of date.
     GetLayerManager()->ScheduleComposite();
   }
   mLastPaintBounds = mBounds;