Bug 942501 - Part 3: move CreateTextureImage and TileGenFunc out of GLContext - r=BenWa
authorBenoit Jacob <bjacob@mozilla.com>
Tue, 03 Dec 2013 13:44:38 -0500
changeset 158921 17964f955e0cfbe306b4afdc427643686fef8936
parent 158920 55109f1334e77064af6bff3d10ea618b27cc4b01
child 158922 3f08f279aec71e1f8c3248d49db58a3a4c978d83
push id270
push userpvanderbeken@mozilla.com
push dateThu, 06 Mar 2014 09:24:21 +0000
reviewersBenWa
bugs942501
milestone28.0a1
Bug 942501 - Part 3: move CreateTextureImage and TileGenFunc out of GLContext - r=BenWa
gfx/gl/GLContext.cpp
gfx/gl/GLContext.h
gfx/gl/GLContextProviderCGL.mm
gfx/gl/GLContextProviderEGL.cpp
gfx/gl/GLContextProviderGLX.cpp
gfx/gl/GLTextureImage.cpp
gfx/gl/GLTextureImage.h
gfx/gl/TextureImageCGL.h
gfx/gl/TextureImageCGL.mm
gfx/gl/TextureImageEGL.cpp
gfx/gl/TextureImageEGL.h
gfx/layers/opengl/TextureHostOGL.cpp
--- a/gfx/gl/GLContext.cpp
+++ b/gfx/gl/GLContext.cpp
@@ -1315,27 +1315,16 @@ GLContext::ListHasExtension(const GLubyt
                 return true;
             }
         }
         start = terminator;
     }
     return false;
 }
 
-already_AddRefed<TextureImage>
-GLContext::CreateTextureImage(const nsIntSize& aSize,
-                              TextureImage::ContentType aContentType,
-                              GLenum aWrapMode,
-                              TextureImage::Flags aFlags,
-                              TextureImage::ImageFormat aImageFormat)
-{
-    return CreateBasicTextureImage(this, aSize, aContentType, aWrapMode,
-                                   aFlags, aImageFormat);
-}
-
 void GLContext::ApplyFilterToBoundTexture(GraphicsFilter aFilter)
 {
     ApplyFilterToBoundTexture(LOCAL_GL_TEXTURE_2D, aFilter);
 }
 
 void GLContext::ApplyFilterToBoundTexture(GLuint aTarget,
                                           GraphicsFilter aFilter)
 {
--- a/gfx/gl/GLContext.h
+++ b/gfx/gl/GLContext.h
@@ -2620,55 +2620,16 @@ public:
 
     void ForceDirtyScreen();
     void CleanDirtyScreen();
 
     virtual GLenum GetPreferredARGB32Format() { return LOCAL_GL_RGBA; }
 
     virtual bool RenewSurface() { return false; }
 
-    /**
-     * Return a valid, allocated TextureImage of |aSize| with
-     * |aContentType|.  If |aContentType| is COLOR, |aImageFormat| can be used
-     * to hint at the preferred RGB format, however it is not necessarily
-     * respected.  The TextureImage's texture is configured to use
-     * |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by
-     * default, GL_LINEAR filtering.  Specify
-     * |aFlags=UseNearestFilter| for GL_NEAREST filtering. Specify
-     * |aFlags=NeedsYFlip| if the image is flipped. Return
-     * nullptr if creating the TextureImage fails.
-     *
-     * The returned TextureImage may only be used with this GLContext.
-     * Attempting to use the returned TextureImage after this
-     * GLContext is destroyed will result in undefined (and likely
-     * crashy) behavior.
-     */
-    virtual already_AddRefed<TextureImage>
-    CreateTextureImage(const nsIntSize& aSize,
-                       TextureImage::ContentType aContentType,
-                       GLenum aWrapMode,
-                       TextureImage::Flags aFlags = TextureImage::NoFlags,
-                       TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown);
-
-    /**
-     * In EGL we want to use Tiled Texture Images, which we return
-     * from CreateTextureImage above.
-     * Inside TiledTextureImage we need to create actual images and to
-     * prevent infinite recursion we need to differentiate the two
-     * functions.
-     **/
-    virtual already_AddRefed<TextureImage>
-    TileGenFunc(const nsIntSize& aSize,
-                TextureImage::ContentType aContentType,
-                TextureImage::Flags aFlags = TextureImage::NoFlags,
-                TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown)
-    {
-        return nullptr;
-    }
-
 private:
     /**
      * Helpers for ReadTextureImage
      */
     GLuint TextureImageProgramFor(GLenum aTextureTarget, int aShader);
     bool ReadBackPixelsIntoSurface(gfxImageSurface* aSurface, const gfxIntSize& aSize);
 
 public:
--- a/gfx/gl/GLContextProviderCGL.mm
+++ b/gfx/gl/GLContextProviderCGL.mm
@@ -185,105 +185,26 @@ public:
     {
       PROFILER_LABEL("GLContext", "SwapBuffers");
       [mContext flushBuffer];
       return true;
     }
 
     bool ResizeOffscreen(const gfxIntSize& aNewSize);
 
-    virtual already_AddRefed<TextureImage>
-    CreateTextureImage(const nsIntSize& aSize,
-                       TextureImage::ContentType aContentType,
-                       GLenum aWrapMode,
-                       TextureImage::Flags aFlags = TextureImage::NoFlags,
-                       TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown) MOZ_OVERRIDE;
-
-    virtual already_AddRefed<TextureImage>
-    TileGenFunc(const nsIntSize& aSize,
-                TextureImage::ContentType aContentType,
-                TextureImage::Flags aFlags = TextureImage::NoFlags,
-                TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown) MOZ_OVERRIDE;
-
     NSOpenGLContext *mContext;
     GLuint mTempTextureName;
-
-    already_AddRefed<TextureImage>
-    CreateTextureImageInternal(const nsIntSize& aSize,
-                               TextureImage::ContentType aContentType,
-                               GLenum aWrapMode,
-                               TextureImage::Flags aFlags,
-                               TextureImage::ImageFormat aImageFormat);
-
 };
 
 bool
 GLContextCGL::ResizeOffscreen(const gfxIntSize& aNewSize)
 {
     return ResizeScreenBuffer(aNewSize);
 }
 
