Bug 926128 - Use a single configurable shader in OpenGL layers backend. r=vlad, r=nical, r=gal
authorMorris Tseng <mtseng@mozilla.com>
Thu, 07 Nov 2013 22:22:05 -0800
changeset 169667 c0e256be477547426276d2a9d078e7a4c6c1729b
parent 169666 9db0ee6f95e19c773e3eabad288bbb6e9efc9260
child 169668 6f1e6f7d3041bc1da91f1814497a71366a9bdbc3
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersvlad, nical, gal
bugs926128
milestone30.0a1
Bug 926128 - Use a single configurable shader in OpenGL layers backend. r=vlad, r=nical, r=gal
gfx/gl/GLReadTexImageHelper.cpp
gfx/layers/CompositorTypes.h
gfx/layers/Effects.h
gfx/layers/LayerScope.cpp
gfx/layers/basic/BasicCompositor.cpp
gfx/layers/d3d11/CompositorD3D11.cpp
gfx/layers/d3d11/CompositorD3D11.h
gfx/layers/d3d9/CompositorD3D9.cpp
gfx/layers/moz.build
gfx/layers/opengl/CompositorOGL.cpp
gfx/layers/opengl/CompositorOGL.h
gfx/layers/opengl/GLManager.cpp
gfx/layers/opengl/GLManager.h
gfx/layers/opengl/OGLShaderProgram.cpp
gfx/layers/opengl/OGLShaderProgram.h
gfx/layers/opengl/OGLShaders.h
gfx/layers/opengl/OGLShaders.txt
gfx/layers/opengl/TextureHostOGL.h
gfx/layers/opengl/genshaders.py
gfx/layers/opengl/genshaders.sh
widget/cocoa/nsChildView.mm
--- a/gfx/gl/GLReadTexImageHelper.cpp
+++ b/gfx/gl/GLReadTexImageHelper.cpp
@@ -77,23 +77,22 @@ readTextureImageFS_TEXTURE_RECTANGLE[] =
     "#ifdef GL_ES\n"
     "precision mediump float;\n"
     "#endif\n"
     "varying vec2 vTexCoord;\n"
     "uniform sampler2DRect uTexture;\n"
     "void main() { gl_FragColor = texture2DRect(uTexture, vTexCoord).bgra; }";
 
 GLuint
