Bug 1646835 - refactor RenderCompositorOGL into RenderCompositorNative. r?mstange draft
authorLee Salzman <lsalzman@mozilla.com>
Tue, 23 Jun 2020 23:39:52 +0000
changeset 2999961 2d64d61aa4d46d5e99ffea07c6a4963ccd02b723
parent 2999960 8b3263b050d7953bba2c581778d4135c405a82d3
child 2999962 6d92405d048a1520fcad18a260b0b1b4ef1337ea
push id558590
push userreviewbot
push dateTue, 23 Jun 2020 23:40:15 +0000
treeherdertry@6c92d9a126da [default view] [failures only]
reviewersmstange
bugs1646835
milestone79.0a1
Bug 1646835 - refactor RenderCompositorOGL into RenderCompositorNative. r?mstange Summary: RenderCompositorOGL currently has many responsibilities including supporting OpenGL compositor for Linux, whole-window compositing for Mac NativeLayerCA, and per-cache-tile compositing for Mac NativeLayerCA. With the addition of support for SWGL, this becomes even further complicated. It becomes advantageous to separate out RenderCompositorOGL specifically as only the basic OpenGL compositing case, as that naturally yields a simple and isolated RenderCompositor. What is left over becomes RenderCompositorNative, a basis for implementing NativeLayer-based RenderCompositors. To cleanly isolate state and details of when HW compositing or SW compositing is being used, these are further split off into RCNativeOGL and RCNativeSWGL versions that deal with specific isolated details of OpenGL and SWGL respectively. RCNativeOGL deals with just setting up OpenGL FBOs for NativeLayers. RCNativeSWGL's new task is just to deal mapping NativeLayers and providing SWGL FBOs for them without involving OpenGL. Differential Revision: https://phabricator.services.mozilla.com/D80270 Depends on D80269 Test Plan: Reviewers: mstange Subscribers: Bug #: 1646835 Differential Diff: PHID-DIFF-tx6ulmxbj5afhsucaav6
gfx/webrender_bindings/RenderCompositor.cpp
gfx/webrender_bindings/RenderCompositorNative.cpp
gfx/webrender_bindings/RenderCompositorNative.h
gfx/webrender_bindings/RenderCompositorOGL.cpp
gfx/webrender_bindings/RenderCompositorOGL.h
gfx/webrender_bindings/moz.build
--- a/gfx/webrender_bindings/RenderCompositor.cpp
+++ b/gfx/webrender_bindings/RenderCompositor.cpp
@@ -15,16 +15,20 @@
 #ifdef XP_WIN
 #  include "mozilla/webrender/RenderCompositorANGLE.h"
 #endif
 
 #if defined(MOZ_WAYLAND) || defined(MOZ_WIDGET_ANDROID)
 #  include "mozilla/webrender/RenderCompositorEGL.h"
 #endif
 