-already_AddRefed<TextureImage>
-GLContextCGL::CreateTextureImageInternal(const nsIntSize& aSize,
-                                         TextureImage::ContentType aContentType,
-                                         GLenum aWrapMode,
-                                         TextureImage::Flags aFlags,
-                                         TextureImage::ImageFormat aImageFormat)
-{
-    bool useNearestFilter = aFlags & TextureImage::UseNearestFilter;
-    MakeCurrent();
-
-    GLuint texture;
-    fGenTextures(1, &texture);
-
-    fActiveTexture(LOCAL_GL_TEXTURE0);
-    fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
-
-    GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
-    fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
-    fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
-    fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, aWrapMode);
-    fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, aWrapMode);
-
-    nsRefPtr<TextureImageCGL> teximage
-        (new TextureImageCGL(texture, aSize, aWrapMode, aContentType,
-                             this, aFlags, aImageFormat));
-    return teximage.forget();
-}
-
-already_AddRefed<TextureImage>
-GLContextCGL::CreateTextureImage(const nsIntSize& aSize,
-                                 TextureImage::ContentType aContentType,
-                                 GLenum aWrapMode,
-                                 TextureImage::Flags aFlags,
-                                 TextureImage::ImageFormat aImageFormat)
-{
-    if (!IsOffscreenSizeAllowed(gfxIntSize(aSize.width, aSize.height)) &&
-        gfxPlatform::OffMainThreadCompositingEnabled()) {
-      NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!");
-      nsRefPtr<TextureImage> t = new gl::TiledTextureImage(this, aSize, aContentType,
-                                                           aFlags, aImageFormat);
-      return t.forget();
-    }
-
-    return CreateBasicTextureImage(this, aSize, aContentType, aWrapMode,
-                                   aFlags, aImageFormat);
-}
-
-already_AddRefed<TextureImage>
-GLContextCGL::TileGenFunc(const nsIntSize& aSize,
-                          TextureImage::ContentType aContentType,
-                          TextureImage::Flags aFlags,
-                          TextureImage::ImageFormat aImageFormat)
-{
-    return CreateTextureImageInternal(aSize, aContentType,
-                                      LOCAL_GL_CLAMP_TO_EDGE, aFlags,
-                                      aImageFormat);
-}
-
 static GLContextCGL *
 GetGlobalContextCGL()
 {
     return static_cast<GLContextCGL*>(GLContextProviderCGL::GetGlobalContext());
 }
 
 already_AddRefed<GLContext>
 GLContextProviderCGL::CreateForWindow(nsIWidget *aWidget)
