Bug 990233 - Back out Bug 978479 and Bug 980364 because of a 5% tresize regression on Mac OSX 10.6 - no review, just a backout on a CLOSED TREE
authorBenoit Jacob <bjacob@mozilla.com>
Mon, 31 Mar 2014 22:31:24 -0400
changeset 176436 a63f5694f562aa9c4301760ab5eea23cc18eaef0
parent 176435 0483fe9d0b74e4dfe6df1f74379e03bd055b0fd3
child 176437 d313210d26195e2e22c120d0c4955a6e21500d1b
push id26524
push userryanvm@gmail.com
push dateTue, 01 Apr 2014 20:44:18 +0000
treeherderautoland@0ff6afce0133 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs990233, 978479, 980364
milestone31.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 990233 - Back out Bug 978479 and Bug 980364 because of a 5% tresize regression on Mac OSX 10.6 - no review, just a backout on a CLOSED TREE
gfx/gl/DecomposeIntoNoRepeatTriangles.h
gfx/gl/GLBlitTextureImageHelper.cpp
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLDrawRectHelper.cpp
gfx/gl/GLDrawRectHelper.h
gfx/gl/moz.build
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/CompositorOGL.h
--- a/gfx/gl/DecomposeIntoNoRepeatTriangles.h
+++ b/gfx/gl/DecomposeIntoNoRepeatTriangles.h
@@ -42,16 +42,20 @@ public:
       */
     InfallibleTArray<coord>& vertCoords() {
         return mVertexCoords;
     }
 
     InfallibleTArray<coord>& texCoords() {
         return mTexCoords;
     }
+
+    unsigned int elements() {
+        return mVertexCoords.Length();
+    }
 private:
     // Reserve inline storage for one quad (2 triangles, 3 coords).
     nsAutoTArray<coord, 6> mVertexCoords;
     nsAutoTArray<coord, 6> mTexCoords;
 
     static void
     AppendRectToCoordArray(InfallibleTArray<coord>& array, GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1);
 };
--- a/gfx/gl/GLBlitTextureImageHelper.cpp
+++ b/gfx/gl/GLBlitTextureImageHelper.cpp
@@ -7,17 +7,16 @@
 #include "GLBlitTextureImageHelper.h"
 #include "GLUploadHelpers.h"
 #include "DecomposeIntoNoRepeatTriangles.h"
 #include "GLContext.h"
 #include "ScopedGLHelpers.h"
 #include "nsRect.h"
 #include "gfx2DGlue.h"
 #include "gfxUtils.h"
-#include "GLDrawRectHelper.h"
 
 namespace mozilla {
 namespace gl {
 
 GLBlitTextureImageHelper::GLBlitTextureImageHelper(GLContext* gl)
     : mGL(gl)
     , mBlitProgram(0)
     , mBlitFramebuffer(0)
@@ -143,20 +142,35 @@ GLBlitTextureImageHelper::BlitTextureIma
                     coords[i].x = (coords[i].x * (dx1 - dx0)) + dx0;
                     coords[i].y = (coords[i].y * (dy1 - dy0)) + dy0;
                 }
             }
 
             ScopedBindTextureUnit autoTexUnit(mGL, LOCAL_GL_TEXTURE0);
             ScopedBindTexture autoTex(mGL, aSrc->GetTextureID());
 
-            mGL->DrawRectHelper()->DrawRects(0, 1, rects);
+            mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
+
+            mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.vertCoords().Elements());
+            mGL->fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, rects.texCoords().Elements());
+
+            mGL->fEnableVertexAttribArray(0);
+            mGL->fEnableVertexAttribArray(1);
+
+            mGL->fDrawArrays(LOCAL_GL_TRIANGLES, 0, rects.elements());
+
+            mGL->fDisableVertexAttribArray(0);
+            mGL->fDisableVertexAttribArray(1);
+
         } while (aSrc->NextTile());
     } while (aDst->NextTile());
 
+    mGL->fVertexAttribPointer(0, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, nullptr);
+    mGL->fVertexAttribPointer(1, 2, LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0, nullptr);
+
     // unbind the previous texture from the framebuffer
     SetBlitFramebufferForDestTexture(0);
 
     mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, savedFb);
 }
 
 void
 GLBlitTextureImageHelper::SetBlitFramebufferForDestTexture(GLuint aTexture)
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -8,17 +8,16 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 
 #include "GLContext.h"
 #include "GLBlitHelper.h"
 #include "GLBlitTextureImageHelper.h"
 #include "GLReadTexImageHelper.h"