-GLReadTexImageHelper::TextureImageProgramFor(GLenum aTextureTarget, int aShader) {
+GLReadTexImageHelper::TextureImageProgramFor(GLenum aTextureTarget, int aConfig) {
     int variant = 0;
     const GLchar* readTextureImageFS = nullptr;
     if (aTextureTarget == LOCAL_GL_TEXTURE_2D)
     {
-        if (aShader == layers::BGRALayerProgramType ||
-            aShader == layers::BGRXLayerProgramType)
+        if (aConfig & mozilla::layers::ENABLE_TEXTURE_RB_SWAP)
         {   // Need to swizzle R/B.
             readTextureImageFS = readTextureImageFS_TEXTURE_2D_BGRA;
             variant = 1;
         }
         else
         {
             readTextureImageFS = readTextureImageFS_TEXTURE_2D;
             variant = 0;
@@ -519,22 +518,19 @@ ReadScreenIntoImageSurface(GLContext* gl
         isurf = nullptr;                                                    \
         break;                                                              \
     }
 
 already_AddRefed<gfxImageSurface>
 GLReadTexImageHelper::ReadTexImage(GLuint aTextureId,
                                    GLenum aTextureTarget,
                                    const gfxIntSize& aSize,
-           /* ShaderProgramType */ int aShaderProgram,
+    /* ShaderConfigOGL.mFeature */ int aConfig,
                                    bool aYInvert)
 {
-    // Check aShaderProgram is in bounds for a layers::ShaderProgramType
-    MOZ_ASSERT(0 <= aShaderProgram && aShaderProgram < layers::NumProgramTypes);
-
     MOZ_ASSERT(aTextureTarget == LOCAL_GL_TEXTURE_2D ||
                aTextureTarget == LOCAL_GL_TEXTURE_EXTERNAL ||
                aTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB);
 
     mGL->MakeCurrent();
 
     /* Allocate resulting image surface */
     nsRefPtr<gfxImageSurface> isurf = new gfxImageSurface(aSize, gfxImageFormat::ARGB32);
@@ -585,18 +581,17 @@ GLReadTexImageHelper::ReadTexImage(GLuin
         mGL->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, fb);
         mGL->fFramebufferRenderbuffer(LOCAL_GL_FRAMEBUFFER, LOCAL_GL_COLOR_ATTACHMENT0,
                                       LOCAL_GL_RENDERBUFFER, rb);
         CLEANUP_IF_GLERROR_OCCURRED("when binding and creating framebuffer");
 
         MOZ_ASSERT(mGL->fCheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER) == LOCAL_GL_FRAMEBUFFER_COMPLETE);
 
         /* Setup vertex and fragment shader */
-        layers::ShaderProgramType shaderProgram = (layers::ShaderProgramType) aShaderProgram;
-        GLuint program = TextureImageProgramFor(aTextureTarget, shaderProgram);
+        GLuint program = TextureImageProgramFor(aTextureTarget, aConfig);
         MOZ_ASSERT(program);
 
         mGL->fUseProgram(program);
         CLEANUP_IF_GLERROR_OCCURRED("when using program");
         mGL->fUniform1i(mGL->fGetUniformLocation(program, "uTexture"), 0);
         CLEANUP_IF_GLERROR_OCCURRED("when setting uniform location");
 
         /* Setup quad geometry */
--- a/gfx/layers/CompositorTypes.h
+++ b/gfx/layers/CompositorTypes.h
@@ -119,20 +119,17 @@ const DiagnosticFlags DIAGNOSTIC_REGION_
 
 /**
  * See gfx/layers/Effects.h
  */
 enum EffectTypes
 {
   EFFECT_MASK,
   EFFECT_MAX_SECONDARY, // sentinel for the count of secondary effect types
-  EFFECT_BGRX,
-  EFFECT_RGBX,
-  EFFECT_BGRA,
-  EFFECT_RGBA,
+  EFFECT_RGB,
   EFFECT_YCBCR,
   EFFECT_COMPONENT_ALPHA,
   EFFECT_SOLID_COLOR,
   EFFECT_RENDER_TARGET,
   EFFECT_MAX  //sentinel for the count of all effect types
 };
 
 /**
--- a/gfx/layers/Effects.h
+++ b/gfx/layers/Effects.h
@@ -100,59 +100,26 @@ struct EffectRenderTarget : public Textu
   {}
 
   virtual const char* Name() { return "EffectRenderTarget"; }
   virtual void PrintInfo(nsACString& aTo, const char* aPrefix);
 
   RefPtr<CompositingRenderTarget> mRenderTarget;
 };
 
-struct EffectBGRX : public TexturedEffect
+struct EffectRGB : public TexturedEffect
 {
-  EffectBGRX(TextureSource *aBGRXTexture,
-             bool aPremultiplied,
-             gfx::Filter aFilter,
-             bool aFlipped = false)
-    : TexturedEffect(EFFECT_BGRX, aBGRXTexture, aPremultiplied, aFilter)
-  {}
-
-  virtual const char* Name() { return "EffectBGRX"; }
-};
-
-struct EffectRGBX : public TexturedEffect
-{
-  EffectRGBX(TextureSource *aRGBXTexture,
-             bool aPremultiplied,
-             gfx::Filter aFilter)
-    : TexturedEffect(EFFECT_RGBX, aRGBXTexture, aPremultiplied, aFilter)
+  EffectRGB(TextureSource *aTexture,
+            bool aPremultiplied,
+            gfx::Filter aFilter,
+            bool aFlipped = false)
+    : TexturedEffect(EFFECT_RGB, aTexture, aPremultiplied, aFilter)
   {}
 
-  virtual const char* Name() { return "EffectRGBX"; }
-};
-
-struct EffectBGRA : public TexturedEffect
-{
-  EffectBGRA(TextureSource *aBGRATexture,
-             bool aPremultiplied,
-             gfx::Filter aFilter)
-    : TexturedEffect(EFFECT_BGRA, aBGRATexture, aPremultiplied, aFilter)
-  {}
-
-  virtual const char* Name() { return "EffectBGRA"; }
-};
-
-struct EffectRGBA : public TexturedEffect
-{
-  EffectRGBA(TextureSource *aRGBATexture,
-             bool aPremultiplied,
-             gfx::Filter aFilter)
-    : TexturedEffect(EFFECT_RGBA, aRGBATexture, aPremultiplied, aFilter)
-  {}
-
-  virtual const char* Name() { return "EffectRGBA"; }
+  virtual const char* Name() { return "EffectRGB"; }
 };
 
 struct EffectYCbCr : public TexturedEffect
 {
   EffectYCbCr(TextureSource *aSource, gfx::Filter aFilter)
     : TexturedEffect(EFFECT_YCBCR, aSource, false, aFilter)
   {}
 
@@ -210,29 +177,21 @@ inline TemporaryRef<TexturedEffect>
 CreateTexturedEffect(gfx::SurfaceFormat aFormat,
                      TextureSource* aSource,
                      const gfx::Filter& aFilter)
 {
   MOZ_ASSERT(aSource);
   RefPtr<TexturedEffect> result;
   switch (aFormat) {
   case gfx::SurfaceFormat::B8G8R8A8:
-    result = new EffectBGRA(aSource, true, aFilter);
-    break;
   case gfx::SurfaceFormat::B8G8R8X8:
-    result = new EffectBGRX(aSource, true, aFilter);
-    break;
   case gfx::SurfaceFormat::R8G8B8X8:
-    result = new EffectRGBX(aSource, true, aFilter);
-    break;
   case gfx::SurfaceFormat::R5G6B5:
-    result = new EffectRGBX(aSource, true, aFilter);
-    break;
   case gfx::SurfaceFormat::R8G8B8A8:
-    result = new EffectRGBA(aSource, true, aFilter);
+    result = new EffectRGB(aSource, true, aFilter);
     break;
   case gfx::SurfaceFormat::YUV:
     result = new EffectYCbCr(aSource, aFilter);
     break;
   default:
     NS_WARNING("unhandled program type");
     break;
   }
--- a/gfx/layers/LayerScope.cpp
+++ b/gfx/layers/LayerScope.cpp
@@ -696,19 +696,19 @@ SendColor(void* aLayerRef, const gfxRGBA
 
 static void
 SendTextureSource(GLContext* aGLContext,
                   void* aLayerRef,
                   TextureSourceOGL* aSource,
                   bool aFlipY)
 {
     GLenum textureTarget = aSource->GetTextureTarget();
-    int shaderProgram =
-        (int) ShaderProgramFromTargetAndFormat(textureTarget,
-                                               aSource->GetFormat());
+    ShaderConfigOGL config = ShaderConfigFromTargetAndFormat(textureTarget,
+                                                             aSource->GetFormat());
+    int shaderConfig = config.mFeatures;
 
     aSource->BindTexture(LOCAL_GL_TEXTURE0);
 
     GLuint textureId = 0;
     // This is horrid hack. It assumes that aGLContext matches the context
     // aSource has bound to.
     if (textureTarget == LOCAL_GL_TEXTURE_2D) {
         aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &textureId);
@@ -720,17 +720,17 @@ SendTextureSource(GLContext* aGLContext,
 
     gfx::IntSize size = aSource->GetSize();
 
     // By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding
     // texture correctly. textureId is used for tracking in DebugGLTextureData.
     nsRefPtr<gfxImageSurface> img =
         aGLContext->ReadTexImageHelper()->ReadTexImage(0, textureTarget,
                                                        gfxIntSize(size.width, size.height),
-                                                       shaderProgram, aFlipY);
+                                                       shaderConfig, aFlipY);
 
     gLayerScopeWebSocketManager->AppendDebugData(
         new DebugGLTextureData(aGLContext, aLayerRef, textureTarget,
                                textureId, img));
 }
 
 static void
 SendTexturedEffect(GLContext* aGLContext,
@@ -770,20 +770,17 @@ LayerScope::SendEffectChain(GLContext* a
                             const EffectChain& aEffectChain,
                             int aWidth, int aHeight)
 {
     if (!CheckSender())
         return;
 
     const Effect* primaryEffect = aEffectChain.mPrimaryEffect;
     switch (primaryEffect->mType) {
-    case EFFECT_BGRX:
-    case EFFECT_RGBX:
-    case EFFECT_BGRA:
-    case EFFECT_RGBA:
+    case EFFECT_RGB:
     {
         const TexturedEffect* texturedEffect =
             static_cast<const TexturedEffect*>(primaryEffect);
         SendTexturedEffect(aGLContext, aEffectChain.mLayerRef, texturedEffect);
     }
     break;
     case EFFECT_YCBCR:
     {
--- a/gfx/layers/basic/BasicCompositor.cpp
+++ b/gfx/layers/basic/BasicCompositor.cpp
@@ -477,20 +477,17 @@ BasicCompositor::DrawQuad(const gfx::Rec
       EffectSolidColor* effectSolidColor =
         static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());
 
       dest->FillRect(aRect,
                      ColorPattern(effectSolidColor->mColor),
                      DrawOptions(aOpacity));
       break;
     }
-    case EFFECT_BGRA:
-    case EFFECT_BGRX:
-    case EFFECT_RGBA:
-    case EFFECT_RGBX: {
+    case EFFECT_RGB: {
       TexturedEffect* texturedEffect =
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
       TextureSourceBasic* source = texturedEffect->mTexture->AsSourceBasic();
 
       DrawSurfaceWithTextureCoords(dest, aRect,
                                    source->GetSurface(),
                                    texturedEffect->mTextureCoords,
                                    texturedEffect->mFilter,
--- a/gfx/layers/d3d11/CompositorD3D11.cpp
+++ b/gfx/layers/d3d11/CompositorD3D11.cpp
@@ -456,28 +456,29 @@ CompositorD3D11::SetRenderTarget(Composi
     static_cast<CompositingRenderTargetD3D11*>(aRenderTarget);
   ID3D11RenderTargetView* view = newRT->mRTView;
   mCurrentRT = newRT;
   mContext->OMSetRenderTargets(1, &view, nullptr);
   PrepareViewport(newRT->GetSize(), gfx::Matrix());
 }
 
 void
-CompositorD3D11::SetPSForEffect(Effect* aEffect, MaskType aMaskType)
+CompositorD3D11::SetPSForEffect(Effect* aEffect, MaskType aMaskType, gfx::SurfaceFormat aFormat)
 {
   switch (aEffect->mType) {
   case EFFECT_SOLID_COLOR:
     mContext->PSSetShader(mAttachments->mSolidColorShader[aMaskType], nullptr, 0);
     return;
-  case EFFECT_BGRA:
   case EFFECT_RENDER_TARGET:
     mContext->PSSetShader(mAttachments->mRGBAShader[aMaskType], nullptr, 0);
     return;
-  case EFFECT_BGRX:
-    mContext->PSSetShader(mAttachments->mRGBShader[aMaskType], nullptr, 0);
+  case EFFECT_RGB:
+    mContext->PSSetShader((aFormat == SurfaceFormat::B8G8R8A8 || aFormat == SurfaceFormat::R8G8B8A8)
+                          ? mAttachments->mRGBAShader[aMaskType]
+                          : mAttachments->mRGBShader[aMaskType], nullptr, 0);
     return;
   case EFFECT_YCBCR:
     mContext->PSSetShader(mAttachments->mYCbCrShader[aMaskType], nullptr, 0);
     return;
   case EFFECT_COMPONENT_ALPHA:
     mContext->PSSetShader(mAttachments->mComponentAlphaShader[aMaskType], nullptr, 0);
     return;
   default:
@@ -505,17 +506,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
   bool restoreBlendMode = false;
 
   MaskType maskType = MaskNone;
 
   if (aEffectChain.mSecondaryEffects[EFFECT_MASK]) {
     if (aTransform.Is2D()) {
       maskType = Mask2d;
     } else {
-      MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EFFECT_BGRA);
+      MOZ_ASSERT(aEffectChain.mPrimaryEffect->mType == EFFECT_RGB);
       maskType = Mask3d;
     }
 
     EffectMask* maskEffect =
       static_cast<EffectMask*>(aEffectChain.mSecondaryEffects[EFFECT_MASK].get());
     TextureSourceD3D11* source = maskEffect->mMaskTexture->AsSourceD3D11();
 
     if (!source) {
@@ -541,35 +542,35 @@ CompositorD3D11::DrawQuad(const gfx::Rec
   scissor.left = aClipRect.x;
   scissor.right = aClipRect.XMost();
   scissor.top = aClipRect.y;
   scissor.bottom = aClipRect.YMost();
   mContext->RSSetScissorRects(1, &scissor);
   mContext->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
   mContext->VSSetShader(mAttachments->mVSQuadShader[maskType], nullptr, 0);
 
-  SetPSForEffect(aEffectChain.mPrimaryEffect, maskType);
 
   switch (aEffectChain.mPrimaryEffect->mType) {
   case EFFECT_SOLID_COLOR: {
       Color color =
         static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get())->mColor;
       mPSConstants.layerColor[0] = color.r * color.a * aOpacity;
       mPSConstants.layerColor[1] = color.g * color.a * aOpacity;
       mPSConstants.layerColor[2] = color.b * color.a * aOpacity;
       mPSConstants.layerColor[3] = color.a * aOpacity;
     }
     break;
-  case EFFECT_BGRX:
-  case EFFECT_BGRA:
+  case EFFECT_RGB:
   case EFFECT_RENDER_TARGET:
     {
       TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
 
+      SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, texturedEffect->mTexture->GetFormat());
+
       mVSConstants.textureCoords = texturedEffect->mTextureCoords;
 
       TextureSourceD3D11* source = texturedEffect->mTexture->AsSourceD3D11();
 
       if (!source) {
         NS_WARNING("Missing texture source!");
         return;
       }
@@ -587,16 +588,17 @@ CompositorD3D11::DrawQuad(const gfx::Rec
 
       SetSamplerForFilter(texturedEffect->mFilter);
     }
     break;
   case EFFECT_YCBCR: {
       EffectYCbCr* ycbcrEffect =
         static_cast<EffectYCbCr*>(aEffectChain.mPrimaryEffect.get());
 
+      SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, ycbcrEffect->mTexture->GetFormat());
       SetSamplerForFilter(Filter::LINEAR);
 
       mVSConstants.textureCoords = ycbcrEffect->mTextureCoords;
 
       const int Y = 0, Cb = 1, Cr = 2;
       TextureSource* source = ycbcrEffect->mTexture;
 
       if (!source) {
@@ -627,16 +629,18 @@ CompositorD3D11::DrawQuad(const gfx::Rec
     }
     break;
   case EFFECT_COMPONENT_ALPHA:
     {
       MOZ_ASSERT(gfxPlatform::ComponentAlphaEnabled());
       MOZ_ASSERT(mAttachments->mComponentBlendState);
       EffectComponentAlpha* effectComponentAlpha =
         static_cast<EffectComponentAlpha*>(aEffectChain.mPrimaryEffect.get());
+
+      SetPSForEffect(aEffectChain.mPrimaryEffect, maskType, effectComponentAlpha->mTexture->GetFormat());
       TextureSourceD3D11* sourceOnWhite = effectComponentAlpha->mOnWhite->AsSourceD3D11();
       TextureSourceD3D11* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceD3D11();
 
       if (!sourceOnWhite || !sourceOnBlack) {
         NS_WARNING("Missing texture source(s)!");
         return;
       }
 
--- a/gfx/layers/d3d11/CompositorD3D11.h
+++ b/gfx/layers/d3d11/CompositorD3D11.h
@@ -147,17 +147,17 @@ public:
 private:
   // ensure mSize is up to date with respect to mWidget
   void EnsureSize();
   void VerifyBufferSize();
   void UpdateRenderTarget();
   bool CreateShaders();
   void UpdateConstantBuffers();
   void SetSamplerForFilter(gfx::Filter aFilter);
-  void SetPSForEffect(Effect *aEffect, MaskType aMaskType);
+  void SetPSForEffect(Effect *aEffect, MaskType aMaskType, gfx::SurfaceFormat aFormat);
   void PaintToTarget();
 
   RefPtr<ID3D11DeviceContext> mContext;
   RefPtr<ID3D11Device> mDevice;
   RefPtr<IDXGISwapChain> mSwapChain;
   RefPtr<CompositingRenderTargetD3D11> mDefaultRT;
   RefPtr<CompositingRenderTargetD3D11> mCurrentRT;
 
--- a/gfx/layers/d3d9/CompositorD3D9.cpp
+++ b/gfx/layers/d3d9/CompositorD3D9.cpp
@@ -186,25 +186,26 @@ CompositorD3D9::SetRenderTarget(Composit
   MOZ_ASSERT(aRenderTarget && mDeviceManager);
   RefPtr<CompositingRenderTargetD3D9> oldRT = mCurrentRT;
   mCurrentRT = static_cast<CompositingRenderTargetD3D9*>(aRenderTarget);
   mCurrentRT->BindRenderTarget(device());
   PrepareViewport(mCurrentRT->GetSize(), Matrix());
 }
 
 static DeviceManagerD3D9::ShaderMode
-ShaderModeForEffectType(EffectTypes aEffectType)
+ShaderModeForEffectType(EffectTypes aEffectType, gfx::SurfaceFormat aFormat)
 {
   switch (aEffectType) {
   case EFFECT_SOLID_COLOR:
     return DeviceManagerD3D9::SOLIDCOLORLAYER;
-  case EFFECT_BGRA:
   case EFFECT_RENDER_TARGET:
     return DeviceManagerD3D9::RGBALAYER;
-  case EFFECT_BGRX:
+  case EFFECT_RGB:
+    if (aFormat == SurfaceFormat::B8G8R8A8 || aFormat == SurfaceFormat::R8G8B8A8)
+      return DeviceManagerD3D9::RGBALAYER;
     return DeviceManagerD3D9::RGBLAYER;
   case EFFECT_YCBCR:
     return DeviceManagerD3D9::YCBCRLAYER;
   }
 
   MOZ_CRASH("Bad effect type");
 }
 
@@ -282,18 +283,17 @@ CompositorD3D9::DrawQuad(const gfx::Rect
 
       d3d9Device->SetPixelShaderConstantF(CBvColor, color, 1);
 
       maskTexture = mDeviceManager
         ->SetShaderMode(DeviceManagerD3D9::SOLIDCOLORLAYER, maskType);
     }
     break;
   case EFFECT_RENDER_TARGET:
-  case EFFECT_BGRX:
-  case EFFECT_BGRA:
+  case EFFECT_RGB:
     {
       TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
 
       Rect textureCoords = texturedEffect->mTextureCoords;
       d3d9Device->SetVertexShaderConstantF(CBvTextureCoords,
                                            ShaderConstantRect(
                                              textureCoords.x,
@@ -303,17 +303,18 @@ CompositorD3D9::DrawQuad(const gfx::Rect
                                            1);
 
       SetSamplerForFilter(texturedEffect->mFilter);
 
       TextureSourceD3D9* source = texturedEffect->mTexture->AsSourceD3D9();
       d3d9Device->SetTexture(0, source->GetD3D9Texture());
 
       maskTexture = mDeviceManager
-        ->SetShaderMode(ShaderModeForEffectType(aEffectChain.mPrimaryEffect->mType),
+        ->SetShaderMode(ShaderModeForEffectType(aEffectChain.mPrimaryEffect->mType,
+                                                texturedEffect->mTexture->GetFormat()),
                         maskType);
 
       isPremultiplied = texturedEffect->mPremultiplied;
     }
     break;
   case EFFECT_YCBCR:
     {
       EffectYCbCr* ycbcrEffect =
--- a/gfx/layers/moz.build
+++ b/gfx/layers/moz.build
@@ -29,17 +29,16 @@ EXPORTS += [
     'ipc/ShadowLayersManager.h',
     'Layers.h',
     'LayerScope.h',
     'LayersLogging.h',
     'LayerSorter.h',
     'LayerTreeInvalidation.h',
     'opengl/Composer2D.h',
     'opengl/OGLShaderProgram.h',
-    'opengl/OGLShaders.h',
     'opengl/TexturePoolOGL.h',
     'ReadbackLayer.h',
     'SharedTextureImage.h',
     'TiledLayerBuffer.h',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     UNIFIED_SOURCES += [
--- a/gfx/layers/opengl/CompositorOGL.cpp
+++ b/gfx/layers/opengl/CompositorOGL.cpp
@@ -47,16 +47,17 @@
 #include "TexturePoolOGL.h"
 #endif
 #include "GeckoProfiler.h"
 
 #define BUFFER_OFFSET(i) ((char *)nullptr + (i))
 
 namespace mozilla {
 
+using namespace std;
 using namespace gfx;
 
 namespace layers {
 
 using namespace mozilla::gl;
 
 static inline IntSize ns2gfxSize(const nsIntSize& s) {
   return IntSize(s.width, s.height);
@@ -172,29 +173,16 @@ CompositorOGL::CreateContext()
 
   if (!context) {
     NS_WARNING("Failed to create CompositorOGL context");
   }
 
   return context.forget();
 }
 
-void
-CompositorOGL::AddPrograms(ShaderProgramType aType)
-{
-  for (uint32_t maskType = MaskNone; maskType < NumMaskTypes; ++maskType) {
-    if (ProgramProfileOGL::ProgramExists(aType, static_cast<MaskType>(maskType))) {
-      mPrograms[aType].mVariations[maskType] = new ShaderProgramOGL(this->gl(),
-        ProgramProfileOGL::GetProfileFor(aType, static_cast<MaskType>(maskType)));
-    } else {
-      mPrograms[aType].mVariations[maskType] = nullptr;
-    }
-  }
-}
-
 GLuint
 CompositorOGL::GetTemporaryTexture(GLenum aTextureUnit)
 {
   size_t index = aTextureUnit - LOCAL_GL_TEXTURE0;
   // lazily grow the array of temporary textures
   if (mTextures.Length() <= index) {
     size_t prevLength = mTextures.Length();
     mTextures.SetLength(index + 1);
@@ -234,17 +222,22 @@ CompositorOGL::CleanupResources()
   if (!mGLContext)
     return;
 
   nsRefPtr<GLContext> ctx = mGLContext->GetSharedContext();
   if (!ctx) {
     ctx = mGLContext;
   }
 
-  mPrograms.Clear();
+  for (std::map<ShaderConfigOGL, ShaderProgramOGL *>::iterator iter = mPrograms.begin();
+       iter != mPrograms.end();
+       iter++) {
+    delete iter->second;
+  }
+  mPrograms.clear();
 
   if (!ctx->MakeCurrent()) {
     mQuadVBO = 0;
     mGLContext = nullptr;
     return;
   }
 
   ctx->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, 0);
@@ -280,23 +273,20 @@ CompositorOGL::Initialize()
   mHasBGRA =
     mGLContext->IsExtensionSupported(gl::GLContext::EXT_texture_format_BGRA8888) ||
     mGLContext->IsExtensionSupported(gl::GLContext::EXT_bgra);
 
   mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                  LOCAL_GL_ONE, LOCAL_GL_ONE);
   mGLContext->fEnable(LOCAL_GL_BLEND);
 
-  mPrograms.AppendElements(NumProgramTypes);
-  for (int type = 0; type < NumProgramTypes; ++type) {
-    AddPrograms(static_cast<ShaderProgramType>(type));
-  }
-
   // initialise a common shader to check that we can actually compile a shader
-  if (!mPrograms[RGBALayerProgramType].mVariations[MaskNone]->Initialize()) {
+  RefPtr<EffectSolidColor> effect = new EffectSolidColor(Color(0, 0, 0, 0));
+  ShaderConfigOGL config = GetShaderConfigFor(effect);
+  if (!GetShaderProgramFor(config)) {
     return false;
   }
 
   if (mGLContext->WorkAroundDriverBugs()) {
     /**
     * We'll test the ability here to bind NPOT textures to a framebuffer, if
     * this fails we'll try ARB_texture_rectangle.
     */
@@ -538,31 +528,17 @@ CompositorOGL::PrepareViewport(const gfx
     viewMatrix.Translate(mRenderOffset.x, mRenderOffset.y);
   }
 
   viewMatrix = aWorldTransform * viewMatrix;
 
   Matrix4x4 matrix3d = Matrix4x4::From2D(viewMatrix);
   matrix3d._33 = 0.0f;
 
-  SetLayerProgramProjectionMatrix(matrix3d);
-}
-
-void
-CompositorOGL::SetLayerProgramProjectionMatrix(const Matrix4x4& aMatrix)
-{
-  // Update the projection matrix in all of the programs, without activating them.
-  // The uniform will actually be set the next time the program is activated.
-  for (unsigned int i = 0; i < mPrograms.Length(); ++i) {
-    for (uint32_t mask = MaskNone; mask < NumMaskTypes; ++mask) {
-      if (mPrograms[i].mVariations[mask]) {
-        mPrograms[i].mVariations[mask]->DelayedSetProjectionMatrix(aMatrix);
-      }
-    }
-  }
+  mProjMatrix = matrix3d;
 }
 
 TemporaryRef<CompositingRenderTarget>
 CompositorOGL::CreateRenderTarget(const IntRect &aRect, SurfaceInitMode aInit)
 {
   GLuint tex = 0;
   GLuint fbo = 0;
   CreateFBOWithTexture(aRect, false, 0, &fbo, &tex);
@@ -830,41 +806,72 @@ CompositorOGL::CreateFBOWithTexture(cons
   mGLContext->fBindTexture(mFBOTextureTarget, 0);
 
   mGLContext->fGenFramebuffers(1, &fbo);
 
   *aFBO = fbo;
   *aTexture = tex;
 }
 
-ShaderProgramType
-CompositorOGL::GetProgramTypeForEffect(Effect *aEffect) const
+ShaderConfigOGL
+CompositorOGL::GetShaderConfigFor(Effect *aEffect, MaskType aMask) const
 {
+  ShaderConfigOGL config;
+
   switch(aEffect->mType) {
   case EFFECT_SOLID_COLOR:
-    return ColorLayerProgramType;
-  case EFFECT_RGBA:
-  case EFFECT_RGBX:
-  case EFFECT_BGRA:
-  case EFFECT_BGRX:
+    config.SetRenderColor(true);
+    break;
+  case EFFECT_YCBCR:
+    config.SetYCbCr(true);
+    break;
+  case EFFECT_COMPONENT_ALPHA:
+    config.SetComponentAlpha(true);
+    break;
+  case EFFECT_RENDER_TARGET:
+    config.SetTextureTarget(mFBOTextureTarget);
+    break;
+  default:
   {
+    MOZ_ASSERT(aEffect->mType == EFFECT_RGB);
     TexturedEffect* texturedEffect =
         static_cast<TexturedEffect*>(aEffect);
     TextureSourceOGL* source = texturedEffect->mTexture->AsSourceOGL();
-
-    return ShaderProgramFromTargetAndFormat(source->GetTextureTarget(),
-                                            source->GetFormat());
+    MOZ_ASSERT_IF(source->GetTextureTarget() == LOCAL_GL_TEXTURE_EXTERNAL,
+                  source->GetFormat() == gfx::SurfaceFormat::R8G8B8A8);
+    MOZ_ASSERT_IF(source->GetTextureTarget() == LOCAL_GL_TEXTURE_RECTANGLE_ARB,
+                  source->GetFormat() == gfx::SurfaceFormat::R8G8B8A8 ||
+                  source->GetFormat() == gfx::SurfaceFormat::R8G8B8X8 ||
+                  source->GetFormat() == gfx::SurfaceFormat::R5G6B5);
+    config = ShaderConfigFromTargetAndFormat(source->GetTextureTarget(),
+                                             source->GetFormat());
+    break;
+  }
   }
-  case EFFECT_YCBCR:
-    return YCbCrLayerProgramType;
-  case EFFECT_RENDER_TARGET:
-    return GetFBOLayerProgramType();
-  default:
-    return RGBALayerProgramType;
+  config.SetMask2D(aMask == Mask2d);
+  config.SetMask3D(aMask == Mask3d);
+  return config;
+}
+
+ShaderProgramOGL*
+CompositorOGL::GetShaderProgramFor(const ShaderConfigOGL &aConfig)
+{
+  std::map<ShaderConfigOGL, ShaderProgramOGL *>::iterator iter = mPrograms.find(aConfig);
+  if (iter != mPrograms.end())
+    return iter->second;
+
+  ProgramProfileOGL profile = ProgramProfileOGL::GetProfileFor(aConfig);
+  ShaderProgramOGL *shader = new ShaderProgramOGL(gl(), profile);
+  if (!shader->Initialize()) {
+    delete shader;
+    return nullptr;
   }
+
+  mPrograms[aConfig] = shader;
+  return shader;
 }
 
 struct MOZ_STACK_CLASS AutoBindTexture
   : public ScopedGLWrapper<AutoBindTexture>
 {
   friend struct ScopedGLWrapper<AutoBindTexture>;
 
 protected:
@@ -1024,67 +1031,69 @@ CompositorOGL::DrawQuadInternal(const Re
                  ? Mask3d
                  : Mask2d;
   } else {
     maskType = MaskNone;
   }
 
   mPixelsFilled += aRect.width * aRect.height;
 
-  ShaderProgramType programType = GetProgramTypeForEffect(aEffectChain.mPrimaryEffect);
-  ShaderProgramOGL *program = GetProgram(programType, maskType);
+  // Determine the color if this is a color shader and fold the opacity into
+  // the color since color shaders don't have an opacity uniform.
+  Color color;
+  if (aEffectChain.mPrimaryEffect->mType == EFFECT_SOLID_COLOR) {
+    EffectSolidColor* effectSolidColor =
+      static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());
+    color = effectSolidColor->mColor;
+
+    Float opacity = aOpacity * color.a;
+    color.r *= opacity;
+    color.g *= opacity;
+    color.b *= opacity;
+    color.a = opacity;
+
+    // We can fold opacity into the color, so no need to consider it further.
+    aOpacity = 1.f;
+  }
+
+  ShaderConfigOGL config = GetShaderConfigFor(aEffectChain.mPrimaryEffect, maskType);
+  config.SetOpacity(aOpacity != 1.f);
+  ShaderProgramOGL *program = GetShaderProgramFor(config);
   program->Activate();
-  if (programType == RGBARectLayerProgramType ||
-      programType == RGBXRectLayerProgramType) {
+  program->SetProjectionMatrix(mProjMatrix);
+  program->SetLayerQuadRect(aRect);
+  program->SetLayerTransform(aTransform);
+  IntPoint offset = mCurrentRenderTarget->GetOrigin();
+  program->SetRenderOffset(offset.x, offset.y);
+  if (aOpacity != 1.f)
+    program->SetLayerOpacity(aOpacity);
+  if (config.mFeatures & ENABLE_TEXTURE_RECT) {
     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);
-  IntPoint offset = mCurrentRenderTarget->GetOrigin();
-  program->SetRenderOffset(offset.x, offset.y);
 
   switch (aEffectChain.mPrimaryEffect->mType) {
     case EFFECT_SOLID_COLOR: {
-      EffectSolidColor* effectSolidColor =
-        static_cast<EffectSolidColor*>(aEffectChain.mPrimaryEffect.get());
-
-      Color color = effectSolidColor->mColor;
-      /* Multiply color by the layer opacity, as the shader
-       * ignores layer opacity and expects a final color to
-       * write to the color buffer.  This saves a needless
-       * multiply in the fragment shader.
-       */
-      Float opacity = aOpacity * color.a;
-      color.r *= opacity;
-      color.g *= opacity;
-      color.b *= opacity;
-      color.a = opacity;
-
       program->SetRenderColor(color);
 
       AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE0);
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE0, maskQuadTransform);
       }
 
       BindAndDrawQuad(program, false, aDrawMode);
     }
     break;
 
-  case EFFECT_BGRA:
-  case EFFECT_BGRX:
-  case EFFECT_RGBA:
-  case EFFECT_RGBX: {
+  case EFFECT_RGB: {
       TexturedEffect* texturedEffect =
           static_cast<TexturedEffect*>(aEffectChain.mPrimaryEffect.get());
-      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(mGLContext, source->AsSourceOGL(), LOCAL_GL_TEXTURE0);
@@ -1104,17 +1113,16 @@ CompositorOGL::DrawQuadInternal(const Re
         // code should not be needed!
         filter = GraphicsFilter::FILTER_NEAREST;
       }
 #endif
       ApplyFilterToBoundTexture(mGLContext, filter,
                                 source->AsSourceOGL()->GetTextureTarget());
 
       program->SetTextureUnit(0);
-      program->SetLayerOpacity(aOpacity);
 
       AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE1);
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE1, maskQuadTransform);
       }
 
       BindAndDrawQuadWithTextureRect(program, textureTransform,
                                      texturedEffect->mTextureCoords, source);
@@ -1144,17 +1152,16 @@ CompositorOGL::DrawQuadInternal(const Re
       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);
 
       AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE3);
       if (maskType != MaskNone) {
         BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE3, maskQuadTransform);
       }
       BindAndDrawQuadWithTextureRect(program,
                                      gfx3DMatrix(),
                                      effectYCbCr->mTextureCoords,
@@ -1162,33 +1169,29 @@ CompositorOGL::DrawQuadInternal(const Re
     }
     break;
   case EFFECT_RENDER_TARGET: {
       EffectRenderTarget* effectRenderTarget =
         static_cast<EffectRenderTarget*>(aEffectChain.mPrimaryEffect.get());
       RefPtr<CompositingRenderTargetOGL> surface
         = static_cast<CompositingRenderTargetOGL*>(effectRenderTarget->mRenderTarget.get());
 
-      ShaderProgramOGL *program = GetProgram(GetFBOLayerProgramType(), maskType);
-
       surface->BindTexture(LOCAL_GL_TEXTURE0, mFBOTextureTarget);
 
-      program->Activate();
+      program->SetTextureTransform(Matrix4x4());
       program->SetTextureUnit(0);
-      program->SetLayerOpacity(aOpacity);
-      program->SetTextureTransform(Matrix4x4());
 
       AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE1);
       if (maskType != MaskNone) {
         sourceMask->BindTexture(LOCAL_GL_TEXTURE1);
         program->SetMaskTextureUnit(1);
         program->SetMaskLayerTransform(maskQuadTransform);
       }
 
-      if (program->GetTexCoordMultiplierUniformLocation() != -1) {
+      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, true);
@@ -1202,57 +1205,47 @@ CompositorOGL::DrawQuadInternal(const Re
       TextureSourceOGL* sourceOnBlack = effectComponentAlpha->mOnBlack->AsSourceOGL();
 
       if (!sourceOnBlack->IsValid() ||
           !sourceOnWhite->IsValid()) {
         NS_WARNING("Invalid layer texture for component alpha");
         return;
       }
 
-      for (int32_t pass = 1; pass <=2; ++pass) {
-        ShaderProgramOGL* program;
-        if (pass == 1) {
-          ShaderProgramType type = gl()->GetPreferredARGB32Format() == LOCAL_GL_BGRA ?
-                                   ComponentAlphaPass1RGBProgramType :
-                                   ComponentAlphaPass1ProgramType;
-          program = GetProgram(type, maskType);
-          gl()->fBlendFuncSeparate(LOCAL_GL_ZERO, LOCAL_GL_ONE_MINUS_SRC_COLOR,
-                                   LOCAL_GL_ONE, LOCAL_GL_ONE);
-        } else {
-          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(mGLContext, sourceOnBlack, LOCAL_GL_TEXTURE0);
+      AutoBindTexture bindSourceOnWhite(mGLContext, sourceOnWhite, LOCAL_GL_TEXTURE1);
 
-        AutoBindTexture bindSourceOnBlack(mGLContext, sourceOnBlack, LOCAL_GL_TEXTURE0);
-        AutoBindTexture bindSourceOnWhite(mGLContext, sourceOnWhite, LOCAL_GL_TEXTURE1);
+      program->SetBlackTextureUnit(0);
+      program->SetWhiteTextureUnit(1);
+      program->SetTextureTransform(gfx::Matrix4x4());
 
-        program->Activate();
-        program->SetBlackTextureUnit(0);
-        program->SetWhiteTextureUnit(1);
-        program->SetLayerOpacity(aOpacity);
-        program->SetLayerTransform(aTransform);
-        program->SetRenderOffset(offset.x, offset.y);
-        program->SetLayerQuadRect(aRect);
-        AutoSaveTexture bindMask(mGLContext, LOCAL_GL_TEXTURE2);
-        if (maskType != MaskNone) {
-          BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2, maskQuadTransform);
-        }
+      AutoBindTexture bindMask(mGLContext);
+      if (maskType != MaskNone) {
+        BindMaskForProgram(program, sourceMask, LOCAL_GL_TEXTURE2, maskQuadTransform);
+      }
+      // Pass 1.
+      gl()->fBlendFuncSeparate(LOCAL_GL_ZERO, LOCAL_GL_ONE_MINUS_SRC_COLOR,
+                               LOCAL_GL_ONE, LOCAL_GL_ONE);
+      program->SetTexturePass2(false);
+      BindAndDrawQuadWithTextureRect(program,
+                                     gfx3DMatrix(),
+                                     effectComponentAlpha->mTextureCoords,
+                                     effectComponentAlpha->mOnBlack);
 
-        BindAndDrawQuadWithTextureRect(program,
-                                       gfx3DMatrix(),
-                                       effectComponentAlpha->mTextureCoords,
-                                       effectComponentAlpha->mOnBlack);
+      // Pass 2.
+      gl()->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE,
+                               LOCAL_GL_ONE, LOCAL_GL_ONE);
+      program->SetTexturePass2(true);
+      BindAndDrawQuadWithTextureRect(program,
+                                     gfx3DMatrix(),
+                                     effectComponentAlpha->mTextureCoords,
+                                     effectComponentAlpha->mOnBlack);
 
-        mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
-                                       LOCAL_GL_ONE, LOCAL_GL_ONE);
-      }
+      mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
+                                     LOCAL_GL_ONE, LOCAL_GL_ONE);
     }
     break;
   default:
     MOZ_ASSERT(false, "Unhandled effect type");
     break;
   }
 
   mGLContext->fActiveTexture(LOCAL_GL_TEXTURE0);