--- a/gfx/gl/GLContextProviderEGL.cpp
+++ b/gfx/gl/GLContextProviderEGL.cpp
@@ -529,30 +529,17 @@ public:
                 }
             } else
 #endif
                 return sEGLLibrary.fSwapBuffers(EGL_DISPLAY(), mSurface);
         } else {
             return false;
         }
     }
-    // GLContext interface - returns Tiled Texture Image in our case
-    virtual already_AddRefed<TextureImage>
-    CreateTextureImage(const nsIntSize& aSize,
-                       TextureImage::ContentType aContentType,
-                       GLenum aWrapMode,
-                       TextureImage::Flags aFlags = TextureImage::NoFlags,
-                       TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown);
 
-    // a function to generate Tiles for Tiled Texture Image
-    virtual already_AddRefed<TextureImage>
-    TileGenFunc(const nsIntSize& aSize,
-                TextureImage::ContentType aContentType,
-                TextureImage::Flags aFlags = TextureImage::NoFlags,
-                TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown) MOZ_OVERRIDE;
     // hold a reference to the given surface
     // for the lifetime of this context.
     void HoldSurface(gfxASurface *aSurf) {
         mThebesSurface = aSurf;
     }
 
     EGLContext Context() {
         return mContext;
@@ -632,53 +619,16 @@ protected:
 };
 
 bool
 GLContextEGL::ResizeOffscreen(const gfxIntSize& aNewSize)
 {
 	return ResizeScreenBuffer(aNewSize);
 }
 
