Bug 1429997 - Add RenderCompositor to wrap platform dependent code r=nical
authorsotaro <sotaro.ikeda.g@gmail.com>
Mon, 15 Jan 2018 22:22:15 +0900
changeset 399268 c9cc2133f2152b5aecea2212195dcd16a2f17258
parent 399267 6f2cf6d0e15afe9f414d6ab545ed4413fc4772b4
child 399269 a99a53c8f13d7a93eb1c532358d5e36dc6eece61
push id98926
push usersikeda@mozilla.com
push dateMon, 15 Jan 2018 13:22:31 +0000
treeherdermozilla-inbound@c9cc2133f215 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnical
bugs1429997
milestone59.0a1
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
Bug 1429997 - Add RenderCompositor to wrap platform dependent code r=nical
gfx/webrender_bindings/RenderCompositor.cpp
gfx/webrender_bindings/RenderCompositor.h
gfx/webrender_bindings/RenderCompositorOGL.cpp
gfx/webrender_bindings/RenderCompositorOGL.h
gfx/webrender_bindings/RendererOGL.cpp
gfx/webrender_bindings/RendererOGL.h
gfx/webrender_bindings/WebRenderAPI.cpp
gfx/webrender_bindings/moz.build
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderCompositor.cpp
@@ -0,0 +1,33 @@
+/* -*- 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 "RenderCompositor.h"
+
+#include "GLContext.h"
+#include "mozilla/layers/SyncObject.h"
+#include "mozilla/webrender/RenderCompositorOGL.h"
+#include "mozilla/widget/CompositorWidget.h"
+
+namespace mozilla {
+namespace wr {
+
+/* static */ UniquePtr<RenderCompositor>
+RenderCompositor::Create(RefPtr<widget::CompositorWidget>&& aWidget)
+{
+  return RenderCompositorOGL::Create(Move(aWidget));
+}
+
+RenderCompositor::RenderCompositor(RefPtr<widget::CompositorWidget>&& aWidget)
+  : mWidget(aWidget)
+{
+}
+
+RenderCompositor::~RenderCompositor()
+{
+}
+
+} // namespace wr
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderCompositor.h
@@ -0,0 +1,60 @@
+/* -*- 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_H
+#define MOZILLA_GFX_RENDERCOMPOSITOR_H
+
+#include "mozilla/RefPtr.h"
+
+namespace mozilla {
+
+namespace gl {
+class GLContext;
+}
+
+namespace layers {
+class SyncObjectHost;
+}
+
+namespace widget {
+class CompositorWidget;
+}
+
+namespace wr {
+
+class RenderCompositor
+{
+public:
+  static UniquePtr<RenderCompositor> Create(RefPtr<widget::CompositorWidget>&& aWidget);
+
+  RenderCompositor(RefPtr<widget::CompositorWidget>&& aWidget);
+  virtual ~RenderCompositor();
+
+  virtual bool Destroy() = 0;
+  virtual bool BeginFrame() = 0;
+  virtual void EndFrame() = 0;
+  virtual void Pause() = 0;
+  virtual bool Resume() = 0;
+
+  virtual gl::GLContext* gl() const { return nullptr; }
+
+  virtual bool UseANGLE() const { return false; }
+
+  virtual LayoutDeviceIntSize GetClientSize() = 0;
+
+  widget::CompositorWidget* GetWidget() const { return mWidget; }
+
+  layers::SyncObjectHost* GetSyncObject() const { return mSyncObject.get(); }
+
+protected:
+  RefPtr<widget::CompositorWidget> mWidget;
+  RefPtr<layers::SyncObjectHost> mSyncObject;
+};
+
+} // namespace wr
+} // namespace mozilla
+
+#endif
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderCompositorOGL.cpp
@@ -0,0 +1,145 @@
+/* -*- 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 "GLContext.h"
+#include "GLContextProvider.h"
+#include "mozilla/gfx/gfxVars.h"
+#include "mozilla/layers/SyncObject.h"
+#include "mozilla/widget/CompositorWidget.h"
+
+#ifdef XP_WIN
+#include "GLContextEGL.h"
+#endif
+
+namespace mozilla {
+namespace wr {
+
+/* static */ UniquePtr<RenderCompositor>
+RenderCompositorOGL::Create(RefPtr<widget::CompositorWidget>&& aWidget)
+{
+  RefPtr<gl::GLContext> gl;
+  if (gfx::gfxVars::UseWebRenderANGLE()) {
+    gl = gl::GLContextProviderEGL::CreateForCompositorWidget(aWidget, true);
+    if (!gl || !gl->IsANGLE()) {
+      gfxCriticalNote << "Failed ANGLE GL context creation for WebRender: " << gfx::hexa(gl.get());
+      return nullptr;
+    }
+  }
+  if (!gl) {
+    gl = gl::GLContextProvider::CreateForCompositorWidget(aWidget, true);
+  }
+  if (!gl || !gl->MakeCurrent()) {
+    gfxCriticalNote << "Failed GL context creation for WebRender: " << gfx::hexa(gl.get());
+    return nullptr;
+  }
+  return MakeUnique<RenderCompositorOGL>(Move(gl), Move(aWidget));
+}
+
+RenderCompositorOGL::RenderCompositorOGL(RefPtr<gl::GLContext>&& aGL,
+                                             RefPtr<widget::CompositorWidget>&& aWidget)
+  : RenderCompositor(Move(aWidget))
+  , mGL(aGL)
+{
+  MOZ_ASSERT(mGL);
+
+#ifdef XP_WIN
+  if (mGL->IsANGLE()) {
+    gl::GLLibraryEGL* egl = &gl::sEGLLibrary;
+
+    // Fetch the D3D11 device.
+    EGLDeviceEXT eglDevice = nullptr;
+    egl->fQueryDisplayAttribEXT(egl->Display(), LOCAL_EGL_DEVICE_EXT, (EGLAttrib*)&eglDevice);
+    MOZ_ASSERT(eglDevice);
+    ID3D11Device* device = nullptr;
+    egl->fQueryDeviceAttribEXT(eglDevice, LOCAL_EGL_D3D11_DEVICE_ANGLE, (EGLAttrib*)&device);
+    MOZ_ASSERT(device);
+
+    mSyncObject = layers::SyncObjectHost::CreateSyncObjectHost(device);
+    if (mSyncObject) {
+      if (!mSyncObject->Init()) {
+        // Some errors occur. Clear the mSyncObject here.
+        // Then, there will be no texture synchronization.
+        mSyncObject = nullptr;
+      }
+    }
+  }
+#endif
+}
+
+RenderCompositorOGL::~RenderCompositorOGL()
+{
+}
+
+bool
+RenderCompositorOGL::Destroy()
+{
+  return true;
+}
+
+bool
+RenderCompositorOGL::BeginFrame()
+{
+  if (!mGL->MakeCurrent()) {
+    gfxCriticalNote << "Failed to make render context current, can't draw.";
+    return false;
+  }
+
+  if (mSyncObject) {
+    // XXX: if the synchronization is failed, we should handle the device reset.
+    mSyncObject->Synchronize();
+  }
+  return true;
+}
+
+void
+RenderCompositorOGL::EndFrame()
+{
+  mGL->SwapBuffers();
+}
+
+void
+RenderCompositorOGL::Pause()
+{
+#ifdef MOZ_WIDGET_ANDROID
+  if (!mGL || mGL->IsDestroyed()) {
+    return;
+  }
+  // ReleaseSurface internally calls MakeCurrent.
+  mGL->ReleaseSurface();
+#endif
+}
+
+bool
+RenderCompositorOGL::Resume()
+{
+#ifdef MOZ_WIDGET_ANDROID
+  if (!mGL || mGL->IsDestroyed()) {
+    return false;
+  }
+  // RenewSurface internally calls MakeCurrent.
+  return mGL->RenewSurface(mWidget);
+#else
+  return true;
+#endif
+}
+
+bool
+RenderCompositorOGL::UseANGLE() const
+{
+  return mGL->IsANGLE();
+}
+
+LayoutDeviceIntSize
+RenderCompositorOGL::GetClientSize()
+{
+  return mWidget->GetClientSize();
+}
+
+
+} // namespace wr
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/gfx/webrender_bindings/RenderCompositorOGL.h
@@ -0,0 +1,56 @@
+/* -*- 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
+
+#include "mozilla/webrender/RenderCompositor.h"
+
+namespace mozilla {
+/*
+namespace gl {
+class GLContext;
+}
+
+namespace layers {
+class SyncObjectHost;
+}
+
+namespace widget {
+class CompositorWidget;
+}
+*/
+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 Destroy() override;
+  bool BeginFrame() override;
+  void EndFrame() override;
+  void Pause() override;
+  bool Resume() override;
+
+  gl::GLContext* gl() const override { return mGL; }
+
+  bool UseANGLE() const override;
+
+  LayoutDeviceIntSize GetClientSize() override;
+
+protected:
+  RefPtr<gl::GLContext> mGL;
+};
+
+} // namespace wr
+} // namespace mozilla
+
+#endif
--- a/gfx/webrender_bindings/RendererOGL.cpp
+++ b/gfx/webrender_bindings/RendererOGL.cpp
@@ -1,101 +1,74 @@
 /* -*- 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 "RendererOGL.h"
 #include "GLContext.h"
-#include "GLContextProvider.h"
 #include "mozilla/gfx/Logging.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/CompositorBridgeParent.h"
 #include "mozilla/layers/CompositorThread.h"
 #include "mozilla/layers/LayersTypes.h"
-#include "mozilla/webrender/RenderBufferTextureHost.h"
-#include "mozilla/webrender/RenderTextureHostOGL.h"
+#include "mozilla/webrender/RenderCompositor.h"
+#include "mozilla/webrender/RenderTextureHost.h"
 #include "mozilla/widget/CompositorWidget.h"
 
 namespace mozilla {
 namespace wr {
 
 wr::WrExternalImage LockExternalImage(void* aObj, wr::WrExternalImageId aId, uint8_t aChannelIndex)
 {
   RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
   RenderTextureHost* texture = renderer->GetRenderTexture(aId);
   MOZ_ASSERT(texture);
   if (!texture) {
     gfxCriticalNote << "Failed to lock ExternalImage for extId:" << AsUint64(aId);
     return InvalidToWrExternalImage();
   }
-  return texture->Lock(aChannelIndex, renderer->mGL);
+  return texture->Lock(aChannelIndex, renderer->gl());
 }
 
 void UnlockExternalImage(void* aObj, wr::WrExternalImageId aId, uint8_t aChannelIndex)
 {
   RendererOGL* renderer = reinterpret_cast<RendererOGL*>(aObj);
   RenderTextureHost* texture = renderer->GetRenderTexture(aId);
   MOZ_ASSERT(texture);
   if (!texture) {
     return;
   }
   texture->Unlock();
 }
 
 RendererOGL::RendererOGL(RefPtr<RenderThread>&& aThread,
-                         RefPtr<gl::GLContext>&& aGL,
-                         RefPtr<widget::CompositorWidget>&& aWidget,
+                         UniquePtr<RenderCompositor> aCompositor,
                          wr::WindowId aWindowId,
                          wr::Renderer* aRenderer,
                          layers::CompositorBridgeParentBase* aBridge)
   : mThread(aThread)
-  , mGL(aGL)
-  , mWidget(aWidget)
+  , mCompositor(Move(aCompositor))
   , mRenderer(aRenderer)
   , mBridge(aBridge)
   , mWindowId(aWindowId)
   , mDebugFlags({ 0 })
 {
   MOZ_ASSERT(mThread);
-  MOZ_ASSERT(mGL);
-  MOZ_ASSERT(mWidget);
+  MOZ_ASSERT(mCompositor);
   MOZ_ASSERT(mRenderer);
   MOZ_ASSERT(mBridge);
   MOZ_COUNT_CTOR(RendererOGL);
-
-#ifdef XP_WIN
-  if (aGL->IsANGLE()) {
-    gl::GLLibraryEGL* egl = &gl::sEGLLibrary;
-
-    // Fetch the D3D11 device.
-    EGLDeviceEXT eglDevice = nullptr;
-    egl->fQueryDisplayAttribEXT(egl->Display(), LOCAL_EGL_DEVICE_EXT, (EGLAttrib*)&eglDevice);
-    MOZ_ASSERT(eglDevice);
-    ID3D11Device* device = nullptr;
-    egl->fQueryDeviceAttribEXT(eglDevice, LOCAL_EGL_D3D11_DEVICE_ANGLE, (EGLAttrib*)&device);
-    MOZ_ASSERT(device);
-
-    mSyncObject = layers::SyncObjectHost::CreateSyncObjectHost(device);
-    if (mSyncObject) {
-      if (!mSyncObject->Init()) {
-        // Some errors occur. Clear the mSyncObject here.
-        // Then, there will be no texture synchronization.
-        mSyncObject = nullptr;
-      }
-    }
-  }
-#endif
 }
 
 RendererOGL::~RendererOGL()
 {
   MOZ_COUNT_DTOR(RendererOGL);
-  if (!mGL->MakeCurrent()) {
+  if (!mCompositor->gl()->MakeCurrent()) {
     gfxCriticalNote << "Failed to make render context current during destroying.";
     // Leak resources!
     return;
   }
   wr_renderer_delete(mRenderer);
 }
 
 wr::WrExternalImageHandler
@@ -119,51 +92,45 @@ RendererOGL::Render()
 {
   uint32_t flags = gfx::gfxVars::WebRenderDebugFlags();
 
   if (mDebugFlags.mBits != flags) {
     mDebugFlags.mBits = flags;
     wr_renderer_set_debug_flags(mRenderer, mDebugFlags);
   }
 
-  if (!mGL->MakeCurrent()) {
-    gfxCriticalNote << "Failed to make render context current, can't draw.";
-    NotifyWebRenderError(WebRenderError::MAKE_CURRENT);
-    return false;
-  }
-
   mozilla::widget::WidgetRenderingContext widgetContext;
 
 #if defined(XP_MACOSX)
-  widgetContext.mGL = mGL;
+  widgetContext.mGL = mCompositor->gl();
 // TODO: we don't have a notion of compositor here.
 //#elif defined(MOZ_WIDGET_ANDROID)
 //  widgetContext.mCompositor = mCompositor;
 #endif
 
-  if (!mWidget->PreRender(&widgetContext)) {
+  if (!mCompositor->GetWidget()->PreRender(&widgetContext)) {
     // XXX This could cause oom in webrender since pending_texture_updates is not handled.
     // It needs to be addressed.
     return false;
   }
   // XXX set clear color if MOZ_WIDGET_ANDROID is defined.
 
-  auto size = mWidget->GetClientSize();
+  if (!mCompositor->BeginFrame()) {
+    return false;
+  }
 
-  if (mSyncObject) {
-    // XXX: if the synchronization is failed, we should handle the device reset.
-    mSyncObject->Synchronize();
-  }
+  auto size = mCompositor->GetClientSize();
 
   if (!wr_renderer_render(mRenderer, size.width, size.height)) {
     NotifyWebRenderError(WebRenderError::RENDER);
   }
 
-  mGL->SwapBuffers();
-  mWidget->PostRender(&widgetContext);
+  mCompositor->EndFrame();
+
+  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();
@@ -173,37 +140,35 @@ RendererOGL::Render()
   //       textureHosts recycling.
 
   return true;
 }
 
 void
 RendererOGL::Pause()
 {
-#ifdef MOZ_WIDGET_ANDROID
-  if (!mGL || mGL->IsDestroyed()) {
-    return;
-  }
-  // ReleaseSurface internally calls MakeCurrent.
-  mGL->ReleaseSurface();
-#endif
+  mCompositor->Pause();
 }
 
 bool
 RendererOGL::Resume()
 {
-#ifdef MOZ_WIDGET_ANDROID
-  if (!mGL || mGL->IsDestroyed()) {
-    return false;
-  }
-  // RenewSurface internally calls MakeCurrent.
-  return mGL->RenewSurface(mWidget);
-#else
-  return true;
-#endif
+  return mCompositor->Resume();
+}
+
+layers::SyncObjectHost*
+RendererOGL::GetSyncObject() const
+{
+  return mCompositor->GetSyncObject();
+}
+
+gl::GLContext*
+RendererOGL::gl() const
+{
+  return mCompositor->gl();
 }
 
 void
 RendererOGL::SetFrameStartTime(const TimeStamp& aTime)
 {
   if (mFrameStartTime) {
     // frame start time is already set. This could happen when multiple
     // generate frame requests are merged by webrender.
--- a/gfx/webrender_bindings/RendererOGL.h
+++ b/gfx/webrender_bindings/RendererOGL.h
@@ -3,41 +3,42 @@
 /* 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_LAYERS_RENDEREROGL_H
 #define MOZILLA_LAYERS_RENDEREROGL_H
 
 #include "mozilla/layers/CompositorTypes.h"
-#include "mozilla/layers/SyncObject.h"
 #include "mozilla/webrender/RenderThread.h"
 #include "mozilla/webrender/WebRenderTypes.h"
 #include "mozilla/webrender/webrender_ffi.h"
 
 namespace mozilla {
 
 namespace gfx {
 class DrawTarget;
 }
 
 namespace gl {
 class GLContext;
 }
 
 namespace layers {
 class CompositorBridgeParentBase;
+class SyncObjectHost;
 }
 
 namespace widget {
 class CompositorWidget;
 }
 
 namespace wr {
 
+class RenderCompositor;
 class RenderTextureHost;
 
 /// Owns the WebRender renderer and GL context.
 ///
 /// There is one renderer per window, all owned by the render thread.
 /// This class is a similar abstraction to CompositorOGL except that it is used
 /// on the render thread instead of the compositor thread.
 class RendererOGL
@@ -63,48 +64,47 @@ public:
   /// This can be called on the render thread only.
   void SetFrameStartTime(const TimeStamp& aTime);
 
   /// This can be called on the render thread only.
   ~RendererOGL();
 
   /// This can be called on the render thread only.
   RendererOGL(RefPtr<RenderThread>&& aThread,
-              RefPtr<gl::GLContext>&& aGL,
-              RefPtr<widget::CompositorWidget>&&,
+              UniquePtr<RenderCompositor> aCompositor,
               wr::WindowId aWindowId,
               wr::Renderer* aRenderer,
               layers::CompositorBridgeParentBase* aBridge);
 
   /// This can be called on the render thread only.
   void Pause();
 
   /// This can be called on the render thread only.
   bool Resume();
 
-  layers::SyncObjectHost* GetSyncObject() const { return mSyncObject.get(); }
+  layers::SyncObjectHost* GetSyncObject() const;
 
   layers::CompositorBridgeParentBase* GetCompositorBridge() { return mBridge; }
 
   wr::WrRenderedEpochs* FlushRenderedEpochs();
 
   RenderTextureHost* GetRenderTexture(wr::WrExternalImageId aExternalImageId);
 
   wr::Renderer* GetRenderer() { return mRenderer; }
 
+  gl::GLContext* gl() const;
+
 protected:
   void NotifyWebRenderError(WebRenderError aError);
 
   RefPtr<RenderThread> mThread;
-  RefPtr<gl::GLContext> mGL;
-  RefPtr<widget::CompositorWidget> mWidget;
+  UniquePtr<RenderCompositor> mCompositor;
   wr::Renderer* mRenderer;
   layers::CompositorBridgeParentBase* mBridge;
   wr::WindowId mWindowId;
   TimeStamp mFrameStartTime;
-  RefPtr<layers::SyncObjectHost> mSyncObject;
   wr::DebugFlags mDebugFlags;
 };
 
 } // namespace wr
 } // namespace mozilla
 
 #endif
--- a/gfx/webrender_bindings/WebRenderAPI.cpp
+++ b/gfx/webrender_bindings/WebRenderAPI.cpp
@@ -5,16 +5,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "WebRenderAPI.h"
 #include "DisplayItemClipChain.h"
 #include "LayersLogging.h"
 #include "mozilla/webrender/RendererOGL.h"
 #include "mozilla/gfx/gfxVars.h"
 #include "mozilla/layers/CompositorThread.h"
+#include "mozilla/webrender/RenderCompositor.h"
 #include "mozilla/widget/CompositorWidget.h"
 #include "mozilla/layers/SynchronousTask.h"
 
 #define WRDL_LOG(...)
 //#define WRDL_LOG(...) printf_stderr("WRDL(%p): " __VA_ARGS__)
 //#define WRDL_LOG(...) if (XRE_IsContentProcess()) printf_stderr("WRDL(%p): " __VA_ARGS__)
 
 namespace mozilla {
@@ -48,48 +49,33 @@ public:
   {
     MOZ_COUNT_DTOR(NewRenderer);
   }
 
   virtual void Run(RenderThread& aRenderThread, WindowId aWindowId) override
   {
     layers::AutoCompleteTask complete(mTask);
 
-    RefPtr<gl::GLContext> gl;
-    if (gfx::gfxVars::UseWebRenderANGLE()) {
-      gl = gl::GLContextProviderEGL::CreateForCompositorWidget(mCompositorWidget, true);
-      if (!gl || !gl->IsANGLE()) {
-        gfxCriticalNote << "Failed ANGLE GL context creation for WebRender: " << gfx::hexa(gl.get());
-        return;
-      }
-    }
-    if (!gl) {
-      gl = gl::GLContextProvider::CreateForCompositorWidget(mCompositorWidget, true);
-    }
-    if (!gl || !gl->MakeCurrent()) {
-      gfxCriticalNote << "Failed GL context creation for WebRender: " << gfx::hexa(gl.get());
-      return;
-    }
+    UniquePtr<RenderCompositor> compositor = RenderCompositor::Create(Move(mCompositorWidget));
 
-    *mUseANGLE = gl->IsANGLE();
+    *mUseANGLE = compositor->UseANGLE();
 
     wr::Renderer* wrRenderer = nullptr;
-    if (!wr_window_new(aWindowId, mSize.width, mSize.height, gl.get(),
+    if (!wr_window_new(aWindowId, mSize.width, mSize.height, compositor->gl(),
                        aRenderThread.ThreadPool().Raw(),
                        mDocHandle, &wrRenderer,
                        mMaxTextureSize)) {
       // wr_window_new puts a message into gfxCriticalNote if it returns false
       return;
     }
     MOZ_ASSERT(wrRenderer);
 
     RefPtr<RenderThread> thread = &aRenderThread;
     auto renderer = MakeUnique<RendererOGL>(Move(thread),
-                                            Move(gl),
-                                            Move(mCompositorWidget),
+                                            Move(compositor),
                                             aWindowId,
                                             wrRenderer,
                                             mBridge);
     if (wrRenderer && renderer) {
       wr::WrExternalImageHandler handler = renderer->GetExternalImageHandler();
       wr_renderer_set_external_image_handler(wrRenderer, &handler);
       if (gfx::gfxVars::UseWebRenderProgramBinary()) {
         wr_renderer_update_program_cache(wrRenderer, aRenderThread.ProgramCache()->Raw());
--- a/gfx/webrender_bindings/moz.build
+++ b/gfx/webrender_bindings/moz.build
@@ -4,30 +4,34 @@
 # 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/.
 
 with Files('**'):
     BUG_COMPONENT = ('Core', 'Graphics: WebRender')
 
 EXPORTS.mozilla.webrender += [
     'RenderBufferTextureHost.h',
+    'RenderCompositor.h',
+    'RenderCompositorOGL.h',
     'RendererOGL.h',
     'RenderSharedSurfaceTextureHost.h',
     'RenderTextureHost.h',
     'RenderTextureHostOGL.h',
     'RenderThread.h',
     'webrender_ffi.h',
     'webrender_ffi_generated.h',
     'WebRenderAPI.h',
     'WebRenderTypes.h',
 ]
 
 UNIFIED_SOURCES += [
     'Moz2DImageRenderer.cpp',
     'RenderBufferTextureHost.cpp',
+    'RenderCompositor.cpp',
+    'RenderCompositorOGL.cpp',
     'RendererOGL.cpp',
     'RenderSharedSurfaceTextureHost.cpp',
     'RenderTextureHost.cpp',
     'RenderTextureHostOGL.cpp',
     'RenderThread.cpp',
     'WebRenderAPI.cpp',
     'WebRenderTypes.cpp',
 ]