--- a/gfx/layers/opengl/CompositorOGL.h
+++ b/gfx/layers/opengl/CompositorOGL.h
@@ -50,20 +50,20 @@ class DataTextureSource;
 class GLManagerCompositor;
 class TextureSource;
 struct Effect;
 struct EffectChain;
 
 class CompositorOGL : public Compositor
 {
   typedef mozilla::gl::GLContext GLContext;
-  typedef ShaderProgramType ProgramType;
   
   friend class GLManagerCompositor;
 
+  std::map<ShaderConfigOGL, ShaderProgramOGL*> mPrograms;
 public:
   CompositorOGL(nsIWidget *aWidget, int aSurfaceWidth = -1, int aSurfaceHeight = -1,
                 bool aUseExternalSurfaceSize = false);
 
   virtual ~CompositorOGL();
 
   virtual TemporaryRef<DataTextureSource>
   CreateDataTextureSource(TextureFlags aFlags = 0) MOZ_OVERRIDE;
@@ -155,31 +155,31 @@ public:
   }
 
   virtual void Pause() MOZ_OVERRIDE;
   virtual bool Resume() MOZ_OVERRIDE;
 
   virtual nsIWidget* GetWidget() const MOZ_OVERRIDE { return mWidget; }
 
   GLContext* gl() const { return mGLContext; }
-  ShaderProgramType GetFBOLayerProgramType() const {
-    return mFBOTextureTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB ?
-           RGBARectLayerProgramType : RGBALayerProgramType;
-  }
   gfx::SurfaceFormat GetFBOFormat() const {
     return gfx::SurfaceFormat::R8G8B8A8;
   }
 
   /**
    * The compositor provides with temporary textures for use with direct
    * textruing like gralloc texture.
    * Doing so lets us use gralloc the way it has been designed to be used
    * (see https://wiki.mozilla.org/Platform/GFX/Gralloc)
    */
   GLuint GetTemporaryTexture(GLenum aUnit);
