Bug 604101 - Part 5 - Use Pixel Buffer Objects in TextureImageCGL. r=joe,jrmuizel a=blocking2.0
authorMatt Woodrow <mwoodrow@mozilla.com>
Thu, 16 Dec 2010 23:49:42 -0800
changeset 59442 c5aeb066cbb5ac67f2a71772ea0de96b56038030
parent 59441 a977bda3a362fb551d5e58696a65340196c758ed
child 59443 d1da1005b6d61e9aec2ea40dbef18d9120dad7f7
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersjoe, jrmuizel, blocking2
bugs604101
milestone2.0b9pre
Bug 604101 - Part 5 - Use Pixel Buffer Objects in TextureImageCGL. r=joe,jrmuizel a=blocking2.0
gfx/thebes/GLContext.cpp
gfx/thebes/GLContext.h
gfx/thebes/GLContextProviderCGL.mm
gfx/thebes/GLContextProviderGLX.cpp
gfx/thebes/GLContextProviderWGL.cpp
gfx/thebes/GLContextSymbols.h
gfx/thebes/GLDefs.h
--- a/gfx/thebes/GLContext.cpp
+++ b/gfx/thebes/GLContext.cpp
@@ -42,17 +42,17 @@
 #include <string.h>
 #include <stdio.h>
 
 #include "prlink.h"
 #include "prenv.h"
 
 #include "nsThreadUtils.h"
 
