Bug 811958 - Pull GLContext out of Cocoa stuff - r=bgirard
☠☠ backed out by 7ca16b44a6db ☠ ☠
authorJeff Gilbert <jgilbert@mozilla.com>
Mon, 26 Nov 2012 12:51:57 -0800
changeset 114138 ec29e09a270e3e5c268f30d409ab392f7b2c288f
parent 114136 072afb032cce8665033dedc24b96c5324da432f4
child 114139 1637c39b4ed69b9bc07b8146e1e83d090b0fe545
push id23907
push useremorley@mozilla.com
push dateTue, 27 Nov 2012 14:15:28 +0000
treeherdermozilla-central@532d0832c09d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbgirard
bugs811958
milestone20.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 811958 - Pull GLContext out of Cocoa stuff - r=bgirard
gfx/gl/GLContext.h
gfx/gl/GLContextTypes.h
gfx/gl/Makefile.in
gfx/layers/opengl/LayerManagerOGL.cpp
gfx/layers/opengl/LayerManagerOGL.h
gfx/layers/opengl/LayerManagerOGLProgram.cpp
gfx/layers/opengl/LayerManagerOGLProgram.h
gfx/layers/opengl/ReusableTileStoreOGL.cpp
widget/cocoa/nsChildView.mm
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -27,16 +27,17 @@
 #include "nsISupportsImpl.h"
 #include "prlink.h"
 
 #include "nsDataHashtable.h"
 #include "nsHashKeys.h"
 #include "nsRegion.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
+#include "GLContextTypes.h"
 
 typedef char realGLboolean;
 
 #include "GLContextSymbols.h"
 
 #include "mozilla/mozalloc.h"
 #include "mozilla/Preferences.h"
 
