Bug 942506 - Remove ApplyFilterToBoundTexture from GLContext - r=bjacob
authorDan Glastonbury <dglastonbury@mozilla.com>
Mon, 09 Dec 2013 14:07:18 +1000
changeset 159997 01df0b7dcd8ff80ecb3f53899788059081c15d17
parent 159996 fd0594ff74ce27db29c4267a14773a3e77cb4059
child 159998 c1b544bfad40a132b03b34c5961eac9e290a2c38
push id37478
push userbjacob@mozilla.com
push dateThu, 12 Dec 2013 01:46:40 +0000
treeherdermozilla-inbound@c1b544bfad40 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbjacob
bugs942506
milestone29.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 942506 - Remove ApplyFilterToBoundTexture from GLContext - r=bjacob Move it to CompositorOGL.
gfx/gl/GLBlitTextureImageHelper.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLTextureImage.cpp
gfx/gl/GLTextureImage.h
gfx/gl/TextureImageEGL.cpp
gfx/gl/TextureImageEGL.h
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/GrallocTextureHost.h
gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
gfx/layers/opengl/TextureHostOGL.h
--- a/gfx/gl/GLBlitTextureImageHelper.cpp
+++ b/gfx/gl/GLBlitTextureImageHelper.cpp
@@ -3,16 +3,17 @@
 /* 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 "GLBlitTextureImageHelper.h"
 #include "GLUploadHelpers.h"
 #include "DecomposeIntoNoRepeatTriangles.h"
 #include "GLContext.h"
+#include "ScopedGLHelpers.h"
 #include "nsRect.h"
 #include "gfx2DGlue.h"
 #include "gfxUtils.h"
 
 namespace mozilla {
 namespace gl {
 
 GLBlitTextureImageHelper::GLBlitTextureImageHelper(GLContext* gl)
@@ -138,17 +139,18 @@ GLBlitTextureImageHelper::BlitTextureIma
                 RectTriangles::vert_coord* v = (RectTriangles::vert_coord*)rects.vertexPointer();
 
                 for (unsigned int i = 0; i < rects.elements(); ++i) {
                     v[i].x = (v[i].x * (dx1 - dx0)) + dx0;
                     v[i].y = (v[i].y * (dy1 - dy0)) + dy0;
                 }
             }
 
-            TextureImage::ScopedBindTexture texBind(aSrc, LOCAL_GL_TEXTURE0);
+            ScopedBindTextureUnit autoTexUnit(mGL, LOCAL_GL_TEXTURE0);
+            ScopedBindTexture autoTex(mGL, aSrc->GetTextureID());
 
             mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 
             mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.vertexPointer());
             mGL->fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.texCoordPointer());
 
             mGL->fEnableVertexAttribArray(0);
             mGL->fEnableVertexAttribArray(1);
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1184,34 +1184,16 @@ GLContext::ListHasExtension(const GLubyt
                 return true;
             }
         }
         start = terminator;
     }
     return false;
 }
 
-void GLContext::ApplyFilterToBoundTexture(GraphicsFilter aFilter)
-{
-    ApplyFilterToBoundTexture(LOCAL_GL_TEXTURE_2D, aFilter);
-}
-
-void GLContext::ApplyFilterToBoundTexture(GLuint aTarget,
-                                          GraphicsFilter aFilter)
-{
-    if (aFilter == GraphicsFilter::FILTER_NEAREST) {
-        fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_NEAREST);
-        fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_NEAREST);
-    } else {
-        fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
-        fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
-    }
-}
-
-
 void
 GLContext::DetermineCaps()
 {
     PixelBufferFormat format = QueryPixelFormat();
 
     SurfaceCaps caps;
     caps.color = !!format.red && !!format.green && !!format.blue;
     caps.bpp16 = caps.color && format.ColorBits() == 16;
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -2477,27 +2477,16 @@ public:
      * Defines a two-dimensional texture image for context target surface
      */
     virtual bool BindTexImage() { return false; }
     /*
      * Releases a color buffer that is being used as a texture
      */
     virtual bool ReleaseTexImage() { return false; }
 