-#include "gfxImageSurface.h"
+#include "gfxPlatform.h"
 #include "GLContext.h"
 #include "GLContextProvider.h"
 
 namespace mozilla {
 namespace gl {
 
 #ifdef DEBUG
 // see comment near declaration in GLContext.h. Should be thread-local.
@@ -307,25 +307,34 @@ GLContext::InitWithPrefix(const char *pr
           { mIsGLES2 ? "ClearDepthf" : "ClearDepth", NULL } },
         { mIsGLES2 ? (PRFuncPtr*) &mSymbols.fDepthRangef : (PRFuncPtr*) &mSymbols.fDepthRange,
           { mIsGLES2 ? "DepthRangef" : "DepthRange", NULL } },
 
         // XXX FIXME -- we shouldn't be using glReadBuffer!
         { mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fReadBuffer,
           { mIsGLES2 ? NULL : "ReadBuffer", NULL } },
 
+        { mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fMapBuffer,
+          { mIsGLES2 ? NULL : "MapBuffer", NULL } },
+        { mIsGLES2 ? (PRFuncPtr*) NULL : (PRFuncPtr*) &mSymbols.fUnmapBuffer,
+          { mIsGLES2 ? NULL : "UnmapBuffer", NULL } },
+
         { NULL, { NULL } },
 
     };
 
     mInitialized = LoadSymbols(&symbols[0], trygl, prefix);
 
     if (mInitialized) {
         InitExtensions();
 
+        NS_ASSERTION(!IsExtensionSupported(GLContext::ARB_pixel_buffer_object) ||
+                     (mSymbols.fMapBuffer && mSymbols.fUnmapBuffer),
+                     "ARB_pixel_buffer_object supported without glMapBuffer/UnmapBuffer being available!");
+
         GLint v[4];
 
         fGetIntegerv(LOCAL_GL_SCISSOR_BOX, v);
         mScissorStack.AppendElement(nsIntRect(v[0], v[1], v[2], v[3]));
 
         fGetIntegerv(LOCAL_GL_VIEWPORT, v);
         mViewportStack.AppendElement(nsIntRect(v[0], v[1], v[2], v[3]));
 
@@ -399,16 +408,17 @@ static const char *sExtensionNames[] = {
     "GL_OES_stencil8",
     "GL_OES_texture_npot",
     "GL_OES_depth_texture",
     "GL_OES_packed_depth_stencil",
     "GL_IMG_read_format",
     "GL_EXT_read_format_bgra",
     "GL_APPLE_client_storage",
     "GL_ARB_texture_non_power_of_two",
+    "GL_ARB_pixel_buffer_object",
     NULL
 };
 
 void
 GLContext::InitExtensions()
 {
     MakeCurrent();
     const GLubyte *extensions = fGetString(LOCAL_GL_EXTENSIONS);
@@ -561,59 +571,85 @@ BasicTextureImage::BeginUpdate(nsIntRegi
     aRegion = nsIntRegion(mUpdateRect);
 
     nsIntSize rgnSize = mUpdateRect.Size();
     if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) {
         NS_ERROR("update outside of image");
         return NULL;
     }
 
-    nsRefPtr<gfxASurface> updateSurface =
-        CreateUpdateSurface(gfxIntSize(rgnSize.width, rgnSize.height),
-                            format);
+    nsRefPtr<gfxASurface> updateSurface = 
+      GetSurfaceForUpdate(gfxIntSize(rgnSize.width, rgnSize.height), format);
+
     if (!updateSurface)
         return NULL;
 
     updateSurface->SetDeviceOffset(gfxPoint(-mUpdateRect.x, -mUpdateRect.y));
 
     mUpdateContext = new gfxContext(updateSurface);
+   
+    // Clear the returned surface because it might have been re-used.
+    if (format == gfxASurface::ImageFormatARGB32) {
+      mUpdateContext->SetOperator(gfxContext::OPERATOR_CLEAR);
+      mUpdateContext->Paint();
+      mUpdateContext->SetOperator(gfxContext::OPERATOR_OVER);
+    }
     return mUpdateContext;
 }
 
 PRBool
 BasicTextureImage::EndUpdate()
 {
     NS_ASSERTION(!!mUpdateContext, "EndUpdate() without BeginUpdate()?");
 
     // FIXME: this is the slow boat.  Make me fast (with GLXPixmap?).
     nsRefPtr<gfxASurface> originalSurface = mUpdateContext->OriginalSurface();
 
     // Undo the device offset that BeginUpdate set; doesn't much matter for us here,
     // but important if we ever do anything directly with the surface.
     originalSurface->SetDeviceOffset(gfxPoint(0, 0));
 
+    bool relative = FinishedSurfaceUpdate();
+
     // The rect to upload from the surface is mUpdateRect sized and located at mUpdateOffset.
     nsIntRect surfaceRect(mUpdateOffset.x, mUpdateOffset.y, mUpdateRect.width, mUpdateRect.height);
-    if (!mTextureInited) {
-     surfaceRect.x = 0;
-     surfaceRect.y = 0;
-    }
 
     mShaderType =
       mGLContext->UploadSurfaceToTexture(originalSurface,
                                          surfaceRect,
                                          mTexture,
                                          !mTextureInited,
-                                         mUpdateRect.TopLeft());
+                                         mUpdateRect.TopLeft(),
+                                         relative);
+    FinishedSurfaceUpload();
+
     mUpdateContext = nsnull;
     mTextureInited = PR_TRUE;
 
     return PR_TRUE;         // mTexture is bound
 }
 
+already_AddRefed<gfxASurface>
+BasicTextureImage::GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
+{
+    return gfxPlatform::GetPlatform()->
+      CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
+}
+
+bool
+BasicTextureImage::FinishedSurfaceUpdate()
+{
+  return false;
+}
+
+void
+BasicTextureImage::FinishedSurfaceUpload()
+{
+}
+
 void
 BasicTextureImage::Resize(const nsIntSize& aSize)
 {
     NS_ASSERTION(!mUpdateContext, "Resize() while in update?");
 
     mGLContext->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
 
     mGLContext->fTexImage2D(LOCAL_GL_TEXTURE_2D,
@@ -1203,17 +1239,18 @@ GLContext::BlitTextureImage(TextureImage
 }
 
 
 ShaderProgramType 
 GLContext::UploadSurfaceToTexture(gfxASurface *aSurface, 
                                   const nsIntRect& aSrcRect,
                                   GLuint& aTexture,
                                   bool aOverwrite,
-                                  const nsIntPoint& aDstPoint)
+                                  const nsIntPoint& aDstPoint,
+                                  bool aPixelBuffer)
 {
   bool textureInited = aOverwrite ? false : true;
   MakeCurrent();
   fActiveTexture(LOCAL_GL_TEXTURE0);
   
   if (!aTexture) {
     fGenTextures(1, &aTexture);
     fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
@@ -1230,35 +1267,35 @@ GLContext::UploadSurfaceToTexture(gfxASu
                    LOCAL_GL_TEXTURE_WRAP_T, 
                    LOCAL_GL_CLAMP_TO_EDGE);
     textureInited = false;
   } else {
     fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
   }
 
   nsRefPtr<gfxImageSurface> imageSurface = aSurface->GetAsImageSurface();
-  unsigned char* data;
+  // If a pixel buffer is bound the data pointer parameter is relative
+  // to the start of the data block.
+  unsigned char* data = aPixelBuffer ? NULL : imageSurface->Data();
 
   if (!imageSurface || 
       (imageSurface->Format() != gfxASurface::ImageFormatARGB32 &&
        imageSurface->Format() != gfxASurface::ImageFormatRGB24 &&
        imageSurface->Format() != gfxASurface::ImageFormatRGB16_565)) {
     // We can't get suitable pixel data for the surface, make a copy
     imageSurface = 
       new gfxImageSurface(gfxIntSize(aSrcRect.width, aSrcRect.height), 
                           gfxASurface::ImageFormatARGB32);
   
     nsRefPtr<gfxContext> context = new gfxContext(imageSurface);
 
     context->Translate(-gfxPoint(aSrcRect.x, aSrcRect.y));
     context->SetSource(aSurface);
     context->Paint();
-    data = imageSurface->Data();
   } else {
-    data = imageSurface->Data();
     data += aSrcRect.y * imageSurface->Stride();
     data += aSrcRect.x * 4;
   }
 
   GLenum format;
   GLenum internalformat;
   GLenum type;
   PRInt32 pixelSize = gfxASurface::BytePerPixelFromFormat(imageSurface->Format());
--- a/gfx/thebes/GLContext.h
+++ b/gfx/thebes/GLContext.h
@@ -274,40 +274,49 @@ protected:
  * into which the updated pixels will be drawn, and the code to
  * convert the update surface's pixels into an image on which we can
  * glTexSubImage2D().
  */
 class BasicTextureImage
     : public TextureImage
 {
 public:
+    typedef gfxASurface::gfxImageFormat ImageFormat;
     virtual ~BasicTextureImage();
 
-    virtual gfxContext* BeginUpdate(nsIntRegion& aRegion);
-    virtual PRBool EndUpdate();
-
-    virtual PRBool InUpdate() const { return !!mUpdateContext; }
-
-    virtual void Resize(const nsIntSize& aSize);
-protected:
-    typedef gfxASurface::gfxImageFormat ImageFormat;
-
     BasicTextureImage(GLuint aTexture,
                       const nsIntSize& aSize,
                       GLenum aWrapMode,
                       ContentType aContentType,
                       GLContext* aContext)
         : TextureImage(aTexture, aSize, aWrapMode, aContentType)
         , mTextureInited(PR_FALSE)
         , mGLContext(aContext)
         , mUpdateOffset(0, 0)
     {}
 
+    virtual gfxContext* BeginUpdate(nsIntRegion& aRegion);
+    virtual PRBool EndUpdate();
+
+    // Returns a surface to draw into
     virtual already_AddRefed<gfxASurface>
-    CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt) = 0;
+      GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt);
+
+    // Call when drawing into the update surface is complete.
+    // Returns true if textures should be upload with a relative 
+    // offset - See UploadSurfaceToTexture.
+    virtual bool FinishedSurfaceUpdate();
+
+    // Call after surface data has been uploaded to a texture.
+    virtual void FinishedSurfaceUpload();
+
+    virtual PRBool InUpdate() const { return !!mUpdateContext; }
+
+    virtual void Resize(const nsIntSize& aSize);
+protected:
 
     PRBool mTextureInited;
     GLContext* mGLContext;
     nsRefPtr<gfxContext> mUpdateContext;
     nsIntRect mUpdateRect;
 
     // The offset into the update surface at which the update rect is located.
     nsIntPoint mUpdateOffset;
@@ -741,23 +750,27 @@ public:
      * The aDstPoint parameter is ignored if no texture was provided
      * or aOverwrite is true.
      *
      * \param aSurface Surface to upload. 
      * \param aSrcRect Region of aSurface to upload.
      * \param aTexture Texture to use, or 0 to have one created for you.
      * \param aOverwrite Over an existing texture with a new one.
      * \param aDstPoint Offset into existing texture to upload contents.
+     * \param aPixelBuffer Pass true to upload texture data with an
+     *  offset from the base data (generally for pixel buffer objects), 
+     *  otherwise textures are upload with an absolute pointer to the data.
      * \return Shader program needed to render this texture.
      */
     ShaderProgramType UploadSurfaceToTexture(gfxASurface *aSurface, 
                                              const nsIntRect& aSrcRect,
                                              GLuint& aTexture,
                                              bool aOverwrite = false,
-                                             const nsIntPoint& aDstPoint = nsIntPoint(0, 0));
+                                             const nsIntPoint& aDstPoint = nsIntPoint(0, 0),
+                                             bool aPixelBuffer = PR_FALSE);
 
     /** Helper for DecomposeIntoNoRepeatTriangles
      */
     struct RectTriangles {
         RectTriangles() : numRects(0) { }
 
         void addRect(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
                      GLfloat tx0, GLfloat ty0, GLfloat tx1, GLfloat ty1);
@@ -803,16 +816,17 @@ public:
         OES_stencil8,
         OES_texture_npot,
         OES_depth_texture,
         OES_packed_depth_stencil,
         IMG_read_format,
         EXT_read_format_bgra,
         APPLE_client_storage,
         ARB_texture_non_power_of_two,
+        ARB_pixel_buffer_object,
         Extensions_Max
     };
 
     PRBool IsExtensionSupported(GLExtensions aKnownExtension) {
         return mAvailableExtensions[aKnownExtension];
     }
 
     // Shared code for GL extensions and GLX extensions.
@@ -907,17 +921,21 @@ protected:
     PRBool IsExtensionSupported(const char *extension);
 
     virtual already_AddRefed<TextureImage>
     CreateBasicTextureImage(GLuint aTexture,
                             const nsIntSize& aSize,
                             GLenum aWrapMode,
                             TextureImage::ContentType aContentType,
                             GLContext* aContext)
-    { return NULL; }
+    {
+        nsRefPtr<BasicTextureImage> teximage(
+            new BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext));
+        return teximage.forget();
+    }
 
 protected:
     nsTArray<nsIntRect> mViewportStack;
     nsTArray<nsIntRect> mScissorStack;
 
     GLint mMaxTextureSize;
 
 public:
