Backed out changeset f3b490c076d6 (bug 1602643) for causing bustages regarding CompositorKindChanged
authorMihai Alexandru Michis <malexandru@mozilla.com>
Thu, 23 Jan 2020 16:27:33 +0200
changeset 511472 52234324a69eb012bac0b0897a66b754f416e413
parent 511471 f2b77060cc80e064f5095a2f06690e7c5d32289a
child 511473 8b8a272428800614fcbc975c1ed93b663950ba89
push id37048
push userrmaries@mozilla.com
push dateThu, 23 Jan 2020 21:42:24 +0000
treeherdermozilla-central@fb6b61e49217 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1602643
milestone74.0a1
backs outf3b490c076d623d6ef3bcfd297a0522d9727477c
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Backed out changeset f3b490c076d6 (bug 1602643) for causing bustages regarding CompositorKindChanged CLOSED TREE
gfx/layers/ipc/CompositorBridgeParent.cpp
gfx/layers/ipc/CompositorBridgeParent.h
gfx/layers/wr/WebRenderBridgeParent.cpp
gfx/layers/wr/WebRenderBridgeParent.h
gfx/webrender_bindings/DCLayerTree.cpp
gfx/webrender_bindings/DCLayerTree.h
gfx/webrender_bindings/RenderCompositor.cpp
gfx/webrender_bindings/RenderCompositor.h
gfx/webrender_bindings/RenderCompositorANGLE.cpp
gfx/webrender_bindings/RenderCompositorANGLE.h
gfx/webrender_bindings/RenderThread.cpp
gfx/webrender_bindings/RendererOGL.cpp
gfx/webrender_bindings/RendererOGL.h
gfx/webrender_bindings/RendererScreenshotGrabber.cpp
gfx/webrender_bindings/RendererScreenshotGrabber.h
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/WebRenderAPI.h
gfx/webrender_bindings/src/bindings.rs
gfx/wr/webrender/src/composite.rs
gfx/wr/webrender/src/picture.rs
gfx/wr/webrender/src/render_backend.rs
gfx/wr/webrender/src/renderer.rs
gfx/wr/webrender_api/src/api.rs
--- a/gfx/layers/ipc/CompositorBridgeParent.cpp
+++ b/gfx/layers/ipc/CompositorBridgeParent.cpp
@@ -2495,23 +2495,16 @@ bool CompositorBridgeParent::IsSameProce
 
 void CompositorBridgeParent::NotifyWebRenderContextPurge() {
   MOZ_ASSERT(CompositorLoop() == MessageLoop::current());
   RefPtr<wr::WebRenderAPI> api =
       mWrBridge->GetWebRenderAPI(wr::RenderRoot::Default);
   api->ClearAllCaches();
 }
 
-void CompositorBridgeParent::NotifyWebRenderDisableNativeCompositor() {
-  MOZ_ASSERT(CompositorLoop() == MessageLoop::current());
-  if (mWrBridge) {
-    mWrBridge->DisableNativeCompositor();
-  }
-}
-
 #if defined(XP_WIN) || defined(MOZ_WIDGET_GTK)
 //#define PLUGINS_LOG(...) printf_stderr("CP [%s]: ", __FUNCTION__);
 //                         printf_stderr(__VA_ARGS__);
 //                         printf_stderr("\n");
 #  define PLUGINS_LOG(...)
 
 bool CompositorBridgeParent::UpdatePluginWindowState(LayersId aId) {
   MonitorAutoLock lock(*sIndirectLayerTreesLock);
--- a/gfx/layers/ipc/CompositorBridgeParent.h
+++ b/gfx/layers/ipc/CompositorBridgeParent.h
@@ -438,18 +438,16 @@ class CompositorBridgeParent final : pub
   mozilla::ipc::IPCResult RecvInitPCanvasParent(
       Endpoint<PCanvasParent>&& aEndpoint) final;
 
   mozilla::ipc::IPCResult RecvReleasePCanvasParent() final;
 
   bool IsSameProcess() const override;
 
   void NotifyWebRenderContextPurge();
-  void NotifyWebRenderDisableNativeCompositor();
-
   void NotifyPipelineRendered(const wr::PipelineId& aPipelineId,
                               const wr::Epoch& aEpoch,
                               const VsyncId& aCompositeStartId,
                               TimeStamp& aCompositeStart,
                               TimeStamp& aRenderStart, TimeStamp& aCompositeEnd,
                               wr::RendererStats* aStats = nullptr);
   void NotifyDidSceneBuild(const nsTArray<wr::RenderRoot>& aRenderRoots,
                            RefPtr<wr::WebRenderPipelineInfo> aInfo);
--- a/gfx/layers/wr/WebRenderBridgeParent.cpp
+++ b/gfx/layers/wr/WebRenderBridgeParent.cpp
@@ -1729,25 +1729,16 @@ void WebRenderBridgeParent::FlushFramePr
   // This sends a message to the render backend thread to send a message
   // to the renderer thread, and waits for that message to be processed. So
   // this effectively blocks on the render backend and renderer threads,
   // following the same codepath that WebRender takes to render and composite
   // a frame.
   mApis[wr::RenderRoot::Default]->WaitFlushed();
 }
 