-    /**
-     * Applies aFilter to the texture currently bound to GL_TEXTURE_2D.
-     */
-    void ApplyFilterToBoundTexture(GraphicsFilter aFilter);
-
-    /**
-     * Applies aFilter to the texture currently bound to aTarget.
-     */
-    void ApplyFilterToBoundTexture(GLuint aTarget,
-                                   GraphicsFilter aFilter);
-
     // Before reads from offscreen texture
     void GuaranteeResolve();
 
     /*
      * Resize the current offscreen buffer.  Returns true on success.
      * If it returns false, the context should be treated as unusable
      * and should be recreated.  After the resize, the viewport is not
      * changed; glViewport should be called as appropriate.
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -53,17 +53,17 @@ LibType
 GLXLibrary::SelectLibrary(const ContextFlags& aFlags)
 {
   return (aFlags & ContextFlagsMesaLLVMPipe)
           ? GLXLibrary::MESA_LLVMPIPE_LIB
           : GLXLibrary::OPENGL_LIB;
 }
 
 // Check that we have at least version aMajor.aMinor .
-bool 
+bool
 GLXLibrary::GLXVersionCheck(int aMajor, int aMinor)
 {
     return aMajor < mGLXMajorVersion ||
            (aMajor == mGLXMajorVersion && aMinor <= mGLXMinorVersion);
 }
 
 static inline bool
 HasExtension(const char* aExtensions, const char* aRequiredExtension)
@@ -239,17 +239,17 @@ GLXLibrary::EnsureInitialized(LibType li
         sym14 = symbols14;
     }
     if (!GLLibraryLoader::LoadSymbols(mOGLLibrary, sym14)) {
         NS_WARNING("Couldn't find required entry point in OpenGL shared library");
         return false;
     }
 
     if (HasExtension(extensionsStr, "GLX_EXT_texture_from_pixmap") &&
-        GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap, 
+        GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_texturefrompixmap,
                                          (GLLibraryLoader::PlatformLookupFunction)&xGetProcAddress))
     {
 #ifdef MOZ_WIDGET_GTK
         mUseTextureFromPixmap = gfxPlatformGtk::GetPlatform()->UseXRender();
 #else
         mUseTextureFromPixmap = true;
 #endif
     } else {
@@ -273,25 +273,25 @@ GLXLibrary::EnsureInitialized(LibType li
 }
 
 bool
 GLXLibrary::SupportsTextureFromPixmap(gfxASurface* aSurface)
 {
     if (!EnsureInitialized(mLibType)) {
         return false;
     }
-    
+
     if (aSurface->GetType() != gfxSurfaceTypeXlib || !mUseTextureFromPixmap) {
         return false;
     }
 
     return true;
 }
 
-GLXPixmap 
+GLXPixmap
 GLXLibrary::CreatePixmap(gfxASurface* aSurface)
 {
     if (!SupportsTextureFromPixmap(aSurface)) {
         return None;
     }
 
     gfxXlibSurface *xs = static_cast<gfxXlibSurface*>(aSurface);
     const XRenderPictFormat *format = xs->XRenderFormat();
@@ -315,17 +315,17 @@ GLXLibrary::CreatePixmap(gfxASurface* aS
     Display *display = xs->XDisplay();
     int xscreen = DefaultScreen(display);
 
     ScopedXFree<GLXFBConfig> cfgs(xChooseFBConfig(display,
                                                   xscreen,
                                                   attribs,
                                                   &numConfigs));
 
-    // Find an fbconfig that matches the pixel format used on the Pixmap. 
+    // Find an fbconfig that matches the pixel format used on the Pixmap.
     int matchIndex = -1;
     unsigned long redMask =
         static_cast<unsigned long>(direct.redMask) << direct.red;
     unsigned long greenMask =
         static_cast<unsigned long>(direct.greenMask) << direct.green;
     unsigned long blueMask =
         static_cast<unsigned long>(direct.blueMask) << direct.blue;
     // This is true if the Pixmap has bits for alpha or unused bits.
@@ -431,17 +431,17 @@ GLXLibrary::DestroyPixmap(GLXPixmap aPix
     }
 
     Display *display = DefaultXDisplay();
     xDestroyPixmap(display, aPixmap);
 }
 
 void
 GLXLibrary::BindTexImage(GLXPixmap aPixmap)
-{    
+{
     if (!mUseTextureFromPixmap) {
         return;
     }
 
     Display *display = DefaultXDisplay();
     // Make sure all X drawing to the surface has finished before binding to a texture.
     if (mClientIsMesa) {
         // Using XSync instead of Mesa's glXWaitX, because its glxWaitX is a
@@ -503,97 +503,97 @@ GLXLibrary::AfterGLXCall()
         }
         XSetErrorHandler(sOldErrorHandler);
     }
 }
 
 #define BEFORE_GLX_CALL do {                     \
     sGLXLibrary[gCurrLib].BeforeGLXCall();       \
 } while (0)
-    
+
 #define AFTER_GLX_CALL do {                      \
     sGLXLibrary[gCurrLib].AfterGLXCall();        \
 } while (0)
 
 #else
 
 #define BEFORE_GLX_CALL do { } while(0)
 #define AFTER_GLX_CALL do { } while(0)
 
 #endif
-    
-void 
+
+void
 GLXLibrary::xDestroyContext(Display* display, GLXContext context)
 {
     BEFORE_GLX_CALL;
     xDestroyContextInternal(display, context);
     AFTER_GLX_CALL;
 }
 
-Bool 
-GLXLibrary::xMakeCurrent(Display* display, 
-                         GLXDrawable drawable, 
+Bool
+GLXLibrary::xMakeCurrent(Display* display,
+                         GLXDrawable drawable,
                          GLXContext context)
 {
     BEFORE_GLX_CALL;
     Bool result = xMakeCurrentInternal(display, drawable, context);
     AFTER_GLX_CALL;
     return result;
 }
 
-GLXContext 
+GLXContext
 GLXLibrary::xGetCurrentContext()
 {
     BEFORE_GLX_CALL;
     GLXContext result = xGetCurrentContextInternal();
     AFTER_GLX_CALL;
     return result;
 }
 
-/* static */ void* 
+/* static */ void*
 GLXLibrary::xGetProcAddress(const char *procName)
 {
     BEFORE_GLX_CALL;
     void* result = sGLXLibrary[gCurrLib].xGetProcAddressInternal(procName);
     AFTER_GLX_CALL;
     return result;
 }
 
 GLXFBConfig*