+
+  const gfx::Matrix4x4& GetProjMatrix() const {
+    return mProjMatrix;
+  }
 private:
   virtual void DrawQuadInternal(const gfx::Rect& aRect,
                                 const gfx::Rect& aClipRect,
                                 const EffectChain &aEffectChain,
                                 gfx::Float aOpacity,
                                 const gfx::Matrix4x4 &aTransformi,
                                 GLuint aDrawMode);
 
@@ -187,37 +187,25 @@ private:
    * Context target, nullptr when drawing directly to our swap chain.
    */
   RefPtr<gfx::DrawTarget> mTarget;
 
   /** Widget associated with this compositor */
   nsIWidget *mWidget;
   nsIntSize mWidgetSize;
   nsRefPtr<GLContext> mGLContext;
+  gfx::Matrix4x4 mProjMatrix;
 
   /** The size of the surface we are rendering to */
   nsIntSize mSurfaceSize;
 
   ScreenPoint mRenderOffset;
 
   already_AddRefed<mozilla::gl::GLContext> CreateContext();
 
-  /** Shader Programs */
-  struct ShaderProgramVariations {
-    nsAutoTArray<nsAutoPtr<ShaderProgramOGL>, NumMaskTypes> mVariations;
-    ShaderProgramVariations() {
-      MOZ_COUNT_CTOR(ShaderProgramVariations);
-      mVariations.SetLength(NumMaskTypes);
-    }
-    ~ShaderProgramVariations() {
-      MOZ_COUNT_DTOR(ShaderProgramVariations);
-    }
-  };
-  nsTArray<ShaderProgramVariations> mPrograms;
-
   /** Texture target to use for FBOs */
   GLenum mFBOTextureTarget;
 
   /** Currently bound render target */
   RefPtr<CompositingRenderTargetOGL> mCurrentRenderTarget;
 #ifdef DEBUG
   CompositingRenderTargetOGL* mWindowRenderTarget;
 #endif
@@ -256,35 +244,18 @@ private:
    */
   virtual void BeginFrame(const nsIntRegion& aInvalidRegion,
                           const gfx::Rect *aClipRectIn,
                           const gfx::Matrix& aTransform,
                           const gfx::Rect& aRenderBounds,
                           gfx::Rect *aClipRectOut = nullptr,
                           gfx::Rect *aRenderBoundsOut = nullptr) MOZ_OVERRIDE;
 
-  ShaderProgramType GetProgramTypeForEffect(Effect* aEffect) const;
-
-  /**
-   * Updates all layer programs with a new projection matrix.
-   */
-  void SetLayerProgramProjectionMatrix(const gfx::Matrix4x4& aMatrix);
-
-  /**
-   * Helper method for Initialize, creates all valid variations of a program
-   * and adds them to mPrograms
-   */
-  void AddPrograms(ShaderProgramType aType);
-
-  ShaderProgramOGL* GetProgram(ShaderProgramType aType,
-                               MaskType aMask = MaskNone) {
-    MOZ_ASSERT(ProgramProfileOGL::ProgramExists(aType, aMask),
-               "Invalid program type.");
-    return mPrograms[aType].mVariations[aMask];
-  }
+  ShaderConfigOGL GetShaderConfigFor(Effect *aEffect, MaskType aMask = MaskNone) const;
+  ShaderProgramOGL* GetShaderProgramFor(const ShaderConfigOGL &aConfig);
 
   /**
    * Create a FBO backed by a texture.
    * Note that the texture target type will be
    * of the type returned by FBOTextureTarget; different
    * shaders are required to sample from the different
    * texture types.
    */
--- a/gfx/layers/opengl/GLManager.cpp
+++ b/gfx/layers/opengl/GLManager.cpp
@@ -27,19 +27,25 @@ public:
     : mImpl(aCompositor)
   {}
 
   virtual GLContext* gl() const MOZ_OVERRIDE
   {
     return mImpl->gl();
   }
 
-  virtual ShaderProgramOGL* GetProgram(ShaderProgramType aType) MOZ_OVERRIDE
+  virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) MOZ_OVERRIDE
   {
-    return mImpl->GetProgram(aType);
+    ShaderConfigOGL config = ShaderConfigFromTargetAndFormat(aTarget, aFormat);
+    return mImpl->GetShaderProgramFor(config);
+  }
+
+  virtual const gfx::Matrix4x4& GetProjMatrix() const MOZ_OVERRIDE
+  {
+    return mImpl->GetProjMatrix();
   }
 
   virtual void BindAndDrawQuad(ShaderProgramOGL *aProg) MOZ_OVERRIDE
   {
     mImpl->BindAndDrawQuad(aProg);
   }
 
 private:
--- a/gfx/layers/opengl/GLManager.h
+++ b/gfx/layers/opengl/GLManager.h
@@ -26,19 +26,16 @@ class LayerManagerComposite;
 class GLManager
 {
 public:
   static GLManager* CreateGLManager(LayerManagerComposite* aManager);
 
   virtual ~GLManager() {}
 
   virtual gl::GLContext* gl() const = 0;
-  virtual ShaderProgramOGL* GetProgram(ShaderProgramType aType) = 0;
+  virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) = 0;
+  virtual const gfx::Matrix4x4& GetProjMatrix() const = 0;
   virtual void BindAndDrawQuad(ShaderProgramOGL *aProg) = 0;
-
-  ShaderProgramOGL* GetProgram(gfx::SurfaceFormat aFormat) {
-    return GetProgram(ShaderProgramFromSurfaceFormat(aFormat));
-  }
 };
 
 }
 }
 #endif
--- a/gfx/layers/opengl/OGLShaderProgram.cpp
+++ b/gfx/layers/opengl/OGLShaderProgram.cpp
@@ -1,31 +1,36 @@
 /* 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 "OGLShaderProgram.h"
 #include <stdint.h>                     // for uint32_t
+#include <sstream>                      // for ostringstream
 #include "gfxRect.h"                    // for gfxRect
 #include "mozilla/DebugOnly.h"          // for DebugOnly
 #include "nsAString.h"
 #include "nsAutoPtr.h"                  // for nsRefPtr
 #include "nsString.h"                   // for nsAutoCString
 #include "prenv.h"                      // for PR_GetEnv
-#include "OGLShaders.h"
 #include "Layers.h"
 #include "GLContext.h"
 
 struct gfxRGBA;
 
 namespace mozilla {
 namespace layers {
 
+using namespace std;
+
 typedef ProgramProfileOGL::Argument Argument;
 
+#define GAUSSIAN_KERNEL_HALF_WIDTH 11
+#define GAUSSIAN_KERNEL_STEP 0.2
+
 void
 AddUniforms(ProgramProfileOGL& aProfile)
 {
     static const char *sKnownUniformNames[] = {
         "uLayerTransform",
         "uMaskQuadTransform",
         "uLayerQuadTransform",
         "uMatrixProj",
@@ -36,253 +41,333 @@ AddUniforms(ProgramProfileOGL& aProfile)
         "uYTexture",
         "uCbTexture",
         "uCrTexture",
         "uBlackTexture",
         "uWhiteTexture",
         "uMaskTexture",
         "uRenderColor",
         "uTexCoordMultiplier",
+        "uTexturePass2",
         nullptr
     };
 
     for (int i = 0; sKnownUniformNames[i] != nullptr; ++i) {
         aProfile.mUniforms[i].mNameString = sKnownUniformNames[i];
         aProfile.mUniforms[i].mName = (KnownUniform::KnownUniformName) i;
     }
 }
 
 void
-AddCommonArgs(ProgramProfileOGL& aProfile)
+ShaderConfigOGL::SetRenderColor(bool aEnabled)
+{
+  SetFeature(ENABLE_RENDER_COLOR, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetTextureTarget(GLenum aTarget)
 {
-  aProfile.mAttributes.AppendElement(Argument("aVertexCoord"));
+  SetFeature(ENABLE_TEXTURE_EXTERNAL | ENABLE_TEXTURE_RECT, false);
+  switch (aTarget) {
+  case LOCAL_GL_TEXTURE_EXTERNAL:
+    SetFeature(ENABLE_TEXTURE_EXTERNAL, true);
+    break;
+  case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
+    SetFeature(ENABLE_TEXTURE_RECT, true);
+    break;
+  }
+}
+
+void
+ShaderConfigOGL::SetRBSwap(bool aEnabled)
+{
+  SetFeature(ENABLE_TEXTURE_RB_SWAP, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetNoAlpha(bool aEnabled)
+{
+  SetFeature(ENABLE_TEXTURE_NO_ALPHA, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetOpacity(bool aEnabled)
+{
+  SetFeature(ENABLE_OPACITY, aEnabled);
 }
+
 void
-AddCommonTextureArgs(ProgramProfileOGL& aProfile)
+ShaderConfigOGL::SetYCbCr(bool aEnabled)
+{
+  SetFeature(ENABLE_TEXTURE_YCBCR, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetComponentAlpha(bool aEnabled)
+{
+  SetFeature(ENABLE_TEXTURE_COMPONENT_ALPHA, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetColorMatrix(bool aEnabled)
 {
-  aProfile.mAttributes.AppendElement(Argument("aTexCoord"));
+  SetFeature(ENABLE_COLOR_MATRIX, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetBlur(bool aEnabled)
+{
+  SetFeature(ENABLE_BLUR, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetMask2D(bool aEnabled)
+{
+  SetFeature(ENABLE_MASK_2D, aEnabled);
+}
+
+void
+ShaderConfigOGL::SetMask3D(bool aEnabled)
+{
+  SetFeature(ENABLE_MASK_3D, aEnabled);
 }
 
 /* static */ ProgramProfileOGL
-ProgramProfileOGL::GetProfileFor(ShaderProgramType aType,
-                                 MaskType aMask)
+ProgramProfileOGL::GetProfileFor(ShaderConfigOGL aConfig)
 {
-  NS_ASSERTION(ProgramExists(aType, aMask), "Invalid program type.");
   ProgramProfileOGL result;
+  ostringstream fs, vs;
 
   AddUniforms(result);
 
-  switch (aType) {
-  case RGBALayerProgramType:
-    if (aMask == Mask3d) {
-      result.mVertexShaderString = sLayerMask3DVS;
-      result.mFragmentShaderString = sRGBATextureLayerMask3DFS;
-    } else if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sRGBATextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sRGBATextureLayerFS;
-    }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case BGRALayerProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sBGRATextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sBGRATextureLayerFS;
-    }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case RGBXLayerProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sRGBXTextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sRGBXTextureLayerFS;
-    }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case BGRXLayerProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sBGRXTextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sBGRXTextureLayerFS;
-    }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case RGBARectLayerProgramType:
-    if (aMask == Mask3d) {
-      result.mVertexShaderString = sLayerMask3DVS;
-      result.mFragmentShaderString = sRGBARectTextureLayerMask3DFS;
-    } else if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sRGBARectTextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sRGBARectTextureLayerFS;
-    }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case RGBXRectLayerProgramType:
-    if (aMask == Mask3d) {
-      result.mVertexShaderString = sLayerMask3DVS;
-      result.mFragmentShaderString = sRGBXRectTextureLayerMask3DFS;
-    } else if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sRGBXRectTextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sRGBXRectTextureLayerFS;
+  vs << "uniform mat4 uMatrixProj;" << endl;
+  vs << "uniform mat4 uLayerQuadTransform;" << endl;
+  vs << "uniform mat4 uLayerTransform;" << endl;
+  vs << "uniform vec4 uRenderTargetOffset;" << endl;
+
+  vs << "attribute vec4 aVertexCoord;" << endl;
+
+  if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
+    vs << "uniform mat4 uTextureTransform;" << endl;
+    vs << "attribute vec2 aTexCoord;" << endl;
+    vs << "varying vec2 vTexCoord;" << endl;
+  }
+
+  if (aConfig.mFeatures & ENABLE_MASK_2D ||
+      aConfig.mFeatures & ENABLE_MASK_3D) {
+    vs << "uniform mat4 uMaskQuadTransform;" << endl;
+    vs << "varying vec3 vMaskCoord;" << endl;
+  }
+
+  vs << "void main() {" << endl;
+  vs << "  vec4 finalPosition = aVertexCoord;" << endl;
+  vs << "  finalPosition = uLayerQuadTransform * finalPosition;" << endl;
+  vs << "  finalPosition = uLayerTransform * finalPosition;" << endl;
+  vs << "  finalPosition.xyz /= finalPosition.w;" << endl;
+
+  if (aConfig.mFeatures & ENABLE_MASK_3D) {
+    vs << "  vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;" << endl;
+    // correct for perspective correct interpolation, see comment in D3D10 shader
+    vs << "  vMaskCoord.z = 1.0;" << endl;
+    vs << "  vMaskCoord *= finalPosition.w;" << endl;
+  } else if (aConfig.mFeatures & ENABLE_MASK_2D) {
+    vs << "  vMaskCoord.xy = (uMaskQuadTransform * finalPosition).xy;" << endl;
+  }
+
+  vs << "  finalPosition = finalPosition - uRenderTargetOffset;" << endl;
+  vs << "  finalPosition.xyz *= finalPosition.w;" << endl;
+  vs << "  finalPosition = uMatrixProj * finalPosition;" << endl;
+
+  if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
+    vs << "  vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;" << endl;
+  }
+
+  vs << "  gl_Position = finalPosition;" << endl;
+  vs << "}" << endl;
+
+  fs << "#ifdef GL_ES" << endl;
+  fs << "precision mediump float;" << endl;
+  fs << "#define COLOR_PRECISION lowp" << endl;
+  fs << "#else" << endl;
+  fs << "#define COLOR_PRECISION" << endl;
+  fs << "#endif" << endl;
+  if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
+    fs << "uniform COLOR_PRECISION vec4 uRenderColor;" << endl;
+  } else {
+    // for tiling, texcoord can be greater than the lowfp range
+    fs << "varying vec2 vTexCoord;" << endl;
+    if (aConfig.mFeatures & ENABLE_BLUR) {
+      fs << "uniform bool uBlurAlpha;" << endl;
+      fs << "uniform vec2 uBlurRadius;" << endl;
+      fs << "uniform vec2 uBlurOffset;" << endl;
+      fs << "uniform float uBlurGaussianKernel[" << GAUSSIAN_KERNEL_HALF_WIDTH << "];" << endl;
     }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case BGRARectLayerProgramType:
-    MOZ_ASSERT(aMask == MaskNone, "BGRARectLayerProgramType can't handle masks.");
-    result.mVertexShaderString = sLayerVS;
-    result.mFragmentShaderString = sBGRARectTextureLayerFS;
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case RGBAExternalLayerProgramType:
-    if (aMask == Mask3d) {
-      result.mVertexShaderString = sLayerMask3DVS;
-      result.mFragmentShaderString = sRGBAExternalTextureLayerMask3DFS;
-    } else if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sRGBAExternalTextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sRGBAExternalTextureLayerFS;
+    if (aConfig.mFeatures & ENABLE_COLOR_MATRIX) {
+      fs << "uniform mat4 uColorMatrix;" << endl;
+      fs << "uniform vec4 uColorMatrixVector;" << endl;
     }
-    AddCommonArgs(result);
-    AddCommonTextureArgs(result);
-    result.mTextureCount = 1;
-    break;
-  case ColorLayerProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sSolidColorLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sSolidColorLayerFS;
-    }
-    AddCommonArgs(result);
-    break;
-  case YCbCrLayerProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sYCbCrTextureLayerMaskFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sYCbCrTextureLayerFS;
-    }
-    AddCommonArgs(result);
-    result.mAttributes.AppendElement(Argument("aTexCoord"));
-    result.mTextureCount = 3;
-    break;
-  case ComponentAlphaPass1ProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sComponentPassMask1FS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sComponentPass1FS;
+    if (aConfig.mFeatures & ENABLE_OPACITY) {
+      fs << "uniform COLOR_PRECISION float uLayerOpacity;" << endl;
     }