-already_AddRefed<TextureImage>
-GLContextEGL::CreateTextureImage(const nsIntSize& aSize,
-                                 TextureImage::ContentType aContentType,
-                                 GLenum aWrapMode,
-                                 TextureImage::Flags aFlags,
-                                 TextureImage::ImageFormat aImageFormat)
-{
-    nsRefPtr<TextureImage> t = new gl::TiledTextureImage(this, aSize, aContentType, aFlags, aImageFormat);
-    return t.forget();
-}
-
-already_AddRefed<TextureImage>
-GLContextEGL::TileGenFunc(const nsIntSize& aSize,
-                          TextureImage::ContentType aContentType,
-                          TextureImage::Flags aFlags,
-                          TextureImage::ImageFormat aImageFormat)
-{
-  MakeCurrent();
-
-  GLuint texture;
-  fGenTextures(1, &texture);
-
-  nsRefPtr<TextureImageEGL> teximage =
-      new TextureImageEGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType,
-                          this, aFlags, TextureImage::Created, aImageFormat);
-  
-  teximage->BindTexture(LOCAL_GL_TEXTURE0);
-
-  GLint texfilter = aFlags & TextureImage::UseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
-  fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
-  fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
-  fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
-  fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
-
-  return teximage.forget();
-}
-
 static const EGLint kEGLConfigAttribsOffscreenPBuffer[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_PBUFFER_BIT,
     LOCAL_EGL_RENDERABLE_TYPE, LOCAL_EGL_OPENGL_ES2_BIT,
     LOCAL_EGL_NONE
 };
 
 static const EGLint kEGLConfigAttribsRGB16[] = {
     LOCAL_EGL_SURFACE_TYPE,    LOCAL_EGL_WINDOW_BIT,
--- a/gfx/gl/GLContextProviderGLX.cpp
+++ b/gfx/gl/GLContextProviderGLX.cpp
@@ -928,23 +928,16 @@ TRY_AGAIN_NO_SHARING:
     {
         if (!mDoubleBuffered)
             return false;
         mGLX->xSwapBuffers(mDisplay, mDrawable);
         mGLX->xWaitGL();
         return true;
     }
 
-    virtual already_AddRefed<TextureImage>
-    CreateTextureImage(const nsIntSize& aSize,
-                       TextureImage::ContentType aContentType,
-                       GLenum aWrapMode,
-                       TextureImage::Flags aFlags = TextureImage::NoFlags,
-                       TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown);
-
 private:
     friend class GLContextProviderGLX;
 
     GLContextGLX(const SurfaceCaps& caps,
                  GLContext* shareContext,
                  bool isOffscreen,
                  Display *aDisplay,
                  GLXDrawable aDrawable,
@@ -975,30 +968,16 @@ private:
     bool mDoubleBuffered;
 
     LibType mLibType;
     GLXLibrary* mGLX;
 
     nsRefPtr<gfxXlibSurface> mPixmap;
 };
 
-already_AddRefed<TextureImage>
-GLContextGLX::CreateTextureImage(const nsIntSize& aSize,
-                                 TextureImage::ContentType aContentType,
-                                 GLenum aWrapMode,
-                                 TextureImage::Flags aFlags,
-                                 TextureImage::ImageFormat aImageFormat)
-{
-    return GLContext::CreateTextureImage(aSize,
-                                         aContentType,
-                                         aWrapMode,
-                                         aFlags,
-                                         aImageFormat);
-}
-
 static GLContextGLX *
 GetGlobalContextGLX(const ContextFlags aFlags = ContextFlagsNone)
 {
     return static_cast<GLContextGLX*>(GLContextProviderGLX::GetGlobalContext(aFlags));
 }
 
 static bool
 AreCompatibleVisuals(Visual *one, Visual *two)
--- a/gfx/gl/GLTextureImage.cpp
+++ b/gfx/gl/GLTextureImage.cpp
@@ -6,27 +6,72 @@
 #include "GLTextureImage.h"
 #include "GLContext.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "gfx2DGlue.h"
 #include "ScopedGLHelpers.h"
 
+#include "TextureImageEGL.h"
+#ifdef XP_MACOSX
+#include "TextureImageCGL.h"
+#endif
+
 namespace mozilla {
 namespace gl {
 
 already_AddRefed<TextureImage>
+CreateTextureImage(GLContext* gl,
+                   const nsIntSize& aSize,
+                   TextureImage::ContentType aContentType,
+                   GLenum aWrapMode,
+                   TextureImage::Flags aFlags,
+                   TextureImage::ImageFormat aImageFormat)
+{
+    switch (gl->GetContextType()) {
+#ifdef XP_MACOSX
+        case ContextTypeCGL:
+            return CreateTextureImageCGL(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat);
+#endif
+        case ContextTypeEGL:
+            return CreateTextureImageEGL(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat);
+        default:
+            return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode, aFlags, aImageFormat);
+    }
+}
+
+
+static already_AddRefed<TextureImage>
+TileGenFunc(GLContext* gl,
+            const nsIntSize& aSize,
+            TextureImage::ContentType aContentType,
+            TextureImage::Flags aFlags,
+            TextureImage::ImageFormat aImageFormat)
+{
+    switch (gl->GetContextType()) {
+#ifdef XP_MACOSX
+        case ContextTypeCGL:
+            return TileGenFuncCGL(gl, aSize, aContentType, aFlags, aImageFormat);
+#endif
+        case ContextTypeEGL:
+            return TileGenFuncEGL(gl, aSize, aContentType, aFlags, aImageFormat);
+        default:
+            return nullptr;
+    }
+}
+already_AddRefed<TextureImage>
+
 TextureImage::Create(GLContext* gl,
                      const nsIntSize& size,
                      TextureImage::ContentType contentType,
                      GLenum wrapMode,
                      TextureImage::Flags flags)
 {
-    return gl->CreateTextureImage(size, contentType, wrapMode, flags);
+    return CreateTextureImage(gl, size, contentType, wrapMode, flags);
 }
 
 // Moz2D equivalent...
 already_AddRefed<TextureImage>
 TextureImage::Create(GLContext* gl,
                      const gfx::IntSize& size,
                      TextureImage::ContentType contentType,
                      GLenum wrapMode,
@@ -640,17 +685,17 @@ void TiledTextureImage::Resize(const nsI
                     // Width hasn't changed, reuse existing tile.
                     i++;
                     continue;
                 }
             }
 
             // Create a new tile.
             nsRefPtr<TextureImage> teximg =
-                    mGL->TileGenFunc(size, mContentType, mFlags, mImageFormat);
+                TileGenFunc(mGL, size, mContentType, mFlags, mImageFormat);
             if (replace)
                 mImages.ReplaceElementAt(i, teximg.forget());
             else
                 mImages.InsertElementAt(i, teximg.forget());
             i++;
         }
 
         // Prune any unused tiles on the end of the column.
--- a/gfx/gl/GLTextureImage.h
+++ b/gfx/gl/GLTextureImage.h
@@ -427,12 +427,36 @@ CreateBasicTextureImage(GLContext* aGL,
 
 already_AddRefed<TextureImage>
 CreateBasicTextureImage(GLContext* aGL,
                         const gfx::IntSize& aSize,
                         TextureImage::ContentType aContentType,
                         GLenum aWrapMode,
                         TextureImage::Flags aFlags);
 
+/**
+  * Return a valid, allocated TextureImage of |aSize| with
+  * |aContentType|.  If |aContentType| is COLOR, |aImageFormat| can be used
+  * to hint at the preferred RGB format, however it is not necessarily
+  * respected.  The TextureImage's texture is configured to use
+  * |aWrapMode| (usually GL_CLAMP_TO_EDGE or GL_REPEAT) and by
+  * default, GL_LINEAR filtering.  Specify
+  * |aFlags=UseNearestFilter| for GL_NEAREST filtering. Specify
+  * |aFlags=NeedsYFlip| if the image is flipped. Return
+  * nullptr if creating the TextureImage fails.
+  *
+  * The returned TextureImage may only be used with this GLContext.
+  * Attempting to use the returned TextureImage after this
+  * GLContext is destroyed will result in undefined (and likely
+  * crashy) behavior.
+  */
+already_AddRefed<TextureImage>
+CreateTextureImage(GLContext* gl,
+                   const nsIntSize& aSize,
+                   TextureImage::ContentType aContentType,
+                   GLenum aWrapMode,
+                   TextureImage::Flags aFlags = TextureImage::NoFlags,
+                   TextureImage::ImageFormat aImageFormat = gfxImageFormatUnknown);
+
 } // namespace gl
 } // namespace mozilla
 
 #endif /* GLTEXTUREIMAGE_H_ */
