Bug 894891 - Move texture transform from the RGBATextureLayerExternal shader into the vertex shader, and combine the two GL_TEXTURE_EXTERNAL shaders. r=jrmuziel
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 18 Jul 2013 23:05:06 -0400
changeset 139203 d220422b5e8da3bb187e5aa1f42dc86c16bc412d
parent 139202 d1902866884cd4680da80396a92f81db97e719f2
child 139204 3e969b1777a7db826491fdb887693909c77e3898
push id24980
push userryanvm@gmail.com
push dateFri, 19 Jul 2013 17:42:29 +0000
treeherdermozilla-central@0983f1a0961c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjrmuziel
bugs894891
milestone25.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 894891 - Move texture transform from the RGBATextureLayerExternal shader into the vertex shader, and combine the two GL_TEXTURE_EXTERNAL shaders. r=jrmuziel
gfx/layers/opengl/CanvasLayerOGL.cpp
gfx/layers/opengl/ColorLayerOGL.cpp
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/ContainerLayerOGL.cpp
gfx/layers/opengl/ImageLayerOGL.cpp
gfx/layers/opengl/LayerManagerOGLProgram.cpp
gfx/layers/opengl/LayerManagerOGLProgram.h
gfx/layers/opengl/LayerManagerOGLShaders.h
gfx/layers/opengl/LayerManagerOGLShaders.txt
gfx/layers/opengl/ThebesLayerOGL.cpp
widget/cocoa/nsChildView.mm
--- a/gfx/layers/opengl/CanvasLayerOGL.cpp
+++ b/gfx/layers/opengl/CanvasLayerOGL.cpp
@@ -325,16 +325,17 @@ CanvasLayerOGL::RenderLayer(int aPreviou
   program->Activate();
   if (mLayerProgram == RGBARectLayerProgramType ||
       mLayerProgram == RGBXRectLayerProgramType) {
     // This is used by IOSurface that use 0,0...w,h coordinate rather then 0,0..1,1.
     program->SetTexCoordMultiplier(mBounds.width, mBounds.height);
   }
   program->SetLayerQuadRect(drawRect);
   program->SetLayerTransform(GetEffectiveTransform());
+  program->SetTextureTransform(gfx3DMatrix());
   program->SetLayerOpacity(GetEffectiveOpacity());
   program->SetRenderOffset(aOffset);
   program->SetTextureUnit(0);
   program->LoadMask(GetMaskLayer());
 
   if (gl()->CanUploadNonPowerOfTwo()) {
     mOGLManager->BindAndDrawQuad(program, mNeedsYFlip ? true : false);
   } else {
--- a/gfx/layers/opengl/ColorLayerOGL.cpp
+++ b/gfx/layers/opengl/ColorLayerOGL.cpp
@@ -32,16 +32,17 @@ RenderColorLayer(ColorLayer* aLayer, Lay
   color.b *= opacity;
   color.a = opacity;
 
   ShaderProgramOGL *program = aManager->GetProgram(ColorLayerProgramType,
                                                    aLayer->GetMaskLayer());
   program->Activate();
   program->SetLayerQuadRect(aLayer->GetBounds());
   program->SetLayerTransform(aLayer->GetEffectiveTransform());
+  program->SetTextureTransform(gfx3DMatrix());
   program->SetRenderOffset(aOffset);
   program->SetRenderColor(color);
   program->LoadMask(aLayer->GetMaskLayer());
 
   aManager->BindAndDrawQuad(program);
 }
 
 void
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -1033,16 +1033,17 @@ CompositorOGL::DrawQuad(const Rect& aRec
     TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
     TextureSourceOGL* source = texturedEffect->mTexture->AsSourceOGL();
     // This is used by IOSurface that use 0,0...w,h coordinate rather then 0,0..1,1.
     program->SetTexCoordMultiplier(source->GetSize().width, source->GetSize().height);
   }
   program->SetLayerQuadRect(aRect);
   program->SetLayerTransform(aTransform);
+  program->SetTextureTransform(gfx3DMatrix());
   program->SetRenderOffset(aOffset.x, aOffset.y);
 
   switch (aEffectChain.mPrimaryEffect->mType) {
     case EFFECT_SOLID_COLOR: {
       EffectSolidColor* effectSolidColor =
         static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());
 
       Color color = effectSolidColor->mColor;
@@ -1080,19 +1081,18 @@ CompositorOGL::DrawQuad(const Rect& aRec
       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);
-      if (programType == RGBALayerExternalProgramType) {
-        program->SetTextureTransform(source->AsSourceOGL()->GetTextureTransform());
-      }
+  
+      program->SetTextureTransform(source->AsSourceOGL()->GetTextureTransform());
 
       mGLContext->ApplyFilterToBoundTexture(source->AsSourceOGL()->GetTextureTarget(),
                                             ThebesFilter(texturedEffect->mFilter));
 
       program->SetTextureUnit(0);
       program->SetLayerOpacity(aOpacity);
 
       AutoBindTexture bindMask;
@@ -1211,16 +1211,17 @@ CompositorOGL::DrawQuad(const Rect& aRec
         AutoBindTexture bindSourceOnBlack(sourceOnBlack, LOCAL_GL_TEXTURE0);
         AutoBindTexture bindSourceOnWhite(sourceOnWhite, LOCAL_GL_TEXTURE1);
 
         program->Activate();
         program->SetBlackTextureUnit(0);
         program->SetWhiteTextureUnit(1);
         program->SetLayerOpacity(aOpacity);
         program->SetLayerTransform(aTransform);
+        program->SetTextureTransform(gfx3DMatrix());
         program->SetRenderOffset(aOffset.x, aOffset.y);
         program->SetLayerQuadRect(aRect);
         AutoBindTexture bindMask;
         if (maskType != MaskNone) {
           bindMask.Bind(sourceMask, LOCAL_GL_TEXTURE2);
           program->SetMaskTextureUnit(2);
           program->SetMaskLayerTransform(maskQuadTransform);
         }
--- a/gfx/layers/opengl/ContainerLayerOGL.cpp
+++ b/gfx/layers/opengl/ContainerLayerOGL.cpp
@@ -317,16 +317,17 @@ ContainerRender(Container* aContainer,
         }
       }
       ShaderProgramOGL *rgb =
         aManager->GetFBOLayerProgram(maskType);
 
       rgb->Activate();
       rgb->SetLayerQuadRect(visibleRect);
       rgb->SetLayerTransform(transform);
+      rgb->SetTextureTransform(gfx3DMatrix());
       rgb->SetLayerOpacity(opacity);
       rgb->SetRenderOffset(aOffset);
       rgb->SetTextureUnit(0);
       rgb->LoadMask(aContainer->GetMaskLayer());
 
       if (rgb->GetTexCoordMultiplierUniformLocation() != -1) {
         // 2DRect case, get the multiplier right for a sampler2DRect
         rgb->SetTexCoordMultiplier(visibleRect.width, visibleRect.height);
--- a/gfx/layers/opengl/ImageLayerOGL.cpp
+++ b/gfx/layers/opengl/ImageLayerOGL.cpp
@@ -234,16 +234,17 @@ ImageLayerOGL::RenderLayer(int,
     ShaderProgramOGL *program = mOGLManager->GetProgram(YCbCrLayerProgramType,
                                                         GetMaskLayer());
 
     program->Activate();
     program->SetLayerQuadRect(nsIntRect(0, 0,
                                         yuvImage->GetSize().width,
                                         yuvImage->GetSize().height));
     program->SetLayerTransform(GetEffectiveTransform());
+    program->SetTextureTransform(gfx3DMatrix());
     program->SetLayerOpacity(GetEffectiveOpacity());
     program->SetRenderOffset(aOffset);
     program->SetYCbCrTextureUnits(0, 1, 2);
     program->LoadMask(GetMaskLayer());
 
     mOGLManager->BindAndDrawQuadWithTextureRect(program,
                                                 yuvImage->GetData()->GetPictureRect(),
                                                 nsIntSize(yuvImage->GetData()->mYSize.width,
@@ -292,16 +293,17 @@ ImageLayerOGL::RenderLayer(int,
 
     gl()->ApplyFilterToBoundTexture(mFilter);
 
     program->Activate();
     program->SetLayerQuadRect(nsIntRect(0, 0, 
                                         cairoImage->GetSize().width, 
                                         cairoImage->GetSize().height));
     program->SetLayerTransform(GetEffectiveTransform());
+    program->SetTextureTransform(gfx3DMatrix());
     program->SetLayerOpacity(GetEffectiveOpacity());
     program->SetRenderOffset(aOffset);
     program->SetTextureUnit(0);
     program->LoadMask(GetMaskLayer());
 
     mOGLManager->BindAndDrawQuad(program);
   } else if (image->GetFormat() == SHARED_TEXTURE) {
     SharedTextureImage* texImage =
@@ -319,16 +321,17 @@ ImageLayerOGL::RenderLayer(int,
     ShaderProgramOGL* program = mOGLManager->GetProgram(programType, GetMaskLayer());
 
     program->Activate();
     if (programType == RGBARectLayerProgramType) {
       // 2DRect case, get the multiplier right for a sampler2DRect
       program->SetTexCoordMultiplier(data->mSize.width, data->mSize.height);
     }
     program->SetLayerTransform(GetEffectiveTransform());
+    program->SetTextureTransform(gfx3DMatrix());
     program->SetLayerOpacity(GetEffectiveOpacity());
     program->SetRenderOffset(aOffset);
     program->SetTextureUnit(0);
     program->SetTextureTransform(handleDetails.mTextureTransform);
     program->LoadMask(GetMaskLayer());
 
     if (!texImage->GetBackendData(LAYERS_OPENGL)) {
       AllocateTextureSharedTexture(texImage, gl(), handleDetails.mTarget);
--- a/gfx/layers/opengl/LayerManagerOGLProgram.cpp
+++ b/gfx/layers/opengl/LayerManagerOGLProgram.cpp
@@ -17,16 +17,17 @@ namespace layers {
 typedef ProgramProfileOGL::Argument Argument;
 
 // helper methods for GetProfileFor
 void
 AddCommonArgs(ProgramProfileOGL& aProfile)
 {
   aProfile.mUniforms.AppendElement(Argument("uLayerTransform"));
   aProfile.mUniforms.AppendElement(Argument("uLayerQuadTransform"));
+  aProfile.mUniforms.AppendElement(Argument("uTextureTransform"));
   aProfile.mUniforms.AppendElement(Argument("uMatrixProj"));
   aProfile.mHasMatrixProj = true;
   aProfile.mUniforms.AppendElement(Argument("uRenderTargetOffset"));
   aProfile.mAttributes.AppendElement(Argument("aVertexCoord"));
 }
 void
 AddCommonTextureArgs(ProgramProfileOGL& aProfile)
 {
@@ -53,33 +54,16 @@ ProgramProfileOGL::GetProfileFor(ShaderP
     } else {
       result.mVertexShaderString = sLayerVS;
       result.mFragmentShaderString = sRGBATextureLayerFS;
     }
     AddCommonArgs(result);
     AddCommonTextureArgs(result);
     result.mTextureCount = 1;
     break;
-  case RGBALayerExternalProgramType:
-    if (aMask == Mask3d) {
-      result.mVertexShaderString = sLayerMask3DVS;
-      result.mFragmentShaderString = sRGBATextureLayerExternalMask3DFS;
-    } else if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sRGBATextureLayerExternalMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sRGBATextureLayerExternalFS;
-    }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mUniforms.AppendElement(Argument("uTextureTransform"));
-    result.mHasTextureTransform = true;
-    result.mTextureCount = 1;
-    break;
   case BGRALayerProgramType:
     if (aMask == Mask2d) {
       result.mVertexShaderString = sLayerMaskVS;
       result.mFragmentShaderString = sBGRATextureLayerMaskFS;
     } else {
       result.mVertexShaderString = sLayerVS;
       result.mFragmentShaderString = sBGRATextureLayerFS;
     }
--- a/gfx/layers/opengl/LayerManagerOGLProgram.h
+++ b/gfx/layers/opengl/LayerManagerOGLProgram.h
@@ -184,22 +184,20 @@ struct ProgramProfileOGL
   // the source code for the program's shaders
   const char *mVertexShaderString;
   const char *mFragmentShaderString;
 
   nsTArray<Argument> mUniforms;
   nsTArray<Argument> mAttributes;
   uint32_t mTextureCount;
   bool mHasMatrixProj;
-  bool mHasTextureTransform;
 private:
   ProgramProfileOGL() :
     mTextureCount(0),
-    mHasMatrixProj(false),
-    mHasTextureTransform(false) {}
+    mHasMatrixProj(false) {}
 };
 
 
 #if defined(DEBUG)
 #define CHECK_CURRENT_PROGRAM 1
 #define ASSERT_THIS_PROGRAM                                             \
   do {                                                                  \
     NS_ASSERTION(mGL->GetUserData(&sCurrentProgramKey) == this, \
@@ -310,23 +308,21 @@ public:
 
   void SetProjectionMatrix(const gfx3DMatrix& aMatrix) {
     SetMatrixUniform(mProfile.LookupUniformLocation("uMatrixProj"), aMatrix);
     mIsProjectionMatrixStale = false;
   }
 
   // sets this program's texture transform, if it uses one
   void SetTextureTransform(const gfx3DMatrix& aMatrix) {
-    if (mProfile.mHasTextureTransform)
-      SetMatrixUniform(mProfile.LookupUniformLocation("uTextureTransform"), aMatrix);
+    SetMatrixUniform(mProfile.LookupUniformLocation("uTextureTransform"), aMatrix);
   }
 
   void SetTextureTransform(const gfx::Matrix4x4& aMatrix) {
-    if (mProfile.mHasTextureTransform)
-      SetMatrixUniform(mProfile.LookupUniformLocation("uTextureTransform"), aMatrix);
+    SetMatrixUniform(mProfile.LookupUniformLocation("uTextureTransform"), aMatrix);
   }
 
   void SetRenderOffset(const nsIntPoint& aOffset) {
     float vals[4] = { float(aOffset.x), float(aOffset.y), 0.0f, 0.0f };
     SetUniform(mProfile.LookupUniformLocation("uRenderTargetOffset"), 4, vals);
   }
 
   void SetRenderOffset(float aX, float aY) {
--- a/gfx/layers/opengl/LayerManagerOGLShaders.h
+++ b/gfx/layers/opengl/LayerManagerOGLShaders.h
@@ -1,16 +1,17 @@
 /* AUTOMATICALLY GENERATED from LayerManagerOGLShaders.txt */
 /* DO NOT EDIT! */
 
 static const char sLayerVS[] = "/* sLayerVS */\n\
 /* Vertex Shader */\n\
 uniform mat4 uMatrixProj;\n\
 uniform mat4 uLayerQuadTransform;\n\
 uniform mat4 uLayerTransform;\n\
+uniform mat4 uTextureTransform;\n\
 uniform vec4 uRenderTargetOffset;\n\
 attribute vec4 aVertexCoord;\n\
 attribute vec2 aTexCoord;\n\
 #ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
 varying mediump vec2 vTexCoord;\n\
 #else\n\
 varying vec2 vTexCoord;\n\
 #endif\n\
@@ -21,26 +22,27 @@ vec4 finalPosition = aVertexCoord;\n\
 finalPosition = uLayerQuadTransform * finalPosition;\n\
 finalPosition = uLayerTransform * finalPosition;\n\
 finalPosition.xyz /= finalPosition.w;\n\
 \n\
 \n\
 finalPosition = finalPosition - uRenderTargetOffset;\n\
 finalPosition.xyz *= finalPosition.w;\n\
 finalPosition = uMatrixProj * finalPosition;\n\
-vTexCoord = aTexCoord;\n\
+vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;\n\
 gl_Position = finalPosition;\n\
 }\n\
 ";
 
 static const char sLayerMaskVS[] = "/* sLayerMaskVS */\n\
 /* Vertex Shader */\n\
 uniform mat4 uMatrixProj;\n\
 uniform mat4 uLayerQuadTransform;\n\
 uniform mat4 uLayerTransform;\n\
+uniform mat4 uTextureTransform;\n\
 uniform vec4 uRenderTargetOffset;\n\
 attribute vec4 aVertexCoord;\n\
 attribute vec2 aTexCoord;\n\
 #ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
 varying mediump vec2 vTexCoord;\n\
 #else\n\
 varying vec2 vTexCoord;\n\
 #endif\n\
@@ -54,26 +56,27 @@ vec4 finalPosition = aVertexCoord;\n\
 finalPosition = uLayerQuadTransform * finalPosition;\n\
 finalPosition = uLayerTransform * finalPosition;\n\
 finalPosition.xyz /= finalPosition.w;\n\
 vMaskCoord = (uMaskQuadTransform * finalPosition).xy;\n\
 \n\
 finalPosition = finalPosition - uRenderTargetOffset;\n\
 finalPosition.xyz *= finalPosition.w;\n\
 finalPosition = uMatrixProj * finalPosition;\n\
-vTexCoord = aTexCoord;\n\
+vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;\n\
 gl_Position = finalPosition;\n\
 }\n\
 ";
 
 static const char sLayerMask3DVS[] = "/* sLayerMask3DVS */\n\
 /* Vertex Shader */\n\
 uniform mat4 uMatrixProj;\n\
 uniform mat4 uLayerQuadTransform;\n\
 uniform mat4 uLayerTransform;\n\
+uniform mat4 uTextureTransform;\n\
 uniform vec4 uRenderTargetOffset;\n\
 attribute vec4 aVertexCoord;\n\
 attribute vec2 aTexCoord;\n\
 #ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
 varying mediump vec2 vTexCoord;\n\
 #else\n\
 varying vec2 vTexCoord;\n\
 #endif\n\
@@ -90,17 +93,17 @@ finalPosition.xyz /= finalPosition.w;\n\
 vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;\n\
 // correct for perspective correct interpolation, see comment in D3D10 shader\n\
 vMaskCoord.z = 1.0;\n\
 vMaskCoord *= finalPosition.w;\n\
 \n\
 finalPosition = finalPosition - uRenderTargetOffset;\n\
 finalPosition.xyz *= finalPosition.w;\n\
 finalPosition = uMatrixProj * finalPosition;\n\
-vTexCoord = aTexCoord;\n\
+vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;\n\
 gl_Position = finalPosition;\n\
 }\n\
 ";
 
 static const char sSolidColorLayerFS[] = "/* sSolidColorLayerFS */\n\
 #define NO_LAYER_OPACITY 1\n\
 /* Fragment Shader */\n\
 #ifdef GL_ES\n\
@@ -247,116 +250,16 @@ void main()\n\
 {\n\
 vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
 float mask = texture2D(uMaskTexture, maskCoords).r;\n\
 \n\
 gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
 }\n\
 ";
 
-static const char sRGBATextureLayerExternalFS[] = "/* sRGBATextureLayerExternalFS */\n\
-#extension GL_OES_EGL_image_external : require\n\
-#define MEDIUMP_SHADER 1\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-#ifdef MEDIUMP_SHADER\n\
-precision mediump float;\n\
-#else\n\
-precision lowp float;\n\
-#endif\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-uniform samplerExternalOES uTexture;\n\
-uniform mat4 uTextureTransform;\n\
-void main()\n\
-{\n\
-float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerExternalMaskFS[] = "/* sRGBATextureLayerExternalMaskFS */\n\
-#extension GL_OES_EGL_image_external : require\n\
-#define MEDIUMP_SHADER 1\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-#ifdef MEDIUMP_SHADER\n\
-precision mediump float;\n\
-#else\n\
-precision lowp float;\n\
-#endif\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform samplerExternalOES uTexture;\n\
-uniform mat4 uTextureTransform;\n\
-void main()\n\
-{\n\
-float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerExternalMask3DFS[] = "/* sRGBATextureLayerExternalMask3DFS */\n\
-#extension GL_OES_EGL_image_external : require\n\
-#define MEDIUMP_SHADER 1\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-#ifdef MEDIUMP_SHADER\n\
-precision mediump float;\n\
-#else\n\
-precision lowp float;\n\
-#endif\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform float uLayerOpacity;\n\
-#endif\n\
-#ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range\n\
-varying mediump vec2 vTexCoord;\n\
-#else\n\
-varying vec2 vTexCoord;\n\
-#endif\n\
-\n\
-varying vec3 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform samplerExternalOES uTexture;\n\
-uniform mat4 uTextureTransform;\n\
-void main()\n\
-{\n\
-vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
-float mask = texture2D(uMaskTexture, maskCoords).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;\n\
-}\n\
-";
-
 static const char sRGBARectTextureLayerFS[] = "/* sRGBARectTextureLayerFS */\n\
 #extension GL_ARB_texture_rectangle : enable\n\
 /* Fragment Shader */\n\
 #ifdef GL_ES\n\
 #ifdef MEDIUMP_SHADER\n\
 precision mediump float;\n\
 #else\n\
 precision lowp float;\n\
--- a/gfx/layers/opengl/LayerManagerOGLShaders.txt
+++ b/gfx/layers/opengl/LayerManagerOGLShaders.txt
@@ -57,16 +57,17 @@
 // 
 
 @define VERTEX_SHADER_HEADER<>
 /* Vertex Shader */
 
 uniform mat4 uMatrixProj;
 uniform mat4 uLayerQuadTransform;
 uniform mat4 uLayerTransform;
+uniform mat4 uTextureTransform;
 uniform vec4 uRenderTargetOffset;
 
 attribute vec4 aVertexCoord;
 attribute vec2 aTexCoord;
 
 #ifdef GL_ES // for tiling, texcoord can be greater than the lowfp range
 varying mediump vec2 vTexCoord;
 #else
@@ -118,17 +119,17 @@ void main()
   finalPosition.xyz /= finalPosition.w;
 
 $VERTEX_MASK_STUFF<mask>$
 
   finalPosition = finalPosition - uRenderTargetOffset;
   finalPosition.xyz *= finalPosition.w;
   finalPosition = uMatrixProj * finalPosition;
 
-  vTexCoord = aTexCoord;
+  vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;
   gl_Position = finalPosition;
 }
 @end
 
 
 /*
  * Fragment shaders
  */
@@ -210,34 +211,16 @@ uniform sampler2D uTexture;
 
 void main()
 {
 $FRAGMENT_CALC_MASK<mask>$
   gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;
 }
 @end
 
-// Single texture in RGBA format for use with GL_TEXTURE_EXTERNAL_OES
-@shader sRGBATextureLayerExternal<mask:,Mask,Mask3D>FS
-#extension GL_OES_EGL_image_external : require
-
-#define MEDIUMP_SHADER 1
-$LAYER_FRAGMENT<mask>$
-
-uniform samplerExternalOES uTexture;
-uniform mat4 uTextureTransform;
-
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = texture2D(uTexture, (uTextureTransform * vec4(vTexCoord.x, vTexCoord.y, 0.0, 1.0)).xy) * uLayerOpacity * mask;
-}
-@end
-
-
 // Single texture in RGBA format, but with a Rect texture.
 // Container layer needs this to render a FBO group.
 @shader sRGBARectTextureLayer<mask:,Mask,Mask3D>FS
 #extension GL_ARB_texture_rectangle : enable
 
 $LAYER_FRAGMENT<mask>$
 
 /* This should not be used on GL ES */
--- a/gfx/layers/opengl/ThebesLayerOGL.cpp
+++ b/gfx/layers/opengl/ThebesLayerOGL.cpp
@@ -176,16 +176,17 @@ ThebesLayerBufferOGL::RenderTo(const nsI
 
       basicProgram->Activate();
       basicProgram->SetTextureUnit(0);
       program = basicProgram;
     }
 
     program->SetLayerOpacity(mLayer->GetEffectiveOpacity());
     program->SetLayerTransform(mLayer->GetEffectiveTransform());
+    program->SetTextureTransform(gfx3DMatrix());
     program->SetRenderOffset(aOffset);
     program->LoadMask(mLayer->GetMaskLayer());
 
     const nsIntRegion& visibleRegion = mLayer->GetEffectiveVisibleRegion();
     nsIntRegion tmpRegion;
     const nsIntRegion* renderRegion;
     if (aFlags & PAINT_WILL_RESAMPLE) {
       // If we're resampling, then the texture image will contain exactly the
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -2581,16 +2581,17 @@ RectTextureImage::Draw(GLManager* aManag
 {
   ShaderProgramOGL* program = aManager->GetProgram(RGBARectLayerProgramType);
 
   aManager->gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, mTexture);
 
   program->Activate();
   program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mUsedSize));
   program->SetLayerTransform(aTransform * gfx3DMatrix::Translation(aLocation.x, aLocation.y, 0));
+  program->SetTextureTransform(gfx3DMatrix());
   program->SetLayerOpacity(1.0);
   program->SetRenderOffset(nsIntPoint(0, 0));
   program->SetTexCoordMultiplier(mUsedSize.width, mUsedSize.height);
   program->SetTextureUnit(0);
 
   aManager->BindAndDrawQuad(program);
 
   aManager->gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);