-    AddCommonArgs(result);
-    result.mAttributes.AppendElement(Argument("aTexCoord"));
-    result.mTextureCount = 2;
-    break;
-  case ComponentAlphaPass1RGBProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sComponentPassMask1RGBFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sComponentPass1RGBFS;
-    }
-    AddCommonArgs(result);
-    result.mAttributes.AppendElement(Argument("aTexCoord"));
-    result.mTextureCount = 2;
-    break;
-  case ComponentAlphaPass2ProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sComponentPassMask2FS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sComponentPass2FS;
-    }
-    AddCommonArgs(result);
-    result.mAttributes.AppendElement(Argument("aTexCoord"));
-    result.mTextureCount = 2;
-    break;
-  case ComponentAlphaPass2RGBProgramType:
-    if (aMask == Mask2d) {
-      result.mVertexShaderString = sLayerMaskVS;
-      result.mFragmentShaderString = sComponentPassMask2RGBFS;
-    } else {
-      result.mVertexShaderString = sLayerVS;
-      result.mFragmentShaderString = sComponentPass2RGBFS;
-    }
-    AddCommonArgs(result);
-    result.mAttributes.AppendElement(Argument("aTexCoord"));
-    result.mTextureCount = 2;
-    break;
-  case Copy2DProgramType:
-    NS_ASSERTION(!aMask, "Program does not have masked variant.");
-    result.mVertexShaderString = sCopyVS;
-    result.mFragmentShaderString = sCopy2DFS;
-    result.mAttributes.AppendElement(Argument("aVertexCoord"));
-    result.mAttributes.AppendElement(Argument("aTexCoord"));
-    result.mTextureCount = 1;
-    break;
-  case Copy2DRectProgramType:
-    NS_ASSERTION(!aMask, "Program does not have masked variant.");
-    result.mVertexShaderString = sCopyVS;
-    result.mFragmentShaderString = sCopy2DRectFS;
-    result.mAttributes.AppendElement(Argument("aVertexCoord"));
-    result.mAttributes.AppendElement(Argument("aTexCoord"));
-    result.mTextureCount = 1;
-    break;
-  default:
-    NS_NOTREACHED("Unknown shader program type.");
+  }
+
+  const char *sampler2D = "sampler2D";
+  const char *texture2D = "texture2D";
+
+  if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
+    fs << "#extension GL_ARB_texture_rectangle : require" << endl;
+    fs << "uniform vec2 uTexCoordMultiplier;" << endl;
+    sampler2D = "sampler2DRect";
+    texture2D = "texture2DRect";
+  }
+
+  if (aConfig.mFeatures & ENABLE_TEXTURE_EXTERNAL) {
+    fs << "#extension GL_OES_EGL_image_external : require" << endl;
+    sampler2D = "samplerExternalOES";
+  }
+
+  if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
+    fs << "uniform sampler2D uYTexture;" << endl;
+    fs << "uniform sampler2D uCbTexture;" << endl;
+    fs << "uniform sampler2D uCrTexture;" << endl;
+  } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
+    fs << "uniform sampler2D uBlackTexture;" << endl;
+    fs << "uniform sampler2D uWhiteTexture;" << endl;
+    fs << "uniform bool uTexturePass2;" << endl;
+  } else {
+    fs << "uniform " << sampler2D << " uTexture;" << endl;
+  }
+
+  if (aConfig.mFeatures & ENABLE_MASK_2D ||
+      aConfig.mFeatures & ENABLE_MASK_3D) {
+    fs << "varying vec3 vMaskCoord;" << endl;
+    fs << "uniform sampler2D uMaskTexture;" << endl;
   }
 
-  if (aMask > MaskNone) {
-    result.mTextureCount += 1;
+  if (!(aConfig.mFeatures & ENABLE_RENDER_COLOR)) {
+    fs << "vec4 sample(vec2 coord) {" << endl;
+    fs << "  vec4 color;" << endl;
+    if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
+      fs << "  COLOR_PRECISION float y = texture2D(uYTexture, coord).r;" << endl;
+      fs << "  COLOR_PRECISION float cb = texture2D(uCbTexture, coord).r;" << endl;
+      fs << "  COLOR_PRECISION float cr = texture2D(uCrTexture, coord).r;" << endl;
+      fs << "  y = (y - 0.0625) * 1.164;" << endl;
+      fs << "  cb = cb - 0.5;" << endl;
+      fs << "  cr = cr - 0.5;" << endl;
+      fs << "  color.r = y + cr * 1.596;" << endl;
+      fs << "  color.g = y - 0.813 * cr - 0.391 * cb;" << endl;
+      fs << "  color.b = y + cb * 2.018;" << endl;
+      fs << "  color.a = 1.0;" << endl;
+    } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
+      fs << "  COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, coord).rgb;" << endl;
+      fs << "  COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, coord).rgb;" << endl;
+      fs << "  COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;" << endl;
+      fs << "  if (uTexturePass2)" << endl;
+      fs << "    color = vec4(onBlack, alphas.a);" << endl;
+      fs << "  else" << endl;
+      fs << "    color = alphas;" << endl;
+    } else {
+      fs << "  color = " << texture2D << "(uTexture, coord);" << endl;
+    }
+    if (aConfig.mFeatures & ENABLE_TEXTURE_RB_SWAP) {
+      fs << "  color = color.bgra;" << endl;
+    }
+    if (aConfig.mFeatures & ENABLE_TEXTURE_NO_ALPHA) {
+      fs << "  color = vec4(color.rgb, 1.0);" << endl;
+    }
+    fs << "  return color;" << endl;
+    fs << "}" << endl;
+    if (aConfig.mFeatures & ENABLE_BLUR) {
+      fs << "vec4 sampleAtRadius(vec2 coord, float radius) {" << endl;
+      fs << "  coord += uBlurOffset;" << endl;
+      fs << "  coord += radius * uBlurRadius;" << endl;
+      fs << "  if (coord.x < 0. || coord.y < 0. || coord.x > 1. || coord.y > 1.)" << endl;
+      fs << "    return vec4(0, 0, 0, 0);" << endl;
+      fs << "  return sample(coord);" << endl;
+      fs << "}" << endl;
+      fs << "vec4 blur(vec4 color, vec2 coord) {" << endl;
+      fs << "  vec4 total = color * uBlurGaussianKernel[0];" << endl;
+      fs << "  for (int i = 1; i < " << GAUSSIAN_KERNEL_HALF_WIDTH << "; ++i) {" << endl;
+      fs << "    float r = float(i) * " << GAUSSIAN_KERNEL_STEP << " << endl;" << endl;
+      fs << "    float k = uBlurGaussianKernel[i];" << endl;
+      fs << "    total += sampleAtRadius(coord, r) * k;" << endl;
+      fs << "    total += sampleAtRadius(coord, -r) * k;" << endl;
+      fs << "  }" << endl;
+      fs << "  if (uBlurAlpha) {" << endl;
+      fs << "    color *= total.a;" << endl;
+      fs << "  } else {" << endl;
+      fs << "    color = total;" << endl;
+      fs << "  }" << endl;
+      fs << "  return color;" << endl;
+      fs << "}" << endl;
+    }
+  }
+  fs << "void main() {" << endl;
+  if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
+    fs << "  vec4 color = uRenderColor;" << endl;
+  } else {
+    if (aConfig.mFeatures & ENABLE_TEXTURE_RECT) {
+      fs << "  vec4 color = sample(vTexCoord * uTexCoordMultiplier);" << endl;
+    } else {
+      fs << "  vec4 color = sample(vTexCoord);" << endl;
+    }
+    if (aConfig.mFeatures & ENABLE_BLUR) {
+      fs << "  color = blur(color, vTexCoord);" << endl;
+    }
+    if (aConfig.mFeatures & ENABLE_COLOR_MATRIX) {
+      fs << "  color = uColorMatrix * vec4(color.rgb / color.a, color.a) + uColorMatrixVector;" << endl;
+      fs << "  color.rgb *= color.a;" << endl;
+    }
+    if (aConfig.mFeatures & ENABLE_OPACITY) {
+      fs << "  color *= uLayerOpacity;" << endl;
+    }
+  }
+  if (aConfig.mFeatures & ENABLE_MASK_3D) {
+    fs << "  vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;" << endl;
+    fs << "  COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;" << endl;
+    fs << "  color *= mask;" << endl;
+  } else if (aConfig.mFeatures & ENABLE_MASK_2D) {
+    fs << "  COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord.xy).r;" << endl;
+    fs << "  color *= mask;" << endl;
+  } else {
+    fs << "  COLOR_PRECISION float mask = 1.0;" << endl;
+    fs << "  color *= mask;" << endl;
+  }
+  fs << "  gl_FragColor = color;" << endl;
+  fs << "}" << endl;
+
+  result.mVertexShaderString = vs.str();
+  result.mFragmentShaderString = fs.str();
+
+  result.mAttributes.AppendElement(Argument("aVertexCoord"));
+  if (aConfig.mFeatures & ENABLE_RENDER_COLOR) {
+    result.mTextureCount = 0;
+  } else {
+    result.mAttributes.AppendElement(Argument("aTexCoord"));
+    if (aConfig.mFeatures & ENABLE_TEXTURE_YCBCR) {
+      result.mTextureCount = 3;
+    } else if (aConfig.mFeatures & ENABLE_TEXTURE_COMPONENT_ALPHA) {
+      result.mTextureCount = 2;
+    } else {
+      result.mTextureCount = 1;
+    }
+  }
+  if (aConfig.mFeatures & ENABLE_MASK_2D ||
+      aConfig.mFeatures & ENABLE_MASK_3D) {
+    result.mTextureCount = 1;
   }
 
   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)
+  : mGL(aGL)
   , mProgram(0)
   , mProfile(aProfile)
   , mProgramState(STATE_NEW)
 {
 }
 
 ShaderProgramOGL::~ShaderProgramOGL()
 {
@@ -298,18 +383,25 @@ ShaderProgramOGL::~ShaderProgramOGL()
   ctx->fDeleteProgram(mProgram);
 }
 
 bool
 ShaderProgramOGL::Initialize()
 {
   NS_ASSERTION(mProgramState == STATE_NEW, "Shader program has already been initialised");
 
-  if (!CreateProgram(mProfile.mVertexShaderString,
-                     mProfile.mFragmentShaderString)) {
+  ostringstream vs, fs;
+  for (uint32_t i = 0; i < mProfile.mDefines.Length(); ++i) {
+    vs << mProfile.mDefines[i] << endl;
+    fs << mProfile.mDefines[i] << endl;
+  }
+  vs << mProfile.mVertexShaderString << endl;
+  fs << mProfile.mFragmentShaderString << endl;
+
+  if (!CreateProgram(vs.str().c_str(), fs.str().c_str())) {
     mProgramState = STATE_ERROR;
     return false;
   }
 
   mProgramState = STATE_OK;
 
   for (uint32_t i = 0; i < KnownUniform::KnownUniformCount; ++i) {
     mProfile.mUniforms[i].mLocation =
@@ -317,17 +409,17 @@ ShaderProgramOGL::Initialize()
   }
 
   for (uint32_t i = 0; i < mProfile.mAttributes.Length(); ++i) {
     mProfile.mAttributes[i].mLocation =
       mGL->fGetAttribLocation(mProgram, mProfile.mAttributes[i].mName);
     NS_ASSERTION(mProfile.mAttributes[i].mLocation >= 0, "Bad attribute location.");
   }
 
-  mProfile.mHasMatrixProj = mProfile.mUniforms[KnownUniform::MatrixProj].mLocation != -1;
+  //mProfile.mHasMatrixProj = mProfile.mUniforms[KnownUniform::MatrixProj].mLocation != -1;
 
   return true;
 }
 
 GLint
 ShaderProgramOGL::CreateShader(GLenum aShaderType, const char *aShaderSource)
 {
   GLint success, len = 0;
@@ -434,17 +526,12 @@ 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);
-
-  // check if we need to set the projection matrix
-  if (mIsProjectionMatrixStale) {
-    SetProjectionMatrix(mProjectionMatrix);
-  }
 }
 
 } /* layers */
 } /* mozilla */
--- a/gfx/layers/opengl/OGLShaderProgram.h
+++ b/gfx/layers/opengl/OGLShaderProgram.h
@@ -14,42 +14,39 @@
 #include "mozilla/gfx/Matrix.h"         // for Matrix4x4
 #include "mozilla/gfx/Rect.h"           // for Rect
 #include "mozilla/gfx/Types.h"
 #include "nsDebug.h"                    // for NS_ASSERTION
 #include "nsPoint.h"                    // for nsIntPoint
 #include "nsTArray.h"                   // for nsTArray
 #include "mozilla/layers/CompositorTypes.h"
 