--- a/gfx/gl/TextureImageCGL.h
+++ b/gfx/gl/TextureImageCGL.h
@@ -40,12 +40,27 @@ protected:
 
 private:
 
     GLuint mPixelBuffer;
     int32_t mPixelBufferSize;
     bool mBoundPixelBuffer;
 };
 
+already_AddRefed<TextureImage>
+CreateTextureImageCGL(GLContext *gl,
+                      const nsIntSize& aSize,
+                      TextureImage::ContentType aContentType,
+                      GLenum aWrapMode,
+                      TextureImage::Flags aFlags,
+                      TextureImage::ImageFormat aImageFormat);
+
+already_AddRefed<TextureImage>
+TileGenFuncCGL(GLContext *gl,
+               const nsIntSize& aSize,
+               TextureImage::ContentType aContentType,
+               TextureImage::Flags aFlags,
+               TextureImage::ImageFormat aImageFormat);
+
 }
 }
 
 #endif
--- a/gfx/gl/TextureImageCGL.mm
+++ b/gfx/gl/TextureImageCGL.mm
@@ -101,10 +101,58 @@ TextureImageCGL::FinishedSurfaceUpload()
 {
     if (mBoundPixelBuffer) {
         mGLContext->MakeCurrent();
         mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
         mBoundPixelBuffer = false;
     }
 }
 