-#include "GLDrawRectHelper.h"
 
 #include "gfxCrashReporterUtils.h"
 #include "gfxUtils.h"
 #include "GLContextProvider.h"
 #include "GLTextureImage.h"
 #include "nsPrintfCString.h"
 #include "nsThreadUtils.h"
 #include "prenv.h"
@@ -1681,17 +1680,16 @@ GLContext::MarkDestroyed()
         return;
 
     if (MakeCurrent()) {
         DestroyScreenBuffer();
 
         mBlitHelper = nullptr;
         mBlitTextureImageHelper = nullptr;
         mReadTexImageHelper = nullptr;
-        mDrawRectHelper = nullptr;
 
         mTexGarbageBin->GLContextTeardown();
     } else {
         NS_WARNING("MakeCurrent() failed during MarkDestroyed! Skipping GL object teardown.");
     }
 
     mSymbols.Zero();
 }
@@ -2007,26 +2005,16 @@ GLContext::ReadTexImageHelper()
 {
     if (!mReadTexImageHelper) {
         mReadTexImageHelper = new GLReadTexImageHelper(this);
     }
 
     return mReadTexImageHelper;
 }
 
-GLDrawRectHelper*
-GLContext::DrawRectHelper()
-{
-    if (!mDrawRectHelper) {
-        mDrawRectHelper = new GLDrawRectHelper(this);
-    }
-
-    return mDrawRectHelper;
-}
-
 bool
 DoesStringMatch(const char* aString, const char *aWantedString)
 {
     if (!aString || !aWantedString)
         return false;
 
     const char *occurrence = strstr(aString, aWantedString);
 
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -66,17 +66,16 @@ namespace mozilla {
         class GLContext;
         class GLLibraryEGL;
         class GLScreenBuffer;
         class TextureGarbageBin;
         class GLBlitHelper;
         class GLBlitTextureImageHelper;
         class GLReadTexImageHelper;
         class SharedSurface_GL;
-        class GLDrawRectHelper;
     }
 
     namespace layers {
         class ColorTextureLayerProgram;
     }
 }
 
 namespace mozilla {
@@ -2721,23 +2720,21 @@ protected:
     // Store the current context when binding to thread local
     // storage to support DebugMode on an arbitrary thread.
     static unsigned sCurrentGLContextTLS;
 #endif
 
     ScopedDeletePtr<GLBlitHelper> mBlitHelper;
     ScopedDeletePtr<GLBlitTextureImageHelper> mBlitTextureImageHelper;
     ScopedDeletePtr<GLReadTexImageHelper> mReadTexImageHelper;
-    ScopedDeletePtr<GLDrawRectHelper> mDrawRectHelper;
 
 public:
     GLBlitHelper* BlitHelper();
     GLBlitTextureImageHelper* BlitTextureImageHelper();
     GLReadTexImageHelper* ReadTexImageHelper();
-    GLDrawRectHelper* DrawRectHelper();
 
     // Assumes shares are created by all sharing with the same global context.
     bool SharesWith(const GLContext* other) const {
         MOZ_ASSERT(!this->mSharedContext || !this->mSharedContext->mSharedContext);
         MOZ_ASSERT(!other->mSharedContext || !other->mSharedContext->mSharedContext);
         MOZ_ASSERT(!this->mSharedContext ||
                    !other->mSharedContext ||
                    this->mSharedContext == other->mSharedContext);
deleted file mode 100644
--- a/gfx/gl/GLDrawRectHelper.cpp
+++ /dev/null
@@ -1,122 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=8 sts=4 et sw=4 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 "GLDrawRectHelper.h"
-#include "GLContext.h"
-#include "DecomposeIntoNoRepeatTriangles.h"
-
-namespace mozilla {
-namespace gl {
-
-static GLfloat quad[] = {
-    /* First quad vertices */
-    0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-    /* Then quad texcoords */
-    0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
-};
-
-#define BUFFER_OFFSET(i) ((char *)nullptr + (i))
-
-GLDrawRectHelper::GLDrawRectHelper(GLContext *aGL)
-    : mGL(aGL)
-{
-    mGL->fGenBuffers(1, &mQuadVBO);
-    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
-
-    mGL->fBufferData(LOCAL_GL_ARRAY_BUFFER, sizeof(quad), quad, LOCAL_GL_STATIC_DRAW);
-    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-}
-
-GLDrawRectHelper::~GLDrawRectHelper()
-{
-    mGL->fDeleteBuffers(1, &mQuadVBO);
-}
-
-void
-GLDrawRectHelper::DrawRect(GLuint aVertAttribIndex,
-                           GLuint aTexCoordAttribIndex)
-{
-    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
-
-    mGL->fVertexAttribPointer(aVertAttribIndex,
-                              2, LOCAL_GL_FLOAT,
-                              LOCAL_GL_FALSE,
-                              0, BUFFER_OFFSET(0));
-    mGL->fEnableVertexAttribArray(aVertAttribIndex);
-
-    if (aTexCoordAttribIndex != GLuint(-1)) {
-        mGL->fVertexAttribPointer(aTexCoordAttribIndex,
-                                  2, LOCAL_GL_FLOAT,
-                                  LOCAL_GL_FALSE,
-                                  0, BUFFER_OFFSET(sizeof(quad)/2));
-        mGL->fEnableVertexAttribArray(aTexCoordAttribIndex);
-    }
-
-    mGL->fDrawArrays(LOCAL_GL_TRIANGLE_STRIP, 0, 4);
-
-    if (aTexCoordAttribIndex != GLuint(-1)) {
-        mGL->fDisableVertexAttribArray(aTexCoordAttribIndex);
-    }
-    mGL->fDisableVertexAttribArray(aVertAttribIndex);
-
-    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-}
-
-void
-GLDrawRectHelper::DrawRects(GLuint aVertAttribIndex,
-                            GLuint aTexCoordAttribIndex,
-                            RectTriangles& aRects)
-{
-    GLsizei bytes = aRects.vertCoords().Length() * 2 * sizeof(GLfloat);
-    GLsizei total = bytes;
-    if (aTexCoordAttribIndex != GLuint(-1)) {
-        total *= 2;
-    }
-
-    GLuint vbo;
-    mGL->fGenBuffers(1, &vbo);
-    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, vbo);
-    mGL->fBufferData(LOCAL_GL_ARRAY_BUFFER,
-                     total,
-                     nullptr,
-                     LOCAL_GL_STREAM_DRAW);
-
-    mGL->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
-                        0,
-                        bytes,
-                        aRects.vertCoords().Elements());
-    mGL->fVertexAttribPointer(aVertAttribIndex,
-                              2, LOCAL_GL_FLOAT,
-                              LOCAL_GL_FALSE,
-                              0, BUFFER_OFFSET(0));
-    mGL->fEnableVertexAttribArray(aVertAttribIndex);
-
-    if (aTexCoordAttribIndex != GLuint(-1)) {
-        mGL->fBufferSubData(LOCAL_GL_ARRAY_BUFFER,
-                            bytes,
-                            bytes,
-                            aRects.texCoords().Elements());
-        mGL->fVertexAttribPointer(aTexCoordAttribIndex,
-                                  2, LOCAL_GL_FLOAT,
-                                  LOCAL_GL_FALSE,
-                                  0, BUFFER_OFFSET(bytes));
-        mGL->fEnableVertexAttribArray(aTexCoordAttribIndex);
-    }
-
-    mGL->fDrawArrays(LOCAL_GL_TRIANGLES, 0, aRects.vertCoords().Length());
-
-    if (aTexCoordAttribIndex != GLuint(-1)) {
-        mGL->fDisableVertexAttribArray(aTexCoordAttribIndex);
-    }
-    mGL->fDisableVertexAttribArray(aVertAttribIndex);
-
-    mGL->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
-
-    mGL->fDeleteBuffers(1, &vbo);
-}
-
-}
-}
deleted file mode 100644
--- a/gfx/gl/GLDrawRectHelper.h
+++ /dev/null
@@ -1,41 +0,0 @@
-/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/* vim: set ts=8 sts=4 et sw=4 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 GLDRAWRECTHELPER_H_
-#define GLDRAWRECTHELPER_H_
-
-#include "GLContextTypes.h"
-#include "GLConsts.h"
-
-namespace mozilla {
-namespace gl {
-
-class GLContext;
-class RectTriangles;
-
-/** Helper to draw rectangles to the frame buffer. */
-class GLDrawRectHelper MOZ_FINAL
-{
-public:
-    GLDrawRectHelper(GLContext* aGL);
-    ~GLDrawRectHelper();
-
-    void DrawRect(GLuint aVertAttribIndex,
-                  GLuint aTexCoordAttribIndex);
-    void DrawRects(GLuint aVertAttribIndex,
-                   GLuint aTexCoordAttribIndex,
-                   RectTriangles& aRects);
-
-private:
-    // The GLContext is the sole owner of the GLDrawHelper.
-    GLContext* mGL;
-    GLuint mQuadVBO;
-};
-
-}
-}
-
-#endif // GLDRAWRECTHELPER_H_
--- a/gfx/gl/moz.build
+++ b/gfx/gl/moz.build
@@ -33,17 +33,16 @@ EXPORTS += [
     'GLConsts.h',
     'GLContext.h',
     'GLContextEGL.h',
     'GLContextProvider.h',
     'GLContextProviderImpl.h',
     'GLContextSymbols.h',
     'GLContextTypes.h',
     'GLDefs.h',
-    'GLDrawRectHelper.h',
     'GLLibraryEGL.h',
     'GLLibraryLoader.h',
     'GLReadTexImageHelper.h',
     'GLScreenBuffer.h',
     'GLSharedHandleHelpers.h',
     'GLTextureImage.h',
     'GLTypes.h',
     'GLUploadHelpers.h',
@@ -119,17 +118,16 @@ UNIFIED_SOURCES += [
     'DecomposeIntoNoRepeatTriangles.cpp',
     'GfxTexturesReporter.cpp',
     'GLBlitHelper.cpp',
     'GLBlitTextureImageHelper.cpp',
     'GLContext.cpp',
     'GLContextFeatures.cpp',
     'GLContextTypes.cpp',
     'GLDebugUtils.cpp',
-    'GLDrawRectHelper.cpp',
     'GLLibraryEGL.cpp',
     'GLLibraryLoader.cpp',
     'GLReadTexImageHelper.cpp',
     'GLScreenBuffer.cpp',
     'GLSharedHandleHelpers.cpp',
     'GLTextureImage.cpp',
     'GLUploadHelpers.cpp',
     'ScopedGLHelpers.cpp',
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -93,17 +93,17 @@ DrawQuads(GLContext *aGLContext,
 {
   NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
   GLuint vertAttribIndex =
     aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
   GLuint texCoordAttribIndex =
     aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
   bool texCoords = (texCoordAttribIndex != GLuint(-1));
 
-  GLsizei bytes = aRects.vertCoords().Length() * 2 * sizeof(GLfloat);
+  GLsizei bytes = aRects.elements() * 2 * sizeof(GLfloat);
 
   GLsizei total = bytes;
   if (texCoords) {
     total *= 2;
   }
 
   aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER,
                           aVBOs.Allocate(aGLContext));
@@ -131,17 +131,17 @@ DrawQuads(GLContext *aGLContext,
     aGLContext->fVertexAttribPointer(texCoordAttribIndex,
                                      2, LOCAL_GL_FLOAT,
                                      LOCAL_GL_FALSE,
                                      0, BUFFER_OFFSET(bytes));
   } else {
     aGLContext->fDisableVertexAttribArray(texCoordAttribIndex);
   }
 
-  aGLContext->fDrawArrays(aMode, 0, aRects.vertCoords().Length());
+  aGLContext->fDrawArrays(aMode, 0, aRects.elements());
 
   aGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 }
 
 CompositorOGL::CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth,
                              int aSurfaceHeight, bool aUseExternalSurfaceSize)
   : mWidget(aWidget)
   , mWidgetSize(-1, -1)
@@ -367,16 +367,18 @@ CompositorOGL::Initialize()
   mGLContext->fGenBuffers(1, &mQuadVBO);
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
 
   GLfloat vertices[] = {
     /* First quad vertices */
     0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
     /* Then quad texcoords */
     0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f,
+    /* Then flipped quad texcoords */
+    0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f,
   };
   mGLContext->fBufferData(LOCAL_GL_ARRAY_BUFFER, sizeof(vertices), vertices, LOCAL_GL_STATIC_DRAW);
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
 
   nsCOMPtr<nsIConsoleService>
     console(do_GetService(NS_CONSOLESERVICE_CONTRACTID));
 
   if (console) {
@@ -472,17 +474,17 @@ CompositorOGL::BindAndDrawQuadWithTextur
                                    rects, flipped);
   }
 
   gfx3DMatrix textureTransform;
   if (rects.isSimpleQuad(textureTransform)) {
     Matrix4x4 transform;
     ToMatrix4x4(aTextureTransform * textureTransform, transform);
     aProg->SetTextureTransform(transform);
-    BindAndDrawQuad(aProg);
+    BindAndDrawQuad(aProg, false);
   } else {
     Matrix4x4 transform;
     ToMatrix4x4(aTextureTransform, transform);
     aProg->SetTextureTransform(transform);
     DrawQuads(mGLContext, mVBOs, aProg, LOCAL_GL_TRIANGLES, rects);
   }
 }
 