+#include <string>
+
 struct gfxRGBA;
 struct nsIntRect;
 
 namespace mozilla {
 namespace layers {
 
 class Layer;
 
-enum ShaderProgramType {
-  RGBALayerProgramType,
-  BGRALayerProgramType,
-  RGBXLayerProgramType,
-  BGRXLayerProgramType,
-  RGBARectLayerProgramType,
-  RGBXRectLayerProgramType,
-  BGRARectLayerProgramType,
-  RGBAExternalLayerProgramType,
-  ColorLayerProgramType,
-  YCbCrLayerProgramType,
-  ComponentAlphaPass1ProgramType,
-  ComponentAlphaPass1RGBProgramType,
-  ComponentAlphaPass2ProgramType,
-  ComponentAlphaPass2RGBProgramType,
-  Copy2DProgramType,
-  Copy2DRectProgramType,
-  NumProgramTypes
+enum ShaderFeatures {
+  ENABLE_RENDER_COLOR=0x01,
+  ENABLE_TEXTURE_RECT=0x02,
+  ENABLE_TEXTURE_EXTERNAL=0x04,
+  ENABLE_TEXTURE_YCBCR=0x08,
+  ENABLE_TEXTURE_COMPONENT_ALPHA=0x10,
+  ENABLE_TEXTURE_NO_ALPHA=0x20,
+  ENABLE_TEXTURE_RB_SWAP=0x40,
+  ENABLE_OPACITY=0x80,
+  ENABLE_BLUR=0x100,
+  ENABLE_COLOR_MATRIX=0x200,
+  ENABLE_MASK_2D=0x400,
+  ENABLE_MASK_3D=0x800
 };
 
 class KnownUniform {
 public:
   enum KnownUniformName {
     NotAKnownUniform = -1,
 
     LayerTransform = 0,
@@ -63,16 +60,17 @@ public:
     YTexture,
     CbTexture,
     CrTexture,
     BlackTexture,
     WhiteTexture,
     MaskTexture,
     RenderColor,
     TexCoordMultiplier,
+    TexturePass2,
 
     KnownUniformCount
   };
 
   KnownUniform()
   {
     mName = NotAKnownUniform;
     mNameString = nullptr;
@@ -151,109 +149,76 @@ public:
 
   union {
     int i1;
     float f1;
     float f16v[16];
   } mValue;
 };
 
-static inline ShaderProgramType
-ShaderProgramFromSurfaceFormat(gfx::SurfaceFormat aFormat)
+class ShaderConfigOGL
 {
-  switch (aFormat) {
-    case gfx::SurfaceFormat::B8G8R8A8:
-      return BGRALayerProgramType;
-    case gfx::SurfaceFormat::B8G8R8X8:
-      return BGRXLayerProgramType;
-    case gfx::SurfaceFormat::R8G8B8A8:
-      return RGBALayerProgramType;
-    case gfx::SurfaceFormat::R8G8B8X8:
-    case gfx::SurfaceFormat::R5G6B5:
-      return RGBXLayerProgramType;
-    case gfx::SurfaceFormat::A8:
-      // We don't have a specific luminance shader
-      break;
-    default:
-      NS_ASSERTION(false, "Unhandled surface format!");
+public:
+  ShaderConfigOGL() :
+    mFeatures(0) {}
+
+  void SetRenderColor(bool aEnabled);
+  void SetTextureTarget(GLenum aTarget);
+  void SetRBSwap(bool aEnabled);
+  void SetNoAlpha(bool aEnabled);
+  void SetOpacity(bool aEnabled);
+  void SetYCbCr(bool aEnabled);
+  void SetComponentAlpha(bool aEnabled);
+  void SetColorMatrix(bool aEnabled);
+  void SetBlur(bool aEnabled);
+  void SetMask2D(bool aEnabled);
+  void SetMask3D(bool aEnabled);
+
+  bool operator< (const ShaderConfigOGL& other) const {
+    return mFeatures < other.mFeatures;
   }
-  return ShaderProgramType(0);
-}
 
-static inline ShaderProgramType
-ShaderProgramFromTargetAndFormat(GLenum aTarget,
-                                 gfx::SurfaceFormat aFormat)
+public:
+  void SetFeature(int aBitmask, bool aState) {
+    if (aState)
+      mFeatures |= aBitmask;
+    else
+      mFeatures &= (~aBitmask);
+  }
+
+  int mFeatures;
+};
+
+static inline ShaderConfigOGL
+ShaderConfigFromTargetAndFormat(GLenum aTarget,
+                                gfx::SurfaceFormat aFormat)
 {
-  switch(aTarget) {
-    case LOCAL_GL_TEXTURE_EXTERNAL:
-      MOZ_ASSERT(aFormat == gfx::SurfaceFormat::R8G8B8A8);
-      return RGBAExternalLayerProgramType;
-    case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
-      MOZ_ASSERT(aFormat == gfx::SurfaceFormat::R8G8B8A8 ||
-                 aFormat == gfx::SurfaceFormat::R8G8B8X8);
-      if (aFormat == gfx::SurfaceFormat::R8G8B8A8)
-        return RGBARectLayerProgramType;
-      else
-        return RGBXRectLayerProgramType;
-    default:
-      return ShaderProgramFromSurfaceFormat(aFormat);
-  }
-}
-
-static inline ShaderProgramType
-ShaderProgramFromContentType(gfxContentType aContentType)
-{
-  if (aContentType == gfxContentType::COLOR_ALPHA)
-    return RGBALayerProgramType;
-  return RGBXLayerProgramType;
+  ShaderConfigOGL config;
+  config.SetTextureTarget(aTarget);
+  config.SetRBSwap(aFormat == gfx::SurfaceFormat::B8G8R8A8 ||
+                   aFormat == gfx::SurfaceFormat::B8G8R8X8);
+  config.SetNoAlpha(aFormat == gfx::SurfaceFormat::B8G8R8X8 ||
+                    aFormat == gfx::SurfaceFormat::R8G8B8X8 ||
+                    aFormat == gfx::SurfaceFormat::R5G6B5);
+  return config;
 }
 
 /**
  * This struct represents the shaders that make up a program and the uniform
  * and attribute parmeters that those shaders take.
  * It is used by ShaderProgramOGL.
  * Use the factory method GetProfileFor to create instances.
  */
 struct ProgramProfileOGL
 {
   /**
    * Factory method; creates an instance of this class for the given
-   * ShaderProgramType
-   */
-  static ProgramProfileOGL GetProfileFor(ShaderProgramType aType,
-                                         MaskType aMask);
-
-  /**
-   * returns true if such a shader program exists
+   * ShaderConfigOGL
    */
-  static bool ProgramExists(ShaderProgramType aType, MaskType aMask)
-  {
-    if (aType < 0 ||
-        aType >= NumProgramTypes)
-      return false;
-
-    if (aMask < MaskNone ||
-        aMask >= NumMaskTypes)
-      return false;
-
-    if (aMask == Mask2d &&
-        (aType == Copy2DProgramType ||
-         aType == Copy2DRectProgramType))
-      return false;
-
-    if (aMask != MaskNone &&
-        aType == BGRARectLayerProgramType)
-      return false;
-
-    return aMask != Mask3d ||
-           aType == RGBARectLayerProgramType ||
-           aType == RGBXRectLayerProgramType ||
-           aType == RGBALayerProgramType;
-  }
-
+  static ProgramProfileOGL GetProfileFor(ShaderConfigOGL aConfig);
 
   /**
    * These two methods lookup the location of a uniform and attribute,
    * respectively. Returns -1 if the named uniform/attribute does not
    * have a location for the shaders represented by this profile.
    */
   GLint LookupAttributeLocation(const char* aName)
   {
@@ -271,27 +236,27 @@ struct ProgramProfileOGL
   {
     Argument(const char* aName) :
       mName(aName) {}
     const char* mName;
     GLint mLocation;
   };
 
   // the source code for the program's shaders
-  const char *mVertexShaderString;
-  const char *mFragmentShaderString;
+  std::string mVertexShaderString;
+  std::string mFragmentShaderString;
 
   KnownUniform mUniforms[KnownUniform::KnownUniformCount];
   nsTArray<Argument> mAttributes;
+  nsTArray<const char *> mDefines;
   uint32_t mTextureCount;
-  bool mHasMatrixProj;
-private:
+
   ProgramProfileOGL() :
-    mTextureCount(0),
-    mHasMatrixProj(false) {}
+    mTextureCount(0)
+  {}
 };
 
 
 #if defined(DEBUG)
 #define CHECK_CURRENT_PROGRAM 1
 #define ASSERT_THIS_PROGRAM                                             \
   do {                                                                  \
     GLuint currentProgram;                                              \
@@ -336,20 +301,16 @@ public:
 
   /**
    * Lookup the location of an attribute
    */
   GLint AttribLocation(const char* aName) {
     return mProfile.LookupAttributeLocation(aName);
   }
 
-  GLint GetTexCoordMultiplierUniformLocation() {
-    return mProfile.mUniforms[KnownUniform::TexCoordMultiplier].mLocation;
-  }
-
   /**
    * The following set of methods set a uniform argument to the shader program.
    * Not all uniforms may be set for all programs, and such uses will throw
    * an assertion.
    */
   void SetLayerTransform(const gfx::Matrix4x4& aMatrix) {
     SetMatrixUniform(KnownUniform::LayerTransform, aMatrix);
   }
@@ -371,27 +332,18 @@ public:
     gfx3DMatrix m;
     m._11 = aRect.width;
     m._22 = aRect.height;
     m._41 = aRect.x;
     m._42 = aRect.y;
     SetMatrixUniform(KnownUniform::LayerQuadTransform, m);
   }
 
-  // Set a projection matrix on the program to be set the next time
-  // the program is activated.
-  void DelayedSetProjectionMatrix(const gfx::Matrix4x4& aMatrix)
-  {
-    mIsProjectionMatrixStale = true;
-    mProjectionMatrix = aMatrix;
-  }
-
   void SetProjectionMatrix(const gfx::Matrix4x4& aMatrix) {
     SetMatrixUniform(KnownUniform::MatrixProj, aMatrix);
-    mIsProjectionMatrixStale = false;
   }
 
   // sets this program's texture transform, if it uses one
   void SetTextureTransform(const gfx::Matrix4x4& aMatrix) {
     SetMatrixUniform(KnownUniform::TextureTransform, aMatrix);
   }
 
   void SetRenderOffset(const nsIntPoint& aOffset) {
@@ -449,35 +401,42 @@ public:
     SetUniform(KnownUniform::RenderColor, aColor);
   }
 
   void SetTexCoordMultiplier(float aWidth, float aHeight) {
     float f[] = {aWidth, aHeight};
     SetUniform(KnownUniform::TexCoordMultiplier, 2, f);
   }
 
+  // Set whether we want the component alpha shader to return the color
+  // vector (pass 1, false) or the alpha vector (pass2, true). With support
+  // for multiple render targets we wouldn't need two passes here.
+  void SetTexturePass2(bool aFlag) {
+    SetUniform(KnownUniform::TexturePass2, aFlag ? 1 : 0);
+  }
+
   // the names of attributes
   static const char* const VertexCoordAttrib;
   static const char* const TexCoordAttrib;
 
 protected:
-  gfx::Matrix4x4 mProjectionMatrix;
-  // true if the projection matrix needs setting
-  bool mIsProjectionMatrixStale;
-
   RefPtr<GLContext> mGL;
   // the OpenGL id of the program
   GLuint mProgram;
   ProgramProfileOGL mProfile;
   enum {
     STATE_NEW,
     STATE_OK,
     STATE_ERROR
   } mProgramState;
 
+#ifdef CHECK_CURRENT_PROGRAM
+  static int sCurrentProgramKey;
+#endif
+
   void SetUniform(KnownUniform::KnownUniformName aKnownUniform, float aFloatValue)
   {
     ASSERT_THIS_PROGRAM;
     NS_ASSERTION(aKnownUniform >= 0 && aKnownUniform < KnownUniform::KnownUniformCount, "Invalid known uniform");
 
     KnownUniform& ku(mProfile.mUniforms[aKnownUniform]);
     if (ku.UpdateUniform(aFloatValue)) {
       mGL->fUniform1f(ku.mLocation, aFloatValue);
deleted file mode 100644
--- a/gfx/layers/opengl/OGLShaders.h
+++ /dev/null
@@ -1,1045 +0,0 @@
-/* AUTOMATICALLY GENERATED from OGLShaders.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\
-varying vec2 vTexCoord;\n\
-\n\
-void main()\n\
-{\n\
-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 = (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\
-varying vec2 vTexCoord;\n\
-\n\
-uniform mat4 uMaskQuadTransform;\n\
-varying vec2 vMaskCoord;\n\
-\n\
-void main()\n\
-{\n\
-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 = (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\
-varying vec2 vTexCoord;\n\
-\n\
-uniform mat4 uMaskQuadTransform;\n\
-varying vec3 vMaskCoord;\n\
-\n\
-void main()\n\
-{\n\
-vec4 finalPosition = aVertexCoord;\n\
-finalPosition = uLayerQuadTransform * finalPosition;\n\
-finalPosition = uLayerTransform * finalPosition;\n\
-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 = (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\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform COLOR_PRECISION vec4 uRenderColor;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = mask * uRenderColor;\n\
-}\n\
-";
-
-static const char sSolidColorLayerMaskFS[] = "/* sSolidColorLayerMaskFS */\n\
-#define NO_LAYER_OPACITY 1\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform COLOR_PRECISION vec4 uRenderColor;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = mask * uRenderColor;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerFS[] = "/* sRGBATextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerMaskFS[] = "/* sRGBATextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBATextureLayerMask3DFS[] = "/* sRGBATextureLayerMask3DFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec3 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBARectTextureLayerFS[] = "/* sRGBARectTextureLayerFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sRGBARectTextureLayerMaskFS[] = "/* sRGBARectTextureLayerMaskFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sRGBARectTextureLayerMask3DFS[] = "/* sRGBARectTextureLayerMask3DFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec3 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;\n\
-\n\
-gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sRGBXRectTextureLayerFS[] = "/* sRGBXRectTextureLayerFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).rgb, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sRGBXRectTextureLayerMaskFS[] = "/* sRGBXRectTextureLayerMaskFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).rgb, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sRGBXRectTextureLayerMask3DFS[] = "/* sRGBXRectTextureLayerMask3DFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec3 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-/* This should not be used on GL ES */\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;\n\
-\n\
-gl_FragColor = vec4(texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).rgb, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
-static const char sBGRARectTextureLayerFS[] = "/* sBGRARectTextureLayerFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2DRect uTexture;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-void main()\n\
-{\n\
-gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).bgra * uLayerOpacity;\n\
-}\n\
-";
-
-static const char sRGBAExternalTextureLayerFS[] = "/* sRGBAExternalTextureLayerFS */\n\
-#extension GL_OES_EGL_image_external : require\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform samplerExternalOES uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBAExternalTextureLayerMaskFS[] = "/* sRGBAExternalTextureLayerMaskFS */\n\
-#extension GL_OES_EGL_image_external : require\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform samplerExternalOES uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBAExternalTextureLayerMask3DFS[] = "/* sRGBAExternalTextureLayerMask3DFS */\n\
-#extension GL_OES_EGL_image_external : require\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec3 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform samplerExternalOES uTexture;\n\
-void main()\n\
-{\n\
-vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sBGRATextureLayerFS[] = "/* sBGRATextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord).bgra * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sBGRATextureLayerMaskFS[] = "/* sBGRATextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = texture2D(uTexture, vTexCoord).bgra * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBXTextureLayerFS[] = "/* sRGBXTextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).rgb, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sRGBXTextureLayerMaskFS[] = "/* sRGBXTextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).rgb, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sBGRXTextureLayerFS[] = "/* sBGRXTextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sBGRXTextureLayerMaskFS[] = "/* sBGRXTextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sYCbCrTextureLayerFS[] = "/* sYCbCrTextureLayerFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#endif\n\
-uniform sampler2D uYTexture;\n\
-uniform sampler2D uCbTexture;\n\
-uniform sampler2D uCrTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec4 color;\n\
-COLOR_PRECISION float y = texture2D(uYTexture, vTexCoord).r;\n\
-COLOR_PRECISION float cb = texture2D(uCbTexture, vTexCoord).r;\n\
-COLOR_PRECISION float cr = texture2D(uCrTexture, vTexCoord).r;\n\
-y = (y - 0.0625) * 1.164;\n\
-cb = cb - 0.5;\n\
-cr = cr - 0.5;\n\
-color.r = y + cr * 1.596;\n\
-color.g = y - 0.813 * cr - 0.391 * cb;\n\
-color.b = y + cb * 2.018;\n\
-color.a = 1.0;\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = color * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sYCbCrTextureLayerMaskFS[] = "/* sYCbCrTextureLayerMaskFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#endif\n\
-uniform sampler2D uYTexture;\n\
-uniform sampler2D uCbTexture;\n\
-uniform sampler2D uCrTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec4 color;\n\
-COLOR_PRECISION float y = texture2D(uYTexture, vTexCoord).r;\n\
-COLOR_PRECISION float cb = texture2D(uCbTexture, vTexCoord).r;\n\
-COLOR_PRECISION float cr = texture2D(uCrTexture, vTexCoord).r;\n\
-y = (y - 0.0625) * 1.164;\n\
-cb = cb - 0.5;\n\
-cr = cr - 0.5;\n\
-color.r = y + cr * 1.596;\n\
-color.g = y - 0.813 * cr - 0.391 * cb;\n\
-color.b = y + cb * 2.018;\n\
-color.a = 1.0;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = color * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPass1FS[] = "/* sComponentPass1FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = alphas * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPassMask1FS[] = "/* sComponentPassMask1FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = alphas * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPass1RGBFS[] = "/* sComponentPass1RGBFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = alphas * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPassMask1RGBFS[] = "/* sComponentPassMask1RGBFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = alphas * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPass2FS[] = "/* sComponentPass2FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPassMask2FS[] = "/* sComponentPassMask2FS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPass2RGBFS[] = "/* sComponentPass2RGBFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = 1.0;\n\
-\n\
-gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sComponentPassMask2RGBFS[] = "/* sComponentPassMask2RGBFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-#ifndef NO_LAYER_OPACITY\n\
-uniform COLOR_PRECISION float uLayerOpacity;\n\
-#endif\n\
-varying vec2 vTexCoord;\n\
-\n\
-varying vec2 vMaskCoord;\n\
-uniform sampler2D uMaskTexture;\n\
-\n\
-uniform sampler2D uBlackTexture;\n\
-uniform sampler2D uWhiteTexture;\n\
-void main()\n\
-{\n\
-COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).rgb;\n\
-COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;\n\
-COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;\n\
-\n\
-gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;\n\
-}\n\
-";
-
-static const char sCopyVS[] = "/* sCopyVS */\n\
-/* Vertex Shader */\n\
-attribute vec4 aVertexCoord;\n\
-attribute vec2 aTexCoord;\n\
-varying vec2 vTexCoord;\n\
-void main()\n\
-{\n\
-gl_Position = aVertexCoord;\n\
-vTexCoord = aTexCoord;\n\
-}\n\
-";
-
-static const char sCopy2DFS[] = "/* sCopy2DFS */\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-varying vec2 vTexCoord;\n\
-uniform sampler2D uTexture;\n\
-void main()\n\
-{\n\
-gl_FragColor = texture2D(uTexture, vTexCoord);\n\
-}\n\
-";
-
-static const char sCopy2DRectFS[] = "/* sCopy2DRectFS */\n\
-#extension GL_ARB_texture_rectangle : enable\n\
-/* Fragment Shader */\n\
-#ifdef GL_ES\n\
-precision mediump float;\n\
-#define COLOR_PRECISION lowp\n\
-#else\n\
-#define COLOR_PRECISION\n\
-#endif\n\
-\n\
-varying vec2 vTexCoord;\n\
-uniform vec2 uTexCoordMultiplier;\n\
-#ifndef GL_ES\n\
-uniform sampler2DRect uTexture;\n\
-void main()\n\
-{\n\
-gl_FragColor = texture2DRect(uTexture, vTexCoord * uTexCoordMultiplier);\n\
-}\n\
-#else\n\
-void main()\n\
-{\n\
-gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n\
-}\n\
-#endif\n\
-";
-
deleted file mode 100644
--- a/gfx/layers/opengl/OGLShaders.txt
+++ /dev/null
@@ -1,495 +0,0 @@
-// -*- Mode: glsl; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40; -*-
-
-// 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/.
-
-// This file is compiled by genshaders.py, use genshaders.sh, no arguments necessary.
-// The compiled shaders will be in LayerManagerOGLShaders.h.
-// This file must be compiled after editing, it is not compiled as part of the
-// build process.
-//
-// Syntax:
-//
-// // comments (only at the start of a line)
-//
-// (@ is used because # is valid inside GLSL)
-//
-// multi-line:
-// @define FOO
-// ...
-// @end
-//
-// single:
-// @define FOO 123
-//
-// $FOO$ to paste
-//
-// To generate a constant string named ShaderName (shader name should not
-// use '<', '>', ',', ':', except for parameters, see below):
-// @shader ShaderName
-// ...
-// @end
-//
-// @shader may have a single parameter with multiple values using
-// <param:val1,val2> an empty value is allowed. The shader is expanded for
-// each value, <param> in the body of the shader will be expanded to
-// the current value, as will the declaration of the parameter. The name of
-// defines may include <...> and this should work as expected.
-// 
-// For example:
-//
-// @Shader<name:Name1,Name2>
-// string name = "<name>";
-// @end
-//
-// will be expanded to
-//
-// @ShaderName1
-// string name = "Name1";
-// @end
-// @ShaderName2
-// string name = "Name2";
-// @end
-//
-// This will be straightaway compiled to two constant strings named
-// ShaderName1 and ShaderName2.
-// 
-
-@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;
-
-varying vec2 vTexCoord;
-@end
-
-@define VERTEX_SHADER_HEADER<Mask>
-$VERTEX_SHADER_HEADER<>$
-
-uniform mat4 uMaskQuadTransform;
-varying vec2 vMaskCoord;
-@end
-
-@define VERTEX_SHADER_HEADER<Mask3D>
-$VERTEX_SHADER_HEADER<>$
-
-uniform mat4 uMaskQuadTransform;
-varying vec3 vMaskCoord;
-@end
-
-@define VERTEX_MASK_STUFF<>
-@end
-
-@define VERTEX_MASK_STUFF<Mask>
-  vMaskCoord = (uMaskQuadTransform * finalPosition).xy;
-@end
-
-@define VERTEX_MASK_STUFF<Mask3D> 
-  vMaskCoord.xy = (uMaskQuadTransform * vec4(finalPosition.xyz, 1.0)).xy;
-  // correct for perspective correct interpolation, see comment in D3D10 shader
-  vMaskCoord.z = 1.0;
-  vMaskCoord *= finalPosition.w;
-@end
-
-
-// This is a basic Layer vertex shader.  It's used for all
-// Layer programs.
-
-@shader sLayer<mask:,Mask,Mask3D>VS
-$VERTEX_SHADER_HEADER<mask>$
-
-
-void main()
-{
-  vec4 finalPosition = aVertexCoord;
-  finalPosition = uLayerQuadTransform * finalPosition;
-  finalPosition = uLayerTransform * finalPosition;
-  finalPosition.xyz /= finalPosition.w;
-
-$VERTEX_MASK_STUFF<mask>$
-
-  finalPosition = finalPosition - uRenderTargetOffset;
-  finalPosition.xyz *= finalPosition.w;
-  finalPosition = uMatrixProj * finalPosition;
-
-  vTexCoord = (uTextureTransform * vec4(aTexCoord.x, aTexCoord.y, 0.0, 1.0)).xy;
-
-  gl_Position = finalPosition;
-}
-@end
-
-
-/*
- * Fragment shaders
- */
-
-@define FRAGMENT_SHADER_HEADER
-/* Fragment Shader */
-#ifdef GL_ES
-precision mediump float;
-#define COLOR_PRECISION lowp
-#else
-#define COLOR_PRECISION
-#endif
-@end
-
-// fragment shader header for layers
-@define LAYER_FRAGMENT<>
-$FRAGMENT_SHADER_HEADER$
-
-#ifndef NO_LAYER_OPACITY
-uniform COLOR_PRECISION float uLayerOpacity;
-#endif
-
-varying vec2 vTexCoord;
-@end
-
-// fragment shader header for layers with masks
-@define LAYER_FRAGMENT<Mask>
-$LAYER_FRAGMENT<>$
-
-varying vec2 vMaskCoord;
-uniform sampler2D uMaskTexture;
-@end
-
-// fragment shader header for layers with masks and 3D transforms
-@define LAYER_FRAGMENT<Mask3D>
-$LAYER_FRAGMENT<>$
-
-varying vec3 vMaskCoord;
-uniform sampler2D uMaskTexture;
-@end
-
-@define FRAGMENT_CALC_MASK<>
-  COLOR_PRECISION float mask = 1.0;
-@end
-
-@define FRAGMENT_CALC_MASK<Mask>
-  COLOR_PRECISION float mask = texture2D(uMaskTexture, vMaskCoord).r;
-@end
-
-@define FRAGMENT_CALC_MASK<Mask3D>
-  vec2 maskCoords = vMaskCoord.xy / vMaskCoord.z;
-  COLOR_PRECISION float mask = texture2D(uMaskTexture, maskCoords).r;
-@end
-
-// Solid color rendering.
-// texcoords are ignored (no texture to sample).
-// The layer opacity is baked in to the color.
-@shader sSolidColorLayer<mask:,Mask>FS
-#define NO_LAYER_OPACITY 1
-$LAYER_FRAGMENT<mask>$
-uniform COLOR_PRECISION vec4 uRenderColor;
-
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = mask * uRenderColor;
-}
-@end
-
-// Single texture in RGBA format
-@shader sRGBATextureLayer<mask:,Mask,Mask3D>FS
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uTexture;
-
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = texture2D(uTexture, vTexCoord) * 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 */
-#ifndef GL_ES
-uniform sampler2DRect uTexture;
-uniform vec2 uTexCoordMultiplier;
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)) * uLayerOpacity * mask;
-}
-#else
-void main()
-{
-  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
-}
-#endif
-@end
-
-@shader sRGBXRectTextureLayer<mask:,Mask,Mask3D>FS
-#extension GL_ARB_texture_rectangle : enable
-
-$LAYER_FRAGMENT<mask>$
-
-/* This should not be used on GL ES */
-#ifndef GL_ES
-uniform sampler2DRect uTexture;
-uniform vec2 uTexCoordMultiplier;
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = vec4(texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).rgb, 1.0) * uLayerOpacity * mask;
-}
-#else
-void main()
-{
-  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
-}
-#endif
-@end
-
-// Single texture in BGRA format, but with a Rect texture.
-// nsChildView needs this for old Mac hardware.
-@shader sBGRARectTextureLayerFS
-#extension GL_ARB_texture_rectangle : enable
-
-$LAYER_FRAGMENT<>$
-
-uniform sampler2DRect uTexture;
-uniform vec2 uTexCoordMultiplier;
-void main()
-{
-  gl_FragColor = texture2DRect(uTexture, vec2(vTexCoord * uTexCoordMultiplier)).bgra * uLayerOpacity;
-}
-@end
-
-
-// Single texture in RGBA format, but uses external image.  External
-// image is an EGLImage which have internal formats not otherwise
-// supported by OpenGL ES. It is up to the implementation exactly what
-// formats are accepted. It is specified in the OES_EGL_image_external
-// extension.
-@shader sRGBAExternalTextureLayer<mask:,Mask,Mask3D>FS
-#extension GL_OES_EGL_image_external : require
-
-$LAYER_FRAGMENT<mask>$
-uniform samplerExternalOES uTexture;
-
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = texture2D(uTexture, vTexCoord) * uLayerOpacity * mask;
-}
-@end
-
-
-// Single texture in BGRA format (via swizzle)
-@shader sBGRATextureLayer<mask:,Mask>FS
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uTexture;
-
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = texture2D(uTexture, vTexCoord).bgra * uLayerOpacity * mask;
-}
-@end
-
-// Single texture in RGBX format
-@shader sRGBXTextureLayer<mask:,Mask>FS
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uTexture;
-
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = vec4(texture2D(uTexture, vTexCoord).rgb, 1.0) * uLayerOpacity * mask;
-}
-@end
-
-// Single texture in BGRX format (via swizzle)
-@shader sBGRXTextureLayer<mask:,Mask>FS
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uTexture;
-
-void main()
-{
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = vec4(texture2D(uTexture, vTexCoord).bgr, 1.0) * uLayerOpacity * mask;
-}
-@end
-
-// Three textures, representing YCbCr planes of a video image.
-//
-// Some older versions of the Tegra 2 android driver have a bug
-// where arithmetic ops on a texture read are just ignored.  So,
-// if the below was |cb = texture2D(...).r - 0.5|, the "- 0.5" was
-// just being ignored/skipped.  This, of course, lead to crappy
-// rendering -- see bug 765150.  Doing them separately like below
-// makes it all OK.  We don't know if this is special to constants,
-// special to 0.5, special to addition/subtraction, etc.
-@shader sYCbCrTextureLayer<mask:,Mask>FS
-$LAYER_FRAGMENT<mask>$
-#ifdef GL_ES
-precision mediump float;
-#endif
-uniform sampler2D uYTexture;
-uniform sampler2D uCbTexture;
-uniform sampler2D uCrTexture;
-
-void main()
-{
-  COLOR_PRECISION vec4 color;
-
-  COLOR_PRECISION float y = texture2D(uYTexture, vTexCoord).r;
-  COLOR_PRECISION float cb = texture2D(uCbTexture, vTexCoord).r;
-  COLOR_PRECISION float cr = texture2D(uCrTexture, vTexCoord).r;
-
-  y = (y - 0.0625) * 1.164;
-  cb = cb - 0.5;
-  cr = cr - 0.5;
-
-  color.r = y + cr * 1.596;
-  color.g = y - 0.813 * cr - 0.391 * cb;
-  color.b = y + cb * 2.018;
-  color.a = 1.0;
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = color * uLayerOpacity * mask;
-}
-@end
-
-// Two textures and two passes for component alpha rendering
-@shader sComponentPass<mask:,Mask>1FS
-
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uBlackTexture;
-uniform sampler2D uWhiteTexture;
-
-void main()
-{
-  COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;
-  COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;
-  COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = alphas * uLayerOpacity * mask;
-}
-@end
-
-@shader sComponentPass<mask:,Mask>1RGBFS
-
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uBlackTexture;
-uniform sampler2D uWhiteTexture;
-
-void main()
-{
-  COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).rgb;
-  COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).rgb;
-  COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = alphas * uLayerOpacity * mask;
-}
-@end
-
-@shader sComponentPass<mask:,Mask>2FS
-
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uBlackTexture;
-uniform sampler2D uWhiteTexture;
-
-void main()
-{
-  COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).bgr;
-  COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).bgr;
-  COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;
-}
-@end
-
-@shader sComponentPass<mask:,Mask>2RGBFS
-
-$LAYER_FRAGMENT<mask>$
-uniform sampler2D uBlackTexture;
-uniform sampler2D uWhiteTexture;
-
-void main()
-{
-  COLOR_PRECISION vec3 onBlack = texture2D(uBlackTexture, vTexCoord).rgb;
-  COLOR_PRECISION vec3 onWhite = texture2D(uWhiteTexture, vTexCoord).rgb;
-  COLOR_PRECISION vec4 alphas = (1.0 - onWhite + onBlack).rgbg;
-$FRAGMENT_CALC_MASK<mask>$
-  gl_FragColor = vec4(onBlack, alphas.a) * uLayerOpacity * mask;
-}
-@end
-
-
-//
-// The "Copy" program is used for blitting a texture to a destination
-// with no transforms or any other manipulation.  They're used for
-// blitting the contents of a FBO-rendered texture to a destination.
-//
-// There are two variants of the fragment shader: one that uses 2D
-// textures and one that uses 2DRect textures (for when
-// EXT_TEXTURE_RECTANGLE is used for FBOs).
-//
-// On GL ES, EXT_TEXTURE_RECTANGLE isn't available, so we still
-// compile the shader but have it render pure red.  It should never
-// be used.
-//
-
-@shader sCopyVS
-/* Vertex Shader */
-
-attribute vec4 aVertexCoord;
-attribute vec2 aTexCoord;
-
-varying vec2 vTexCoord;
-
-void main()
-{
-  gl_Position = aVertexCoord;
-  vTexCoord = aTexCoord;
-}
-@end
-
-@shader sCopy2DFS
-$FRAGMENT_SHADER_HEADER$
-
-varying vec2 vTexCoord;
-
-uniform sampler2D uTexture;
-void main()
-{
-  gl_FragColor = texture2D(uTexture, vTexCoord);
-}
-@end
-
-@shader sCopy2DRectFS
-#extension GL_ARB_texture_rectangle : enable
-
-$FRAGMENT_SHADER_HEADER$
-
-varying vec2 vTexCoord;
-uniform vec2 uTexCoordMultiplier;
-
-#ifndef GL_ES
-uniform sampler2DRect uTexture;
-void main()
-{
-  gl_FragColor = texture2DRect(uTexture, vTexCoord * uTexCoordMultiplier);
-}
-#else
-void main()
-{
-  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
-}
-#endif
-@end
-
--- a/gfx/layers/opengl/TextureHostOGL.h
+++ b/gfx/layers/opengl/TextureHostOGL.h
@@ -88,39 +88,16 @@ protected:
  * released. At the moment the teardown sequence happens in the middle of
  * the nsBaseWidget's destructor, meaning that at a given moment we must be
  * able to easily find and release all the GL resources.
  * The point is: be careful about the ownership model and limit the number
  * of objects sharing references to GL resources to make the tear down
  * sequence as simple as possible.
  */
 