+already_AddRefed<TextureImage>
+CreateTextureImageCGL(GLContext* gl,
+                      const nsIntSize& aSize,
+                      TextureImage::ContentType aContentType,
+                      GLenum aWrapMode,
+                      TextureImage::Flags aFlags,
+                      TextureImage::ImageFormat aImageFormat)
+{
+    if (!gl->IsOffscreenSizeAllowed(gfxIntSize(aSize.width, aSize.height)) &&
+        gfxPlatform::OffMainThreadCompositingEnabled()) {
+      NS_ASSERTION(aWrapMode == LOCAL_GL_CLAMP_TO_EDGE, "Can't support wrapping with tiles!");
+      nsRefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType,
+                                                           aFlags, aImageFormat);
+      return t.forget();
+    }
+
+    return CreateBasicTextureImage(gl, aSize, aContentType, aWrapMode,
+                                   aFlags, aImageFormat);
+}
+
+already_AddRefed<TextureImage>
+TileGenFuncCGL(GLContext *gl,
+               const nsIntSize& aSize,
+               TextureImage::ContentType aContentType,
+               TextureImage::Flags aFlags,
+               TextureImage::ImageFormat aImageFormat)
+{
+    bool useNearestFilter = aFlags & TextureImage::UseNearestFilter;
+    gl->MakeCurrent();
+
+    GLuint texture;
+    gl->fGenTextures(1, &texture);
+
+    gl->fActiveTexture(LOCAL_GL_TEXTURE0);
+    gl->fBindTexture(LOCAL_GL_TEXTURE_2D, texture);
+
+    GLint texfilter = useNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
+    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
+    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
+    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+    gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+
+    nsRefPtr<TextureImageCGL> teximage
+        (new TextureImageCGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType,
+                             gl, aFlags, aImageFormat));
+    return teximage.forget();
+}
+
 }
 }
--- a/gfx/gl/TextureImageEGL.cpp
+++ b/gfx/gl/TextureImageEGL.cpp
@@ -310,10 +310,49 @@ TextureImageEGL::DestroyEGLSurface(void)
 }
 
 void
 TextureImageEGL::ApplyFilter()
 {
     mGLContext->ApplyFilterToBoundTexture(mFilter);
 }
 
+already_AddRefed<TextureImage>
+CreateTextureImageEGL(GLContext *gl,
+                      const nsIntSize& aSize,
+                      TextureImage::ContentType aContentType,
+                      GLenum aWrapMode,
+                      TextureImage::Flags aFlags,
+                      TextureImage::ImageFormat aImageFormat)
+{
+    nsRefPtr<TextureImage> t = new gl::TiledTextureImage(gl, aSize, aContentType, aFlags, aImageFormat);
+    return t.forget();
+}
+
+already_AddRefed<TextureImage>
+TileGenFuncEGL(GLContext *gl,
+               const nsIntSize& aSize,
+               TextureImage::ContentType aContentType,
+               TextureImage::Flags aFlags,
+               TextureImage::ImageFormat aImageFormat)
+{
+  gl->MakeCurrent();
+
+  GLuint texture;
+  gl->fGenTextures(1, &texture);
+
+  nsRefPtr<TextureImageEGL> teximage =
+      new TextureImageEGL(texture, aSize, LOCAL_GL_CLAMP_TO_EDGE, aContentType,
+                          gl, aFlags, TextureImage::Created, aImageFormat);
+
+  teximage->BindTexture(LOCAL_GL_TEXTURE0);
+
+  GLint texfilter = aFlags & TextureImage::UseNearestFilter ? LOCAL_GL_NEAREST : LOCAL_GL_LINEAR;
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, texfilter);
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, texfilter);
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
+  gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
+
+  return teximage.forget();
+}
+
 }
 }
\ No newline at end of file
--- a/gfx/gl/TextureImageEGL.h
+++ b/gfx/gl/TextureImageEGL.h
@@ -74,13 +74,27 @@ protected:
     EGLConfig mConfig;
     TextureState mTextureState;
 
     bool mBound;
 
     virtual void ApplyFilter();
 };
 