-void WebRenderBridgeParent::DisableNativeCompositor() {
-  // Make sure that SceneBuilder thread does not have a task.
-  mApis[wr::RenderRoot::Default]->FlushSceneBuilder();
-  // Disable WebRender's native compositor usage
-  mApis[wr::RenderRoot::Default]->EnableNativeCompositor(false);
-  // Ensure we generate and render a frame immediately.
-  ScheduleForcedGenerateFrame();
-}
-
 void WebRenderBridgeParent::UpdateQualitySettings() {
   for (auto& api : mApis) {
     if (!api) {
       continue;
     }
     wr::TransactionBuilder txn;
     txn.UpdateQualitySettings(gfxVars::AllowSacrificingSubpixelAA());
     api->SendTransaction(txn);
--- a/gfx/layers/wr/WebRenderBridgeParent.h
+++ b/gfx/layers/wr/WebRenderBridgeParent.h
@@ -312,18 +312,16 @@ class WebRenderBridgeParent final
    * Return the frames collected by the |WebRenderCompositionRecorder| encoded
    * as data URIs.
    *
    * If there is not currently a recorder, this is a no-op and the promise will
    * be rejected.
    */
   RefPtr<wr::WebRenderAPI::GetCollectedFramesPromise> GetCollectedFrames();
 
-  void DisableNativeCompositor();
-
  private:
   class ScheduleSharedSurfaceRelease;
 
   explicit WebRenderBridgeParent(const wr::PipelineId& aPipelineId);
   virtual ~WebRenderBridgeParent();
 
   wr::WebRenderAPI* Api(wr::RenderRoot aRenderRoot) {
     if (IsRootWebRenderBridgeParent()) {
--- a/gfx/webrender_bindings/DCLayerTree.cpp
+++ b/gfx/webrender_bindings/DCLayerTree.cpp
@@ -47,22 +47,19 @@ DCLayerTree::DCLayerTree(gl::GLContext* 
                          IDCompositionDevice2* aCompositionDevice)
     : mGL(aGL),
       mEGLConfig(aEGLConfig),
       mDevice(aDevice),
       mCompositionDevice(aCompositionDevice),
       mDebugCounter(false),
       mDebugVisualRedrawRegions(false),
       mEGLImage(EGL_NO_IMAGE),
-      mColorRBO(0),
-      mPendingCommit(false) {}
+      mColorRBO(0) {}
 
-DCLayerTree::~DCLayerTree() { ReleaseNativeCompositorResources(); }
-
-void DCLayerTree::ReleaseNativeCompositorResources() {
+DCLayerTree::~DCLayerTree() {
   const auto gl = GetGLContext();
 
   DestroyEGLSurface();
 
   // Delete any cached FBO objects
   for (auto it = mFrameBuffers.begin(); it != mFrameBuffers.end(); ++it) {
     gl->fDeleteRenderbuffers(1, &it->depthRboId);
     gl->fDeleteFramebuffers(1, &it->fboId);
@@ -118,48 +115,32 @@ DCSurface* DCLayerTree::GetSurface(wr::N
 }
 
 void DCLayerTree::SetDefaultSwapChain(IDXGISwapChain1* aSwapChain) {
   mRootVisual->AddVisual(mDefaultSwapChainVisual, TRUE, nullptr);
   mDefaultSwapChainVisual->SetContent(aSwapChain);
   // Default SwapChain's visual does not need linear interporation.
   mDefaultSwapChainVisual->SetBitmapInterpolationMode(
       DCOMPOSITION_BITMAP_INTERPOLATION_MODE_NEAREST_NEIGHBOR);
-  mPendingCommit = true;
+  mCompositionDevice->Commit();
 }
 
 void DCLayerTree::MaybeUpdateDebug() {
   bool updated = false;
   updated |= MaybeUpdateDebugCounter();
   updated |= MaybeUpdateDebugVisualRedrawRegions();
   if (updated) {
-    mPendingCommit = true;
+    mCompositionDevice->Commit();
   }
 }
 
-void DCLayerTree::MaybeCommit() {
-  if (!mPendingCommit) {
-    return;
-  }
-  mCompositionDevice->Commit();
-}
-
 void DCLayerTree::WaitForCommitCompletion() {
   mCompositionDevice->WaitForCommitCompletion();
 }
 
-void DCLayerTree::DisableNativeCompositor() {
-  MOZ_ASSERT(mCurrentSurface.isNothing());
-  MOZ_ASSERT(mCurrentLayers.empty());
-
-  ReleaseNativeCompositorResources();
-  mPrevLayers.clear();
-  mRootVisual->RemoveAllVisuals();
-}
-
 bool DCLayerTree::MaybeUpdateDebugCounter() {
   bool debugCounter = StaticPrefs::gfx_webrender_debug_dcomp_counter();
   if (mDebugCounter == debugCounter) {
     return false;
   }
 
   RefPtr<IDCompositionDeviceDebug> debugDevice;
   HRESULT hr = mCompositionDevice->QueryInterface(
--- a/gfx/webrender_bindings/DCLayerTree.h
+++ b/gfx/webrender_bindings/DCLayerTree.h
@@ -55,19 +55,17 @@ class DCLayerTree {
                                        ID3D11Device* aDevice, HWND aHwnd);
   explicit DCLayerTree(gl::GLContext* aGL, EGLConfig aEGLConfig,
                        ID3D11Device* aDevice,
                        IDCompositionDevice2* aCompositionDevice);
   ~DCLayerTree();
 
   void SetDefaultSwapChain(IDXGISwapChain1* aSwapChain);
   void MaybeUpdateDebug();
-  void MaybeCommit();
   void WaitForCommitCompletion();
-  void DisableNativeCompositor();
 
   // Interface for wr::Compositor
   void CompositorBeginFrame();
   void CompositorEndFrame();
   void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
             wr::DeviceIntRect aDirtyRect);
   void Unbind();
   void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aTileSize,
@@ -93,17 +91,16 @@ class DCLayerTree {
   bool Initialize(HWND aHwnd);
   bool MaybeUpdateDebugCounter();
   bool MaybeUpdateDebugVisualRedrawRegions();
   void DestroyEGLSurface();
   GLuint CreateEGLSurfaceForCompositionSurface(
       wr::DeviceIntRect aDirtyRect, wr::DeviceIntPoint* aOffset,
       RefPtr<IDCompositionSurface> aCompositionSurface,
       wr::DeviceIntPoint aSurfaceOffset);
-  void ReleaseNativeCompositorResources();
 
   RefPtr<gl::GLContext> mGL;
   EGLConfig mEGLConfig;
 
   RefPtr<ID3D11Device> mDevice;
 
   RefPtr<IDCompositionDevice2> mCompositionDevice;
   RefPtr<IDCompositionTarget> mCompositionTarget;
@@ -145,18 +142,16 @@ class DCLayerTree {
     GLuint fboId;
     GLuint depthRboId;
   };
 
   // A cache of FBOs, containing a depth buffer allocated to a specific size.
   // TODO(gw): Might be faster as a hashmap? The length is typically much less
   // than 10.
   std::vector<CachedFrameBuffer> mFrameBuffers;
-
-  bool mPendingCommit;
 };
 
 /**
  Represents a single picture cache slice. Each surface contains some
  number of tiles. An implementation may choose to allocate individual
  tiles to render in to (as the current impl does), or allocate a large
  single virtual surface to draw into (e.g. the DirectComposition virtual
  surface API in future).
--- a/gfx/webrender_bindings/RenderCompositor.cpp
+++ b/gfx/webrender_bindings/RenderCompositor.cpp
@@ -65,21 +65,16 @@ void wr_compositor_destroy_surface(void*
   compositor->DestroySurface(aId);
 }
 
 void wr_compositor_end_frame(void* aCompositor) {
   RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
   compositor->CompositorEndFrame();
 }
 
-void wr_compositor_enable_native_compositor(void* aCompositor, bool aEnable) {
-  RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
-  compositor->EnableNativeCompositor(aEnable);
-}
-
 void wr_compositor_unbind(void* aCompositor) {
   RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
   compositor->Unbind();
 }
 
 /* static */
 UniquePtr<RenderCompositor> RenderCompositor::Create(
     RefPtr<widget::CompositorWidget>&& aWidget) {
--- a/gfx/webrender_bindings/RenderCompositor.h
+++ b/gfx/webrender_bindings/RenderCompositor.h
@@ -74,35 +74,32 @@ class RenderCompositor {
   virtual LayoutDeviceIntSize GetBufferSize() = 0;
 
   widget::CompositorWidget* GetWidget() const { return mWidget; }
 
   layers::SyncObjectHost* GetSyncObject() const { return mSyncObject.get(); }
 
   virtual bool IsContextLost();
 
-  virtual bool SupportAsyncScreenshot() { return true; }
-
   virtual bool ShouldUseNativeCompositor() { return false; }
   virtual uint32_t GetMaxUpdateRects() { return 0; }
 
   // Interface for wr::Compositor
   virtual void CompositorBeginFrame() {}
   virtual void CompositorEndFrame() {}
   virtual void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset,
                     uint32_t* aFboId, wr::DeviceIntRect aDirtyRect) {}
   virtual void Unbind() {}
   virtual void CreateSurface(wr::NativeSurfaceId aId,
                              wr::DeviceIntSize aTileSize, bool aIsOpaque) {}
   virtual void DestroySurface(NativeSurfaceId aId) {}
   virtual void CreateTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) {}
   virtual void DestroyTile(wr::NativeSurfaceId, int32_t aX, int32_t aY) {}
   virtual void AddSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aPosition,
                           wr::DeviceIntRect aClipRect) {}
-  virtual void EnableNativeCompositor(bool aEnable) {}
 
   // Interface for partial present
   virtual bool UsePartialPresent() { return false; }
   virtual bool RequestFullRender() { return false; }
   virtual uint32_t GetMaxPartialPresentRects() { return 0; }
 
   // Whether the surface origin is top-left.
   virtual bool SurfaceOriginIsTopLeft() { return false; }
--- a/gfx/webrender_bindings/RenderCompositorANGLE.cpp
+++ b/gfx/webrender_bindings/RenderCompositorANGLE.cpp
@@ -58,20 +58,18 @@ UniquePtr<RenderCompositor> RenderCompos
 
 RenderCompositorANGLE::RenderCompositorANGLE(
     RefPtr<widget::CompositorWidget>&& aWidget)
     : RenderCompositor(std::move(aWidget)),
       mEGLConfig(nullptr),
       mEGLSurface(nullptr),
       mUseTripleBuffering(false),
       mUseAlpha(false),
-      mUseNativeCompositor(true),
       mUsePartialPresent(false),
-      mFullRender(false),
-      mDisablingNativeCompositor(false) {}
+      mFullRender(false) {}
 
 RenderCompositorANGLE::~RenderCompositorANGLE() {
   DestroyEGLSurface();
   MOZ_ASSERT(!mEGLSurface);
 }
 
 ID3D11Device* RenderCompositorANGLE::GetDeviceOfEGLDisplay() {
   auto* egl = gl::GLLibraryEGL::Get();
@@ -493,26 +491,18 @@ RenderedFrameId RenderCompositorANGLE::E
           mFullRender = true;
         }
       }
     } else {
       mSwapChain->Present(0, 0);
     }
   }
 
-  if (mDisablingNativeCompositor) {
-    // During disabling native compositor, we need to wait all gpu tasks
-    // complete. Otherwise, rendering window could cause white flash.
-    WaitForPreviousGraphicsCommandsFinishedQuery(/* aWaitAll */ true);
-    mDisablingNativeCompositor = false;
-  }
-
   if (mDCLayerTree) {
     mDCLayerTree->MaybeUpdateDebug();
-    mDCLayerTree->MaybeCommit();
   }
 
   return frameId;
 }
 
 bool RenderCompositorANGLE::WaitForGPU() {
   // Note: this waits on the query we inserted in the previous frame,
   // not the one we just inserted now. Example:
@@ -695,22 +685,18 @@ void RenderCompositorANGLE::InsertGraphi
   if (!query) {
     return;
   }
 
   mCtx->End(query);
   mWaitForPresentQueries.emplace(aFrameId, query);
 }
 
-bool RenderCompositorANGLE::WaitForPreviousGraphicsCommandsFinishedQuery(
-    bool aWaitAll) {
+bool RenderCompositorANGLE::WaitForPreviousGraphicsCommandsFinishedQuery() {
   size_t waitLatency = mUseTripleBuffering ? 3 : 2;
-  if (aWaitAll) {
-    waitLatency = 1;
-  }
 
   while (mWaitForPresentQueries.size() >= waitLatency) {
     auto queryPair = mWaitForPresentQueries.front();
     BOOL result;
     bool ret =
         layers::WaitForFrameGPUQuery(mDevice, mCtx, queryPair.second, &result);
 
     if (!ret) {
@@ -752,30 +738,22 @@ bool RenderCompositorANGLE::IsContextLos
   // Then this function just uses GetDeviceRemovedReason().
   if (mDevice->GetDeviceRemovedReason() != S_OK) {
     return true;
   }
   return false;
 }
 
 bool RenderCompositorANGLE::UseCompositor() {
-  if (!mUseNativeCompositor) {
-    return false;
-  }
-
   if (!mDCLayerTree || !gfx::gfxVars::UseWebRenderCompositor()) {
     return false;
   }
   return true;
 }
 
-bool RenderCompositorANGLE::SupportAsyncScreenshot() {
-  return !UseCompositor() && !mDisablingNativeCompositor;
-}
-
 bool RenderCompositorANGLE::ShouldUseNativeCompositor() {
   return UseCompositor();
 }
 
 uint32_t RenderCompositorANGLE::GetMaxUpdateRects() {
   if (UseCompositor() &&
       StaticPrefs::gfx_webrender_compositor_max_update_rects_AtStartup() > 0) {
     return 1;
@@ -820,52 +798,16 @@ void RenderCompositorANGLE::DestroyTile(
 }
 
 void RenderCompositorANGLE::AddSurface(wr::NativeSurfaceId aId,
                                        wr::DeviceIntPoint aPosition,
                                        wr::DeviceIntRect aClipRect) {
   mDCLayerTree->AddSurface(aId, aPosition, aClipRect);
 }
 
-void RenderCompositorANGLE::EnableNativeCompositor(bool aEnable) {
-  // XXX Re-enable native compositor is not handled yet.
-  MOZ_RELEASE_ASSERT(!mDisablingNativeCompositor);
-  MOZ_RELEASE_ASSERT(!aEnable);
-
-  if (!UseCompositor()) {
-    return;
-  }
-
-  mUseNativeCompositor = false;
-  mDCLayerTree->DisableNativeCompositor();
-
-  bool useAlpha = mWidget->AsWindows()->HasGlass();
-  DestroyEGLSurface();
-  mBufferSize.reset();
-
-  RefPtr<IDXGISwapChain1> swapChain1 =
-      CreateSwapChainForDComp(mUseTripleBuffering, useAlpha);
-  if (swapChain1) {
-    mSwapChain = swapChain1;
-    mUseAlpha = useAlpha;
-    mDCLayerTree->SetDefaultSwapChain(swapChain1);
-    // When alpha is used, we want to disable partial present.
-    // See Bug 1595027.
-    if (useAlpha) {
-      mFullRender = true;
-    }
-    ResizeBufferIfNeeded();
-  } else {
-    gfxCriticalNote << "Failed to re-create SwapChain";
-    RenderThread::Get()->HandleWebRenderError(WebRenderError::NEW_SURFACE);
-    return;
-  }
-  mDisablingNativeCompositor = true;
-}
-
 void RenderCompositorANGLE::InitializeUsePartialPresent() {
   if (UseCompositor() || !mSwapChain1 ||
       mWidget->AsWindows()->HasFxrOutputHandler() ||
       gfx::gfxVars::WebRenderMaxPartialPresentRects() <= 0) {
     mUsePartialPresent = false;
   } else {
     mUsePartialPresent = true;
   }
--- a/gfx/webrender_bindings/RenderCompositorANGLE.h
+++ b/gfx/webrender_bindings/RenderCompositorANGLE.h
@@ -59,62 +59,58 @@ class RenderCompositorANGLE : public Ren
   bool UseTripleBuffering() const override { return mUseTripleBuffering; }
 
   LayoutDeviceIntSize GetBufferSize() override;
 
   bool IsContextLost() override;
 
   bool SurfaceOriginIsTopLeft() override { return true; }
 
-  bool SupportAsyncScreenshot() override;
-
   bool ShouldUseNativeCompositor() override;
   uint32_t GetMaxUpdateRects() override;
 
   // Interface for wr::Compositor
   void CompositorBeginFrame() override;
   void CompositorEndFrame() override;
   void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
             wr::DeviceIntRect aDirtyRect) override;
   void Unbind() override;
   void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntSize aTileSize,
                      bool aIsOpaque) override;
   void DestroySurface(NativeSurfaceId aId) override;
   void CreateTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override;
   void DestroyTile(wr::NativeSurfaceId aId, int32_t aX, int32_t aY) override;
   void AddSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aPosition,
                   wr::DeviceIntRect aClipRect) override;
-  void EnableNativeCompositor(bool aEnable) override;
 
   // Interface for partial present
   bool UsePartialPresent() override;
   bool RequestFullRender() override;
   uint32_t GetMaxPartialPresentRects() override;
 
   bool MaybeReadback(const gfx::IntSize& aReadbackSize,
                      const wr::ImageFormat& aReadbackFormat,
                      const Range<uint8_t>& aReadbackBuffer) override;
 
  protected:
   bool UseCompositor();
   void InitializeUsePartialPresent();
   void InsertGraphicsCommandsFinishedWaitQuery(
       RenderedFrameId aRenderedFrameId);
-  bool WaitForPreviousGraphicsCommandsFinishedQuery(bool aWaitAll = false);
+  bool WaitForPreviousGraphicsCommandsFinishedQuery();
   bool ResizeBufferIfNeeded();
   bool CreateEGLSurface();
   void DestroyEGLSurface();
   ID3D11Device* GetDeviceOfEGLDisplay();
   bool CreateSwapChain();
   void CreateSwapChainForDCompIfPossible(IDXGIFactory2* aDXGIFactory2);
   RefPtr<IDXGISwapChain1> CreateSwapChainForDComp(bool aUseTripleBuffering,
                                                   bool aUseAlpha);
   bool SutdownEGLLibraryIfNecessary();
   RefPtr<ID3D11Query> GetD3D11Query();
-  void ReleaseNativeCompositorResources();
 
   EGLConfig mEGLConfig;
   EGLSurface mEGLSurface;
 
   bool mUseTripleBuffering;
   bool mUseAlpha;
 
   RefPtr<ID3D11Device> mDevice;
@@ -125,19 +121,16 @@ class RenderCompositorANGLE : public Ren
   UniquePtr<DCLayerTree> mDCLayerTree;
 
   std::queue<std::pair<RenderedFrameId, RefPtr<ID3D11Query>>>
       mWaitForPresentQueries;
   RefPtr<ID3D11Query> mRecycledQuery;
   RenderedFrameId mLastCompletedFrameId;
 
   Maybe<LayoutDeviceIntSize> mBufferSize;
-  bool mUseNativeCompositor;
   bool mUsePartialPresent;
   bool mFullRender;
-  // Used to know a timing of disabling native compositor.
-  bool mDisablingNativeCompositor;
 };
 
 }  // namespace wr
 }  // namespace mozilla
 
 #endif
--- a/gfx/webrender_bindings/RenderThread.cpp
+++ b/gfx/webrender_bindings/RenderThread.cpp
@@ -488,18 +488,17 @@ void RenderThread::UpdateAndRender(
 
   layers::CompositorThreadHolder::Loop()->PostTask(
       NewRunnableFunction("NotifyDidRenderRunnable", &NotifyDidRender,
                           renderer->GetCompositorBridge(), info, aStartId,
                           aStartTime, start, end, aRender, stats));
 
   if (latestFrameId.IsValid()) {
     auto recorderIt = mCompositionRecorders.find(aWindowId);
-    if (recorderIt != mCompositionRecorders.end() &&
-        renderer->EnsureAsyncScreenshot()) {
+    if (recorderIt != mCompositionRecorders.end()) {
       recorderIt->second->MaybeRecordFrame(renderer->GetRenderer(), info.get());
     }
   }
 
   if (latestFrameId.IsValid()) {
     // Wait for GPU after posting NotifyDidRender, since the wait is not
     // necessary for the NotifyDidRender.
     // The wait is necessary for Textures recycling of AsyncImagePipelineManager
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -65,18 +65,17 @@ void wr_renderer_unlock_external_image(v
 RendererOGL::RendererOGL(RefPtr<RenderThread>&& aThread,
                          UniquePtr<RenderCompositor> aCompositor,
                          wr::WindowId aWindowId, wr::Renderer* aRenderer,
                          layers::CompositorBridgeParent* aBridge)
     : mThread(aThread),
       mCompositor(std::move(aCompositor)),
       mRenderer(aRenderer),
       mBridge(aBridge),
-      mWindowId(aWindowId),
-      mDisableNativeCompositor(false) {
+      mWindowId(aWindowId) {
   MOZ_ASSERT(mThread);
   MOZ_ASSERT(mCompositor);
   MOZ_ASSERT(mRenderer);
   MOZ_ASSERT(mBridge);
   MOZ_COUNT_CTOR(RendererOGL);
 }
 
 RendererOGL::~RendererOGL() {
@@ -103,21 +102,16 @@ void RendererOGL::Update() {
   }
 }
 
 static void DoNotifyWebRenderContextPurge(
     layers::CompositorBridgeParent* aBridge) {
   aBridge->NotifyWebRenderContextPurge();
 }
 
-static void DoWebRenderDisableNativeCompositor(
-    layers::CompositorBridgeParent* aBridge) {
-  aBridge->NotifyWebRenderDisableNativeCompositor();
-}
-
 RenderedFrameId RendererOGL::UpdateAndRender(
     const Maybe<gfx::IntSize>& aReadbackSize,
     const Maybe<wr::ImageFormat>& aReadbackFormat,
     const Maybe<Range<uint8_t>>& aReadbackBuffer, bool aHadSlowFrame,
     RendererStats* aOutStats) {
   mozilla::widget::WidgetRenderingContext widgetContext;
 
 #if defined(XP_MACOSX)
@@ -169,55 +163,40 @@ RenderedFrameId RendererOGL::UpdateAndRe
                                     aReadbackBuffer.ref())) {
       wr_renderer_readback(mRenderer, aReadbackSize.ref().width,
                            aReadbackSize.ref().height, aReadbackFormat.ref(),
                            &aReadbackBuffer.ref()[0],
                            aReadbackBuffer.ref().length());
     }
   }
 
-  mScreenshotGrabber.MaybeGrabScreenshot(this, size.ToUnknownSize());
+  mScreenshotGrabber.MaybeGrabScreenshot(mRenderer, size.ToUnknownSize());
 
   RenderedFrameId frameId = mCompositor->EndFrame(result.DirtyRects());
 
   mCompositor->GetWidget()->PostRender(&widgetContext);
 
 #if defined(ENABLE_FRAME_LATENCY_LOG)
   if (mFrameStartTime) {
     uint32_t latencyMs =
         round((TimeStamp::Now() - mFrameStartTime).ToMilliseconds());
     printf_stderr("generate frame latencyMs latencyMs %d\n", latencyMs);
   }
   // Clear frame start time
   mFrameStartTime = TimeStamp();
 #endif
 
-  mScreenshotGrabber.MaybeProcessQueue(this);
+  mScreenshotGrabber.MaybeProcessQueue(mRenderer);
 
   // TODO: Flush pending actions such as texture deletions/unlocks and
   //       textureHosts recycling.
 
   return frameId;
 }
 
-bool RendererOGL::EnsureAsyncScreenshot() {
-  if (mCompositor->SupportAsyncScreenshot()) {
-    return true;
-  }
-  if (!mDisableNativeCompositor) {
-    layers::CompositorThreadHolder::Loop()->PostTask(
-        NewRunnableFunction("DoWebRenderDisableNativeCompositorRunnable",
-                            &DoWebRenderDisableNativeCompositor, mBridge));
-
-    mDisableNativeCompositor = true;
-    gfxCriticalNote << "Disable native compositor for async screenshot";
-  }
-  return false;
-}
-
 void RendererOGL::CheckGraphicsResetStatus() {
   if (!mCompositor || !mCompositor->gl()) {
     return;
   }
 
   gl::GLContext* gl = mCompositor->gl();
   if (gl->IsSupported(gl::GLFeature::robustness)) {
     GLenum resetStatus = gl->fGetGraphicsResetStatus();
--- a/gfx/webrender_bindings/RendererOGL.h
+++ b/gfx/webrender_bindings/RendererOGL.h
@@ -104,27 +104,23 @@ class RendererOGL {
   RenderTextureHost* GetRenderTexture(wr::ExternalImageId aExternalImageId);
 
   void AccumulateMemoryReport(MemoryReport* aReport);
 
   wr::Renderer* GetRenderer() { return mRenderer; }
 
   gl::GLContext* gl() const;
 
-  bool EnsureAsyncScreenshot();
-
  protected:
   RefPtr<RenderThread> mThread;
   UniquePtr<RenderCompositor> mCompositor;
   wr::Renderer* mRenderer;
   layers::CompositorBridgeParent* mBridge;
   wr::WindowId mWindowId;
   TimeStamp mFrameStartTime;
 
-  bool mDisableNativeCompositor;
-
   RendererScreenshotGrabber mScreenshotGrabber;
 };
 
 }  // namespace wr
 }  // namespace mozilla
 
 #endif
--- a/gfx/webrender_bindings/RendererScreenshotGrabber.cpp
+++ b/gfx/webrender_bindings/RendererScreenshotGrabber.cpp
@@ -11,43 +11,37 @@ using mozilla::layers::ProfilerScreensho
 namespace mozilla {
 namespace wr {
 
 RendererScreenshotGrabber::RendererScreenshotGrabber() {
   mMaxScreenshotSize = ProfilerScreenshots::ScreenshotSize();
 }
 
 void RendererScreenshotGrabber::MaybeGrabScreenshot(
-    RendererOGL* aRendererOGL, const gfx::IntSize& aWindowSize) {
-  bool isEnabled =
-      ProfilerScreenshots::IsEnabled() && aRendererOGL->EnsureAsyncScreenshot();
-
-  if (isEnabled) {
+    Renderer* aRenderer, const gfx::IntSize& aWindowSize) {
+  if (ProfilerScreenshots::IsEnabled()) {
     if (!mProfilerScreenshots) {
       mProfilerScreenshots = new ProfilerScreenshots();
     }
 
-    GrabScreenshot(aRendererOGL->GetRenderer(), aWindowSize);
+    GrabScreenshot(aRenderer, aWindowSize);
   } else if (mProfilerScreenshots) {
-    Destroy(aRendererOGL->GetRenderer());
+    Destroy(aRenderer);
   }
 }
 
-void RendererScreenshotGrabber::MaybeProcessQueue(RendererOGL* aRendererOGL) {
-  bool isEnabled =
-      ProfilerScreenshots::IsEnabled() && aRendererOGL->EnsureAsyncScreenshot();
-
-  if (isEnabled) {
+void RendererScreenshotGrabber::MaybeProcessQueue(Renderer* aRenderer) {
+  if (ProfilerScreenshots::IsEnabled()) {
     if (!mProfilerScreenshots) {
       mProfilerScreenshots = new ProfilerScreenshots();
     }
 
-    ProcessQueue(aRendererOGL->GetRenderer());
+    ProcessQueue(aRenderer);
   } else if (mProfilerScreenshots) {
-    Destroy(aRendererOGL->GetRenderer());
+    Destroy(aRenderer);
   }
 }
 
 void RendererScreenshotGrabber::Destroy(Renderer* aRenderer) {
   mQueue.Clear();
   mCurrentFrameQueueItem = Nothing();
   mProfilerScreenshots = nullptr;
 
--- a/gfx/webrender_bindings/RendererScreenshotGrabber.h
+++ b/gfx/webrender_bindings/RendererScreenshotGrabber.h
@@ -27,24 +27,24 @@ class RendererScreenshotGrabber final {
 
   /**
    * Grab a screenshot from WebRender if we are profiling and screenshots are
    * enabled.
    *
    * The captured screenshot will not be mapped until the second call to
    * |MaybeProcessQueue| after this call to |MaybeGrabScreenshot|.
    */
-  void MaybeGrabScreenshot(RendererOGL* aRendererOGL,
+  void MaybeGrabScreenshot(Renderer* aRenderer,
                            const gfx::IntSize& aWindowSize);
 
   /**
    * Process the screenshots pending in the queue if we are profiling and
    * screenshots are enabled.
    */
-  void MaybeProcessQueue(RendererOGL* aRenderer);
+  void MaybeProcessQueue(Renderer* aRenderer);
 
  private:
   /**
    * Drop all our allocated memory when we are no longer profiling.
    *
    * This will also instruct WebRender to drop all its Gecko profiler
    * associated memory.
    */
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -516,20 +516,16 @@ void WebRenderAPI::Readback(const TimeSt
 
   task.Wait();
 
   UpdateDebugFlags(gfx::gfxVars::WebRenderDebugFlags());
 }
 
 void WebRenderAPI::ClearAllCaches() { wr_api_clear_all_caches(mDocHandle); }
 
-void WebRenderAPI::EnableNativeCompositor(bool aEnable) {
-  wr_api_enable_native_compositor(mDocHandle, aEnable);
-}
-
 void WebRenderAPI::Pause() {
   class PauseEvent : public RendererEvent {
    public:
     explicit PauseEvent(layers::SynchronousTask* aTask) : mTask(aTask) {
       MOZ_COUNT_CTOR(PauseEvent);
     }
 
     virtual ~PauseEvent() { MOZ_COUNT_DTOR(PauseEvent); }
--- a/gfx/webrender_bindings/WebRenderAPI.h
+++ b/gfx/webrender_bindings/WebRenderAPI.h
@@ -242,17 +242,16 @@ class WebRenderAPI final {
 
   void RunOnRenderThread(UniquePtr<RendererEvent> aEvent);
 
   void Readback(const TimeStamp& aStartTime, gfx::IntSize aSize,
                 const gfx::SurfaceFormat& aFormat,
                 const Range<uint8_t>& aBuffer);
 
   void ClearAllCaches();
-  void EnableNativeCompositor(bool aEnable);
 
   void Pause();
   bool Resume();
 
   void WakeSceneBuilder();
   void FlushSceneBuilder();
 
   void NotifyMemoryPressure();
--- a/gfx/webrender_bindings/src/bindings.rs
+++ b/gfx/webrender_bindings/src/bindings.rs
@@ -1215,20 +1215,16 @@ extern "C" {
     fn wr_compositor_begin_frame(compositor: *mut c_void);
     fn wr_compositor_add_surface(
         compositor: *mut c_void,
         id: NativeSurfaceId,
         position: DeviceIntPoint,
         clip_rect: DeviceIntRect,
     );
     fn wr_compositor_end_frame(compositor: *mut c_void);
-    fn wr_compositor_enable_native_compositor(
-        compositor: *mut c_void,
-        enable: bool,
-    );
 }
 
 pub struct WrCompositor(*mut c_void);
 
 impl Compositor for WrCompositor {
     fn create_surface(
         &mut self,
         id: NativeSurfaceId,
@@ -1344,25 +1340,16 @@ impl Compositor for WrCompositor {
 
     fn end_frame(&mut self) {
         unsafe {
             wr_compositor_end_frame(
                 self.0,
             );
         }
     }
-
-    fn enable_native_compositor(&mut self, enable: bool) {
-        unsafe {
-            wr_compositor_enable_native_compositor(
-                self.0,
-                enable,
-            );
-        }
-    }
 }
 
 
 // Call MakeCurrent before this.
 #[no_mangle]
 pub extern "C" fn wr_window_new(window_id: WrWindowId,
                                 window_width: i32,
                                 window_height: i32,
@@ -1593,21 +1580,16 @@ pub unsafe extern "C" fn wr_api_accumula
     *report += dh.api.report_memory();
 }
 
 #[no_mangle]
 pub unsafe extern "C" fn wr_api_clear_all_caches(dh: &mut DocumentHandle) {
     dh.api.send_debug_cmd(DebugCommand::ClearCaches(ClearCache::all()));
 }
 
-#[no_mangle]
-pub unsafe extern "C" fn wr_api_enable_native_compositor(dh: &mut DocumentHandle, enable: bool) {
-    dh.api.send_debug_cmd(DebugCommand::EnableNativeCompositor(enable));
-}
-
 fn make_transaction(do_async: bool) -> Transaction {
     let mut transaction = Transaction::new();
     // Ensure that we either use async scene building or not based on the
     // gecko pref, regardless of what the default is. We can remove this once
     // the scene builder thread is enabled everywhere and working well.
     if do_async {
         transaction.use_scene_builder_thread();
     } else {
--- a/gfx/wr/webrender/src/composite.rs
+++ b/gfx/wr/webrender/src/composite.rs
@@ -89,29 +89,16 @@ pub enum CompositorConfig {
         /// surface update. If this is zero, the entire compositor surface for
         /// a given tile will be drawn if it's dirty.
         max_update_rects: usize,
         /// A client provided interface to a native / OS compositor.
         compositor: Box<dyn Compositor>,
     }
 }
 
-impl CompositorConfig {
-    pub fn compositor(&mut self) -> Option<&mut Box<dyn Compositor>> {
-        match self {
-            CompositorConfig::Native { ref mut compositor, .. } => {
-                Some(compositor)
-            }
-            CompositorConfig::Draw { .. } => {
-                None
-            }
-        }
-    }
-}
-
 impl Default for CompositorConfig {
     /// Default compositor config is full present without partial present.
     fn default() -> Self {
         CompositorConfig::Draw {
             max_partial_present_rects: 0,
         }
     }
 }
@@ -514,19 +501,16 @@ pub trait Compositor {
         position: DeviceIntPoint,
         clip_rect: DeviceIntRect,
     );
 
     /// Commit any changes in the compositor tree for this frame. WR calls
     /// this once when all surface and visual updates are complete, to signal
     /// that the OS composite transaction should be applied.
     fn end_frame(&mut self);
-
-    /// Enable/disable native compositor usage
-    fn enable_native_compositor(&mut self, enable: bool);
 }
 
 /// Return the total area covered by a set of occluders, accounting for
 /// overlapping areas between those rectangles.
 fn area_of_occluders(
     occluders: &[Occluder],
     slice: usize,
     clip_rect: &DeviceIntRect,
--- a/gfx/wr/webrender/src/picture.rs
+++ b/gfx/wr/webrender/src/picture.rs
@@ -603,18 +603,16 @@ pub enum InvalidationReason {
     NoSurface,
     /// The primitive count in the dependency list was different
     PrimCount,
     /// The content of one of the primitives was different
     Content {
         /// What changed in the primitive that was different
         prim_compare_result: PrimitiveCompareResult,
     },
-    // The compositor type changed
-    CompositorKindChanged,
 }
 
 /// A minimal subset of Tile for debug capturing
 #[cfg_attr(feature = "capture", derive(Serialize))]
 #[cfg_attr(feature = "replay", derive(Deserialize))]
 pub struct TileSerializer {
     pub rect: PictureRect,
     pub current_descriptor: TileDescriptor,
@@ -2097,46 +2095,16 @@ impl TileCacheInstance {
         // simple composite mode, the texture cache handle will expire and be collected
         // by the texture cache. For native compositor mode, we need to explicitly
         // invoke a callback to the client to destroy that surface.
         frame_state.composite_state.destroy_native_tiles(
             self.old_tiles.values_mut(),
             frame_state.resource_cache,
         );
 
-        // If compositor mode is changed, need to drop all incompatible tiles.
-        match (frame_context.config.compositor_kind, self.native_surface_id) {
-            (CompositorKind::Draw { .. }, Some(_)) => {
-                frame_state.composite_state.destroy_native_tiles(
-                    self.tiles.values_mut(),
-                    frame_state.resource_cache,
-                );
-                for tile in self.tiles.values_mut() {
-                    tile.surface = None;
-                    // Invalidate the entire tile to force a redraw.
-                    tile.invalidate(None, InvalidationReason::CompositorKindChanged);
-                }
-                if let Some(native_surface_id) = self.native_surface_id.take() {
-                    frame_state.resource_cache.destroy_compositor_surface(native_surface_id);
-                }
-            }
-            (CompositorKind::Native { .. }, None) => {
-                // This could hit even when compositor mode is not changed,
-                // then we need to check if there are incompatible tiles.
-                for tile in self.tiles.values_mut() {
-                    if let Some(TileSurface::Texture { descriptor: SurfaceTextureDescriptor::TextureCache { .. }, .. }) = tile.surface {
-                        tile.surface = None;
-                        // Invalidate the entire tile to force a redraw.
-                        tile.invalidate(None, InvalidationReason::CompositorKindChanged);
-                    }
-                }
-            }
-            (_, _) => {}
-        }
-
         world_culling_rect
     }
 
     /// Update the dependencies for each tile for a given primitive instance.
     pub fn update_prim_dependencies(
         &mut self,
         prim_instance: &PrimitiveInstance,
         prim_spatial_node_index: SpatialNodeIndex,
--- a/gfx/wr/webrender/src/render_backend.rs
+++ b/gfx/wr/webrender/src/render_backend.rs
@@ -706,17 +706,16 @@ pub struct RenderBackend {
     payload_buffer: Vec<Payload>,
 
     default_device_pixel_ratio: f32,
 
     gpu_cache: GpuCache,
     resource_cache: ResourceCache,
 
     frame_config: FrameBuilderConfig,
-    default_compositor_kind: CompositorKind,
     documents: FastHashMap<DocumentId, Document>,
 
     notifier: Box<dyn RenderNotifier>,
     recorder: Option<Box<dyn ApiRecordingReceiver>>,
     logrecorder: Option<Box<LogRecorder>>,
     tile_cache_logger: TileCacheLogger,
     sampler: Option<Box<dyn AsyncPropertySampler + Send>>,
     size_of_ops: Option<MallocSizeOfOps>,
@@ -751,17 +750,16 @@ impl RenderBackend {
             scene_tx,
             low_priority_scene_tx,
             scene_rx,
             payload_buffer: Vec::new(),
             default_device_pixel_ratio,
             resource_cache,
             gpu_cache: GpuCache::new(),
             frame_config,
-            default_compositor_kind : frame_config.compositor_kind,
             documents: FastHashMap::default(),
             notifier,
             recorder,
             logrecorder: None,
             tile_cache_logger: TileCacheLogger::new(500usize),
             sampler,
             size_of_ops,
             debug_flags,
@@ -1222,43 +1220,16 @@ impl RenderBackend {
                         };
 
                         return RenderBackendStatus::Continue;
                     }
                     DebugCommand::ClearCaches(mask) => {
                         self.resource_cache.clear(mask);
                         return RenderBackendStatus::Continue;
                     }
-                    DebugCommand::EnableNativeCompositor(enable) => {
-                        // Default CompositorKind should be Native
-                        if let CompositorKind::Draw { .. } = self.default_compositor_kind {
-                            unreachable!();
-                        }
-
-                        let compositor_kind = if enable {
-                            self.default_compositor_kind
-                        } else {
-                            CompositorKind::default()
-                        };
-
-                        for (_, doc) in &mut self.documents {
-                            doc.scene.config.compositor_kind = compositor_kind;
-                            doc.frame_is_valid = false;
-                        }
-
-                        self.frame_config.compositor_kind = compositor_kind;
-
-                        // Update config in SceneBuilder
-                        self.low_priority_scene_tx.send(SceneBuilderRequest::SetFrameBuilderConfig(
-                            self.frame_config.clone()
-                         )).unwrap();
-
-                        // We don't want to forward this message to the renderer.
-                        return RenderBackendStatus::Continue;
-                    }
                     DebugCommand::SimulateLongSceneBuild(time_ms) => {
                         self.scene_tx.send(SceneBuilderRequest::SimulateLongSceneBuild(time_ms)).unwrap();
                         return RenderBackendStatus::Continue;
                     }
                     DebugCommand::SimulateLongLowPrioritySceneBuild(time_ms) => {
                         self.low_priority_scene_tx.send(
                             SceneBuilderRequest::SimulateLongLowPrioritySceneBuild(time_ms)
                         ).unwrap();
@@ -1538,17 +1509,17 @@ impl RenderBackend {
         let build_frame = (render_frame && !doc.frame_is_valid && doc.has_pixels()) ||
             (requires_frame_build && doc.can_render());
 
         // Request composite is true when we want to composite frame even when
         // there is no frame update. This happens when video frame is updated under
         // external image with NativeTexture or when platform requested to composite frame.
         if invalidate_rendered_frame {
             doc.rendered_frame_is_valid = false;
-            if let CompositorKind::Draw { max_partial_present_rects } = doc.scene.config.compositor_kind {
+            if let CompositorKind::Draw { max_partial_present_rects } = self.frame_config.compositor_kind {
               // When partial present is enabled, we need to force redraw.
               if max_partial_present_rects > 0 {
                   let msg = ResultMsg::ForceRedraw;
                   self.result_tx.send(msg).unwrap();
               }
             }
         }
 
--- a/gfx/wr/webrender/src/renderer.rs
+++ b/gfx/wr/webrender/src/renderer.rs
@@ -1891,18 +1891,16 @@ pub struct Renderer {
     #[cfg(feature = "capture")]
     read_fbo: FBOId,
     #[cfg(feature = "replay")]
     owned_external_images: FastHashMap<(ExternalImageId, u8), ExternalTexture>,
 
     /// The compositing config, affecting how WR composites into the final scene.
     compositor_config: CompositorConfig,
 
-    current_compositor_kind: CompositorKind,
-
     /// Maintains a set of allocated native composite surfaces. This allows any
     /// currently allocated surfaces to be cleaned up as soon as deinit() is
     /// called (the normal bookkeeping for native surfaces exists in the
     /// render backend thread).
     allocated_native_surfaces: FastHashSet<NativeSurfaceId>,
 
     /// If true, partial present state has been reset and everything needs to
     /// be drawn on the next render.
@@ -2420,17 +2418,16 @@ impl Renderer {
             notifications: Vec::new(),
             device_size: None,
             zoom_debug_texture: None,
             cursor_position: DeviceIntPoint::zero(),
             shared_texture_cache_cleared: false,
             documents_seen: FastHashSet::default(),
             force_redraw: true,
             compositor_config: options.compositor_config,
-            current_compositor_kind: compositor_kind,
             allocated_native_surfaces: FastHashSet::default(),
             debug_overlay_state: DebugOverlayState::new(),
         };
 
         // We initially set the flags to default and then now call set_debug_flags
         // to ensure any potential transition when enabling a flag is run.
         renderer.set_debug_flags(debug_flags);
 
@@ -2868,18 +2865,17 @@ impl Renderer {
                 self.debug_server.send(json);
             }
             DebugCommand::SaveCapture(..) |
             DebugCommand::LoadCapture(..) => {
                 panic!("Capture commands are not welcome here! Did you build with 'capture' feature?")
             }
             DebugCommand::ClearCaches(_)
             | DebugCommand::SimulateLongSceneBuild(_)
-            | DebugCommand::SimulateLongLowPrioritySceneBuild(_)
-            | DebugCommand::EnableNativeCompositor(_) => {}
+            | DebugCommand::SimulateLongLowPrioritySceneBuild(_) => {}
             DebugCommand::InvalidateGpuCache => {
                 match self.gpu_cache_texture.bus {
                     GpuCacheBus::PixelBuffer { ref mut rows, .. } => {
                         info!("Invalidating GPU caches");
                         for row in rows {
                             row.is_dirty = true;
                         }
                     }
@@ -2960,19 +2956,17 @@ impl Renderer {
             DebugFlags::GPU_CACHE_DBG |
             DebugFlags::SLOW_FRAME_INDICATOR |
             DebugFlags::PICTURE_CACHING_DBG |
             DebugFlags::PRIMITIVE_DBG |
             DebugFlags::ZOOM_DBG
         );
 
         // Update the debug overlay surface, if we are running in native compositor mode.
-        if let CompositorKind::Native { .. } = self.current_compositor_kind {
-            let compositor = self.compositor_config.compositor().unwrap();
-
+        if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
             // If there is a current surface, destroy it if we don't need it for this frame, or if
             // the size has changed.
             if let Some(current_size) = self.debug_overlay_state.current_size {
                 if !self.debug_overlay_state.is_enabled || current_size != framebuffer_size {
                     compositor.destroy_surface(NativeSurfaceId::DEBUG_OVERLAY);
                     self.debug_overlay_state.current_size = None;
                 }
             }
@@ -2991,18 +2985,17 @@ impl Renderer {
             }
         }
     }
 
     /// Bind a draw target for the debug / profiler overlays, if required.
     fn bind_debug_overlay(&mut self) {
         // Debug overlay setup are only required in native compositing mode
         if self.debug_overlay_state.is_enabled {
-            if let CompositorKind::Native { .. } = self.current_compositor_kind {
-                let compositor = self.compositor_config.compositor().unwrap();
+            if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
                 let surface_size = self.debug_overlay_state.current_size.unwrap();
 
                 // Bind the native surface
                 let surface_info = compositor.bind(
                     NativeTileId::DEBUG_OVERLAY,
                     DeviceIntRect::new(
                         DeviceIntPoint::zero(),
                         surface_size,
@@ -3026,18 +3019,17 @@ impl Renderer {
             }
         }
     }
 
     /// Unbind the draw target for debug / profiler overlays, if required.
     fn unbind_debug_overlay(&mut self) {
         // Debug overlay setup are only required in native compositing mode
         if self.debug_overlay_state.is_enabled {
-            if let CompositorKind::Native { .. } = self.current_compositor_kind {
-                let compositor = self.compositor_config.compositor().unwrap();
+            if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
                 // Unbind the draw target and add it to the visual tree to be composited
                 compositor.unbind();
 
                 compositor.add_surface(
                     NativeSurfaceId::DEBUG_OVERLAY,
                     DeviceIntPoint::zero(),
                     DeviceIntRect::new(
                         DeviceIntPoint::zero(),
@@ -3058,45 +3050,16 @@ impl Renderer {
     ) -> Result<RenderResults, Vec<RendererError>> {
         profile_scope!("render");
         let mut results = RenderResults::default();
         if self.active_documents.is_empty() {
             self.last_time = precise_time_ns();
             return Ok(results);
         }
 
-        let compositor_kind = self.active_documents[0].1.frame.composite_state.compositor_kind;
-        // CompositorKind is updated
-        if self.current_compositor_kind != compositor_kind {
-            let enable = match (self.current_compositor_kind, compositor_kind) {
-                (CompositorKind::Native { .. }, CompositorKind::Draw { .. }) => {
-                    if self.debug_overlay_state.current_size.is_some() {
-                        self.compositor_config
-                            .compositor()
-                            .unwrap()
-                            .destroy_surface(NativeSurfaceId::DEBUG_OVERLAY);
-                        self.debug_overlay_state.current_size = None;
-                    }
-                    false
-                }
-                (CompositorKind::Draw { .. }, CompositorKind::Native { .. }) => {
-                    true
-                }
-                (_, _) => {
-                    unreachable!();
-                }
-            };
-
-            self.compositor_config
-                .compositor()
-                .unwrap()
-                .enable_native_compositor(enable);
-            self.current_compositor_kind = compositor_kind;
-        }
-
         let mut frame_profiles = Vec::new();
         let mut profile_timers = RendererProfileTimers::new();
 
         // The texture resolver scope should be outside of any rendering, including
         // debug rendering. This ensures that when we return render targets to the
         // pool via glInvalidateFramebuffer, we don't do any debug rendering after
         // that point. Otherwise, the bind / invalidate / bind logic trips up the
         // render pass logic in tiled / mobile GPUs, resulting in an extra copy /
@@ -3135,36 +3098,33 @@ impl Renderer {
             self.update_native_surfaces();
 
             frame_id
         });
 
         // Inform the client that we are starting a composition transaction if native
         // compositing is enabled. This needs to be done early in the frame, so that
         // we can create debug overlays after drawing the main surfaces.
-        if let CompositorKind::Native { .. } = self.current_compositor_kind {
-            let compositor = self.compositor_config.compositor().unwrap();
+        if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
             compositor.begin_frame();
         }
 
         profile_timers.cpu_time.profile(|| {
             //Note: another borrowck dance
             let mut active_documents = mem::replace(&mut self.active_documents, Vec::default());
             // sort by the document layer id
             active_documents.sort_by_key(|&(_, ref render_doc)| render_doc.frame.layer);
 
             #[cfg(feature = "replay")]
             self.texture_resolver.external_images.extend(
                 self.owned_external_images.iter().map(|(key, value)| (*key, value.clone()))
             );
 
             let last_document_index = active_documents.len() - 1;
             for (doc_index, (document_id, RenderedDocument { ref mut frame, .. })) in active_documents.iter_mut().enumerate() {
-                assert!(self.current_compositor_kind == frame.composite_state.compositor_kind);
-
                 if self.shared_texture_cache_cleared {
                     assert!(self.documents_seen.contains(&document_id),
                             "Cleared texture cache without sending new document frame.");
                 }
 
                 frame.profile_counters.reset_targets();
                 self.prepare_gpu_cache(frame);
                 assert!(frame.gpu_cache_frame_id <= self.gpu_cache_frame_id,
@@ -3315,19 +3275,19 @@ impl Renderer {
         self.gpu_cache_upload_time = 0;
 
         profile_timers.cpu_time.profile(|| {
             if let Some(debug_renderer) = self.debug.try_get_mut() {
                 let small_screen = self.debug_flags.contains(DebugFlags::SMALL_SCREEN);
                 let scale = if small_screen { 1.6 } else { 1.0 };
                 // TODO(gw): Tidy this up so that compositor config integrates better
                 //           with the (non-compositor) surface y-flip options.
-                let surface_origin_is_top_left = match self.current_compositor_kind {
-                    CompositorKind::Native { .. } => true,
-                    CompositorKind::Draw { .. } => self.device.surface_origin_is_top_left(),
+                let surface_origin_is_top_left = match self.compositor_config {
+                    CompositorConfig::Native { .. } => true,
+                    CompositorConfig::Draw { .. } => self.device.surface_origin_is_top_left(),
                 };
                 debug_renderer.render(
                     &mut self.device,
                     device_size,
                     scale,
                     surface_origin_is_top_left,
                 );
             }
@@ -3346,18 +3306,17 @@ impl Renderer {
             // Unbind the target for the debug overlay. No debug or profiler drawing
             // can occur afer this point.
             self.unbind_debug_overlay();
         }
 
         // Inform the client that we are finished this composition transaction if native
         // compositing is enabled. This must be called after any debug / profiling compositor
         // surfaces have been drawn and added to the visual tree.
-        if let CompositorKind::Native { .. } = self.current_compositor_kind {
-            let compositor = self.compositor_config.compositor().unwrap();
+        if let CompositorConfig::Native { ref mut compositor, .. } = self.compositor_config {
             compositor.end_frame();
         }
 
         self.documents_seen.clear();
         self.shared_texture_cache_cleared = false;
 
         if self.renderer_errors.is_empty() {
             Ok(results)
@@ -5250,22 +5209,21 @@ impl Renderer {
                         };
 
                         // Picture caching can be enabled / disabled dynamically from frame to
                         // frame. This is determined by what the frame builder selected, and is
                         // passed to the renderer via the composite state.
                         if frame.composite_state.picture_caching_is_enabled {
                             // If we have a native OS compositor, then make use of that interface
                             // to specify how to composite each of the picture cache surfaces.
-                            match self.current_compositor_kind {
-                                CompositorKind::Native { .. } => {
-                                    let compositor = self.compositor_config.compositor().unwrap();
+                            match self.compositor_config {
+                                CompositorConfig::Native { ref mut compositor, .. } => {
                                     frame.composite_state.composite_native(&mut **compositor);
                                 }
-                                CompositorKind::Draw { max_partial_present_rects, .. } => {
+                                CompositorConfig::Draw { max_partial_present_rects, .. } => {
                                     self.composite_simple(
                                         &frame.composite_state,
                                         clear_framebuffer,
                                         draw_target,
                                         &projection,
                                         results,
                                         max_partial_present_rects,
                                     );
@@ -5334,22 +5292,21 @@ impl Renderer {
 
                                     DrawTarget::from_texture(
                                         texture,
                                         layer as usize,
                                         true,
                                     )
                                 }
                                 ResolvedSurfaceTexture::Native { id, size } => {
-                                    let surface_info = match self.current_compositor_kind {
-                                        CompositorKind::Native { .. } => {
-                                            let compositor = self.compositor_config.compositor().unwrap();
+                                    let surface_info = match self.compositor_config {
+                                        CompositorConfig::Native { ref mut compositor, .. } => {
                                             compositor.bind(id, picture_target.dirty_rect)
                                         }
-                                        CompositorKind::Draw { .. } => {
+                                        CompositorConfig::Draw { .. } => {
                                             unreachable!();
                                         }
                                     };
 
                                     DrawTarget::NativeSurface {
                                         offset: surface_info.origin,
                                         external_fbo_id: surface_info.fbo_id,
                                         dimensions: size,
@@ -5372,22 +5329,21 @@ impl Renderer {
                                 frame.content_origin,
                                 &projection,
                                 &frame.render_tasks,
                                 &mut results.stats,
                             );
 
                             // Native OS surfaces must be unbound at the end of drawing to them
                             if let ResolvedSurfaceTexture::Native { .. } = picture_target.surface {
-                                match self.current_compositor_kind {
-                                    CompositorKind::Native { .. } => {
-                                        let compositor = self.compositor_config.compositor().unwrap();
+                                match self.compositor_config {
+                                    CompositorConfig::Native { ref mut compositor, .. } => {
                                         compositor.unbind();
                                     }
-                                    CompositorKind::Draw { .. } => {
+                                    CompositorConfig::Draw { .. } => {
                                         unreachable!();
                                     }
                                 }
                             }
                         }
                     }
 
                     for (target_index, target) in alpha.targets.iter().enumerate() {
--- a/gfx/wr/webrender_api/src/api.rs
+++ b/gfx/wr/webrender_api/src/api.rs
@@ -962,18 +962,16 @@ pub enum DebugCommand {
     /// Fetch screenshot.
     FetchScreenshot,
     /// Save a capture of all the documents state.
     SaveCapture(PathBuf, CaptureBits),
     /// Load a capture of all the documents state.
     LoadCapture(PathBuf, MsgSender<CapturedDocument>),
     /// Clear cached resources, forcing them to be re-uploaded from templates.
     ClearCaches(ClearCache),
-    /// Enable/disable native compositor usage
-    EnableNativeCompositor(bool),
     /// Invalidate GPU cache, forcing the update from the CPU mirror.
     InvalidateGpuCache,
     /// Causes the scene builder to pause for a given amount of milliseconds each time it
     /// processes a transaction.
     SimulateLongSceneBuild(u32),
     /// Causes the low priority scene builder to pause for a given amount of milliseconds
     /// each time it processes a transaction.
     SimulateLongLowPrioritySceneBuild(u32),