@@ -1837,16 +1855,30 @@ public:
         if (mIsGLES2) {
             mSymbols.fClearDepthf(v);
         } else {
             mSymbols.fClearDepth(v);
         }
         AFTER_GL_CALL;
     }
 
+    void* fMapBuffer(GLenum target, GLenum access) {
+        BEFORE_GL_CALL;
+        void *ret = mSymbols.fMapBuffer(target, access);
+        AFTER_GL_CALL;
+        return ret;
+    }
+
+    realGLboolean fUnmapBuffer(GLenum target) {
+        BEFORE_GL_CALL;
+        realGLboolean ret = mSymbols.fUnmapBuffer(target);
+        AFTER_GL_CALL;
+        return ret;
+    }
+
 
  #ifndef DEBUG
      GLuint GLAPIENTRY fCreateProgram() {
          return mSymbols.fCreateProgram();
      }
 
      GLuint GLAPIENTRY fCreateShader(GLenum t) {
          return mSymbols.fCreateShader(t);
--- a/gfx/thebes/GLContextProviderCGL.mm
+++ b/gfx/thebes/GLContextProviderCGL.mm
@@ -289,95 +289,87 @@ GLContextCGL::ResizeOffscreen(const gfxI
 class TextureImageCGL : public BasicTextureImage
 {
     friend already_AddRefed<TextureImage>
     GLContextCGL::CreateBasicTextureImage(GLuint,
                                           const nsIntSize&,
                                           GLenum,
                                           TextureImage::ContentType,
                                           GLContext*);
+public:
+    ~TextureImageCGL()
+    {
+        if (mPixelBuffer) {
+            mGLContext->fDeleteBuffers(1, &mPixelBuffer);
+        }
+    }
 
 protected:
-    virtual gfxContext*
-    BeginUpdate(nsIntRegion& aRegion)
+    already_AddRefed<gfxASurface>
+    GetSurfaceForUpdate(const gfxIntSize& aSize, ImageFormat aFmt)
     {
-        ImageFormat format;
-        if (GetContentType() == gfxASurface::CONTENT_COLOR)
-            format = gfxASurface::ImageFormatRGB24;
-        else
-            format = gfxASurface::ImageFormatARGB32;
-
-        if (!mTextureInited || !mUpdateSurface ||
-            mUpdateSurface->GetContentType() != GetContentType())
-        {
-            mUpdateSurface = nsnull;
-            mUpdateOffset = nsIntPoint(0, 0);
-            // We need to (re)create our backing store. Let the base class to that.
-            return BasicTextureImage::BeginUpdate(aRegion);
-        }
-
-        nsRefPtr<gfxImageSurface> imageSurface = mUpdateSurface->GetAsImageSurface();
-        if (!imageSurface ||
-            nsIntSize(imageSurface->Width(), imageSurface->Height()) < mSize) {
-          mUpdateSurface = nsnull;
-          mUpdateOffset = nsIntPoint(0, 0);
-          // We need to (re)create our backing store. Let the base class to that.
-          return BasicTextureImage::BeginUpdate(aRegion);
+        if (!mGLContext->IsExtensionSupported(GLContext::ARB_pixel_buffer_object)) {
+            return gfxPlatform::GetPlatform()->
+                CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
         }
 
-        // the basic impl can only upload updates to rectangles
-        mUpdateRect = aRegion.GetBounds();
-        aRegion = nsIntRegion(mUpdateRect);
+        if (!mPixelBuffer) {
+            mGLContext->fGenBuffers(1, &mPixelBuffer);
+        }
+        mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, mPixelBuffer);
+        PRInt32 size = aSize.width * 4 * aSize.height;
 
-        if (!nsIntRect(nsIntPoint(0, 0), mSize).Contains(mUpdateRect)) {
-            NS_ERROR("update outside of image");
-            return NULL;
+        if (size > mPixelBufferSize) {
+            mGLContext->fBufferData(LOCAL_GL_PIXEL_UNPACK_BUFFER, size,
+                                    NULL, LOCAL_GL_STREAM_DRAW);
+            mPixelBufferSize = size;
+        }
+        unsigned char* data = 
+          (unsigned char*)mGLContext->fMapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, LOCAL_GL_WRITE_ONLY);
+
+        if (!data) {
+          return nsnull;
         }
 
-        mUpdateContext = new gfxContext(mUpdateSurface);
-        mUpdateContext->Clip(gfxRect(mUpdateRect.x, mUpdateRect.y,
-                                     mUpdateRect.width, mUpdateRect.height));
-        if (GetContentType() != gfxASurface::CONTENT_COLOR)
-        {
-            mUpdateContext->SetOperator(gfxContext::OPERATOR_CLEAR);
-            mUpdateContext->Paint();
-            mUpdateContext->SetOperator(gfxContext::OPERATOR_OVER);
+        nsRefPtr<gfxQuartzSurface> surf = 
+            new gfxQuartzSurface(data, aSize,
+                                 aSize.width * 4, aFmt);
+
+        return surf.forget();
+    }
+  
+    bool FinishedSurfaceUpdate()
+    {
+        if (mPixelBuffer) {
+            mGLContext->fUnmapBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER);
+            return true;
         }
-        mUpdateOffset = mUpdateRect.TopLeft();
-
-        return mUpdateContext;
+        return false;
     }
 
-    virtual PRBool
-    EndUpdate()
+    void FinishedSurfaceUpload()
     {
-        if (!mUpdateSurface)
-            mUpdateSurface = mUpdateContext->OriginalSurface();
-
-        return BasicTextureImage::EndUpdate();
-    }
-
-    virtual already_AddRefed<gfxASurface>
-    CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt)
-    {
-        mUpdateFormat = aFmt;
-        return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
+        if (mPixelBuffer) {
+            mGLContext->fBindBuffer(LOCAL_GL_PIXEL_UNPACK_BUFFER, 0);
+        }
     }
 
 private:
     TextureImageCGL(GLuint aTexture,
                     const nsIntSize& aSize,
                     GLenum aWrapMode,
                     ContentType aContentType,
                     GLContext* aContext)
         : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext)
+        , mPixelBuffer(0)
+        , mPixelBufferSize(0)
     {}
-
-    ImageFormat mUpdateFormat;
-    nsRefPtr<gfxASurface> mUpdateSurface;
+    
+    GLuint mPixelBuffer;
+    PRInt32 mPixelBufferSize;
 };
 
 already_AddRefed<TextureImage>
 GLContextCGL::CreateBasicTextureImage(GLuint aTexture,
                                       const nsIntSize& aSize,
                                       GLenum aWrapMode,
                                       TextureImage::ContentType aContentType,
                                       GLContext* aContext)