@@ -981,17 +983,17 @@ CompositorOGL::DrawQuadInternal(const Re
   switch (aEffectChain.mPrimaryEffect->mType) {
     case EFFECT_SOLID_COLOR: {
       program->SetRenderColor(color);
 
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE0, maskQuadTransform);
       }
 
-      BindAndDrawQuad(program, aDrawMode);
+      BindAndDrawQuad(program, false, aDrawMode);
     }
     break;
 
   case EFFECT_RGB: {
       TexturedEffect* texturedEffect =
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       TextureSource *source = texturedEffect->mTexture;
 
@@ -1065,39 +1067,34 @@ CompositorOGL::DrawQuadInternal(const Re
   case EFFECT_RENDER_TARGET: {
       EffectRenderTarget* effectRenderTarget =
         static_cast<EffectRenderTarget*>(aEffectChain.mPrimaryEffect.get());
       RefPtr<CompositingRenderTargetOGL> surface
         = static_cast<CompositingRenderTargetOGL*>(effectRenderTarget->mRenderTarget.get());
 
       surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget);
 
-      // Drawing is always flipped, but when copying between surfaces we want to avoid
-      // this, so apply a flip here to cancel the other one out.
-      Matrix transform;
-      transform.Translate(0.0, 1.0);
-      transform.Scale(1.0f, -1.0f);
-      program->SetTextureTransform(Matrix4x4::From2D(transform));
+      program->SetTextureTransform(Matrix4x4());
       program->SetTextureUnit(0);
 
       if (maskType != MaskNone) {
         sourceMask->BindTexture(LOCAL_GL_TEXTURE1, gfx::Filter::LINEAR);
         program->SetMaskTextureUnit(1);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
 
       if (config.mFeatures & ENABLE_TEXTURE_RECT) {
         // 2DRect case, get the multiplier right for a sampler2DRect
         program->SetTexCoordMultiplier(aRect.width, aRect.height);
       }
 
       // Drawing is always flipped, but when copying between surfaces we want to avoid
       // this. Pass true for the flip parameter to introduce a second flip
       // that cancels the other one out.
-      BindAndDrawQuad(program);
+      BindAndDrawQuad(program, true);
     }
     break;
   case EFFECT_COMPONENT_ALPHA: {
       MOZ_ASSERT(gfxPrefs::ComponentAlphaEnabled());
       EffectComponentAlpha* effectComponentAlpha =
         static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
       TextureSourceOGL* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceOGL();
       TextureSourceOGL* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceOGL();
@@ -1428,44 +1425,57 @@ CompositorOGL::QuadVBOVerticesAttrib(GLu
 void
 CompositorOGL::QuadVBOTexCoordsAttrib(GLuint aAttribIndex) {
   mGLContext->fVertexAttribPointer(aAttribIndex, 2,
                                     LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
                                     (GLvoid*) QuadVBOTexCoordOffset());
 }
 
 void
+CompositorOGL::QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex) {
+  mGLContext->fVertexAttribPointer(aAttribIndex, 2,
+                                    LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
+                                    (GLvoid*) QuadVBOFlippedTexCoordOffset());
+}
+
+void
 CompositorOGL::BindAndDrawQuad(GLuint aVertAttribIndex,
                                GLuint aTexCoordAttribIndex,
+                               bool aFlipped,
                                GLuint aDrawMode)
 {
   BindQuadVBO();
   QuadVBOVerticesAttrib(aVertAttribIndex);
 
   if (aTexCoordAttribIndex != GLuint(-1)) {
-    QuadVBOTexCoordsAttrib(aTexCoordAttribIndex);
+    if (aFlipped)
+      QuadVBOFlippedTexCoordsAttrib(aTexCoordAttribIndex);
+    else
+      QuadVBOTexCoordsAttrib(aTexCoordAttribIndex);
+
     mGLContext->fEnableVertexAttribArray(aTexCoordAttribIndex);
   }
 
   mGLContext->fEnableVertexAttribArray(aVertAttribIndex);
   if (aDrawMode == LOCAL_GL_LINE_STRIP) {
     mGLContext->fDrawArrays(aDrawMode, 1, 2);
   } else {
     mGLContext->fDrawArrays(aDrawMode, 0, 4);
   }
 }
 
 void
 CompositorOGL::BindAndDrawQuad(ShaderProgramOGL *aProg,
+                               bool aFlipped,
                                GLuint aDrawMode)
 {
   NS_ASSERTION(aProg->HasInitialized(), "Shader program not correctly initialized");
   BindAndDrawQuad(aProg->AttribLocation(ShaderProgramOGL::VertexCoordAttrib),
                   aProg->AttribLocation(ShaderProgramOGL::TexCoordAttrib),
-                  aDrawMode);
+                  aFlipped, aDrawMode);
 }
 
 GLuint
 CompositorOGL::GetTemporaryTexture(GLenum aTarget, GLenum aUnit)
 {
   if (!mTexturePool) {
 #ifdef MOZ_WIDGET_GONK
     mTexturePool = new PerFrameTexturePoolOGL(gl());
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -306,20 +306,19 @@ private:
   GLenum mFBOTextureTarget;
 
   /** Currently bound render target */
   RefPtr<CompositingRenderTargetOGL> mCurrentRenderTarget;
 #ifdef DEBUG
   CompositingRenderTargetOGL* mWindowRenderTarget;
 #endif
 
-  /**
-   * VBO that has some basics in it for a textured quad, including vertex
-   * coords and texcoords.
-   */
+  /** VBO that has some basics in it for a textured quad,
+   *  including vertex coords and texcoords for both
+   *  flipped and unflipped textures */
   GLuint mQuadVBO;
 
   /**
    * When we can't use mQuadVBO, we allocate VBOs from this arena instead.
    */
   gl::VBOArena mVBOs;
 
   bool mHasBGRA;
@@ -362,24 +361,28 @@ private:
    * texture types.
    */
   void CreateFBOWithTexture(const gfx::IntRect& aRect, bool aCopyFromSource,
                             GLuint aSourceFrameBuffer,
                             GLuint *aFBO, GLuint *aTexture);
 
   GLintptr QuadVBOVertexOffset() { return 0; }
   GLintptr QuadVBOTexCoordOffset() { return sizeof(float)*4*2; }
+  GLintptr QuadVBOFlippedTexCoordOffset() { return sizeof(float)*8*2; }
 
   void BindQuadVBO();
   void QuadVBOVerticesAttrib(GLuint aAttribIndex);
   void QuadVBOTexCoordsAttrib(GLuint aAttribIndex);
+  void QuadVBOFlippedTexCoordsAttrib(GLuint aAttribIndex);
   void BindAndDrawQuad(GLuint aVertAttribIndex,
                        GLuint aTexCoordAttribIndex,
+                       bool aFlipped = false,
                        GLuint aDrawMode = LOCAL_GL_TRIANGLE_STRIP);
   void BindAndDrawQuad(ShaderProgramOGL *aProg,
+                       bool aFlipped = false,
                        GLuint aDrawMode = LOCAL_GL_TRIANGLE_STRIP);
   void BindAndDrawQuadWithTextureRect(ShaderProgramOGL *aProg,
                                       const gfx3DMatrix& aTextureTransform,
                                       const gfx::Rect& aTexCoordRect,
                                       TextureSource *aTexture);
 
   void CleanupResources();