-inline ShaderProgramType
-GetProgramTypeForSurfaceFormat(gfx::SurfaceFormat aFormat)
- {
-  switch (aFormat) {
-  case gfx::SurfaceFormat::B8G8R8A8:
-    return BGRALayerProgramType;;
-  case gfx::SurfaceFormat::B8G8R8X8:
-    return BGRXLayerProgramType;;
-  case gfx::SurfaceFormat::R8G8B8X8:
-    return RGBXLayerProgramType;;
-  case gfx::SurfaceFormat::R8G8B8A8:
-    return RGBALayerProgramType;;
-  default:
-    MOZ_CRASH("unhandled program type");
-  }
-}
-
-inline ShaderProgramType
-GetProgramTypeForTexture(const DeprecatedTextureHost *aDeprecatedTextureHost)
-{
-  return GetProgramTypeForSurfaceFormat(aDeprecatedTextureHost->GetFormat());
-}
-
 /**
  * TextureSourceOGL provides the necessary API for CompositorOGL to composite
  * a TextureSource.
  */
 class TextureSourceOGL
 {
 public:
   virtual bool IsValid() const = 0;
deleted file mode 100644
--- a/gfx/layers/opengl/genshaders.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# 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/.
-
-
-import sys
-import re
-import string
-
-defines = dict()
-
-def parseShaderName(shadername):
-  name = ""
-  params = {}
-  inparams = None
-  inparam = None
-  curparams = []
-  for c in shadername:
-    if c == '<':
-      inparams = ''
-    elif c == ':':
-      if inparams is None:
-        raise Exception(": in shader name")
-      inparam = ''
-    elif c == ',':
-      if inparams is None:
-        raise Exception(", in shader name")
-      if inparam is None:
-        raise Exception("no values for parameter " + inparams)
-      curparams.append(inparam)
-      inparam = ''
-    elif c == '>':
-      if inparams is None:
-        raise Exception("> in shader name")
-      if inparam is None:
-        raise Exception("no values for parameter " + inparams)
-      curparams.append(inparam)
-      params[inparams] = curparams
-      name += '$' + inparams + '$'
-      inparams = None
-      inparam = None
-    else:
-      if inparam is not None:
-        inparam += c
-      elif inparams is not None:
-        inparams += c
-      else:
-        name += c
-  return (name, params)
-
-def emitShader(fp, shadername, shaderlines):
-    (parsedname, params) = parseShaderName(shadername)
-    eolContinue = "\\n\\\n";
-    pvals = ['']
-    pname = ''
-    pnames = params.keys()
-    if len(pnames) > 1:
-      raise Exception("Currently only supports zero or one parameters to a @shader")
-    if pnames:
-      pname = pnames[0]
-      pvals = params[pname]
-    for pval in pvals:
-      name = parsedname.replace('$' + pname + '$', pval, 1);
-      fp.write("static const char %s[] = \"/* %s */%s" % (name,name,eolContinue))
-      for line in shaderlines:
-          line = line.replace("\\", "\\\\")
-          while line.find('$') != -1:
-              expansions = re.findall('\$\S+\$', line)
-              for m in expansions:
-                  mkey = m[1:-1]
-                  mkey = mkey.replace('<' + pname + '>', '<' + pval + '>')
-                  if not defines.has_key(mkey):
-                      print "Error: Undefined expansion used: '%s'" % (m,)
-                      sys.exit(1)
-                  mval = defines[mkey]
-                  if type(mval) == str:
-                      line = line.replace(m, mval)
-                  elif type(mval) == list:
-                      line = line.replace(m, eolContinue.join(mval) + eolContinue);
-                  else:
-                      print "Internal Error: Unknown type in defines array: '%s'" % (str(type(mval)),)
-
-          fp.write("%s%s" % (line,eolContinue))
-      fp.write("\";\n\n");
-
-def genShaders(infile, outfile):
-    source = open(infile, "r").readlines()
-    desthdr = open(outfile, "w+")
-
-    desthdr.write("/* AUTOMATICALLY GENERATED from " + infile + " */\n");
-    desthdr.write("/* DO NOT EDIT! */\n\n");
-
-    global defines
-
-    indefine = None
-    inshader = None
-
-    inblock = False
-    linebuffer = []
-
-    for line in source:
-        # strip comments, if not inblock
-        if not inblock and line.startswith("//"):
-            continue
-        line = string.strip(line)
-
-        if len(line) == 0:
-            continue
-
-        if line[0] == '@':
-            cmd = line
-            rest = ''
-
-            if line.find(' ') != -1:
-                cmd = line[0:line.find(' ')]
-                rest = string.strip(line[len(cmd) + 1:])
-                
-            if cmd == "@define":
-                if inblock:
-                    raise Exception("@define inside a block!")
-                space = rest.find(' ')
-                if space != -1:
-                    defines[rest[0:space]] = rest[space+1:]
-                else:
-                    indefine = rest
-                    inblock = True
-            elif cmd == "@shader":
-                if inblock:
-                    raise Exception("@shader inside a block!")
-                if len(rest) == 0:
-                    raise Exception("@shader without a name!")
-                inshader = rest
-                inblock = True
-            elif cmd == "@end":
-                if indefine is not None:
-                    if type(linebuffer) == list:
-                        for i in range(len(linebuffer)):
-                            linebuffer[i] = linebuffer[i].replace("\\", "\\\\")
-                    defines[indefine] = linebuffer
-                elif inshader is not None:
-                    emitShader(desthdr, inshader, linebuffer)
-                else:
-                    raise Exception("@end outside of a block!")
-                indefine = None
-                inshader = None
-                inblock = None
-                linebuffer = []
-            else:
-                raise Exception("Unknown command: %s" % (cmd,))
-        else:
-            if inblock:
-                linebuffer.append(line)
-
-if (len(sys.argv) != 3):
-    print "Usage: %s infile.txt outfile.h" % (sys.argv[0],)
-    sys.exit(1)
-
-genShaders(sys.argv[1], sys.argv[2])
deleted file mode 100644
--- a/gfx/layers/opengl/genshaders.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-# 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/.
-
-python genshaders.py OGLShaders.txt OGLShaders.h
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -337,34 +337,40 @@ public:
     nsRefPtr<GLContext> context = gl::GLContextProvider::CreateForWindow(aWindow);
     return context ? new GLPresenter(context) : nullptr;
   }
 
   GLPresenter(GLContext* aContext);
   virtual ~GLPresenter();
 
   virtual GLContext* gl() const MOZ_OVERRIDE { return mGLContext; }