+already_AddRefed<TextureImage>
+CreateTextureImageEGL(GLContext *gl,
+                      const nsIntSize& aSize,
+                      TextureImage::ContentType aContentType,
+                      GLenum aWrapMode,
+                      TextureImage::Flags aFlags,
+                      TextureImage::ImageFormat aImageFormat);
+
+already_AddRefed<TextureImage>
+TileGenFuncEGL(GLContext *gl,
+               const nsIntSize& aSize,
+               TextureImage::ContentType aContentType,
+               TextureImage::Flags aFlags,
+               TextureImage::ImageFormat aImageFormat);
 
 }
 }
 
 #endif // TEXTUREIMAGEEGL_H_
\ No newline at end of file
--- a/gfx/layers/opengl/TextureHostOGL.cpp
+++ b/gfx/layers/opengl/TextureHostOGL.cpp
@@ -240,20 +240,21 @@ TextureImageTextureSourceOGL::Update(gfx
   if (!mTexImage ||
       mTexImage->GetSize() != size ||
       mTexImage->GetContentType() != gfx::ContentForFormat(aSurface->GetFormat())) {
     if (mAllowBigImage) {
       // XXX - clarify which size we want to use. IncrementalContentHost will
       // require the size of the destination surface to be different from
       // the size of aSurface.
       // See bug 893300 (tracks the implementation of ContentHost for new textures).
-      mTexImage = mGL->CreateTextureImage(size,
-                                          gfx::ContentForFormat(aSurface->GetFormat()),
-                                          WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT),
-                                          FlagsToGLFlags(aFlags));
+      mTexImage = CreateTextureImage(mGL,
+                                     size,
+                                     gfx::ContentForFormat(aSurface->GetFormat()),
+                                     WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT),
+                                     FlagsToGLFlags(aFlags));
     } else {
       mTexImage = CreateBasicTextureImage(mGL,
                                           size,
                                           gfx::ContentForFormat(aSurface->GetFormat()),
                                           WrapMode(mGL, aFlags & TEXTURE_ALLOW_REPEAT),
                                           FlagsToGLFlags(aFlags));
     }
   }
@@ -496,20 +497,21 @@ TextureImageDeprecatedTextureHostOGL::Se
 
 void
 TextureImageDeprecatedTextureHostOGL::EnsureBuffer(const nsIntSize& aSize,
                                          gfxContentType aContentType)
 {
   if (!mTexture ||
       mTexture->GetSize() != aSize ||
       mTexture->GetContentType() != aContentType) {
-    mTexture = mGL->CreateTextureImage(aSize,
-                                       aContentType,
-                                       WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT),
-                                       FlagsToGLFlags(mFlags));
+    mTexture = CreateTextureImage(mGL,
+                                  aSize,
+                                  aContentType,
+                                  WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT),
+                                  FlagsToGLFlags(mFlags));
   }
   mTexture->Resize(aSize);
 }
 
 void
 TextureImageDeprecatedTextureHostOGL::CopyTo(const nsIntRect& aSourceRect,
                                    DeprecatedTextureHost *aDest,
                                    const nsIntRect& aDestRect)
@@ -552,21 +554,22 @@ TextureImageDeprecatedTextureHostOGL::Up
   TextureImage::ImageFormat format = surf.ImageFormat();
 
   if (!mTexture ||
       (mTexture->GetSize() != size && !aOffset) ||
       mTexture->GetContentType() != surf.ContentType() ||
       (mTexture->GetImageFormat() != format &&
        mTexture->GetImageFormat() != gfxImageFormatUnknown)) {
 
-    mTexture = mGL->CreateTextureImage(size,
-                                       surf.ContentType(),
-                                       WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT),
-                                       FlagsToGLFlags(mFlags),
-                                       format);
+    mTexture = CreateTextureImage(mGL,
+                                  size,
+                                  surf.ContentType(),
+                                  WrapMode(mGL, mFlags & TEXTURE_ALLOW_REPEAT),
+                                  FlagsToGLFlags(mFlags),
+                                  format);
   }
 
   // XXX this is always just ridiculously slow
   nsIntRegion updateRegion;
 
   if (!aRegion) {
     updateRegion = nsIntRegion(nsIntRect(0, 0, size.width, size.height));
   } else {