--- a/gfx/thebes/GLContextProviderGLX.cpp
+++ b/gfx/thebes/GLContextProviderGLX.cpp
@@ -365,23 +365,16 @@ TRY_AGAIN_NO_SHARING:
     PRBool SwapBuffers()
     {
         if (!mDoubleBuffered)
             return PR_FALSE;
         sGLXLibrary.xSwapBuffers(mDisplay, mDrawable);
         return PR_TRUE;
     }
 
-    virtual already_AddRefed<TextureImage>
-    CreateBasicTextureImage(GLuint aTexture,
-                            const nsIntSize& aSize,
-                            GLenum aWrapMode,
-                            TextureImage::ContentType aContentType,
-                            GLContext* aContext);
-
 private:
     friend class GLContextProviderGLX;
 
     GLContextGLX(const ContextFormat& aFormat,
                  GLContext *aShareContext,
                  Display *aDisplay,
                  GLXDrawable aDrawable,
                  GLXContext aContext,
@@ -401,60 +394,16 @@ private:
     Display *mDisplay;
     GLXDrawable mDrawable;
     PRPackedBool mDeleteDrawable;
     PRPackedBool mDoubleBuffered;
 
     nsRefPtr<gfxXlibSurface> mPixmap;
 };
 
-// FIXME/bug 575505: this is a (very slow!) placeholder
-// implementation.  Much better would be to create a Pixmap, wrap that
-// in a GLXPixmap, and then glXBindTexImage() to our texture.
-class TextureImageGLX : public BasicTextureImage
-{
-    friend already_AddRefed<TextureImage>
-    GLContextGLX::CreateBasicTextureImage(GLuint,
-                                          const nsIntSize&,
-                                          GLenum,
-                                          TextureImage::ContentType,
-                                          GLContext*);
-
-protected:
-    virtual already_AddRefed<gfxASurface>
-    CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt)
-    {
-        mUpdateFormat = aFmt;
-        return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
-    }
-
-private:
-    TextureImageGLX(GLuint aTexture,
-                    const nsIntSize& aSize,
-                    GLenum aWrapMode,
-                    ContentType aContentType,
-                    GLContext* aContext)
-        : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext)
-    {}
-
-    ImageFormat mUpdateFormat;
-};
-
-already_AddRefed<TextureImage>
-GLContextGLX::CreateBasicTextureImage(GLuint aTexture,
-                                      const nsIntSize& aSize,
-                                      GLenum aWrapMode,
-                                      TextureImage::ContentType aContentType,
-                                      GLContext* aContext)
-{
-    nsRefPtr<TextureImageGLX> teximage(
-        new TextureImageGLX(aTexture, aSize, aWrapMode, aContentType, aContext));
-    return teximage.forget();
-}
-
 static GLContextGLX *
 GetGlobalContextGLX()
 {
     return static_cast<GLContextGLX*>(GLContextProviderGLX::GetGlobalContext());
 }
 
 static PRBool
 AreCompatibleVisuals(XVisualInfo *one, XVisualInfo *two)