+#ifdef XP_MACOSX
+#  include "mozilla/webrender/RenderCompositorNative.h"
+#endif
+
 namespace mozilla {
 namespace wr {
 
 void wr_compositor_add_surface(void* aCompositor, wr::NativeSurfaceId aId,
                                wr::DeviceIntPoint aPosition,
                                wr::DeviceIntRect aClipRect) {
   RenderCompositor* compositor = static_cast<RenderCompositor*>(aCompositor);
   compositor->AddSurface(aId, aPosition, aClipRect);
@@ -120,16 +124,19 @@ UniquePtr<RenderCompositor> RenderCompos
   if (eglCompositor) {
     return eglCompositor;
   }
 #endif
 
 #if defined(MOZ_WIDGET_ANDROID)
   // RenderCompositorOGL is not used on android
   return nullptr;
+#elif defined(XP_MACOSX)
+  // Mac uses NativeLayerCA
+  return RenderCompositorNativeOGL::Create(std::move(aWidget));
 #else
   return RenderCompositorOGL::Create(std::move(aWidget));
 #endif
 }
 
 RenderCompositor::RenderCompositor(RefPtr<widget::CompositorWidget>&& aWidget)
     : mWidget(aWidget) {}
 
copy from gfx/webrender_bindings/RenderCompositorOGL.cpp
copy to gfx/webrender_bindings/RenderCompositorNative.cpp
--- a/gfx/webrender_bindings/RenderCompositorOGL.cpp
+++ b/gfx/webrender_bindings/RenderCompositorNative.cpp
@@ -1,15 +1,15 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
-#include "RenderCompositorOGL.h"
+#include "RenderCompositorNative.h"
 
 #include "GLContext.h"
 #include "GLContextProvider.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/SurfacePool.h"
 #include "mozilla/StaticPrefs_gfx.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/widget/CompositorWidget.h"
@@ -17,220 +17,251 @@
 #ifdef MOZ_GECKO_PROFILER
 #  include "ProfilerMarkerPayload.h"
 #endif
 
 namespace mozilla {
 namespace wr {
 
 /* static */
-UniquePtr<RenderCompositor> RenderCompositorOGL::Create(
+UniquePtr<RenderCompositor> RenderCompositorNativeOGL::Create(
     RefPtr<widget::CompositorWidget>&& aWidget) {
   RefPtr<gl::GLContext> gl = RenderThread::Get()->SharedGL();
   if (!gl) {
     gl = gl::GLContextProvider::CreateForCompositorWidget(
         aWidget, /* aWebRender */ true, /* aForceAccelerated */ true);
     RenderThread::MaybeEnableGLDebugMessage(gl);
   }
   if (!gl || !gl->MakeCurrent()) {
     gfxCriticalNote << "Failed GL context creation for WebRender: "
                     << gfx::hexa(gl.get());
     return nullptr;
   }
-  return MakeUnique<RenderCompositorOGL>(std::move(gl), std::move(aWidget));
+  return MakeUnique<RenderCompositorNativeOGL>(std::move(aWidget),
+                                               std::move(gl));
+}
+
+/* static */
+UniquePtr<RenderCompositor> RenderCompositorNativeSWGL::Create(
+    RefPtr<widget::CompositorWidget>&& aWidget) {
+  return MakeUnique<RenderCompositorNativeSWGL>(std::move(aWidget));
 }
 
-RenderCompositorOGL::RenderCompositorOGL(
-    RefPtr<gl::GLContext>&& aGL, RefPtr<widget::CompositorWidget>&& aWidget)
+RenderCompositorNative::RenderCompositorNative(
+    RefPtr<widget::CompositorWidget>&& aWidget, gl::GLContext* aGL)
     : RenderCompositor(std::move(aWidget)),
-      mGL(aGL),
-      mNativeLayerRoot(GetWidget()->GetNativeLayerRoot()),
-      mPreviousFrameDoneSync(nullptr),
-      mThisFrameDoneSync(nullptr) {
-  if (mNativeLayerRoot) {
+      mNativeLayerRoot(GetWidget()->GetNativeLayerRoot()) {
 #ifdef XP_MACOSX
-    auto pool = RenderThread::Get()->SharedSurfacePool();
-    if (pool) {
-      mSurfacePoolHandle = pool->GetHandleForGL(mGL);
-    }
+  auto pool = RenderThread::Get()->SharedSurfacePool();
+  if (pool) {
+    mSurfacePoolHandle = pool->GetHandleForGL(aGL);
+  }
 #endif
-    MOZ_RELEASE_ASSERT(mSurfacePoolHandle);
-  }
+  MOZ_RELEASE_ASSERT(mSurfacePoolHandle);
 }
 
-RenderCompositorOGL::~RenderCompositorOGL() {
-  if (mNativeLayerRoot) {
-    mNativeLayerRoot->SetLayers({});
-    mNativeLayerForEntireWindow = nullptr;
-    mNativeLayerRootSnapshotter = nullptr;
-    mNativeLayerRoot = nullptr;
-  }
+RenderCompositorNative::~RenderCompositorNative() {
+  mNativeLayerRoot->SetLayers({});
+  mNativeLayerForEntireWindow = nullptr;
+  mNativeLayerRootSnapshotter = nullptr;
+  mNativeLayerRoot = nullptr;
+}
 
-  if (mGL && !mGL->MakeCurrent()) {
+RenderCompositorNativeOGL::RenderCompositorNativeOGL(
+    RefPtr<widget::CompositorWidget>&& aWidget, RefPtr<gl::GLContext>&& aGL)
+    : RenderCompositorNative(std::move(aWidget), aGL), mGL(aGL) {
+  MOZ_ASSERT(mGL);
+}
+
+RenderCompositorNativeOGL::~RenderCompositorNativeOGL() {
+  if (!mGL->MakeCurrent()) {
     gfxCriticalNote
         << "Failed to make render context current during destroying.";
     // Leak resources!
     mPreviousFrameDoneSync = nullptr;
     mThisFrameDoneSync = nullptr;
     return;
   }
 
   if (mPreviousFrameDoneSync) {
     mGL->fDeleteSync(mPreviousFrameDoneSync);
   }
   if (mThisFrameDoneSync) {
     mGL->fDeleteSync(mThisFrameDoneSync);
   }
 }
 
-bool RenderCompositorOGL::BeginFrame() {
-  if (mGL && !mGL->MakeCurrent()) {
+RenderCompositorNativeSWGL::RenderCompositorNativeSWGL(
+    RefPtr<widget::CompositorWidget>&& aWidget)
+    : RenderCompositorNative(std::move(aWidget)) {}
+
+bool RenderCompositorNative::BeginFrame() {
+  if (!MakeCurrent()) {
     gfxCriticalNote << "Failed to make render context current, can't draw.";
     return false;
   }
 
   gfx::IntSize bufferSize = GetBufferSize().ToUnknownSize();
-  if (mNativeLayerRoot && !ShouldUseNativeCompositor()) {
+  if (!ShouldUseNativeCompositor()) {
     if (mNativeLayerForEntireWindow &&
         mNativeLayerForEntireWindow->GetSize() != bufferSize) {
       mNativeLayerRoot->RemoveLayer(mNativeLayerForEntireWindow);
       mNativeLayerForEntireWindow = nullptr;
     }
     if (!mNativeLayerForEntireWindow) {
       mNativeLayerForEntireWindow =
           mNativeLayerRoot->CreateLayer(bufferSize, false, mSurfacePoolHandle);
       mNativeLayerForEntireWindow->SetSurfaceIsFlipped(true);
       mNativeLayerRoot->AppendLayer(mNativeLayerForEntireWindow);
     }
   }
-  if (mNativeLayerForEntireWindow) {
-    gfx::IntRect bounds({}, bufferSize);
-    if (mGL) {
-      Maybe<GLuint> fbo = mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(
-          bounds, bounds, true);
-      if (!fbo) {
-        return false;
-      }
-      mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, *fbo);
-    } else if (!MapNativeLayer(mNativeLayerForEntireWindow, bounds, bounds)) {
-      return false;
-    }
-  } else if (mGL) {
-    mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
+
+  gfx::IntRect bounds({}, bufferSize);
+  if (!InitDefaultFramebuffer(bounds)) {
+    return false;
   }
 
   return true;
 }
 
-void RenderCompositorOGL::CancelFrame() {
+bool RenderCompositorNativeOGL::InitDefaultFramebuffer(
+    const gfx::IntRect& aBounds) {
+  if (mNativeLayerForEntireWindow) {
+    Maybe<GLuint> fbo = mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(
+        aBounds, aBounds, true);
+    if (!fbo) {
+      return false;
+    }
+    mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, *fbo);
+  } else {
+    mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
+  }
+  return true;
+}
+
+bool RenderCompositorNativeSWGL::InitDefaultFramebuffer(
+    const gfx::IntRect& aBounds) {
+  if (mNativeLayerForEntireWindow) {
+    if (!MapNativeLayer(mNativeLayerForEntireWindow, aBounds, aBounds)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+void RenderCompositorNativeSWGL::CancelFrame() {
   if (mNativeLayerForEntireWindow && mLayerTarget) {
     UnmapNativeLayer();
   }
 }
 
-RenderedFrameId RenderCompositorOGL::EndFrame(
+void RenderCompositorNativeOGL::DoSwap() {
+  InsertFrameDoneSync();
+  if (mNativeLayerForEntireWindow) {
+    mGL->fFlush();
+  }
+}
+
+void RenderCompositorNativeSWGL::DoSwap() {
+  if (mNativeLayerForEntireWindow && mLayerTarget) {
+    UnmapNativeLayer();
+  }
+}
+
+RenderedFrameId RenderCompositorNative::EndFrame(
     const nsTArray<DeviceIntRect>& aDirtyRects) {
   RenderedFrameId frameId = GetNextRenderFrameId();
 
-  if (mGL) {
-    InsertFrameDoneSync();
-    if (!mNativeLayerRoot) {
-      mGL->SwapBuffers();
-    } else if (mNativeLayerForEntireWindow) {
-      mGL->fFlush();
-    }
-  } else if (mNativeLayerForEntireWindow && mLayerTarget) {
-    UnmapNativeLayer();
-  }
+  DoSwap();
 
   if (mNativeLayerForEntireWindow) {
     mNativeLayerForEntireWindow->NotifySurfaceReady();
     mNativeLayerRoot->CommitToScreen();
   }
 
   return frameId;
 }
 
-void RenderCompositorOGL::InsertFrameDoneSync() {
+void RenderCompositorNativeOGL::InsertFrameDoneSync() {
 #ifdef XP_MACOSX
   // Only do this on macOS.
   // On other platforms, SwapBuffers automatically applies back-pressure.
   if (mThisFrameDoneSync) {
     mGL->fDeleteSync(mThisFrameDoneSync);
   }
   mThisFrameDoneSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
 #endif
 }
 
-bool RenderCompositorOGL::WaitForGPU() {
+bool RenderCompositorNativeOGL::WaitForGPU() {
   if (mPreviousFrameDoneSync) {
     AUTO_PROFILER_LABEL("Waiting for GPU to finish previous frame", GRAPHICS);
     mGL->fClientWaitSync(mPreviousFrameDoneSync,
                          LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT,
                          LOCAL_GL_TIMEOUT_IGNORED);
     mGL->fDeleteSync(mPreviousFrameDoneSync);
   }
   mPreviousFrameDoneSync = mThisFrameDoneSync;
   mThisFrameDoneSync = nullptr;
 
   return true;
 }
 
-void RenderCompositorOGL::Pause() {}
+void RenderCompositorNative::Pause() {}
 
-bool RenderCompositorOGL::Resume() { return true; }
+bool RenderCompositorNative::Resume() { return true; }
 
-LayoutDeviceIntSize RenderCompositorOGL::GetBufferSize() {
+LayoutDeviceIntSize RenderCompositorNative::GetBufferSize() {
   return mWidget->GetClientSize();
 }
 
-bool RenderCompositorOGL::ShouldUseNativeCompositor() {
-  return mNativeLayerRoot && gfx::gfxVars::UseWebRenderCompositor();
+bool RenderCompositorNative::ShouldUseNativeCompositor() {
+  return gfx::gfxVars::UseWebRenderCompositor();
 }
 
-bool RenderCompositorOGL::MaybeReadback(const gfx::IntSize& aReadbackSize,
-                                        const wr::ImageFormat& aReadbackFormat,
-                                        const Range<uint8_t>& aReadbackBuffer) {
+bool RenderCompositorNative::MaybeReadback(
+    const gfx::IntSize& aReadbackSize, const wr::ImageFormat& aReadbackFormat,
+    const Range<uint8_t>& aReadbackBuffer) {
   if (!ShouldUseNativeCompositor()) {
     return false;
   }
 
   MOZ_RELEASE_ASSERT(aReadbackFormat == wr::ImageFormat::BGRA8);
   if (!mNativeLayerRootSnapshotter) {
     mNativeLayerRootSnapshotter = mNativeLayerRoot->CreateSnapshotter();
   }
   bool success = mNativeLayerRootSnapshotter->ReadbackPixels(
       aReadbackSize, gfx::SurfaceFormat::B8G8R8A8, aReadbackBuffer);
 
-  // ReadbackPixels might have changed the current context. Make sure mGL is
+  // ReadbackPixels might have changed the current context. Make sure GL is
   // current again.
-  if (mGL) {
-    mGL->MakeCurrent();
-  }
+  MakeCurrent();
 
   return success;
 }
 
-uint32_t RenderCompositorOGL::GetMaxUpdateRects() {
+uint32_t RenderCompositorNative::GetMaxUpdateRects() {
   if (ShouldUseNativeCompositor() &&
       StaticPrefs::gfx_webrender_compositor_max_update_rects_AtStartup() > 0) {
     return 1;
   }
   return 0;
 }
 
-void RenderCompositorOGL::CompositorBeginFrame() {
+void RenderCompositorNative::CompositorBeginFrame() {
   mAddedLayers.Clear();
   mAddedPixelCount = 0;
   mAddedClippedPixelCount = 0;
   mBeginFrameTimeStamp = TimeStamp::NowUnfuzzed();
   mSurfacePoolHandle->OnBeginFrame();
 }
 
-void RenderCompositorOGL::CompositorEndFrame() {
+void RenderCompositorNativeOGL::DoFlush() { mGL->fFlush(); }
+
+void RenderCompositorNative::CompositorEndFrame() {
 #ifdef MOZ_GECKO_PROFILER
   if (profiler_thread_is_being_profiled()) {
     auto bufferSize = GetBufferSize();
     uint64_t windowPixelCount = uint64_t(bufferSize.width) * bufferSize.height;
     int nativeLayerCount = 0;
     for (const auto& it : mSurfaces) {
       nativeLayerCount += int(it.second.mNativeLayers.size());
     }
@@ -246,81 +277,76 @@ void RenderCompositorOGL::CompositorEndF
                         int((mTotalPixelCount - mAddedPixelCount) * 100 /
                             windowPixelCount)),
         JS::ProfilingCategoryPair::GRAPHICS, mBeginFrameTimeStamp,
         TimeStamp::NowUnfuzzed());
   }
 #endif
   mDrawnPixelCount = 0;
 
-  if (mGL) {
-    mGL->fFlush();
-  }
+  DoFlush();
 
   mNativeLayerRoot->SetLayers(mAddedLayers);
   mNativeLayerRoot->CommitToScreen();
   mSurfacePoolHandle->OnEndFrame();
 }
 
-void RenderCompositorOGL::BindNativeLayer(wr::NativeTileId aId,
-                                          wr::DeviceIntRect aDirtyRect,
-                                          wr::DeviceIntRect aValidRect) {
+void RenderCompositorNative::BindNativeLayer(wr::NativeTileId aId,
+                                             const gfx::IntRect& aDirtyRect) {
   MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
 
   auto surfaceCursor = mSurfaces.find(aId.surface_id);
   MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
   Surface& surface = surfaceCursor->second;
 
   auto layerCursor = surface.mNativeLayers.find(TileKey(aId.x, aId.y));
   MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
   RefPtr<layers::NativeLayer> layer = layerCursor->second;
 
-  gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
-                         aDirtyRect.size.width, aDirtyRect.size.height);
-
   mCurrentlyBoundNativeLayer = layer;
 
-  mDrawnPixelCount += dirtyRect.Area();
+  mDrawnPixelCount += aDirtyRect.Area();
 }
 
-void RenderCompositorOGL::UnbindNativeLayer() {
+void RenderCompositorNative::UnbindNativeLayer() {
   MOZ_RELEASE_ASSERT(mCurrentlyBoundNativeLayer);
 
   mCurrentlyBoundNativeLayer->NotifySurfaceReady();
   mCurrentlyBoundNativeLayer = nullptr;
 }
 
-void RenderCompositorOGL::Bind(wr::NativeTileId aId,
-                               wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
-                               wr::DeviceIntRect aDirtyRect,
-                               wr::DeviceIntRect aValidRect) {
-  BindNativeLayer(aId, aDirtyRect, aValidRect);
-
+void RenderCompositorNativeOGL::Bind(wr::NativeTileId aId,
+                                     wr::DeviceIntPoint* aOffset,
+                                     uint32_t* aFboId,
+                                     wr::DeviceIntRect aDirtyRect,
+                                     wr::DeviceIntRect aValidRect) {
   gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
                          aValidRect.size.width, aValidRect.size.height);
   gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
                          aDirtyRect.size.width, aDirtyRect.size.height);
 
+  BindNativeLayer(aId, dirtyRect);
+
   Maybe<GLuint> fbo = mCurrentlyBoundNativeLayer->NextSurfaceAsFramebuffer(
       validRect, dirtyRect, true);
   MOZ_RELEASE_ASSERT(fbo);  // TODO: make fallible
 
   *aFboId = *fbo;
   *aOffset = wr::DeviceIntPoint{0, 0};
 }
 
-void RenderCompositorOGL::Unbind() {
+void RenderCompositorNativeOGL::Unbind() {
   mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
 
   UnbindNativeLayer();
 }
 
-bool RenderCompositorOGL::MapNativeLayer(layers::NativeLayer* aLayer,
-                                         const gfx::IntRect& aDirtyRect,
-                                         const gfx::IntRect& aValidRect) {
+bool RenderCompositorNativeSWGL::MapNativeLayer(
+    layers::NativeLayer* aLayer, const gfx::IntRect& aDirtyRect,
+    const gfx::IntRect& aValidRect) {
   uint8_t* data = nullptr;
   gfx::IntSize size;
   int32_t stride = 0;
   gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
   RefPtr<gfx::DrawTarget> dt = aLayer->NextSurfaceAsDrawTarget(
       aValidRect, gfx::IntRegion(aDirtyRect), gfx::BackendType::SKIA);
   if (!dt || !dt->LockBits(&data, &size, &stride, &format)) {
     return false;
@@ -328,93 +354,96 @@ bool RenderCompositorOGL::MapNativeLayer
   MOZ_ASSERT(format == gfx::SurfaceFormat::B8G8R8A8 ||
              format == gfx::SurfaceFormat::B8G8R8X8);
   mLayerTarget = std::move(dt);
   mLayerData = data;
   mLayerStride = stride;
   return true;
 }
 
-void RenderCompositorOGL::UnmapNativeLayer() {
+void RenderCompositorNativeSWGL::UnmapNativeLayer() {
   MOZ_ASSERT(mLayerTarget && mLayerData);
   mLayerTarget->ReleaseBits(mLayerData);
   mLayerTarget = nullptr;
   mLayerData = nullptr;
   mLayerStride = 0;
 }
 
-bool RenderCompositorOGL::GetMappedBuffer(uint8_t** aData, int32_t* aStride) {
+bool RenderCompositorNativeSWGL::GetMappedBuffer(uint8_t** aData,
+                                                 int32_t* aStride) {
   if (mNativeLayerForEntireWindow && mLayerData) {
     *aData = mLayerData;
     *aStride = mLayerStride;
     return true;
   }
   return false;
 }
 
-bool RenderCompositorOGL::MapTile(wr::NativeTileId aId,
-                                  wr::DeviceIntRect aDirtyRect,
-                                  wr::DeviceIntRect aValidRect,
-                                  void** aData, int32_t* aStride) {
-  if (!mNativeLayerRoot || mNativeLayerForEntireWindow) {
+bool RenderCompositorNativeSWGL::MapTile(wr::NativeTileId aId,
+                                         wr::DeviceIntRect aDirtyRect,
+                                         wr::DeviceIntRect aValidRect,
+                                         void** aData, int32_t* aStride) {
+  if (mNativeLayerForEntireWindow) {
     return false;
   }
-  BindNativeLayer(aId, aDirtyRect, aValidRect);
   gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
                          aDirtyRect.size.width, aDirtyRect.size.height);
   gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
                          aValidRect.size.width, aValidRect.size.height);
+  BindNativeLayer(aId, dirtyRect);
   if (!MapNativeLayer(mCurrentlyBoundNativeLayer, dirtyRect, validRect)) {
     UnbindNativeLayer();
     return false;
   }
   *aData = mLayerData;
   *aStride = mLayerStride;
   return true;
 }
 
-void RenderCompositorOGL::UnmapTile() {
+void RenderCompositorNativeSWGL::UnmapTile() {
   if (!mNativeLayerForEntireWindow && mCurrentlyBoundNativeLayer) {
     UnmapNativeLayer();
     UnbindNativeLayer();
   }
 }
 
-void RenderCompositorOGL::CreateSurface(wr::NativeSurfaceId aId,
-                                        wr::DeviceIntPoint aVirtualOffset,
-                                        wr::DeviceIntSize aTileSize,
-                                        bool aIsOpaque) {
+void RenderCompositorNative::CreateSurface(wr::NativeSurfaceId aId,
+                                           wr::DeviceIntPoint aVirtualOffset,
+                                           wr::DeviceIntSize aTileSize,
+                                           bool aIsOpaque) {
   MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
   mSurfaces.insert({aId, Surface{aTileSize, aIsOpaque}});
 }
 
-void RenderCompositorOGL::DestroySurface(NativeSurfaceId aId) {
+void RenderCompositorNative::DestroySurface(NativeSurfaceId aId) {
   auto surfaceCursor = mSurfaces.find(aId);
   MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
 
   Surface& surface = surfaceCursor->second;
   for (const auto& iter : surface.mNativeLayers) {
     mTotalPixelCount -= gfx::IntRect({}, iter.second->GetSize()).Area();
   }
 
   mSurfaces.erase(surfaceCursor);
 }
 
-void RenderCompositorOGL::CreateTile(wr::NativeSurfaceId aId, int aX, int aY) {
+void RenderCompositorNative::CreateTile(wr::NativeSurfaceId aId, int aX,
+                                        int aY) {
   auto surfaceCursor = mSurfaces.find(aId);
   MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
   Surface& surface = surfaceCursor->second;
 
   RefPtr<layers::NativeLayer> layer = mNativeLayerRoot->CreateLayer(
       surface.TileSize(), surface.mIsOpaque, mSurfacePoolHandle);
   surface.mNativeLayers.insert({TileKey(aX, aY), layer});
   mTotalPixelCount += gfx::IntRect({}, layer->GetSize()).Area();
 }
 
-void RenderCompositorOGL::DestroyTile(wr::NativeSurfaceId aId, int aX, int aY) {
+void RenderCompositorNative::DestroyTile(wr::NativeSurfaceId aId, int aX,
+                                         int aY) {
   auto surfaceCursor = mSurfaces.find(aId);
   MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
   Surface& surface = surfaceCursor->second;
 
   auto layerCursor = surface.mNativeLayers.find(TileKey(aX, aY));
   MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
   RefPtr<layers::NativeLayer> layer = std::move(layerCursor->second);
   surface.mNativeLayers.erase(layerCursor);
@@ -426,19 +455,19 @@ void RenderCompositorOGL::DestroyTile(wr
   // front buffer. However, we can tell it to drop its back buffers now, because
   // we know that we will never draw to it again.
   // Dropping the back buffers now puts them back in the surface pool, so those
   // surfaces can be immediately re-used for drawing in other layers in the
   // current frame.
   layer->DiscardBackbuffers();
 }
 
-void RenderCompositorOGL::AddSurface(wr::NativeSurfaceId aId,
-                                     wr::DeviceIntPoint aPosition,
-                                     wr::DeviceIntRect aClipRect) {
+void RenderCompositorNative::AddSurface(wr::NativeSurfaceId aId,
+                                        wr::DeviceIntPoint aPosition,
+                                        wr::DeviceIntRect aClipRect) {
   MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
 
   auto surfaceCursor = mSurfaces.find(aId);
   MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
   const Surface& surface = surfaceCursor->second;
 
   for (auto it = surface.mNativeLayers.begin();
        it != surface.mNativeLayers.end(); ++it) {
@@ -455,17 +484,17 @@ void RenderCompositorOGL::AddSurface(wr:
 
     mAddedPixelCount += layerSize.width * layerSize.height;
     gfx::IntRect visibleRect =
         clipRect.Intersect(layer->CurrentSurfaceDisplayRect() + layerPosition);
     mAddedClippedPixelCount += visibleRect.Area();
   }
 }
 
-CompositorCapabilities RenderCompositorOGL::GetCompositorCapabilities() {
+CompositorCapabilities RenderCompositorNative::GetCompositorCapabilities() {
   CompositorCapabilities caps;
 
   // CoreAnimation doesn't use virtual surfaces
   caps.virtual_surface_size = 0;
 
   return caps;
 }
 
copy from gfx/webrender_bindings/RenderCompositorOGL.h
copy to gfx/webrender_bindings/RenderCompositorNative.h
--- a/gfx/webrender_bindings/RenderCompositorOGL.h
+++ b/gfx/webrender_bindings/RenderCompositorNative.h
@@ -1,75 +1,58 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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 MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
-#define MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
+#ifndef MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H
+#define MOZILLA_GFX_RENDERCOMPOSITOR_NATIVE_H
 
 #include "GLTypes.h"
 #include "mozilla/webrender/RenderCompositor.h"
 #include "mozilla/TimeStamp.h"
 
 namespace mozilla {
 
 namespace layers {
 class NativeLayerRootSnapshotter;
 class NativeLayerRoot;
 class NativeLayer;
 class SurfacePoolHandle;
 }  // namespace layers
 
 namespace wr {
 
-class RenderCompositorOGL : public RenderCompositor {
+// RenderCompositorNative is a skeleton class for implementing compositors
+// backed by NativeLayer surfaces and tiles. This is not meant to be directly
+// instantiated and is instead derived for various use-cases such as OpenGL or
+// SWGL.
+class RenderCompositorNative : public RenderCompositor {
  public:
-  static UniquePtr<RenderCompositor> Create(
-      RefPtr<widget::CompositorWidget>&& aWidget);
-
-  RenderCompositorOGL(RefPtr<gl::GLContext>&& aGL,
-                      RefPtr<widget::CompositorWidget>&& aWidget);
-  virtual ~RenderCompositorOGL();
+  virtual ~RenderCompositorNative();
 
   bool BeginFrame() override;
-  void CancelFrame() override;
   RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
-  bool WaitForGPU() override;
   void Pause() override;
   bool Resume() override;
 
-  bool GetMappedBuffer(uint8_t** aData, int32_t* aStride) override;
-
-  gl::GLContext* gl() const override { return mGL; }
-
-  bool UseANGLE() const override { return false; }
-
   LayoutDeviceIntSize GetBufferSize() override;
 
   bool ShouldUseNativeCompositor() override;
   uint32_t GetMaxUpdateRects() override;
 
   // Does the readback for the ShouldUseNativeCompositor() case.
   bool MaybeReadback(const gfx::IntSize& aReadbackSize,
                      const wr::ImageFormat& aReadbackFormat,
                      const Range<uint8_t>& aReadbackBuffer) 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,
-            wr::DeviceIntRect aValidRect) override;
-  void Unbind() override;
-  bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
-               wr::DeviceIntRect aValidRect, void** aData,
-               int32_t* aStride) override;
-  void UnmapTile() override;
   void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
                      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;
   CompositorCapabilities GetCompositorCapabilities() override;
@@ -77,28 +60,25 @@ class RenderCompositorOGL : public Rende
   struct TileKey {
     TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
 
     int32_t mX;
     int32_t mY;
   };
 
  protected:
-  void InsertFrameDoneSync();
-
-  void BindNativeLayer(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
-                       wr::DeviceIntRect aValidRect);
-  void UnbindNativeLayer();
+  explicit RenderCompositorNative(RefPtr<widget::CompositorWidget>&& aWidget,
+                                  gl::GLContext* aGL = nullptr);
 
-  bool MapNativeLayer(layers::NativeLayer* aLayer,
-                      const gfx::IntRect& aDirtyRect,
-                      const gfx::IntRect& aValidRect);
-  void UnmapNativeLayer();
+  virtual bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) = 0;
+  virtual void DoSwap() = 0;
+  virtual void DoFlush() {}
 
-  RefPtr<gl::GLContext> mGL;
+  void BindNativeLayer(wr::NativeTileId aId, const gfx::IntRect& aDirtyRect);
+  void UnbindNativeLayer();
 
   // Can be null.
   RefPtr<layers::NativeLayerRoot> mNativeLayerRoot;
   UniquePtr<layers::NativeLayerRootSnapshotter> mNativeLayerRootSnapshotter;
   RefPtr<layers::NativeLayer> mNativeLayerForEntireWindow;
   RefPtr<layers::SurfacePoolHandle> mSurfacePoolHandle;
 
   struct TileKeyHashFn {
@@ -123,34 +103,93 @@ class RenderCompositorOGL : public Rende
   struct SurfaceIdHashFn {
     std::size_t operator()(const wr::NativeSurfaceId& aId) const {
       return HashGeneric(wr::AsUint64(aId));
     }
   };
 
   // Used in native compositor mode:
   RefPtr<layers::NativeLayer> mCurrentlyBoundNativeLayer;
-  RefPtr<gfx::DrawTarget> mLayerTarget;
-  uint8_t* mLayerData = nullptr;
-  int32_t mLayerStride = 0;
   nsTArray<RefPtr<layers::NativeLayer>> mAddedLayers;
   uint64_t mTotalPixelCount = 0;
   uint64_t mAddedPixelCount = 0;
   uint64_t mAddedClippedPixelCount = 0;
   uint64_t mDrawnPixelCount = 0;
   gfx::IntRect mVisibleBounds;
   std::unordered_map<wr::NativeSurfaceId, Surface, SurfaceIdHashFn> mSurfaces;
   TimeStamp mBeginFrameTimeStamp;
+};
+
+static inline bool operator==(const RenderCompositorNative::TileKey& a0,
+                              const RenderCompositorNative::TileKey& a1) {
+  return a0.mX == a1.mX && a0.mY == a1.mY;
+}
+
+// RenderCompositorNativeOGL is a NativeLayer compositor that exposes an
+// OpenGL framebuffer for the respective NativeLayer bound to each tile.
+class RenderCompositorNativeOGL : public RenderCompositorNative {
+ public:
+  static UniquePtr<RenderCompositor> Create(
+      RefPtr<widget::CompositorWidget>&& aWidget);
+
+  RenderCompositorNativeOGL(RefPtr<widget::CompositorWidget>&& aWidget,
+                            RefPtr<gl::GLContext>&& aGL);
+  virtual ~RenderCompositorNativeOGL();
+
+  bool WaitForGPU() override;
+
+  gl::GLContext* gl() const override { return mGL; }
+
+  void Bind(wr::NativeTileId aId, wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
+            wr::DeviceIntRect aDirtyRect,
+            wr::DeviceIntRect aValidRect) override;
+  void Unbind() override;
+
+ protected:
+  void InsertFrameDoneSync();
+
+  bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) override;
+  void DoSwap() override;
+  void DoFlush() override;
+
+  RefPtr<gl::GLContext> mGL;
 
   // Used to apply back-pressure in WaitForGPU().
-  GLsync mPreviousFrameDoneSync;
-  GLsync mThisFrameDoneSync;
+  GLsync mPreviousFrameDoneSync = nullptr;
+  GLsync mThisFrameDoneSync = nullptr;
 };
 
-static inline bool operator==(const RenderCompositorOGL::TileKey& a0,
-                              const RenderCompositorOGL::TileKey& a1) {
-  return a0.mX == a1.mX && a0.mY == a1.mY;
-}
+// RenderCompositorNativeSWGL is a NativeLayer compositor that only
+// deals with mapping the underlying buffer for SWGL usage of a tile.
+class RenderCompositorNativeSWGL : public RenderCompositorNative {
+ public:
+  static UniquePtr<RenderCompositor> Create(
+      RefPtr<widget::CompositorWidget>&& aWidget);
+
+  RenderCompositorNativeSWGL(RefPtr<widget::CompositorWidget>&& aWidget);
+
+  void CancelFrame() override;
+
+  bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
+               wr::DeviceIntRect aValidRect, void** aData,
+               int32_t* aStride) override;
+  void UnmapTile() override;
+
+  bool GetMappedBuffer(uint8_t** aData, int32_t* aStride) override;
+
+ protected:
+  bool InitDefaultFramebuffer(const gfx::IntRect& aBounds) override;
+  void DoSwap() override;
+
+  bool MapNativeLayer(layers::NativeLayer* aLayer,
+                      const gfx::IntRect& aDirtyRect,
+                      const gfx::IntRect& aValidRect);
+  void UnmapNativeLayer();
+
+  RefPtr<gfx::DrawTarget> mLayerTarget;
+  uint8_t* mLayerData = nullptr;
+  int32_t mLayerStride = 0;
+};
 
 }  // namespace wr
 }  // namespace mozilla
 
 #endif
--- a/gfx/webrender_bindings/RenderCompositorOGL.cpp
+++ b/gfx/webrender_bindings/RenderCompositorOGL.cpp
@@ -3,26 +3,19 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * 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/. */
 
 #include "RenderCompositorOGL.h"
 
 #include "GLContext.h"
 #include "GLContextProvider.h"
-#include "mozilla/gfx/gfxVars.h"
-#include "mozilla/layers/SurfacePool.h"
-#include "mozilla/StaticPrefs_gfx.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/widget/CompositorWidget.h"
 
-#ifdef MOZ_GECKO_PROFILER
-#  include "ProfilerMarkerPayload.h"
-#endif
-
 namespace mozilla {
 namespace wr {
 
 /* static */
 UniquePtr<RenderCompositor> RenderCompositorOGL::Create(
     RefPtr<widget::CompositorWidget>&& aWidget) {
   RefPtr<gl::GLContext> gl = RenderThread::Get()->SharedGL();
   if (!gl) {
@@ -35,439 +28,56 @@ UniquePtr<RenderCompositor> RenderCompos
                     << gfx::hexa(gl.get());
     return nullptr;
   }
   return MakeUnique<RenderCompositorOGL>(std::move(gl), std::move(aWidget));
 }
 
 RenderCompositorOGL::RenderCompositorOGL(
     RefPtr<gl::GLContext>&& aGL, RefPtr<widget::CompositorWidget>&& aWidget)
-    : RenderCompositor(std::move(aWidget)),
-      mGL(aGL),
-      mNativeLayerRoot(GetWidget()->GetNativeLayerRoot()),
-      mPreviousFrameDoneSync(nullptr),
-      mThisFrameDoneSync(nullptr) {
-  if (mNativeLayerRoot) {
-#ifdef XP_MACOSX
-    auto pool = RenderThread::Get()->SharedSurfacePool();
-    if (pool) {
-      mSurfacePoolHandle = pool->GetHandleForGL(mGL);
-    }
-#endif
-    MOZ_RELEASE_ASSERT(mSurfacePoolHandle);
-  }
+    : RenderCompositor(std::move(aWidget)), mGL(aGL) {
+  MOZ_ASSERT(mGL);
 }
 
 RenderCompositorOGL::~RenderCompositorOGL() {
-  if (mNativeLayerRoot) {
-    mNativeLayerRoot->SetLayers({});
-    mNativeLayerForEntireWindow = nullptr;
-    mNativeLayerRootSnapshotter = nullptr;
-    mNativeLayerRoot = nullptr;
-  }
-
-  if (mGL && !mGL->MakeCurrent()) {
+  if (!mGL->MakeCurrent()) {
     gfxCriticalNote
         << "Failed to make render context current during destroying.";
     // Leak resources!
-    mPreviousFrameDoneSync = nullptr;
-    mThisFrameDoneSync = nullptr;
     return;
   }
-
-  if (mPreviousFrameDoneSync) {
-    mGL->fDeleteSync(mPreviousFrameDoneSync);
-  }
-  if (mThisFrameDoneSync) {
-    mGL->fDeleteSync(mThisFrameDoneSync);
-  }
 }
 
 bool RenderCompositorOGL::BeginFrame() {
-  if (mGL && !mGL->MakeCurrent()) {
+  if (!mGL->MakeCurrent()) {
     gfxCriticalNote << "Failed to make render context current, can't draw.";
     return false;
   }
 
-  gfx::IntSize bufferSize = GetBufferSize().ToUnknownSize();
-  if (mNativeLayerRoot && !ShouldUseNativeCompositor()) {
-    if (mNativeLayerForEntireWindow &&
-        mNativeLayerForEntireWindow->GetSize() != bufferSize) {
-      mNativeLayerRoot->RemoveLayer(mNativeLayerForEntireWindow);
-      mNativeLayerForEntireWindow = nullptr;
-    }
-    if (!mNativeLayerForEntireWindow) {
-      mNativeLayerForEntireWindow =
-          mNativeLayerRoot->CreateLayer(bufferSize, false, mSurfacePoolHandle);
-      mNativeLayerForEntireWindow->SetSurfaceIsFlipped(true);
-      mNativeLayerRoot->AppendLayer(mNativeLayerForEntireWindow);
-    }
-  }
-  if (mNativeLayerForEntireWindow) {
-    gfx::IntRect bounds({}, bufferSize);
-    if (mGL) {
-      Maybe<GLuint> fbo = mNativeLayerForEntireWindow->NextSurfaceAsFramebuffer(
-          bounds, bounds, true);
-      if (!fbo) {
-        return false;
-      }
-      mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, *fbo);
-    } else if (!MapNativeLayer(mNativeLayerForEntireWindow, bounds, bounds)) {
-      return false;
-    }
-  } else if (mGL) {
-    mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
-  }
-
+  mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mGL->GetDefaultFramebuffer());
   return true;
 }
 
-void RenderCompositorOGL::CancelFrame() {
-  if (mNativeLayerForEntireWindow && mLayerTarget) {
-    UnmapNativeLayer();
-  }
-}
-
 RenderedFrameId RenderCompositorOGL::EndFrame(
     const nsTArray<DeviceIntRect>& aDirtyRects) {
   RenderedFrameId frameId = GetNextRenderFrameId();
-
-  if (mGL) {
-    InsertFrameDoneSync();
-    if (!mNativeLayerRoot) {
-      mGL->SwapBuffers();
-    } else if (mNativeLayerForEntireWindow) {
-      mGL->fFlush();
-    }
-  } else if (mNativeLayerForEntireWindow && mLayerTarget) {
-    UnmapNativeLayer();
-  }
-
-  if (mNativeLayerForEntireWindow) {
-    mNativeLayerForEntireWindow->NotifySurfaceReady();
-    mNativeLayerRoot->CommitToScreen();
-  }
-
+  mGL->SwapBuffers();
   return frameId;
 }
 
-void RenderCompositorOGL::InsertFrameDoneSync() {
-#ifdef XP_MACOSX
-  // Only do this on macOS.
-  // On other platforms, SwapBuffers automatically applies back-pressure.
-  if (mThisFrameDoneSync) {
-    mGL->fDeleteSync(mThisFrameDoneSync);
-  }
-  mThisFrameDoneSync = mGL->fFenceSync(LOCAL_GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
-#endif
-}
-
-bool RenderCompositorOGL::WaitForGPU() {
-  if (mPreviousFrameDoneSync) {
-    AUTO_PROFILER_LABEL("Waiting for GPU to finish previous frame", GRAPHICS);
-    mGL->fClientWaitSync(mPreviousFrameDoneSync,
-                         LOCAL_GL_SYNC_FLUSH_COMMANDS_BIT,
-                         LOCAL_GL_TIMEOUT_IGNORED);
-    mGL->fDeleteSync(mPreviousFrameDoneSync);
-  }
-  mPreviousFrameDoneSync = mThisFrameDoneSync;
-  mThisFrameDoneSync = nullptr;
-
-  return true;
-}
-
 void RenderCompositorOGL::Pause() {}
 
 bool RenderCompositorOGL::Resume() { return true; }
 
 LayoutDeviceIntSize RenderCompositorOGL::GetBufferSize() {
   return mWidget->GetClientSize();
 }
 
-bool RenderCompositorOGL::ShouldUseNativeCompositor() {
-  return mNativeLayerRoot && gfx::gfxVars::UseWebRenderCompositor();
-}
-
-bool RenderCompositorOGL::MaybeReadback(const gfx::IntSize& aReadbackSize,
-                                        const wr::ImageFormat& aReadbackFormat,
-                                        const Range<uint8_t>& aReadbackBuffer) {
-  if (!ShouldUseNativeCompositor()) {
-    return false;
-  }
-
-  MOZ_RELEASE_ASSERT(aReadbackFormat == wr::ImageFormat::BGRA8);
-  if (!mNativeLayerRootSnapshotter) {
-    mNativeLayerRootSnapshotter = mNativeLayerRoot->CreateSnapshotter();
-  }
-  bool success = mNativeLayerRootSnapshotter->ReadbackPixels(
-      aReadbackSize, gfx::SurfaceFormat::B8G8R8A8, aReadbackBuffer);
-
-  // ReadbackPixels might have changed the current context. Make sure mGL is
-  // current again.
-  if (mGL) {
-    mGL->MakeCurrent();
-  }
-
-  return success;
-}
-
-uint32_t RenderCompositorOGL::GetMaxUpdateRects() {
-  if (ShouldUseNativeCompositor() &&
-      StaticPrefs::gfx_webrender_compositor_max_update_rects_AtStartup() > 0) {
-    return 1;
-  }
-  return 0;
-}
-
-void RenderCompositorOGL::CompositorBeginFrame() {
-  mAddedLayers.Clear();
-  mAddedPixelCount = 0;
-  mAddedClippedPixelCount = 0;
-  mBeginFrameTimeStamp = TimeStamp::NowUnfuzzed();
-  mSurfacePoolHandle->OnBeginFrame();
-}
-
-void RenderCompositorOGL::CompositorEndFrame() {
-#ifdef MOZ_GECKO_PROFILER
-  if (profiler_thread_is_being_profiled()) {
-    auto bufferSize = GetBufferSize();
-    uint64_t windowPixelCount = uint64_t(bufferSize.width) * bufferSize.height;
-    int nativeLayerCount = 0;
-    for (const auto& it : mSurfaces) {
-      nativeLayerCount += int(it.second.mNativeLayers.size());
-    }
-    profiler_add_text_marker(
-        "WR OS Compositor frame",
-        nsPrintfCString("%d%% painting, %d%% overdraw, %d used "
-                        "layers (%d%% memory) + %d unused layers (%d%% memory)",
-                        int(mDrawnPixelCount * 100 / windowPixelCount),
-                        int(mAddedClippedPixelCount * 100 / windowPixelCount),
-                        int(mAddedLayers.Length()),
-                        int(mAddedPixelCount * 100 / windowPixelCount),
-                        int(nativeLayerCount - mAddedLayers.Length()),
-                        int((mTotalPixelCount - mAddedPixelCount) * 100 /
-                            windowPixelCount)),
-        JS::ProfilingCategoryPair::GRAPHICS, mBeginFrameTimeStamp,
-        TimeStamp::NowUnfuzzed());
-  }
-#endif
-  mDrawnPixelCount = 0;
-
-  if (mGL) {
-    mGL->fFlush();
-  }
-
-  mNativeLayerRoot->SetLayers(mAddedLayers);
-  mNativeLayerRoot->CommitToScreen();
-  mSurfacePoolHandle->OnEndFrame();
-}
-
-void RenderCompositorOGL::BindNativeLayer(wr::NativeTileId aId,
-                                          wr::DeviceIntRect aDirtyRect,
-                                          wr::DeviceIntRect aValidRect) {
-  MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
-
-  auto surfaceCursor = mSurfaces.find(aId.surface_id);
-  MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
-  Surface& surface = surfaceCursor->second;
-
-  auto layerCursor = surface.mNativeLayers.find(TileKey(aId.x, aId.y));
-  MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
-  RefPtr<layers::NativeLayer> layer = layerCursor->second;
-
-  gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
-                         aDirtyRect.size.width, aDirtyRect.size.height);
-
-  mCurrentlyBoundNativeLayer = layer;
-
-  mDrawnPixelCount += dirtyRect.Area();
-}
-
-void RenderCompositorOGL::UnbindNativeLayer() {
-  MOZ_RELEASE_ASSERT(mCurrentlyBoundNativeLayer);
-
-  mCurrentlyBoundNativeLayer->NotifySurfaceReady();
-  mCurrentlyBoundNativeLayer = nullptr;
-}
-
-void RenderCompositorOGL::Bind(wr::NativeTileId aId,
-                               wr::DeviceIntPoint* aOffset, uint32_t* aFboId,
-                               wr::DeviceIntRect aDirtyRect,
-                               wr::DeviceIntRect aValidRect) {
-  BindNativeLayer(aId, aDirtyRect, aValidRect);
-
-  gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
-                         aValidRect.size.width, aValidRect.size.height);
-  gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
-                         aDirtyRect.size.width, aDirtyRect.size.height);
-
-  Maybe<GLuint> fbo = mCurrentlyBoundNativeLayer->NextSurfaceAsFramebuffer(
-      validRect, dirtyRect, true);
-  MOZ_RELEASE_ASSERT(fbo);  // TODO: make fallible
-
-  *aFboId = *fbo;
-  *aOffset = wr::DeviceIntPoint{0, 0};
-}
-
-void RenderCompositorOGL::Unbind() {
-  mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
-
-  UnbindNativeLayer();
-}
-
-bool RenderCompositorOGL::MapNativeLayer(layers::NativeLayer* aLayer,
-                                         const gfx::IntRect& aDirtyRect,
-                                         const gfx::IntRect& aValidRect) {
-  uint8_t* data = nullptr;
-  gfx::IntSize size;
-  int32_t stride = 0;
-  gfx::SurfaceFormat format = gfx::SurfaceFormat::UNKNOWN;
-  RefPtr<gfx::DrawTarget> dt = aLayer->NextSurfaceAsDrawTarget(
-      aValidRect, gfx::IntRegion(aDirtyRect), gfx::BackendType::SKIA);
-  if (!dt || !dt->LockBits(&data, &size, &stride, &format)) {
-    return false;
-  }
-  MOZ_ASSERT(format == gfx::SurfaceFormat::B8G8R8A8 ||
-             format == gfx::SurfaceFormat::B8G8R8X8);
-  mLayerTarget = std::move(dt);
-  mLayerData = data;
-  mLayerStride = stride;
-  return true;
-}
-
-void RenderCompositorOGL::UnmapNativeLayer() {
-  MOZ_ASSERT(mLayerTarget && mLayerData);
-  mLayerTarget->ReleaseBits(mLayerData);
-  mLayerTarget = nullptr;
-  mLayerData = nullptr;
-  mLayerStride = 0;
-}
-
-bool RenderCompositorOGL::GetMappedBuffer(uint8_t** aData, int32_t* aStride) {
-  if (mNativeLayerForEntireWindow && mLayerData) {
-    *aData = mLayerData;
-    *aStride = mLayerStride;
-    return true;
-  }
-  return false;
-}
-
-bool RenderCompositorOGL::MapTile(wr::NativeTileId aId,
-                                  wr::DeviceIntRect aDirtyRect,
-                                  wr::DeviceIntRect aValidRect,
-                                  void** aData, int32_t* aStride) {
-  if (!mNativeLayerRoot || mNativeLayerForEntireWindow) {
-    return false;
-  }
-  BindNativeLayer(aId, aDirtyRect, aValidRect);
-  gfx::IntRect dirtyRect(aDirtyRect.origin.x, aDirtyRect.origin.y,
-                         aDirtyRect.size.width, aDirtyRect.size.height);
-  gfx::IntRect validRect(aValidRect.origin.x, aValidRect.origin.y,
-                         aValidRect.size.width, aValidRect.size.height);
-  if (!MapNativeLayer(mCurrentlyBoundNativeLayer, dirtyRect, validRect)) {
-    UnbindNativeLayer();
-    return false;
-  }
-  *aData = mLayerData;
-  *aStride = mLayerStride;
-  return true;
-}
-
-void RenderCompositorOGL::UnmapTile() {
-  if (!mNativeLayerForEntireWindow && mCurrentlyBoundNativeLayer) {
-    UnmapNativeLayer();
-    UnbindNativeLayer();
-  }
-}
-
-void RenderCompositorOGL::CreateSurface(wr::NativeSurfaceId aId,
-                                        wr::DeviceIntPoint aVirtualOffset,
-                                        wr::DeviceIntSize aTileSize,
-                                        bool aIsOpaque) {
-  MOZ_RELEASE_ASSERT(mSurfaces.find(aId) == mSurfaces.end());
-  mSurfaces.insert({aId, Surface{aTileSize, aIsOpaque}});
-}
-
-void RenderCompositorOGL::DestroySurface(NativeSurfaceId aId) {
-  auto surfaceCursor = mSurfaces.find(aId);
-  MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
-
-  Surface& surface = surfaceCursor->second;
-  for (const auto& iter : surface.mNativeLayers) {
-    mTotalPixelCount -= gfx::IntRect({}, iter.second->GetSize()).Area();
-  }
-
-  mSurfaces.erase(surfaceCursor);
-}
-
-void RenderCompositorOGL::CreateTile(wr::NativeSurfaceId aId, int aX, int aY) {
-  auto surfaceCursor = mSurfaces.find(aId);
-  MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
-  Surface& surface = surfaceCursor->second;
-
-  RefPtr<layers::NativeLayer> layer = mNativeLayerRoot->CreateLayer(
-      surface.TileSize(), surface.mIsOpaque, mSurfacePoolHandle);
-  surface.mNativeLayers.insert({TileKey(aX, aY), layer});
-  mTotalPixelCount += gfx::IntRect({}, layer->GetSize()).Area();
-}
-
-void RenderCompositorOGL::DestroyTile(wr::NativeSurfaceId aId, int aX, int aY) {
-  auto surfaceCursor = mSurfaces.find(aId);
-  MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
-  Surface& surface = surfaceCursor->second;
-
-  auto layerCursor = surface.mNativeLayers.find(TileKey(aX, aY));
-  MOZ_RELEASE_ASSERT(layerCursor != surface.mNativeLayers.end());
-  RefPtr<layers::NativeLayer> layer = std::move(layerCursor->second);
-  surface.mNativeLayers.erase(layerCursor);
-  mTotalPixelCount -= gfx::IntRect({}, layer->GetSize()).Area();
-
-  // If the layer is currently present in mNativeLayerRoot, it will be destroyed
-  // once CompositorEndFrame() replaces mNativeLayerRoot's layers and drops that
-  // reference. So until that happens, the layer still needs to hold on to its
-  // front buffer. However, we can tell it to drop its back buffers now, because
-  // we know that we will never draw to it again.
-  // Dropping the back buffers now puts them back in the surface pool, so those
-  // surfaces can be immediately re-used for drawing in other layers in the
-  // current frame.
-  layer->DiscardBackbuffers();
-}
-
-void RenderCompositorOGL::AddSurface(wr::NativeSurfaceId aId,
-                                     wr::DeviceIntPoint aPosition,
-                                     wr::DeviceIntRect aClipRect) {
-  MOZ_RELEASE_ASSERT(!mCurrentlyBoundNativeLayer);
-
-  auto surfaceCursor = mSurfaces.find(aId);
-  MOZ_RELEASE_ASSERT(surfaceCursor != mSurfaces.end());
-  const Surface& surface = surfaceCursor->second;
-
-  for (auto it = surface.mNativeLayers.begin();
-       it != surface.mNativeLayers.end(); ++it) {
-    RefPtr<layers::NativeLayer> layer = it->second;
-    gfx::IntSize layerSize = layer->GetSize();
-    gfx::IntPoint layerPosition(
-        aPosition.x + surface.mTileSize.width * it->first.mX,
-        aPosition.y + surface.mTileSize.height * it->first.mY);
-    layer->SetPosition(layerPosition);
-    gfx::IntRect clipRect(aClipRect.origin.x, aClipRect.origin.y,
-                          aClipRect.size.width, aClipRect.size.height);
-    layer->SetClipRect(Some(clipRect));
-    mAddedLayers.AppendElement(layer);
-
-    mAddedPixelCount += layerSize.width * layerSize.height;
-    gfx::IntRect visibleRect =
-        clipRect.Intersect(layer->CurrentSurfaceDisplayRect() + layerPosition);
-    mAddedClippedPixelCount += visibleRect.Area();
-  }
-}
-
 CompositorCapabilities RenderCompositorOGL::GetCompositorCapabilities() {
   CompositorCapabilities caps;
 
-  // CoreAnimation doesn't use virtual surfaces
   caps.virtual_surface_size = 0;
 
   return caps;
 }
 
 }  // namespace wr
 }  // namespace mozilla
--- a/gfx/webrender_bindings/RenderCompositorOGL.h
+++ b/gfx/webrender_bindings/RenderCompositorOGL.h
@@ -4,153 +4,41 @@
  * 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 MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
 #define MOZILLA_GFX_RENDERCOMPOSITOR_OGL_H
 
 #include "GLTypes.h"
 #include "mozilla/webrender/RenderCompositor.h"
-#include "mozilla/TimeStamp.h"
 
 namespace mozilla {
-
-namespace layers {
-class NativeLayerRootSnapshotter;
-class NativeLayerRoot;
-class NativeLayer;
-class SurfacePoolHandle;
-}  // namespace layers
-
 namespace wr {
 
 class RenderCompositorOGL : public RenderCompositor {
  public:
   static UniquePtr<RenderCompositor> Create(
       RefPtr<widget::CompositorWidget>&& aWidget);
 
   RenderCompositorOGL(RefPtr<gl::GLContext>&& aGL,
                       RefPtr<widget::CompositorWidget>&& aWidget);
   virtual ~RenderCompositorOGL();
 
   bool BeginFrame() override;
-  void CancelFrame() override;
   RenderedFrameId EndFrame(const nsTArray<DeviceIntRect>& aDirtyRects) final;
-  bool WaitForGPU() override;
   void Pause() override;
   bool Resume() override;
 
-  bool GetMappedBuffer(uint8_t** aData, int32_t* aStride) override;
-
   gl::GLContext* gl() const override { return mGL; }
 
-  bool UseANGLE() const override { return false; }
-
   LayoutDeviceIntSize GetBufferSize() override;
 
-  bool ShouldUseNativeCompositor() override;
-  uint32_t GetMaxUpdateRects() override;
-
-  // Does the readback for the ShouldUseNativeCompositor() case.
-  bool MaybeReadback(const gfx::IntSize& aReadbackSize,
-                     const wr::ImageFormat& aReadbackFormat,
-                     const Range<uint8_t>& aReadbackBuffer) 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,
-            wr::DeviceIntRect aValidRect) override;
-  void Unbind() override;
-  bool MapTile(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
-               wr::DeviceIntRect aValidRect, void** aData,
-               int32_t* aStride) override;
-  void UnmapTile() override;
-  void CreateSurface(wr::NativeSurfaceId aId, wr::DeviceIntPoint aVirtualOffset,
-                     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;
   CompositorCapabilities GetCompositorCapabilities() override;
 
-  struct TileKey {
-    TileKey(int32_t aX, int32_t aY) : mX(aX), mY(aY) {}
-
-    int32_t mX;
-    int32_t mY;
-  };
-
  protected:
-  void InsertFrameDoneSync();
-
-  void BindNativeLayer(wr::NativeTileId aId, wr::DeviceIntRect aDirtyRect,
-                       wr::DeviceIntRect aValidRect);
-  void UnbindNativeLayer();
-
-  bool MapNativeLayer(layers::NativeLayer* aLayer,
-                      const gfx::IntRect& aDirtyRect,
-                      const gfx::IntRect& aValidRect);
-  void UnmapNativeLayer();
-
   RefPtr<gl::GLContext> mGL;
-
-  // Can be null.
-  RefPtr<layers::NativeLayerRoot> mNativeLayerRoot;
-  UniquePtr<layers::NativeLayerRootSnapshotter> mNativeLayerRootSnapshotter;
-  RefPtr<layers::NativeLayer> mNativeLayerForEntireWindow;
-  RefPtr<layers::SurfacePoolHandle> mSurfacePoolHandle;
-
-  struct TileKeyHashFn {
-    std::size_t operator()(const TileKey& aId) const {
-      return HashGeneric(aId.mX, aId.mY);
-    }
-  };
-
-  struct Surface {
-    explicit Surface(wr::DeviceIntSize aTileSize, bool aIsOpaque)
-        : mTileSize(aTileSize), mIsOpaque(aIsOpaque) {}
-    gfx::IntSize TileSize() {
-      return gfx::IntSize(mTileSize.width, mTileSize.height);
-    }
-
-    wr::DeviceIntSize mTileSize;
-    bool mIsOpaque;
-    std::unordered_map<TileKey, RefPtr<layers::NativeLayer>, TileKeyHashFn>
-        mNativeLayers;
-  };
-
-  struct SurfaceIdHashFn {
-    std::size_t operator()(const wr::NativeSurfaceId& aId) const {
-      return HashGeneric(wr::AsUint64(aId));
-    }
-  };
-
-  // Used in native compositor mode:
-  RefPtr<layers::NativeLayer> mCurrentlyBoundNativeLayer;
-  RefPtr<gfx::DrawTarget> mLayerTarget;
-  uint8_t* mLayerData = nullptr;
-  int32_t mLayerStride = 0;
-  nsTArray<RefPtr<layers::NativeLayer>> mAddedLayers;
-  uint64_t mTotalPixelCount = 0;
-  uint64_t mAddedPixelCount = 0;
-  uint64_t mAddedClippedPixelCount = 0;
-  uint64_t mDrawnPixelCount = 0;
-  gfx::IntRect mVisibleBounds;
-  std::unordered_map<wr::NativeSurfaceId, Surface, SurfaceIdHashFn> mSurfaces;
-  TimeStamp mBeginFrameTimeStamp;
-
-  // Used to apply back-pressure in WaitForGPU().
-  GLsync mPreviousFrameDoneSync;
-  GLsync mThisFrameDoneSync;
 };
 
-static inline bool operator==(const RenderCompositorOGL::TileKey& a0,
-                              const RenderCompositorOGL::TileKey& a1) {
-  return a0.mX == a1.mX && a0.mY == a1.mY;
-}
-
 }  // namespace wr
 }  // namespace mozilla
 
 #endif
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -40,19 +40,21 @@ UNIFIED_SOURCES += [
     'RenderTextureHostWrapper.cpp',
     'RenderThread.cpp',
     'WebRenderAPI.cpp',
     'WebRenderTypes.cpp',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     EXPORTS.mozilla.webrender += [
+        'RenderCompositorNative.h',
         'RenderMacIOSurfaceTextureHostOGL.h',
     ]
     UNIFIED_SOURCES += [
+        'RenderCompositorNative.cpp',
         'RenderMacIOSurfaceTextureHostOGL.cpp',
     ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
     EXPORTS.mozilla.webrender += [
         'RenderAndroidSurfaceTextureHostOGL.h',
         'RenderCompositorEGL.h',
     ]