-  virtual ShaderProgramOGL* GetProgram(ShaderProgramType aType) MOZ_OVERRIDE
+  virtual ShaderProgramOGL* GetProgram(GLenum aTarget, gfx::SurfaceFormat aFormat) MOZ_OVERRIDE
   {
-    MOZ_ASSERT(aType == RGBARectLayerProgramType, "unexpected program type");
+    MOZ_ASSERT(aTarget == LOCAL_GL_TEXTURE_RECTANGLE_ARB);
+    MOZ_ASSERT(aFormat == gfx::SurfaceFormat::R8G8B8A8);
     return mRGBARectProgram;
   }
+  virtual const gfx::Matrix4x4& GetProjMatrix() const MOZ_OVERRIDE
+  {
+    return mProjMatrix;
+  }
   virtual void BindAndDrawQuad(ShaderProgramOGL *aProg) MOZ_OVERRIDE;
 
   void BeginFrame(nsIntSize aRenderSize);
   void EndFrame();
 
   NSOpenGLContext* GetNSOpenGLContext()
   {
     return GLContextCGL::Cast(mGLContext)->GetNSOpenGLContext();
   }
 
 protected:
   nsRefPtr<mozilla::gl::GLContext> mGLContext;
   nsAutoPtr<mozilla::layers::ShaderProgramOGL> mRGBARectProgram;
+  gfx::Matrix4x4 mProjMatrix;
   GLuint mQuadVBO;
 };
 
 } // unnamed namespace
 
 #pragma mark -
 
 nsChildView::nsChildView() : nsBaseWidget()
@@ -2738,44 +2744,47 @@ RectTextureImage::UpdateFromDrawTarget(c
   mUpdateDrawTarget = nullptr;
 }
 
 void
 RectTextureImage::Draw(GLManager* aManager,
                        const nsIntPoint& aLocation,
                        const gfx3DMatrix& aTransform)
 {
-  ShaderProgramOGL* program = aManager->GetProgram(RGBARectLayerProgramType);
+  ShaderProgramOGL* program = aManager->GetProgram(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
+                                                   gfx::SurfaceFormat::R8G8B8A8);
 
   aManager->gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, mTexture);
 
   program->Activate();
+  program->SetProjectionMatrix(aManager->GetProjMatrix());
   program->SetLayerQuadRect(nsIntRect(nsIntPoint(0, 0), mUsedSize));
   gfx::Matrix4x4 transform;
   gfx::ToMatrix4x4(aTransform, transform);
   program->SetLayerTransform(transform * gfx::Matrix4x4().Translate(aLocation.x, aLocation.y, 0));
   program->SetTextureTransform(gfx::Matrix4x4());
-  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);
 }
 
 // GLPresenter implementation
 
 GLPresenter::GLPresenter(GLContext* aContext)
  : mGLContext(aContext)
 {
   mGLContext->MakeCurrent();
+  ShaderConfigOGL config;
+  config.SetTextureTarget(LOCAL_GL_TEXTURE_RECTANGLE_ARB);
   mRGBARectProgram = new ShaderProgramOGL(mGLContext,
-    ProgramProfileOGL::GetProfileFor(RGBARectLayerProgramType, MaskNone));
+    ProgramProfileOGL::GetProfileFor(config));
 
   // Create mQuadVBO.
   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,
@@ -2791,17 +2800,17 @@ GLPresenter::~GLPresenter()
   if (mQuadVBO) {
     mGLContext->MakeCurrent();
     mGLContext->fDeleteBuffers(1, &mQuadVBO);
     mQuadVBO = 0;
   }
 }
 
 void
-GLPresenter::BindAndDrawQuad(ShaderProgramOGL* aProgram)
+GLPresenter::BindAndDrawQuad(ShaderProgramOGL *aProgram)
 {
   mGLContext->MakeCurrent();
 
   GLuint vertAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::VertexCoordAttrib);
   GLuint texCoordAttribIndex = aProgram->AttribLocation(ShaderProgramOGL::TexCoordAttrib);
 
   mGLContext->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, mQuadVBO);
   mGLContext->fVertexAttribPointer(vertAttribIndex, 2,
@@ -2830,17 +2839,17 @@ GLPresenter::BeginFrame(nsIntSize aRende
   viewMatrix.Translate(-1.0, 1.0);
   viewMatrix.Scale(2.0f / float(aRenderSize.width), 2.0f / float(aRenderSize.height));
   viewMatrix.Scale(1.0f, -1.0f);
 
   gfx::Matrix4x4 matrix3d = gfx::Matrix4x4::From2D(viewMatrix);
   matrix3d._33 = 0.0f;
 
   // set the projection matrix for the next time the program is activated
-  mRGBARectProgram->DelayedSetProjectionMatrix(matrix3d);
+  mProjMatrix = matrix3d;
 
   // Default blend function implements "OVER"
   mGLContext->fBlendFuncSeparate(LOCAL_GL_ONE, LOCAL_GL_ONE_MINUS_SRC_ALPHA,
                                  LOCAL_GL_ONE, LOCAL_GL_ONE);
   mGLContext->fEnable(LOCAL_GL_BLEND);
 
   mGLContext->fClearColor(0.0, 0.0, 0.0, 0.0);
   mGLContext->fClear(LOCAL_GL_COLOR_BUFFER_BIT | LOCAL_GL_DEPTH_BUFFER_BIT);