--- a/gfx/thebes/GLContextProviderWGL.cpp
+++ b/gfx/thebes/GLContextProviderWGL.cpp
@@ -322,23 +322,16 @@ public:
     }
 
     PRBool BindTex2DOffscreen(GLContext *aOffscreen);
     void UnbindTex2DOffscreen(GLContext *aOffscreen);
     PRBool ResizeOffscreen(const gfxIntSize& aNewSize);
 
     HGLRC Context() { return mContext; }
 
-    virtual already_AddRefed<TextureImage>
-    CreateBasicTextureImage(GLuint aTexture,
-                            const nsIntSize& aSize,
-                            GLenum aWrapMode,
-                            TextureImage::ContentType aContentType,
-                            GLContext* aContext);
-
 protected:
     friend class GLContextProviderWGL;
 
     HDC mDC;
     HGLRC mContext;
     HWND mWnd;
     HANDLE mPBuffer;
     int mPixelFormat;
@@ -440,60 +433,16 @@ GLContextWGL::ResizeOffscreen(const gfxI
 }
 
 static GLContextWGL *
 GetGlobalContextWGL()
 {
     return static_cast<GLContextWGL*>(GLContextProviderWGL::GetGlobalContext());
 }
 
-class TextureImageWGL : public BasicTextureImage
-{
-    friend already_AddRefed<TextureImage>
-    GLContextWGL::CreateBasicTextureImage(GLuint,
-                                          const nsIntSize&,
-                                          GLenum,
-                                          TextureImage::ContentType,
-                                          GLContext*);
-
-protected:
-    virtual already_AddRefed<gfxASurface>
-    CreateUpdateSurface(const gfxIntSize& aSize, ImageFormat aFmt)
-    {
-        mUpdateSize = aSize;
-        mUpdateFormat = aFmt;
-
-        return gfxPlatform::GetPlatform()->CreateOffscreenSurface(aSize, gfxASurface::ContentFromFormat(aFmt));
-    }
-
-private:
-    TextureImageWGL(GLuint aTexture,
-                    const nsIntSize& aSize,
-                    GLenum aWrapMode,
-                    ContentType aContentType,
-                    GLContext* aContext)
-        : BasicTextureImage(aTexture, aSize, aWrapMode, aContentType, aContext)
-    {}
-
-    gfxIntSize mUpdateSize;
-    ImageFormat mUpdateFormat;
-};
-
-already_AddRefed<TextureImage>
-GLContextWGL::CreateBasicTextureImage(GLuint aTexture,
-                                      const nsIntSize& aSize,
-                                      GLenum aWrapMode,
-                                      TextureImage::ContentType aContentType,
-                                      GLContext* aContext)
-{
-    nsRefPtr<TextureImageWGL> teximage
-        (new TextureImageWGL(aTexture, aSize, aWrapMode, aContentType, aContext));
-    return teximage.forget();
-}
-
 already_AddRefed<GLContext>
 GLContextProviderWGL::CreateForWindow(nsIWidget *aWidget)
 {
     if (!sWGLLibrary.EnsureInitialized()) {
         return nsnull;
     }
 
     /**
--- a/gfx/thebes/GLContextSymbols.h
+++ b/gfx/thebes/GLContextSymbols.h
@@ -358,14 +358,19 @@ struct GLContextSymbols
     PFNGLDELETEBUFFERSPROC fDeleteBuffers;
     typedef void (GLAPIENTRY * PFNGLDELETETEXTURESPROC) (GLsizei n, const GLuint* textures);
     PFNGLDELETETEXTURESPROC fDeleteTextures;
     typedef void (GLAPIENTRY * PFNGLDELETEFRAMEBUFFERS) (GLsizei n, const GLuint* ids);
     PFNGLDELETEFRAMEBUFFERS fDeleteFramebuffers;
     typedef void (GLAPIENTRY * PFNGLDELETERENDERBUFFERS) (GLsizei n, const GLuint* ids);
     PFNGLDELETERENDERBUFFERS fDeleteRenderbuffers;
 
+    typedef void* (GLAPIENTRY * PFNGLMAPBUFFER) (GLenum target, GLenum access);
+    PFNGLMAPBUFFER fMapBuffer;
+    typedef realGLboolean (GLAPIENTRY * PFNGLUNMAPBUFFER) (GLenum target);
+    PFNGLUNMAPBUFFER fUnmapBuffer;
+
 };
 
 }
 }
 
 #endif /* GLCONTEXTSYMBOLS_H_ */
--- a/gfx/thebes/GLDefs.h
+++ b/gfx/thebes/GLDefs.h
@@ -839,16 +839,17 @@ typedef ptrdiff_t GLintptr;
 #define LOCAL_GL_STREAM_READ 0x88E1
 #define LOCAL_GL_STREAM_COPY 0x88E2
 #define LOCAL_GL_STATIC_DRAW 0x88E4
 #define LOCAL_GL_STATIC_READ 0x88E5
 #define LOCAL_GL_STATIC_COPY 0x88E6
 #define LOCAL_GL_DYNAMIC_DRAW 0x88E8
 #define LOCAL_GL_DYNAMIC_READ 0x88E9
 #define LOCAL_GL_DYNAMIC_COPY 0x88EA
+#define LOCAL_GL_PIXEL_UNPACK_BUFFER 0x88EC
 #define LOCAL_GL_SAMPLES_PASSED 0x8914
 #define LOCAL_GL_VERSION_2_0 1
 #define LOCAL_GL_BLEND_EQUATION_RGB 0x8009
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_ENABLED 0x8622
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_SIZE 0x8623
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_STRIDE 0x8624
 #define LOCAL_GL_VERTEX_ATTRIB_ARRAY_TYPE 0x8625
 #define LOCAL_GL_CURRENT_VERTEX_ATTRIB 0x8626