@@ -50,34 +51,16 @@ namespace mozilla {
     class ColorTextureLayerProgram;
   }
 
 namespace gl {
 class GLContext;
 
 typedef uintptr_t SharedTextureHandle;
 
-enum ShaderProgramType {
-    RGBALayerProgramType,
-    RGBALayerExternalProgramType,
-    BGRALayerProgramType,
-    RGBXLayerProgramType,
-    BGRXLayerProgramType,
-    RGBARectLayerProgramType,
-    RGBAExternalLayerProgramType,
-    ColorLayerProgramType,
-    YCbCrLayerProgramType,
-    ComponentAlphaPass1ProgramType,
-    ComponentAlphaPass2ProgramType,
-    Copy2DProgramType,
-    Copy2DRectProgramType,
-    NumProgramTypes
-};
-
-
 /**
  * A TextureImage encapsulates a surface that can be drawn to by a
  * Thebes gfxContext and (hopefully efficiently!) synchronized to a
  * texture in the server.  TextureImages are associated with one and
  * only one GLContext.
  *
  * Implementation note: TextureImages attempt to unify two categories
  * of backends
new file mode 100644
--- /dev/null
+++ b/gfx/gl/GLContextTypes.h
@@ -0,0 +1,44 @@
+/*
+ * GLContextStuff.h
+ *
+ *  Created on: Nov 13, 2012
+ *      Author: jgilbert
+ */
+
+#ifndef GLCONTEXTSTUFF_H_
+#define GLCONTEXTSTUFF_H_
+
+/**
+ * We don't include GLDefs.h here since we don't want to drag in all defines
+ * in for all our users.
+ */
+typedef unsigned int GLenum;
+typedef unsigned int GLbitfield;
+typedef unsigned int GLuint;
+typedef int GLint;
+typedef int GLsizei;
+
+namespace mozilla {
+namespace gl {
+
+enum ShaderProgramType {
+    RGBALayerProgramType,
+    RGBALayerExternalProgramType,
+    BGRALayerProgramType,
+    RGBXLayerProgramType,
+    BGRXLayerProgramType,
+    RGBARectLayerProgramType,
+    RGBAExternalLayerProgramType,
+    ColorLayerProgramType,
+    YCbCrLayerProgramType,
+    ComponentAlphaPass1ProgramType,
+    ComponentAlphaPass2ProgramType,
+    Copy2DProgramType,
+    Copy2DRectProgramType,
+    NumProgramTypes
+};
+
+} // namespace gl
+} // namespace mozilla
+
+#endif /* GLCONTEXTSTUFF_H_ */
--- a/gfx/gl/Makefile.in
+++ b/gfx/gl/Makefile.in
@@ -13,16 +13,17 @@ MODULE		= gl
 LIBRARY_NAME	= gl
 LIBXUL_LIBRARY	= 1
 EXPORT_LIBRARY	= 1
 FAIL_ON_WARNINGS = 1
 
 EXPORTS	= \
 	GLDefs.h \
 	GLContext.h \
+	GLContextTypes.h \
 	GLContextSymbols.h \
 	GLContextProvider.h \
 	GLContextProviderImpl.h \
 	GLLibraryLoader.h \
 	ForceDiscreteGPUHelperCGL.h \
 	$(NULL)
 
 ifdef MOZ_X11
--- a/gfx/layers/opengl/LayerManagerOGL.cpp
+++ b/gfx/layers/opengl/LayerManagerOGL.cpp
@@ -1,20 +1,20 @@
 /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "LayerManagerOGL.h"
+
 #include "mozilla/layers/PLayers.h"
 
 /* This must occur *after* layers/PLayers.h to avoid typedefs conflicts. */
 #include "mozilla/Util.h"
-
 #include "Composer2D.h"
-#include "LayerManagerOGL.h"
 #include "ThebesLayerOGL.h"
 #include "ContainerLayerOGL.h"
 #include "ImageLayerOGL.h"
 #include "ColorLayerOGL.h"
 #include "CanvasLayerOGL.h"
 #include "TiledThebesLayerOGL.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/Preferences.h"
@@ -47,16 +47,101 @@ namespace layers {
 
 using namespace mozilla::gfx;
 using namespace mozilla::gl;
 
 #ifdef CHECK_CURRENT_PROGRAM
 int ShaderProgramOGL::sCurrentProgramKey = 0;
 #endif
 
+bool
+LayerManagerOGL::Initialize(bool force)
+{
+  return Initialize(CreateContext(), force);
+}
+
+int32_t
+LayerManagerOGL::GetMaxTextureSize() const
+{
+  return mGLContext->GetMaxTextureSize();
+}
+
+void
+LayerManagerOGL::MakeCurrent(bool aForce)
+{
+  if (mDestroyed) {
+    NS_WARNING("Call on destroyed layer manager");
+    return;
+  }
+  mGLContext->MakeCurrent(aForce);
+}
+
+void*
+LayerManagerOGL::GetNSOpenGLContext() const
+{
+  return gl()->GetNativeData(GLContext::NativeGLContext);
+}
+
+
+void
+LayerManagerOGL::BindQuadVBO() {
+  mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
+}
+
+void
+LayerManagerOGL::QuadVBOVerticesAttrib(GLuint aAttribIndex) {
+  mGLContext->fVertexAttribPointer(aAttribIndex, 2,
+                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
+                                   (GLvoid*) QuadVBOVertexOffset());
+}
+
+void
+LayerManagerOGL::QuadVBOTexCoordsAttrib(GLuint aAttribIndex) {
+  mGLContext->fVertexAttribPointer(aAttribIndex, 2,
+                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
+                                   (GLvoid*) QuadVBOTexCoordOffset());
+}
+
+void
+LayerManagerOGL::QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex) {
+  mGLContext->fVertexAttribPointer(aAttribIndex, 2,
+                                   LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
+                                   (GLvoid*) QuadVBOFlippedTexCoordOffset());
+}
+
+// Super common
+
+void
+LayerManagerOGL::BindAndDrawQuad(GLuint aVertAttribIndex,
+                     GLuint aTexCoordAttribIndex,
+                     bool aFlipped)
+{
+  BindQuadVBO();
+  QuadVBOVerticesAttrib(aVertAttribIndex);
+
+  if (aTexCoordAttribIndex != GLuint(-1)) {
+    if (aFlipped)
+      QuadVBOFlippedTexCoordsAttrib(aTexCoordAttribIndex);
+    else
+      QuadVBOTexCoordsAttrib(aTexCoordAttribIndex);
+
+    mGLContext->fEnableVertexAttribArray(aTexCoordAttribIndex);
+  }
+
+  mGLContext->fEnableVertexAttribArray(aVertAttribIndex);
+
+  mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
+
+  mGLContext->fDisableVertexAttribArray(aVertAttribIndex);
+
+  if (aTexCoordAttribIndex != GLuint(-1)) {
+    mGLContext->fDisableVertexAttribArray(aTexCoordAttribIndex);
+  }
+}
+
 static const double kFpsWindowMs = 250.0;
 static const size_t kNumFrameTimeStamps = 16;
 struct FPSCounter {
   FPSCounter() : mCurrentFrameIndex(0) {}
 
   // We keep a circular buffer of the time points at which the last K
   // frames were drawn.  To estimate FPS, we count the number of
   // frames we've drawn within the last kFPSWindowMs milliseconds and
--- a/gfx/layers/opengl/LayerManagerOGL.h
+++ b/gfx/layers/opengl/LayerManagerOGL.h
@@ -4,41 +4,33 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef GFX_LAYERMANAGEROGL_H
 #define GFX_LAYERMANAGEROGL_H
 
 #include "LayerManagerOGLProgram.h"
 
 #include "mozilla/layers/ShadowLayers.h"
-
 #include "mozilla/TimeStamp.h"
 
 #ifdef XP_WIN
 #include <windows.h>
 #endif
 
-/**
- * We don't include GLDefs.h here since we don't want to drag in all defines
- * in for all our users.
- */
-typedef unsigned int GLenum;
-typedef unsigned int GLbitfield;
-typedef unsigned int GLuint;
-typedef int GLint;
-typedef int GLsizei;
-
 #define BUFFER_OFFSET(i) ((char *)NULL + (i))
 
 #include "gfxContext.h"
 #include "gfx3DMatrix.h"
 #include "nsIWidget.h"
-#include "GLContext.h"
+#include "GLContextTypes.h"
 
 namespace mozilla {
+namespace gl {
+class GLContext;
+}
 namespace layers {
 
 class Composer2D;
 class LayerOGL;
 class ShadowThebesLayer;
 class ShadowContainerLayer;
 class ShadowImageLayer;
 class ShadowCanvasLayer;
@@ -66,19 +58,17 @@ public:
   /**
    * Initializes the layer manager with a given GLContext. If aContext is null
    * then the layer manager will try to create one for the associated widget.
    *
    * \param aContext an existing GL context to use. Can be created with CreateContext()
    *
    * \return True is initialization was succesful, false when it was not.
    */
-  bool Initialize(bool force = false) {
-    return Initialize(CreateContext(), force);
-  }
+  bool Initialize(bool force = false);
 
   bool Initialize(nsRefPtr<GLContext> aContext, bool force = false);
 
   /**
    * Sets the clipping region for this layer manager. This is important on 
    * windows because using OGL we no longer have GDI's native clipping. Therefor
    * widget must tell us what part of the screen is being invalidated,
    * and we should clip to this.
@@ -105,28 +95,24 @@ public:
   virtual bool EndEmptyTransaction(EndTransactionFlags aFlags = END_DEFAULT);
   virtual void NotifyShadowTreeTransaction();
   virtual void EndTransaction(DrawThebesLayerCallback aCallback,
                               void* aCallbackData,
                               EndTransactionFlags aFlags = END_DEFAULT);
 
   virtual void SetRoot(Layer* aLayer) { mRoot = aLayer; }
 
-  virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize)
-  {
-      if (!mGLContext)
-          return false;
-      int32_t maxSize = mGLContext->GetMaxTextureSize();
-      return aSize <= gfxIntSize(maxSize, maxSize);
+  virtual bool CanUseCanvasLayerForSize(const gfxIntSize &aSize) {
+    if (!mGLContext)
+      return false;
+    int32_t maxSize = GetMaxTextureSize();
+    return aSize <= gfxIntSize(maxSize, maxSize);
   }
 
-  virtual int32_t GetMaxTextureSize() const
-  {
-    return mGLContext->GetMaxTextureSize();
-  }
+  virtual int32_t GetMaxTextureSize() const;
 
   virtual already_AddRefed<ThebesLayer> CreateThebesLayer();
 
   virtual already_AddRefed<ContainerLayer> CreateContainerLayer();
 
   virtual already_AddRefed<ImageLayer> CreateImageLayer();
 
   virtual already_AddRefed<ColorLayer> CreateColorLayer();
@@ -146,23 +132,17 @@ public:
   virtual already_AddRefed<gfxASurface>
     CreateOptimalMaskSurface(const gfxIntSize &aSize);
 
   virtual void ClearCachedResources(Layer* aSubtree = nullptr) MOZ_OVERRIDE;
 
   /**
    * Helper methods.
    */
-  void MakeCurrent(bool aForce = false) {
-    if (mDestroyed) {
-      NS_WARNING("Call on destroyed layer manager");
-      return;
-    }
-    mGLContext->MakeCurrent(aForce);
-  }
+  void MakeCurrent(bool aForce = false);
 
   ShaderProgramOGL* GetBasicLayerProgram(bool aOpaque, bool aIsRGB,
                                          MaskType aMask = MaskNone)
   {
     gl::ShaderProgramType format = gl::BGRALayerProgramType;
     if (aIsRGB) {
       if (aOpaque) {
         format = gl::RGBXLayerProgramType;
@@ -198,16 +178,19 @@ public:
   gl::ShaderProgramType GetFBOLayerProgramType() {
     if (mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB)
       return gl::RGBARectLayerProgramType;
     return gl::RGBALayerProgramType;
   }
 
   GLContext* gl() const { return mGLContext; }
 
+  // |NSOpenGLContext*|:
+  void* GetNSOpenGLContext() const;
+
   DrawThebesLayerCallback GetThebesLayerCallback() const
   { return mThebesLayerCallback; }
 
   void* GetThebesLayerCallbackData() const
   { return mThebesLayerCallbackData; }
 
   /*
    * Helper functions for our layers
@@ -249,66 +232,25 @@ public:
                             GLuint aCurrentFrameBuffer,
                             GLuint *aFBO, GLuint *aTexture);
 
   GLuint QuadVBO() { return mQuadVBO; }
   GLintptr QuadVBOVertexOffset() { return 0; }
   GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; }
   GLintptr QuadVBOFlippedTexCoordOffset() { return sizeof(float)*8*2; }
 
-  void BindQuadVBO() {
-    mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
-  }
-
-  void QuadVBOVerticesAttrib(GLuint aAttribIndex) {
-    mGLContext->fVertexAttribPointer(aAttribIndex, 2,
-                                     LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                     (GLvoid*) QuadVBOVertexOffset());
-  }
-
-  void QuadVBOTexCoordsAttrib(GLuint aAttribIndex) {
-    mGLContext->fVertexAttribPointer(aAttribIndex, 2,
-                                     LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                     (GLvoid*) QuadVBOTexCoordOffset());
-  }
-
-  void QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex) {
-    mGLContext->fVertexAttribPointer(aAttribIndex, 2,
-                                     LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
-                                     (GLvoid*) QuadVBOFlippedTexCoordOffset());
-  }
+  void BindQuadVBO();
+  void QuadVBOVerticesAttrib(GLuint aAttribIndex);
+  void QuadVBOTexCoordsAttrib(GLuint aAttribIndex);
+  void QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex);
 
   // Super common
-
   void BindAndDrawQuad(GLuint aVertAttribIndex,
                        GLuint aTexCoordAttribIndex,
-                       bool aFlipped = false)
-  {
-    BindQuadVBO();
-    QuadVBOVerticesAttrib(aVertAttribIndex);
-
-    if (aTexCoordAttribIndex != GLuint(-1)) {
-      if (aFlipped)
-        QuadVBOFlippedTexCoordsAttrib(aTexCoordAttribIndex);
-      else
-        QuadVBOTexCoordsAttrib(aTexCoordAttribIndex);
-
-      mGLContext->fEnableVertexAttribArray(aTexCoordAttribIndex);
-    }
-
-    mGLContext->fEnableVertexAttribArray(aVertAttribIndex);
-
-    mGLContext->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
-
-    mGLContext->fDisableVertexAttribArray(aVertAttribIndex);
-
-    if (aTexCoordAttribIndex != GLuint(-1)) {
-      mGLContext->fDisableVertexAttribArray(aTexCoordAttribIndex);
-    }
-  }
+                       bool aFlipped = false);
 
   void BindAndDrawQuad(ShaderProgramOGL *aProg,
                        bool aFlipped = false)
   {
     NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
     BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib),
                     aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib),
                     aFlipped);
--- a/gfx/layers/opengl/LayerManagerOGLProgram.cpp
+++ b/gfx/layers/opengl/LayerManagerOGLProgram.cpp
@@ -1,16 +1,23 @@
 /* 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 "LayerManagerOGLProgram.h"
+
+#ifdef GLCONTEXT_H_
+#error GLContext.h should not have been included here.
+#endif
+
 #include "LayerManagerOGLShaders.h"
 #include "LayerManagerOGL.h"
 
+#include "GLContext.h"
+
 namespace mozilla {
 namespace layers {
 
 typedef ProgramProfileOGL::Argument Argument;
 
 // helper methods for GetProfileFor
 void
 AddCommonArgs(ProgramProfileOGL& aProfile)
@@ -222,16 +229,38 @@ ProgramProfileOGL::GetProfileFor(gl::Sha
   }
 
   return result;
 }
 
 const char* const ShaderProgramOGL::VertexCoordAttrib = "aVertexCoord";
 const char* const ShaderProgramOGL::TexCoordAttrib = "aTexCoord";
 
+ShaderProgramOGL::ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile)
+  : mIsProjectionMatrixStale(false)
+  , mGL(aGL)
+  , mProgram(0)
+  , mProfile(aProfile)
+  , mProgramState(STATE_NEW)
+{}
+
+ShaderProgramOGL::~ShaderProgramOGL()
+{
+  if (mProgram <= 0) {
+    return;
+  }
+
+  nsRefPtr<GLContext> ctx = mGL->GetSharedContext();
+  if (!ctx) {
+    ctx = mGL;
+  }
+  ctx->MakeCurrent();
+  ctx->fDeleteProgram(mProgram);
+}
+
 bool
 ShaderProgramOGL::Initialize()
 {
   NS_ASSERTION(mProgramState == STATE_NEW, "Shader program has already been initialised");
 
   if (!CreateProgram(mProfile.mVertexShaderString,
                      mProfile.mFragmentShaderString)) {
     mProgramState = STATE_ERROR;
@@ -389,10 +418,92 @@ ShaderProgramOGL::LoadMask(Layer* aMaskL
   m._41 = float(-bounds.x)/bounds.width;
   m._42 = float(-bounds.y)/bounds.height;
 
   SetMatrixUniform(mProfile.LookupUniformLocation("uMaskQuadTransform"), m);
 
   return true;
 }
 
+void
+ShaderProgramOGL::Activate()
+{
+  if (mProgramState == STATE_NEW) {
+    if (!Initialize()) {
+      NS_WARNING("Shader could not be initialised");
+      return;
+    }
+  }
+  NS_ASSERTION(HasInitialized(), "Attempting to activate a program that's not in use!");
+  mGL->fUseProgram(mProgram);
+#if CHECK_CURRENT_PROGRAM
+  mGL->SetUserData(&sCurrentProgramKey, this);
+#endif
+  // check and set the projection matrix
+  if (mIsProjectionMatrixStale) {
+    SetProjectionMatrix(mProjectionMatrix);
+  }
+}
+
+
+void
+ShaderProgramOGL::SetUniform(GLint aLocation, float aFloatValue)
+{
+  ASSERT_THIS_PROGRAM;
+  NS_ASSERTION(aLocation >= 0, "Invalid location");
+
+  mGL->fUniform1f(aLocation, aFloatValue);
+}
+
+void
+ShaderProgramOGL::SetUniform(GLint aLocation, const gfxRGBA& aColor)
+{
+  ASSERT_THIS_PROGRAM;
+  NS_ASSERTION(aLocation >= 0, "Invalid location");
+
+  mGL->fUniform4f(aLocation, float(aColor.r), float(aColor.g), float(aColor.b), float(aColor.a));
+}
+
+void
+ShaderProgramOGL::SetUniform(GLint aLocation, int aLength, float *aFloatValues)
+{
+  ASSERT_THIS_PROGRAM;
+  NS_ASSERTION(aLocation >= 0, "Invalid location");
+
+  if (aLength == 1) {
+    mGL->fUniform1fv(aLocation, 1, aFloatValues);
+  } else if (aLength == 2) {
+    mGL->fUniform2fv(aLocation, 1, aFloatValues);
+  } else if (aLength == 3) {
+    mGL->fUniform3fv(aLocation, 1, aFloatValues);
+  } else if (aLength == 4) {
+    mGL->fUniform4fv(aLocation, 1, aFloatValues);
+  } else {
+    NS_NOTREACHED("Bogus aLength param");
+  }
+}
+
+void
+ShaderProgramOGL::SetUniform(GLint aLocation, GLint aIntValue)
+{
+  ASSERT_THIS_PROGRAM;
+  NS_ASSERTION(aLocation >= 0, "Invalid location");
+
+  mGL->fUniform1i(aLocation, aIntValue);
+}
+
+void
+ShaderProgramOGL::SetMatrixUniform(GLint aLocation, const gfx3DMatrix& aMatrix)
+{
+  SetMatrixUniform(aLocation, &aMatrix._11);
+}
+
+void
+ShaderProgramOGL::SetMatrixUniform(GLint aLocation, const float *aFloatValues)
+{
+  ASSERT_THIS_PROGRAM;
+  NS_ASSERTION(aLocation >= 0, "Invalid location");
+
+  mGL->fUniformMatrix4fv(aLocation, 1, false, aFloatValues);
+}
+
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/LayerManagerOGLProgram.h
+++ b/gfx/layers/opengl/LayerManagerOGLProgram.h
@@ -5,21 +5,26 @@
 
 #ifndef GFX_LAYERMANAGEROGLPROGRAM_H
 #define GFX_LAYERMANAGEROGLPROGRAM_H
 
 #include <string.h>
 
 #include "prenv.h"
 
+#include "nsAutoPtr.h"
 #include "nsString.h"
-#include "GLContext.h"
+#include "GLContextTypes.h"
 #include "gfx3DMatrix.h"
+#include "gfxColor.h"
 
 namespace mozilla {
+namespace gl {
+class GLContext;
+}
 namespace layers {
 
 class Layer;
 
 // The kinds of mask layer a shader can support
 // We rely on the items in this enum being sequential
 enum MaskType {
   MaskNone = 0,   // no mask layer
@@ -135,55 +140,26 @@ private:
  * Represents an OGL shader program. The details of a program are represented
  * by a ProgramProfileOGL
  */
 class ShaderProgramOGL
 {
 public:
   typedef mozilla::gl::GLContext GLContext;
 
-  ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile) :
-    mIsProjectionMatrixStale(false), mGL(aGL), mProgram(0),
-    mProfile(aProfile), mProgramState(STATE_NEW) { }
+  ShaderProgramOGL(GLContext* aGL, const ProgramProfileOGL& aProfile);
 
-  ~ShaderProgramOGL() {
-    if (mProgram <= 0) {
-      return;
-    }
-
-    nsRefPtr<GLContext> ctx = mGL->GetSharedContext();
-    if (!ctx) {
-      ctx = mGL;
-    }
-    ctx->MakeCurrent();
-    ctx->fDeleteProgram(mProgram);
-  }
+  ~ShaderProgramOGL();
 
   bool HasInitialized() {
     NS_ASSERTION(mProgramState != STATE_OK || mProgram > 0, "Inconsistent program state");
     return mProgramState == STATE_OK;
   }
 
-  void Activate() {
-    if (mProgramState == STATE_NEW) {
-      if (!Initialize()) {
-        NS_WARNING("Shader could not be initialised");
-        return;
-      }
-    }
-    NS_ASSERTION(HasInitialized(), "Attempting to activate a program that's not in use!");
-    mGL->fUseProgram(mProgram);
-#if CHECK_CURRENT_PROGRAM
-    mGL->SetUserData(&sCurrentProgramKey, this);
-#endif
-    // check and set the projection matrix
-    if (mIsProjectionMatrixStale) {
-      SetProjectionMatrix(mProjectionMatrix);
-    }
-  }
+  void Activate();
 
   bool Initialize();
 
   GLint CreateShader(GLenum aShaderType, const char *aShaderSource);
 
   /**
    * Creates a program and stores its id.
    */
@@ -324,63 +300,21 @@ protected:
     STATE_ERROR
   } mProgramState;
 
   GLint mTexCoordMultiplierUniformLocation;
 #ifdef CHECK_CURRENT_PROGRAM
   static int sCurrentProgramKey;
 #endif
 
-  void SetUniform(GLint aLocation, float aFloatValue) {
-    ASSERT_THIS_PROGRAM;
-    NS_ASSERTION(aLocation >= 0, "Invalid location");
-
-    mGL->fUniform1f(aLocation, aFloatValue);
-  }
-
-  void SetUniform(GLint aLocation, const gfxRGBA& aColor) {
-    ASSERT_THIS_PROGRAM;
-    NS_ASSERTION(aLocation >= 0, "Invalid location");
-
-    mGL->fUniform4f(aLocation, float(aColor.r), float(aColor.g), float(aColor.b), float(aColor.a));
-  }
-
-  void SetUniform(GLint aLocation, int aLength, float *aFloatValues) {
-    ASSERT_THIS_PROGRAM;
-    NS_ASSERTION(aLocation >= 0, "Invalid location");
-
-    if (aLength == 1) {
-      mGL->fUniform1fv(aLocation, 1, aFloatValues);
-    } else if (aLength == 2) {
-      mGL->fUniform2fv(aLocation, 1, aFloatValues);
-    } else if (aLength == 3) {
-      mGL->fUniform3fv(aLocation, 1, aFloatValues);
-    } else if (aLength == 4) {
-      mGL->fUniform4fv(aLocation, 1, aFloatValues);
-    } else {
-      NS_NOTREACHED("Bogus aLength param");
-    }
-  }
-
-  void SetUniform(GLint aLocation, GLint aIntValue) {
-    ASSERT_THIS_PROGRAM;
-    NS_ASSERTION(aLocation >= 0, "Invalid location");
-
-    mGL->fUniform1i(aLocation, aIntValue);
-  }
-
-  void SetMatrixUniform(GLint aLocation, const gfx3DMatrix& aMatrix) {
-    SetMatrixUniform(aLocation, &aMatrix._11);
-  }
-
-  void SetMatrixUniform(GLint aLocation, const float *aFloatValues) {
-    ASSERT_THIS_PROGRAM;
-    NS_ASSERTION(aLocation >= 0, "Invalid location");
-
-    mGL->fUniformMatrix4fv(aLocation, 1, false, aFloatValues);
-  }
+  void SetUniform(GLint aLocation, float aFloatValue);
+  void SetUniform(GLint aLocation, const gfxRGBA& aColor);
+  void SetUniform(GLint aLocation, int aLength, float *aFloatValues);
+  void SetUniform(GLint aLocation, GLint aIntValue);
+  void SetMatrixUniform(GLint aLocation, const gfx3DMatrix& aMatrix);
+  void SetMatrixUniform(GLint aLocation, const float *aFloatValues);
 };
 
 
 } /* layers */
 } /* mozilla */
 
 #endif /* GFX_LAYERMANAGEROGLPROGRAM_H */
--- a/gfx/layers/opengl/ReusableTileStoreOGL.cpp
+++ b/gfx/layers/opengl/ReusableTileStoreOGL.cpp
@@ -1,14 +1,16 @@
 /* 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 "ReusableTileStoreOGL.h"
 
+#include "GLContext.h"
+
 namespace mozilla {
 namespace layers {
 
 ReusableTileStoreOGL::~ReusableTileStoreOGL()
 {
   if (mTiles.Length() == 0)
     return;
 
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -46,32 +46,35 @@
 #include "ComplexTextInputPanel.h"
 #endif
 
 #include "gfxContext.h"
 #include "gfxQuartzSurface.h"
 #include "nsRegion.h"
 #include "Layers.h"
 #include "LayerManagerOGL.h"
-#include "GLContext.h"
 #include "mozilla/layers/CompositorCocoaWidgetHelper.h"
 #ifdef ACCESSIBILITY
 #include "nsAccessibilityService.h"
 #endif
 
 #include "mozilla/Preferences.h"
 
 #include <dlfcn.h>
 
 #include <ApplicationServices/ApplicationServices.h>
 
 #include "sampler.h"
 
 #include "nsIDOMWheelEvent.h"
 
+#ifdef GLCONTEXT_H_
+#error GLContext.h should not have been included here.
+#endif
+
 using namespace mozilla;
 using namespace mozilla::layers;
 using namespace mozilla::gl;
 using namespace mozilla::widget;
 using namespace mozilla;
 
 #undef DEBUG_UPDATE
 #undef INVALIDATE_DEBUGGING  // flash areas as they are invalidated
@@ -1687,18 +1690,17 @@ NSView<mozView>* nsChildView::GetEditorV
 void
 nsChildView::CreateCompositor()
 {
   nsBaseWidget::CreateCompositor();
   if (mCompositorChild) {
     LayerManagerOGL *manager =
       static_cast<LayerManagerOGL*>(compositor::GetLayerManager(mCompositorParent));
 
-    NSOpenGLContext *glContext =
-      (NSOpenGLContext *) manager->gl()->GetNativeData(GLContext::NativeGLContext);
+    NSOpenGLContext *glContext = (NSOpenGLContext *)manager->GetNSOpenGLContext();
 
     [(ChildView *)mView setGLContext:glContext];
     [(ChildView *)mView setUsingOMTCompositor:true];
   }
 }
 
 gfxASurface*
 nsChildView::GetThebesSurface()
@@ -2452,17 +2454,17 @@ NSEvent* gLastDragMouseDownEvent = nil;
   }
 
   LayerManager *layerManager = mGeckoChild->GetLayerManager(nullptr);
   if (layerManager->GetBackendType() == mozilla::layers::LAYERS_OPENGL) {
     NSOpenGLContext *glContext;
 
     LayerManagerOGL *manager = static_cast<LayerManagerOGL*>(layerManager);
     manager->SetClippingRegion(region);
-    glContext = (NSOpenGLContext *)manager->gl()->GetNativeData(mozilla::gl::GLContext::NativeGLContext);
+    glContext = (NSOpenGLContext *)manager->GetNSOpenGLContext();
 
     if (!mGLContext) {
       [self setGLContext:glContext];
     }
 
     [glContext setView:self];
     [glContext update];