Bug 1288860 - Change GLContextProvider to use CompositorWidget. r=jrmuizel
authorRyan Hunt <rhunt@mozilla.com>
Mon, 25 Jul 2016 14:41:00 -0400
changeset 332030 a34d250bea8e25d273a9f2239a5f155d0844551c
parent 332029 de70d037b6b908ff34677dcdbdb525492609846e
child 332031 26f41a685662f89b35dd7a10f8fba0ab128a7c2d
push id9858
push userjlund@mozilla.com
push dateMon, 01 Aug 2016 14:37:10 +0000
treeherdermozilla-aurora@203106ef6cb6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuizel
bugs1288860
milestone50.0a1
Bug 1288860 - Change GLContextProvider to use CompositorWidget. r=jrmuizel
gfx/gl/GLContextProvider.h
gfx/gl/GLContextProviderCGL.mm
gfx/gl/GLContextProviderEAGL.mm
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLContextProviderImpl.h
gfx/gl/GLContextProviderNull.cpp
gfx/gl/GLContextProviderWGL.cpp
gfx/layers/opengl/CompositorOGL.cpp
--- a/gfx/gl/GLContextProvider.h
+++ b/gfx/gl/GLContextProvider.h
@@ -9,16 +9,19 @@
 #include "GLContextTypes.h"
 #include "SurfaceTypes.h"
 
 #include "nsSize.h" // for gfx::IntSize (needed by GLContextProviderImpl.h below)
 
 class nsIWidget;
 
 namespace mozilla {
+namespace widget {
+  class CompositorWidget;
+}
 namespace gl {
 
 #define IN_GL_CONTEXT_PROVIDER_H
 
 // Null is always there
 #define GL_CONTEXT_PROVIDER_NAME GLContextProviderNull
 #include "GLContextProviderImpl.h"
 #undef GL_CONTEXT_PROVIDER_NAME
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -9,27 +9,29 @@
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include <OpenGL/gl.h>
 #include "gfxFailure.h"
 #include "gfxPrefs.h"
 #include "prenv.h"
 #include "GeckoProfiler.h"
 #include "mozilla/gfx/MacIOSurface.h"
+#include "mozilla/widget/CompositorWidget.h"
 
 #include <OpenGL/OpenGL.h>
 
 // When running inside a VM, creating an accelerated OpenGL context usually
 // fails. Uncomment this line to emulate that behavior.
 // #define EMULATE_VM
 
 namespace mozilla {
 namespace gl {
 
 using namespace mozilla::gfx;
+using namespace mozilla::widget;
 
 class CGLLibrary
 {
 public:
     CGLLibrary()
         : mInitialized(false)
         , mUseDoubleBufferedWindows(true)
         , mOGLLibrary(nullptr)
@@ -230,16 +232,22 @@ CreateWithFormat(const NSOpenGLPixelForm
                                 shareContext:nullptr];
 
     [format release];
 
     return context;
 }
 
 already_AddRefed<GLContext>
+GLContextProviderCGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+    return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
 GLContextProviderCGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
 {
     if (!sCGLLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
 #ifdef EMULATE_VM
     if (aForceAccelerated) {
--- a/gfx/gl/GLContextProviderEAGL.mm
+++ b/gfx/gl/GLContextProviderEAGL.mm
@@ -6,23 +6,26 @@
 #include "GLContextProvider.h"
 #include "GLContextEAGL.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "gfxPrefs.h"
 #include "gfxFailure.h"
 #include "prenv.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/widget/CompositorWidget.h"
 #include "GeckoProfiler.h"
 
 #import <UIKit/UIKit.h>
 
 namespace mozilla {
 namespace gl {
 
+using namespace mozilla::widget;
+
 GLContextEAGL::GLContextEAGL(CreateContextFlags flags, const SurfaceCaps& caps,
                              EAGLContext* context, GLContext* sharedContext,
                              bool isOffscreen, ContextProfile profile)
     : GLContext(flags, caps, sharedContext, isOffscreen)
     , mContext(context)
     , mBackbufferRB(0)
     , mBackbufferFB(0)
     , mLayer(nil)
@@ -200,16 +203,22 @@ CreateEAGLContext(CreateContextFlags fla
         glContext = nullptr;
         return nullptr;
     }
 
     return glContext.forget();
 }
 
 already_AddRefed<GLContext>
+GLContextProviderEAGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+    return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
 GLContextProviderEAGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
 {
     RefPtr<GLContext> glContext = CreateEAGLContext(CreateContextFlags::NONE, false,
                                                     GetGlobalContextEAGL());
     if (!glContext) {
         return nullptr;
     }
 
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -96,27 +96,30 @@
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "GLBlitHelper.h"
 #include "GLContextEGL.h"
 #include "GLContextProvider.h"
 #include "GLLibraryEGL.h"
 #include "mozilla/ArrayUtils.h"
 #include "mozilla/Preferences.h"
+#include "mozilla/widget/CompositorWidget.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "nsThreadUtils.h"
 #include "ScopedGLHelpers.h"
 #include "TextureImageEGL.h"
 
 using namespace mozilla::gfx;
 
 namespace mozilla {
 namespace gl {
 
+using namespace mozilla::widget;
+
 #define ADD_ATTR_2(_array, _k, _v) do {         \
     (_array).AppendElement(_k);                 \
     (_array).AppendElement(_v);                 \
 } while (0)
 
 #define ADD_ATTR_1(_array, _k) do {             \
     (_array).AppendElement(_k);                 \
 } while (0)
@@ -753,16 +756,22 @@ GLContextProviderEGL::CreateWrappingExis
                                                (EGLContext)aContext);
     gl->SetIsDoubleBuffered(true);
     gl->mOwnsContext = false;
 
     return gl.forget();
 }
 
 already_AddRefed<GLContext>
+GLContextProviderEGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+    return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
 GLContextProviderEGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
 {
     nsCString discardFailureId;
     if (!sEGLLibrary.EnsureInitialized(false, &discardFailureId)) {
         MOZ_CRASH("GFX: Failed to load EGL library 3!\n");
         return nullptr;
     }
 
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -9,16 +9,17 @@
 #define GET_NATIVE_WINDOW(aWidget) GDK_WINDOW_XID((GdkWindow*) aWidget->GetNativeData(NS_NATIVE_WINDOW))
 #endif
 
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 
 #include "mozilla/MathAlgorithms.h"
 #include "mozilla/StaticPtr.h"
+#include "mozilla/widget/CompositorWidget.h"
 
 #include "prenv.h"
 #include "GLContextProvider.h"
 #include "GLLibraryLoader.h"
 #include "nsDebug.h"
 #include "nsIWidget.h"
 #include "GLXLibrary.h"
 #include "gfxXlibSurface.h"
@@ -36,16 +37,17 @@
 #ifdef MOZ_WIDGET_GTK
 #include "gfxPlatformGtk.h"
 #endif
 
 namespace mozilla {
 namespace gl {
 
 using namespace mozilla::gfx;
+using namespace mozilla::widget;
 
 GLXLibrary sGLXLibrary;
 
 // Check that we have at least version aMajor.aMinor .
 bool
 GLXLibrary::GLXVersionCheck(int aMajor, int aMinor)
 {
     return aMajor < mGLXMajorVersion ||
@@ -1083,16 +1085,22 @@ GLContextProviderGLX::CreateWrappingExis
 
         return glContext.forget();
     }
 
     return nullptr;
 }
 
 already_AddRefed<GLContext>
+GLContextProviderGLX::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+    return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
 GLContextProviderGLX::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
 {
     if (!sGLXLibrary.EnsureInitialized()) {
         return nullptr;
     }
 
     // Currently, we take whatever Visual the window already has, and
     // try to create an fbconfig for that visual.  This isn't
--- a/gfx/gl/GLContextProviderImpl.h
+++ b/gfx/gl/GLContextProviderImpl.h
@@ -13,16 +13,42 @@
 #if defined(ANDROID)
 typedef void* EGLSurface;
 #endif // defined(ANDROID)
 
 class GL_CONTEXT_PROVIDER_NAME
 {
 public:
     /**
+     * Create a context that renders to the surface of the widget represented by
+     * the compositor widget that is passed in. The context is always created
+     * with an RGB pixel format, with no alpha, depth or stencil.
+     * If any of those features are needed, either use a framebuffer, or
+     * use CreateOffscreen.
+     *
+     * This context will attempt to share resources with all other window
+     * contexts.  As such, it's critical that resources allocated that are not
+     * needed by other contexts be deleted before the context is destroyed.
+     *
+     * The GetSharedContext() method will return non-null if sharing
+     * was successful.
+     *
+     * Note: a context created for a widget /must not/ hold a strong
+     * reference to the widget; otherwise a cycle can be created through
+     * a GL layer manager.
+     *
+     * @param aCompositorWidget Widget whose surface to create a context for
+     * @param aForceAccelerated true if only accelerated contexts are allowed
+     *
+     * @return Context to use for the window
+     */
+    static already_AddRefed<GLContext>
+    CreateForCompositorWidget(mozilla::widget::CompositorWidget* aCompositorWidget, bool aForceAccelerated);
+
+    /**
      * Create a context that renders to the surface of the widget that is
      * passed in.  The context is always created with an RGB pixel format,
      * with no alpha, depth or stencil.  If any of those features are needed,
      * either use a framebuffer, or use CreateOffscreen.
      *
      * This context will attempt to share resources with all other window
      * contexts.  As such, it's critical that resources allocated that are not
      * needed by other contexts be deleted before the context is destroyed.
@@ -35,17 +61,17 @@ public:
      * a GL layer manager.
      *
      * @param aWidget Widget whose surface to create a context for
      * @param aForceAccelerated true if only accelerated contexts are allowed
      *
      * @return Context to use for the window
      */
     static already_AddRefed<GLContext>
-    CreateForWindow(nsIWidget* widget, bool aForceAccelerated);
+    CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated);
 
     /**
      * Create a context for offscreen rendering.  The target of this
      * context should be treated as opaque -- it might be a FBO, or a
      * pbuffer, or some other construct.  Users of this GLContext
      * should bind framebuffer 0 directly to use this offscreen buffer.
      *
      * The offscreen context returned by this method will always have
--- a/gfx/gl/GLContextProviderNull.cpp
+++ b/gfx/gl/GLContextProviderNull.cpp
@@ -3,18 +3,26 @@
  * 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 "GLContextProvider.h"
 
 namespace mozilla {
 namespace gl {
 
+using namespace mozilla::widget;
+
 already_AddRefed<GLContext>
-GLContextProviderNull::CreateForWindow(nsIWidget*, bool aForceAccelerated)
+GLContextProviderNull::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+    return nullptr;
+}
+
+already_AddRefed<GLContext>
+GLContextProviderNull::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
 GLContextProviderNull::CreateWrappingExisting(void*, void*)
 {
     return nullptr;
--- a/gfx/gl/GLContextProviderWGL.cpp
+++ b/gfx/gl/GLContextProviderWGL.cpp
@@ -12,21 +12,23 @@
 #include "gfxWindowsSurface.h"
 
 #include "gfxCrashReporterUtils.h"
 
 #include "prenv.h"
 
 #include "mozilla/Preferences.h"
 #include "mozilla/StaticPtr.h"
+#include "mozilla/widget/CompositorWidget.h"
 
 namespace mozilla {
 namespace gl {
 
 using namespace mozilla::gfx;
+using namespace mozilla::widget;
 
 WGLLibrary sWGLLib;
 
 HWND
 WGLLibrary::CreateDummyWindow(HDC* aWindowDC)
 {
     WNDCLASSW wc;
     if (!GetClassInfoW(GetModuleHandle(nullptr), L"GLContextWGLClass", &wc)) {
@@ -425,16 +427,22 @@ GetGlobalContextWGL()
 
 already_AddRefed<GLContext>
 GLContextProviderWGL::CreateWrappingExisting(void*, void*)
 {
     return nullptr;
 }
 
 already_AddRefed<GLContext>
+GLContextProviderWGL::CreateForCompositorWidget(CompositorWidget* aCompositorWidget, bool aForceAccelerated)
+{
+    return CreateForWindow(aCompositorWidget->RealWidget(), aForceAccelerated);
+}
+
+already_AddRefed<GLContext>
 GLContextProviderWGL::CreateForWindow(nsIWidget* aWidget, bool aForceAccelerated)
 {
     if (!sWGLLib.EnsureInitialized()) {
         return nullptr;
     }
 
     /**
        * We need to make sure we call SetPixelFormat -after- calling
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -112,34 +112,34 @@ CompositorOGL::CreateContext()
   if (widgetOpenGLContext) {
     GLContext* alreadyRefed = reinterpret_cast<GLContext*>(widgetOpenGLContext);
     return already_AddRefed<GLContext>(alreadyRefed);
   }
 
 #ifdef XP_WIN
   if (gfxEnv::LayersPreferEGL()) {
     printf_stderr("Trying GL layers...\n");
-    context = gl::GLContextProviderEGL::CreateForWindow(mWidget->RealWidget(), false);
+    context = gl::GLContextProviderEGL::CreateForCompositorWidget(mWidget, false);
   }
 #endif
 
   // Allow to create offscreen GL context for main Layer Manager
   if (!context && gfxEnv::LayersPreferOffscreen()) {
     SurfaceCaps caps = SurfaceCaps::ForRGB();
     caps.preserve = false;
     caps.bpp16 = gfxPlatform::GetPlatform()->GetOffscreenFormat() == SurfaceFormat::R5G6B5_UINT16;
 
     nsCString discardFailureId;
     context = GLContextProvider::CreateOffscreen(mSurfaceSize,
                                                  caps, CreateContextFlags::REQUIRE_COMPAT_PROFILE,
                                                  &discardFailureId);
   }
 
   if (!context) {
-    context = gl::GLContextProvider::CreateForWindow(mWidget->RealWidget(),
+    context = gl::GLContextProvider::CreateForCompositorWidget(mWidget,
                 gfxPlatform::GetPlatform()->RequiresAcceleratedGLContextForCompositorOGL());
   }
 
   if (!context) {
     NS_WARNING("Failed to create CompositorOGL context");
   }
 
 #ifdef MOZ_WIDGET_GONK