-GLXLibrary::xChooseFBConfig(Display* display, 
-                            int screen, 
-                            const int *attrib_list, 
+GLXLibrary::xChooseFBConfig(Display* display,
+                            int screen,
+                            const int *attrib_list,
                             int *nelements)
 {
     BEFORE_GLX_CALL;
     GLXFBConfig* result = xChooseFBConfigInternal(display, screen, attrib_list, nelements);
     AFTER_GLX_CALL;
     return result;
 }
 
-GLXFBConfig* 
-GLXLibrary::xGetFBConfigs(Display* display, 
-                          int screen, 
+GLXFBConfig*
+GLXLibrary::xGetFBConfigs(Display* display,
+                          int screen,
                           int *nelements)
 {
     BEFORE_GLX_CALL;
     GLXFBConfig* result = xGetFBConfigsInternal(display, screen, nelements);
     AFTER_GLX_CALL;
     return result;
 }
-    
+
 GLXContext
-GLXLibrary::xCreateNewContext(Display* display, 
-                              GLXFBConfig config, 
-                              int render_type, 
-                              GLXContext share_list, 
+GLXLibrary::xCreateNewContext(Display* display,
+                              GLXFBConfig config,
+                              int render_type,
+                              GLXContext share_list,
                               Bool direct)
 {
     BEFORE_GLX_CALL;
-    GLXContext result = xCreateNewContextInternal(display, config, 
+    GLXContext result = xCreateNewContextInternal(display, config,
                                                   render_type,
                                                   share_list, direct);
     AFTER_GLX_CALL;
     return result;
 }
 
 int
 GLXLibrary::xGetFBConfigAttrib(Display *display,
@@ -642,17 +642,17 @@ GLXLibrary::xQueryServerString(Display *
 {
     BEFORE_GLX_CALL;
     const char *result = xQueryServerStringInternal(display, screen, name);
     AFTER_GLX_CALL;
     return result;
 }
 
 GLXPixmap
-GLXLibrary::xCreatePixmap(Display *display, 
+GLXLibrary::xCreatePixmap(Display *display,
                           GLXFBConfig config,
                           Pixmap pixmap,
                           const int *attrib_list)
 {
     BEFORE_GLX_CALL;
     GLXPixmap result = xCreatePixmapInternal(display, config,
                                              pixmap, attrib_list);
     AFTER_GLX_CALL;
@@ -705,43 +705,43 @@ GLXLibrary::xReleaseTexImage(Display *di
                              GLXDrawable drawable,
                              int buffer)
 {
     BEFORE_GLX_CALL;
     xReleaseTexImageInternal(display, drawable, buffer);
     AFTER_GLX_CALL;
 }
 
-void 
+void
 GLXLibrary::xWaitGL()
 {
     BEFORE_GLX_CALL;
     xWaitGLInternal();
     AFTER_GLX_CALL;
 }
 
 void
 GLXLibrary::xWaitX()
 {
     BEFORE_GLX_CALL;
     xWaitXInternal();
     AFTER_GLX_CALL;
 }
 
 GLXContext
-GLXLibrary::xCreateContextAttribs(Display* display, 
-                                  GLXFBConfig config, 
-                                  GLXContext share_list, 
+GLXLibrary::xCreateContextAttribs(Display* display,
+                                  GLXFBConfig config,
+                                  GLXContext share_list,
                                   Bool direct,
                                   const int* attrib_list)
 {
     BEFORE_GLX_CALL;
-    GLXContext result = xCreateContextAttribsInternal(display, 
-                                                      config, 
-                                                      share_list, 
+    GLXContext result = xCreateContextAttribsInternal(display,
+                                                      config,
+                                                      share_list,
                                                       direct,
                                                       attrib_list);
     AFTER_GLX_CALL;
     return result;
 }
 
 class GLContextGLX : public GLContext
 {
@@ -900,17 +900,17 @@ TRY_AGAIN_NO_SHARING:
         return true;
     }
 
     void *GetNativeData(NativeDataType aType)
     {
         switch(aType) {
         case NativeGLContext:
             return mContext;
- 
+
         case NativeThebesSurface:
             return mPixmap;
 
         default:
             return nullptr;
         }
     }
 
@@ -1007,23 +1007,23 @@ GLContextProviderGLX::CreateForWindow(ns
 
     // Currently, we take whatever Visual the window already has, and
     // try to create an fbconfig for that visual.  This isn't
     // necessarily what we want in the long run; an fbconfig may not
     // be available for the existing visual, or if it is, the GL
     // performance might be suboptimal.  But using the existing visual
     // is a relatively safe intermediate step.
 
-    Display *display = (Display*)aWidget->GetNativeData(NS_NATIVE_DISPLAY); 
+    Display *display = (Display*)aWidget->GetNativeData(NS_NATIVE_DISPLAY);
     int xscreen = DefaultScreen(display);
     Window window = GET_NATIVE_WINDOW(aWidget);
 
     int numConfigs;
     ScopedXFree<GLXFBConfig> cfgs;
-    if (sDefGLXLib.IsATI() || 
+    if (sDefGLXLib.IsATI() ||
         !sDefGLXLib.GLXVersionCheck(1, 3)) {
         const int attribs[] = {
             LOCAL_GLX_DOUBLEBUFFER, False,
             0
         };
         cfgs = sDefGLXLib.xChooseFBConfig(display,
                                        xscreen,
                                        attribs,
--- a/gfx/gl/GLTextureImage.cpp
+++ b/gfx/gl/GLTextureImage.cpp
@@ -200,23 +200,16 @@ BasicTextureImage::EndUpdate()
 void
 BasicTextureImage::BindTexture(GLenum aTextureUnit)
 {
     mGLContext->fActiveTexture(aTextureUnit);
     mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
     mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
 }
 
-void
-BasicTextureImage::ApplyFilter()
-{
-  mGLContext->ApplyFilterToBoundTexture(mFilter);
-}
-
-
 already_AddRefed<gfxASurface>
 BasicTextureImage::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
 {
     return gfxPlatform::GetPlatform()->
         CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
 }
 
 bool
@@ -632,22 +625,16 @@ void
 TiledTextureImage::BindTexture(GLenum aTextureUnit)
 {
     if (!GetTileCount()) {
         return;
     }
     mImages[mCurrentImage]->BindTexture(aTextureUnit);
 }
 
-void
-TiledTextureImage::ApplyFilter()
-{
-   mGL->ApplyFilterToBoundTexture(mFilter);
-}
-
 /*
  * Resize, trying to reuse tiles. The reuse strategy is to decide on reuse per
  * column. A tile on a column is reused if it hasn't changed size, otherwise it
  * is discarded/replaced. Extra tiles on a column are pruned after iterating
  * each column, and extra rows are pruned after iteration over the entire image
  * finishes.
  */
 void TiledTextureImage::Resize(const nsIntSize& aSize)
@@ -740,26 +727,16 @@ void TiledTextureImage::Resize(const nsI
     mCurrentImage = 0;
 }
 
 uint32_t TiledTextureImage::GetTileCount()
 {
     return mImages.Length();
 }
 
-TextureImage::ScopedBindTexture::ScopedBindTexture(TextureImage* aTexture,
-                                                   GLenum aTextureUnit)
-    : mTexture(aTexture)
-{
-    if (mTexture) {
-        MOZ_ASSERT(aTextureUnit >= LOCAL_GL_TEXTURE0);
-        mTexture->BindTexture(aTextureUnit);
-    }
-}
-
 already_AddRefed<TextureImage>
 CreateBasicTextureImage(GLContext* aGL,
                         const nsIntSize& aSize,
                         TextureImage::ContentType aContentType,
                         GLenum aWrapMode,
                         TextureImage::Flags aFlags,
                         TextureImage::ImageFormat aImageFormat)
 {
--- a/gfx/gl/GLTextureImage.h
+++ b/gfx/gl/GLTextureImage.h
@@ -180,51 +180,16 @@ public:
      */
     virtual bool DirectUpdate(gfxASurface *aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0)) = 0;
     // Moz2D equivalent
     bool UpdateFromDataSource(gfx::DataSourceSurface *aSurf,
                               const nsIntRegion* aDstRegion = nullptr,
                               const gfx::IntPoint* aSrcOffset = nullptr);
 
     virtual void BindTexture(GLenum aTextureUnit) = 0;
-    virtual void ReleaseTexture() {}
-
-    void BindTextureAndApplyFilter(GLenum aTextureUnit) {
-        BindTexture(aTextureUnit);
-        ApplyFilter();
-    }
-
-    class ScopedBindTexture
-    {
-    public:
-        ScopedBindTexture(TextureImage *aTexture, GLenum aTextureUnit);
-
-        ~ScopedBindTexture()
-        {
-            if (mTexture) {
-                mTexture->ReleaseTexture();
-            }
-        }
-
-    protected:
-        TextureImage *mTexture;
-    };
-
-    class ScopedBindTextureAndApplyFilter
-        : public ScopedBindTexture
-    {
-    public:
-        ScopedBindTextureAndApplyFilter(TextureImage *aTexture, GLenum aTextureUnit) :
-          ScopedBindTexture(aTexture, aTextureUnit)
-        {
-            if (mTexture) {
-                mTexture->ApplyFilter();
-            }
-        }
-    };
 
     /**
      * Returns the image format of the texture. Only valid after a matching
      * BeginUpdate/EndUpdate pair have been called.
      */
     virtual gfx::SurfaceFormat GetTextureFormat() {
         return mTextureFormat;
     }
@@ -242,22 +207,16 @@ public:
     gfx::IntSize GetSize() const;
     ContentType GetContentType() const { return mContentType; }
     ImageFormat GetImageFormat() const { return mImageFormat; }
     virtual bool InUpdate() const = 0;
     GLenum GetWrapMode() const { return mWrapMode; }
 
     void SetFilter(GraphicsFilter aFilter) { mFilter = aFilter; }
 
-    /**
-     * Applies this TextureImage's filter, assuming that its texture is
-     * the currently bound texture.
-     */
-    virtual void ApplyFilter() = 0;
-
 protected:
     friend class GLContext;
 
     /**
      * After the ctor, the TextureImage is invalid.  Implementations
      * must allocate resources successfully before returning the new
      * TextureImage from GLContext::CreateTextureImage().  That is,
      * clients must not be given partially-constructed TextureImages.
@@ -340,19 +299,17 @@ public:
 
     // Call after surface data has been uploaded to a texture.
     virtual void FinishedSurfaceUpload();
 
     virtual bool InUpdate() const { return !!mUpdateSurface; }
 
     virtual void Resize(const nsIntSize& aSize);
 
-    virtual void ApplyFilter();
 protected:
-
     GLuint mTexture;
     TextureState mTextureState;
     nsRefPtr<GLContext> mGLContext;
     nsRefPtr<gfxASurface> mUpdateSurface;
     nsIntRegion mUpdateRegion;
 
     // The offset into the update surface at which the update rect is located.
     nsIntPoint mUpdateOffset;
@@ -385,17 +342,16 @@ public:
                                       void* aCallbackData);
     virtual gfx::IntRect GetTileRect();
     virtual GLuint GetTextureID() {
         return mImages[mCurrentImage]->GetTextureID();
     }
     virtual bool DirectUpdate(gfxASurface* aSurf, const nsIntRegion& aRegion, const nsIntPoint& aFrom = nsIntPoint(0,0));
     virtual bool InUpdate() const { return mInUpdate; }
     virtual void BindTexture(GLenum);
-    virtual void ApplyFilter();
 
 protected:
     virtual gfx::IntRect GetSrcTileRect();
 
     unsigned int mCurrentImage;
     TileIterationCallback mIterationCallback;
     void* mIterationCallbackData;
     nsTArray< nsRefPtr<TextureImage> > mImages;
--- a/gfx/gl/TextureImageEGL.cpp
+++ b/gfx/gl/TextureImageEGL.cpp
@@ -306,22 +306,16 @@ TextureImageEGL::DestroyEGLSurface(void)
 {
     if (!mSurface)
         return;
 
     sEGLLibrary.fDestroySurface(EGL_DISPLAY(), mSurface);
     mSurface = nullptr;
 }
 
-void
-TextureImageEGL::ApplyFilter()
-{
-    mGLContext->ApplyFilterToBoundTexture(mFilter);
-}
-
 already_AddRefed<TextureImage>
 CreateTextureImageEGL(GLContext *gl,
                       const nsIntSize& aSize,
                       TextureImage::ContentType aContentType,
                       GLenum aWrapMode,
                       TextureImage::Flags aFlags,
                       TextureImage::ImageFormat aImageFormat)
 {
@@ -352,9 +346,9 @@ TileGenFuncEGL(GLContext *gl,
   gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
   gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
   gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
 
   return teximage.forget();
 }
 
 }
-}
\ No newline at end of file
+}
--- a/gfx/gl/TextureImageEGL.h
+++ b/gfx/gl/TextureImageEGL.h
@@ -70,18 +70,16 @@ protected:
     nsRefPtr<gfxASurface> mUpdateSurface;
     EGLImage mEGLImage;
     GLuint mTexture;
     EGLSurface mSurface;
     EGLConfig mConfig;
     TextureState mTextureState;
 
     bool mBound;
-
-    virtual void ApplyFilter();
 };
 
 already_AddRefed<TextureImage>
 CreateTextureImageEGL(GLContext *gl,
                       const nsIntSize& aSize,
                       TextureImage::ContentType aContentType,
                       GLenum aWrapMode,
                       TextureImage::Flags aFlags,
@@ -92,9 +90,9 @@ TileGenFuncEGL(GLContext *gl,
                const nsIntSize& aSize,
                TextureImage::ContentType aContentType,
                TextureImage::Flags aFlags,
                TextureImage::ImageFormat aImageFormat);
 
 }
 }
 
-#endif // TEXTUREIMAGEEGL_H_
\ No newline at end of file
+#endif // TEXTUREIMAGEEGL_H_
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -36,16 +36,17 @@
 #include "nsIConsoleService.h"          // for nsIConsoleService, etc
 #include "nsIWidget.h"                  // for nsIWidget
 #include "nsLiteralString.h"            // for NS_LITERAL_STRING
 #include "nsMathUtils.h"                // for NS_roundf
 #include "nsRect.h"                     // for nsIntRect
 #include "nsServiceManagerUtils.h"      // for do_GetService
 #include "nsString.h"                   // for nsString, nsAutoCString, etc
 #include "DecomposeIntoNoRepeatTriangles.h"
+#include "ScopedGLHelpers.h"
 
 #if MOZ_ANDROID_OMTC
 #include "TexturePoolOGL.h"
 #endif
 #include "GeckoProfiler.h"
 
 #ifdef MOZ_WIDGET_ANDROID
 #include "GfxInfo.h"
@@ -973,38 +974,67 @@ CompositorOGL::GetProgramTypeForEffect(E
   case EFFECT_RENDER_TARGET:
     return GetFBOLayerProgramType();
   default:
     return RGBALayerProgramType;
   }
 }
 
 struct MOZ_STACK_CLASS AutoBindTexture
+  : public ScopedGLWrapper<AutoBindTexture>
 {
-  AutoBindTexture() : mTexture(nullptr) {}
-  AutoBindTexture(TextureSourceOGL* aTexture, GLenum aTextureUnit)
-   : mTexture(nullptr) { Bind(aTexture, aTextureUnit); }
-  ~AutoBindTexture()
+  friend struct ScopedGLWrapper<AutoBindTexture>;
+
+protected:
+  GLenum mTexUnit;
+  GLuint mOldTexId;
+
+public:
+  explicit AutoBindTexture(GLContext* aGL)
+    : ScopedGLWrapper<AutoBindTexture>(aGL)
+    , mTexUnit(0)
+    , mOldTexId((GLuint) -1)
+  { }
+
+  AutoBindTexture(GLContext* aGL, TextureSourceOGL* aTexture,
+                  GLenum aTexUnit = LOCAL_GL_TEXTURE0)
+    : ScopedGLWrapper<AutoBindTexture>(aGL)
+    , mTexUnit(0)
+    , mOldTexId((GLuint) -1)
   {
-    if (mTexture) {
-      mTexture->UnbindTexture();
-    }
+    Bind(aTexture, aTexUnit);
   }
 
-  void Bind(TextureSourceOGL* aTexture, GLenum aTextureUnit)
+  void Bind(TextureSourceOGL* aTexture,
+            GLenum aTexUnit = LOCAL_GL_TEXTURE0)
   {
-    MOZ_ASSERT(!mTexture);
-    mTexture = aTexture;
-    mTexture->BindTexture(aTextureUnit);
+    if (!aTexture)
+      return;
+
+    MOZ_ASSERT(mOldTexId == (GLuint) -1);
+    mTexUnit = aTexUnit;
+
+    ScopedBindTextureUnit savedTexUnit(mGL, aTexUnit);
+
+    mGL->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &mOldTexId);
+    aTexture->BindTexture(mTexUnit);
   }
 
-private:
-  TextureSourceOGL* mTexture;
+protected:
+  void UnwrapImpl()
+  {
+    if (mOldTexId == (GLuint) -1)
+      return;
+
+    ScopedBindTextureUnit savedTexUnit(mGL, mTexUnit);
+    mGL->fBindTexture(LOCAL_GL_TEXTURE_2D, mOldTexId);
+  }
 };
 
+
 void
 CompositorOGL::DrawLines(const std::vector<gfx::Point>& aLines, const gfx::Rect& aClipRect,
                          const gfx::Color& aColor,
                          gfx::Float aOpacity, const gfx::Matrix4x4 &aTransform)
 {
   mGLContext->fLineWidth(2.0);
 
   EffectChain effects;
@@ -1014,16 +1044,30 @@ CompositorOGL::DrawLines(const std::vect
     const gfx::Point& p1 = aLines[i];
     const gfx::Point& p2 = aLines[i+1];
     DrawQuadInternal(Rect(p1.x, p2.y, p2.x - p1.x, p1.y - p2.y),
                      aClipRect, effects, aOpacity, aTransform,
                      LOCAL_GL_LINE_STRIP);
   }
 }
 
+/**
+ * Applies aFilter to the texture currently bound to aTarget.
+ */
+void ApplyFilterToBoundTexture(GLContext* aGL,
+                               GraphicsFilter aFilter,
+                               GLuint aTarget = LOCAL_GL_TEXTURE_2D)
+{
+  GLenum filter =
+    (aFilter == GraphicsFilter::FILTER_NEAREST ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR);
+
+    aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MIN_FILTER, filter);
+    aGL->fTexParameteri(aTarget, LOCAL_GL_TEXTURE_MAG_FILTER, filter);
+}
+
 void
 CompositorOGL::DrawQuadInternal(const Rect& aRect,
                                 const Rect& aClipRect,
                                 const EffectChain &aEffectChain,
                                 Float aOpacity,
                                 const gfx::Matrix4x4 &aTransform,
                                 GLuint aDrawMode)
 {
@@ -1107,17 +1151,17 @@ CompositorOGL::DrawQuadInternal(const Re
       Float opacity = aOpacity * color.a;
       color.r *= opacity;
       color.g *= opacity;
       color.b *= opacity;
       color.a = opacity;
 
       program->SetRenderColor(color);
 
-      AutoBindTexture bindMask;
+      AutoBindTexture bindMask(mGLContext);
       if (maskType != MaskNone) {
         bindMask.Bind(sourceMask, LOCAL_GL_TEXTURE0);
         program->SetMaskTextureUnit(0);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
 
       BindAndDrawQuad(program, false, aDrawMode);
     }
@@ -1132,17 +1176,17 @@ CompositorOGL::DrawQuadInternal(const Re
       Rect textureCoords;
       TextureSource *source = texturedEffect->mTexture;
 
       if (!texturedEffect->mPremultiplied) {
         mGLContext->fBlendFuncSeparate(LOCAL_GL_SRC_ALPHA, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                        LOCAL_GL_ONE, LOCAL_GL_ONE);
       }
 
-      AutoBindTexture bindSource(source->AsSourceOGL(), LOCAL_GL_TEXTURE0);
+      AutoBindTexture bindSource(mGLContext, source->AsSourceOGL(), LOCAL_GL_TEXTURE0);
 
       gfx3DMatrix textureTransform = source->AsSourceOGL()->GetTextureTransform();
       program->SetTextureTransform(textureTransform);
 
       GraphicsFilter filter = ThebesFilter(texturedEffect->mFilter);
       gfxMatrix textureTransform2D;
 #ifdef MOZ_WIDGET_ANDROID
       if (filter != GraphicsFilter::FILTER_NEAREST &&
@@ -1150,23 +1194,23 @@ CompositorOGL::DrawQuadInternal(const Re
           textureTransform.Is2D(&textureTransform2D) &&
           textureTransform2D.HasOnlyIntegerTranslation()) {
         // On Android we encounter small resampling errors in what should be
         // pixel-aligned compositing operations. This works around them. This
         // code should not be needed!
         filter = GraphicsFilter::FILTER_NEAREST;
       }
 #endif
-      mGLContext->ApplyFilterToBoundTexture(source->AsSourceOGL()->GetTextureTarget(),
-                                            filter);
+      ApplyFilterToBoundTexture(mGLContext, filter,
+                                source->AsSourceOGL()->GetTextureTarget());
 
       program->SetTextureUnit(0);
       program->SetLayerOpacity(aOpacity);
 
-      AutoBindTexture bindMask;
+      AutoBindTexture bindMask(mGLContext);
       if (maskType != MaskNone) {
         mGLContext->fActiveTexture(LOCAL_GL_TEXTURE1);
         bindMask.Bind(sourceMask, LOCAL_GL_TEXTURE1);
         program->SetMaskTextureUnit(1);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
 
       BindAndDrawQuadWithTextureRect(program, texturedEffect->mTextureCoords, source);
@@ -1188,28 +1232,28 @@ CompositorOGL::DrawQuadInternal(const Re
 
       if (!sourceY && !sourceCb && !sourceCr) {
         NS_WARNING("Invalid layer texture.");
         return;
       }
 
       GraphicsFilter filter = ThebesFilter(effectYCbCr->mFilter);
 
-      AutoBindTexture bindY(sourceY, LOCAL_GL_TEXTURE0);
-      mGLContext->ApplyFilterToBoundTexture(filter);
-      AutoBindTexture bindCb(sourceCb, LOCAL_GL_TEXTURE1);
-      mGLContext->ApplyFilterToBoundTexture(filter);
-      AutoBindTexture bindCr(sourceCr, LOCAL_GL_TEXTURE2);
-      mGLContext->ApplyFilterToBoundTexture(filter);
+      AutoBindTexture bindY(mGLContext, sourceY, LOCAL_GL_TEXTURE0);
+      ApplyFilterToBoundTexture(mGLContext, filter);
+      AutoBindTexture bindCb(mGLContext, sourceCb, LOCAL_GL_TEXTURE1);
+      ApplyFilterToBoundTexture(mGLContext, filter);
+      AutoBindTexture bindCr(mGLContext, sourceCr, LOCAL_GL_TEXTURE2);
+      ApplyFilterToBoundTexture(mGLContext, filter);
 
       program->SetYCbCrTextureUnits(Y, Cb, Cr);
       program->SetLayerOpacity(aOpacity);
       program->SetTextureTransform(gfx3DMatrix());
 
-      AutoBindTexture bindMask;
+      AutoBindTexture bindMask(mGLContext);
       if (maskType != MaskNone) {
         bindMask.Bind(sourceMask, LOCAL_GL_TEXTURE3);
         program->SetMaskTextureUnit(3);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
       BindAndDrawQuadWithTextureRect(program, effectYCbCr->mTextureCoords, sourceYCbCr->GetSubSource(Y));
     }
     break;
@@ -1223,17 +1267,17 @@ CompositorOGL::DrawQuadInternal(const Re
 
       surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget);
 
       program->Activate();
       program->SetTextureUnit(0);
       program->SetLayerOpacity(aOpacity);
       program->SetTextureTransform(gfx3DMatrix());
 
-      AutoBindTexture bindMask;
+      AutoBindTexture bindMask(mGLContext);
       if (maskType != MaskNone) {
         bindMask.Bind(sourceMask, LOCAL_GL_TEXTURE1);
         program->SetMaskTextureUnit(1);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
 
       if (program->GetTexCoordMultiplierUniformLocation() != -1) {
         // 2DRect case, get the multiplier right for a sampler2DRect
@@ -1272,28 +1316,28 @@ CompositorOGL::DrawQuadInternal(const Re
           ShaderProgramType type = gl()->GetPreferredARGB32Format() == LOCAL_GL_BGRA ?
                                    ComponentAlphaPass2RGBProgramType :
                                    ComponentAlphaPass2ProgramType;
           program = GetProgram(type, maskType);
           gl()->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE,
                                    LOCAL_GL_ONE, LOCAL_GL_ONE);
         }
 
-        AutoBindTexture bindSourceOnBlack(sourceOnBlack, LOCAL_GL_TEXTURE0);
-        AutoBindTexture bindSourceOnWhite(sourceOnWhite, LOCAL_GL_TEXTURE1);
+        AutoBindTexture bindSourceOnBlack(mGLContext, sourceOnBlack, LOCAL_GL_TEXTURE0);
+        AutoBindTexture bindSourceOnWhite(mGLContext, sourceOnWhite, LOCAL_GL_TEXTURE1);
 
         program->Activate();
         program->SetBlackTextureUnit(0);
         program->SetWhiteTextureUnit(1);
         program->SetLayerOpacity(aOpacity);
         program->SetLayerTransform(aTransform);
         program->SetTextureTransform(gfx3DMatrix());
         program->SetRenderOffset(offset.x, offset.y);
         program->SetLayerQuadRect(aRect);
-        AutoBindTexture bindMask;
+        AutoBindTexture bindMask(mGLContext);
         if (maskType != MaskNone) {
           bindMask.Bind(sourceMask, LOCAL_GL_TEXTURE2);
           program->SetMaskTextureUnit(2);
           program->SetMaskLayerTransform(maskQuadTransform);
         }
 
         BindAndDrawQuadWithTextureRect(program, effectComponentAlpha->mTextureCoords, effectComponentAlpha->mOnBlack);
 
--- a/gfx/layers/opengl/GrallocTextureHost.h
+++ b/gfx/layers/opengl/GrallocTextureHost.h
@@ -27,18 +27,16 @@ public:
                           gfx::SurfaceFormat aFormat);
 
   virtual ~GrallocTextureSourceOGL();
 
   virtual bool IsValid() const MOZ_OVERRIDE;
 
   virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
 
-  virtual void UnbindTexture() MOZ_OVERRIDE {}
-
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
 
   virtual GLenum GetTextureTarget() const MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
 
--- a/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
+++ b/gfx/layers/opengl/MacIOSurfaceTextureHostOGL.h
@@ -36,18 +36,16 @@ public:
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
 
   virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_RECTANGLE_ARB; }
 
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
 
-  virtual void UnbindTexture() MOZ_OVERRIDE {}
-
   // MacIOSurfaceTextureSourceOGL doesn't own any gl texture
   virtual void DeallocateDeviceData() {}
 
   void SetCompositor(CompositorOGL* aCompositor) {
     mCompositor = aCompositor;
   }
 
   gl::GLContext* gl() const;
@@ -99,9 +97,9 @@ protected:
   CompositorOGL* mCompositor;
   RefPtr<MacIOSurfaceTextureSourceOGL> mTextureSource;
   RefPtr<MacIOSurface> mSurface;
 };
 
 }
 }
 
-#endif // MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
\ No newline at end of file
+#endif // MOZILLA_GFX_MACIOSURFACETEXTUREHOSTOGL_H
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -122,18 +122,16 @@ GetProgramTypeForTexture(const Deprecate
  */
 class TextureSourceOGL
 {
 public:
   virtual bool IsValid() const = 0;
 
   virtual void BindTexture(GLenum aTextureUnit) = 0;
 
-  virtual void UnbindTexture() = 0;
-
   virtual gfx::IntSize GetSize() const = 0;
 
   virtual GLenum GetTextureTarget() const { return LOCAL_GL_TEXTURE_2D; }
 
   virtual gfx::SurfaceFormat GetFormat() const = 0;
 
   virtual GLenum GetWrapMode() const = 0;
 
@@ -182,21 +180,16 @@ public:
   virtual void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
 
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE;
 
   virtual bool IsValid() const MOZ_OVERRIDE { return !!mTexImage; }
 
-  virtual void UnbindTexture() MOZ_OVERRIDE
-  {
-    mTexImage->ReleaseTexture();
-  }
-
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE
   {
     return mTexImage->GetWrapMode();
   }
 
   // TileIterator
 
   virtual TileIterator* AsTileIterator() MOZ_OVERRIDE { return this; }
@@ -264,18 +257,16 @@ public:
   virtual gfx::SurfaceFormat GetFormat() const MOZ_OVERRIDE { return mFormat; }
 
   virtual gfx3DMatrix GetTextureTransform() MOZ_OVERRIDE;
 
   virtual GLenum GetTextureTarget() const { return mTextureTarget; }
 
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return mWrapMode; }
 
-  virtual void UnbindTexture() MOZ_OVERRIDE {}
-
   // SharedTextureSource doesn't own any gl texture
   virtual void DeallocateDeviceData() {}
 
   void DetachSharedHandle();
 
   void SetCompositor(CompositorOGL* aCompositor);
 
   gl::GLContext* gl() const;
@@ -401,21 +392,16 @@ public:
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 
   // textureSource
   void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE
   {
     mTexture->BindTexture(aTextureUnit);
   }
 
-  void UnbindTexture() MOZ_OVERRIDE
-  {
-    mTexture->ReleaseTexture();
-  }
-
   gfx::IntSize GetSize() const MOZ_OVERRIDE;
 
   GLenum GetWrapMode() const MOZ_OVERRIDE
   {
     return mTexture->GetWrapMode();
   }
 
   gl::TextureImage* GetTextureImage()
@@ -523,20 +509,16 @@ public:
       return this;
     }
     nsRefPtr<gl::TextureImage> mTexImage;
 
     void BindTexture(GLenum aUnit) MOZ_OVERRIDE
     {
       mTexImage->BindTexture(aUnit);
     }
-    void UnbindTexture() MOZ_OVERRIDE
-    {
-      mTexImage->ReleaseTexture();
-    }
     virtual bool IsValid() const MOZ_OVERRIDE
     {
       return !!mTexImage;
     }
     virtual gfx::IntSize GetSize() const MOZ_OVERRIDE
     {
       return gfx::IntSize(mTexImage->GetSize().width, mTexImage->GetSize().height);
     }
@@ -645,17 +627,16 @@ public:
   }
 
   void BindTexture(GLenum activetex) MOZ_OVERRIDE
   {
     MOZ_ASSERT(mGL);
     // Lock already bound us!
     MOZ_ASSERT(activetex == LOCAL_GL_TEXTURE0);
   }
-  void UnbindTexture() MOZ_OVERRIDE {}
   GLuint GetTextureID() { return mTextureHandle; }
   ContentType GetContentType()
   {
     return (mFormat == gfx::FORMAT_B8G8R8A8) ?
              GFX_CONTENT_COLOR_ALPHA :
              GFX_CONTENT_COLOR;
   }
 
@@ -726,18 +707,16 @@ public:
 
   virtual GLenum GetTextureTarget() const MOZ_OVERRIDE
   {
     return mTextureTarget;
   }
 
   void BindTexture(GLenum activetex) MOZ_OVERRIDE;
 
-  void UnbindTexture() MOZ_OVERRIDE {}
-
   GLuint GetTextureID() { return mTextureHandle; }
   ContentType GetContentType() {
     return (mFormat == gfx::FORMAT_B8G8R8A8) ?
              GFX_CONTENT_COLOR_ALPHA :
              GFX_CONTENT_COLOR;
   }
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
@@ -787,17 +766,16 @@ public:
   {
     return DeprecatedTextureHost::GetFormat();
   }
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE { return this; }
   virtual bool IsValid() const MOZ_OVERRIDE { return true; }
   virtual GLenum GetWrapMode() const MOZ_OVERRIDE { return LOCAL_GL_CLAMP_TO_EDGE; }
   virtual void BindTexture(GLenum aTextureUnit);
-  virtual void UnbindTexture() MOZ_OVERRIDE {}
   virtual gfx::IntSize GetSize() const MOZ_OVERRIDE
   {
     return mSize;
   }
 
   virtual void SwapTexturesImpl(const SurfaceDescriptor& aImage,
                                 nsIntRegion* aRegion = nullptr)
   { MOZ_ASSERT(false, "Tiles should not use this path"); }
@@ -870,17 +848,16 @@ public:
 
   bool IsValid() const MOZ_OVERRIDE;
 
   virtual TemporaryRef<gfx::DataSourceSurface> GetAsSurface() MOZ_OVERRIDE;
 
   virtual const char* Name() { return "GrallocDeprecatedTextureHostOGL"; }
 
   void BindTexture(GLenum aTextureUnit) MOZ_OVERRIDE;
-  void UnbindTexture() MOZ_OVERRIDE {}
 
   virtual TextureSourceOGL* AsSourceOGL() MOZ_OVERRIDE
   {
     return this;
   }
 
   // only overridden for hacky fix in gecko 23 for bug 862324
   // see bug 865908 about fixing this.