Bug 1243072 - Make GfxTexturesReporter work again r=nical,jgilbert
authorJames Willcox <snorp@snorp.net>
Tue, 26 Jan 2016 15:03:37 -0600
changeset 309348 9b3e1c0c851fd49cb83aaadd4766d4a7b1dd55a3
parent 309346 15b761835183778c29def19e8f8136d0b1e95d57
child 309349 866edb59ba0903882c0933ab3c3cca89b4108063
push idunknown
push userunknown
push dateunknown
reviewersnical, jgilbert
bugs1243072
milestone47.0a1
Bug 1243072 - Make GfxTexturesReporter work again r=nical,jgilbert
gfx/gl/GLTextureImage.cpp
gfx/gl/GLTextureImage.h
gfx/gl/GLUploadHelpers.cpp
gfx/gl/GLUploadHelpers.h
gfx/gl/GfxTexturesReporter.cpp
gfx/gl/GfxTexturesReporter.h
gfx/gl/TextureImageEGL.cpp
widget/cocoa/nsChildView.mm
--- a/gfx/gl/GLTextureImage.cpp
+++ b/gfx/gl/GLTextureImage.cpp
@@ -7,16 +7,17 @@
 #include "GLContext.h"
 #include "gfxContext.h"
 #include "gfxPlatform.h"
 #include "gfxUtils.h"
 #include "gfx2DGlue.h"
 #include "mozilla/gfx/2D.h"
 #include "ScopedGLHelpers.h"
 #include "GLUploadHelpers.h"
+#include "GfxTexturesReporter.h"
 
 #include "TextureImageEGL.h"
 #ifdef XP_MACOSX
 #include "TextureImageCGL.h"
 #endif
 
 using namespace mozilla::gfx;
 
@@ -90,16 +91,26 @@ TextureImage::UpdateFromDataSource(gfx::
 gfx::IntRect TextureImage::GetTileRect() {
     return gfx::IntRect(gfx::IntPoint(0,0), mSize);
 }
 
 gfx::IntRect TextureImage::GetSrcTileRect() {
     return GetTileRect();
 }
 
+void
+TextureImage::UpdateUploadSize(size_t amount)
+{
+    if (mUploadSize > 0) {
+        GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryFreed, mUploadSize);
+    }
+    mUploadSize = amount;
+    GfxTexturesReporter::UpdateAmount(GfxTexturesReporter::MemoryAllocated, mUploadSize);
+}
+
 BasicTextureImage::~BasicTextureImage()
 {
     GLContext *ctx = mGLContext;
     if (ctx->IsDestroyed() || !ctx->IsOwningThreadCurrent()) {
         ctx = ctx->GetSharedContext();
     }
 
     // If we have a context, then we need to delete the texture;
@@ -157,26 +168,30 @@ BasicTextureImage::EndUpdate()
     NS_ASSERTION(!!mUpdateDrawTarget, "EndUpdate() without BeginUpdate()?");
 
     // FIXME: this is the slow boat.  Make me fast (with GLXPixmap?).
 
     RefPtr<gfx::SourceSurface> updateSnapshot = mUpdateDrawTarget->Snapshot();
     RefPtr<gfx::DataSourceSurface> updateData = updateSnapshot->GetDataSurface();
 
     bool relative = FinishedSurfaceUpdate();
-
+    size_t uploadSize;
     mTextureFormat =
         UploadSurfaceToTexture(mGLContext,
                                updateData,
                                mUpdateRegion,
                                mTexture,
+                               &uploadSize,
                                mTextureState == Created,
                                mUpdateOffset,
                                relative);
     FinishedSurfaceUpload();
+    if (uploadSize > 0) {
+        UpdateUploadSize(uploadSize);
+    }
 
     mUpdateDrawTarget = nullptr;
     mTextureState = Valid;
 }
 
 void
 BasicTextureImage::BindTexture(GLenum aTextureUnit)
 {
@@ -209,24 +224,29 @@ BasicTextureImage::DirectUpdate(gfx::Dat
     nsIntRegion region;
     if (mTextureState != Valid) {
         bounds = IntRect(0, 0, mSize.width, mSize.height);
         region = nsIntRegion(bounds);
     } else {
         region = aRegion;
     }
 
+    size_t uploadSize;
     mTextureFormat =
         UploadSurfaceToTexture(mGLContext,
                                aSurf,
                                region,
                                mTexture,
+                               &uploadSize,
                                mTextureState == Created,
                                bounds.TopLeft() + IntPoint(aFrom.x, aFrom.y),
                                false);
+    if (uploadSize > 0) {
+        UpdateUploadSize(uploadSize);
+    }
     mTextureState = Valid;
     return true;
 }
 
 void
 BasicTextureImage::Resize(const gfx::IntSize& aSize)
 {
     NS_ASSERTION(!mUpdateDrawTarget, "Resize() while in update?");
@@ -268,16 +288,17 @@ TextureImage::TextureImage(const gfx::In
              GLenum aWrapMode, ContentType aContentType,
              Flags aFlags)
     : mSize(aSize)
     , mWrapMode(aWrapMode)
     , mContentType(aContentType)
     , mTextureFormat(gfx::SurfaceFormat::UNKNOWN)
     , mFilter(Filter::GOOD)
     , mFlags(aFlags)
+    , mUploadSize(0)
 {}
 
 BasicTextureImage::BasicTextureImage(GLuint aTexture,
                   const gfx::IntSize& aSize,
                   GLenum aWrapMode,
                   ContentType aContentType,
                   GLContext* aContext,
                   TextureImage::Flags aFlags)
--- a/gfx/gl/GLTextureImage.h
+++ b/gfx/gl/GLTextureImage.h
@@ -198,37 +198,42 @@ public:
     virtual bool InUpdate() const = 0;
     GLenum GetWrapMode() const { return mWrapMode; }
 
     void SetFilter(gfx::Filter aFilter) { mFilter = aFilter; }
 
 protected:
     friend class GLContext;
 
+    void UpdateUploadSize(size_t amount);
+
     /**
      * After the ctor, the TextureImage is invalid.  Implementations
      * must allocate resources successfully before returning the new
      * TextureImage from GLContext::CreateTextureImage().  That is,
      * clients must not be given partially-constructed TextureImages.
      */
     TextureImage(const gfx::IntSize& aSize,
                  GLenum aWrapMode, ContentType aContentType,
                  Flags aFlags = NoFlags);
 
     // Protected destructor, to discourage deletion outside of Release():
-    virtual ~TextureImage() {}
+    virtual ~TextureImage() {
+        UpdateUploadSize(0);
+    }
 
     virtual gfx::IntRect GetSrcTileRect();
 
     gfx::IntSize mSize;
     GLenum mWrapMode;
     ContentType mContentType;
     gfx::SurfaceFormat mTextureFormat;
     gfx::Filter mFilter;
     Flags mFlags;
+    size_t mUploadSize;
 };
 
 /**
  * BasicTextureImage is the baseline TextureImage implementation ---
  * it updates its texture by allocating a scratch buffer for the
  * client to draw into, then using glTexSubImage2D() to upload the new
  * pixels.  Platforms must provide the code to create a new surface
  * into which the updated pixels will be drawn, and the code to
--- a/gfx/gl/GLUploadHelpers.cpp
+++ b/gfx/gl/GLUploadHelpers.cpp
@@ -4,16 +4,18 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GLUploadHelpers.h"
 
 #include "GLContext.h"
 #include "mozilla/gfx/2D.h"
 #include "mozilla/gfx/Tools.h"  // For BytesPerPixel
 #include "nsRegion.h"
+#include "GfxTexturesReporter.h"
+#include "mozilla/gfx/Logging.h"
 
 namespace mozilla {
 
 using namespace gfx;
 
 namespace gl {
 
 /* These two techniques are suggested by "Bit Twiddling Hacks"
@@ -374,23 +376,69 @@ TexImage2DHelper(GLContext *gl,
                         format,
                         type,
                         pixels);
         gl->fPixelStorei(LOCAL_GL_UNPACK_ROW_LENGTH, 0);
         gl->fPixelStorei(LOCAL_GL_UNPACK_ALIGNMENT, 4);
     }
 }
 
+static uint32_t
+GetBytesPerTexel(GLenum format, GLenum type)
+{
+    // If there is no defined format or type, we're not taking up any memory
+    if (!format || !type) {
+        return 0;
+    }
+
+    if (format == LOCAL_GL_DEPTH_COMPONENT) {
+        if (type == LOCAL_GL_UNSIGNED_SHORT)
+            return 2;
+        else if (type == LOCAL_GL_UNSIGNED_INT)
+            return 4;
+    } else if (format == LOCAL_GL_DEPTH_STENCIL) {
+        if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
+            return 4;
+    }
+
+    if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT || type == LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV) {
+        uint32_t multiplier = type == LOCAL_GL_UNSIGNED_BYTE ? 1 : 4;
+        switch (format) {
+            case LOCAL_GL_ALPHA:
+            case LOCAL_GL_LUMINANCE:
+                return 1 * multiplier;
+            case LOCAL_GL_LUMINANCE_ALPHA:
+                return 2 * multiplier;
+            case LOCAL_GL_RGB:
+                return 3 * multiplier;
+            case LOCAL_GL_RGBA:
+                return 4 * multiplier;
+            default:
+                break;
+        }
+    } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
+               type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
+               type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
+    {
+        return 2;
+    }
+
+    gfxCriticalError() << "Unknown texture type " << type << " or format " << format;
+    MOZ_CRASH();
+    return 0;
+}
+
 SurfaceFormat
 UploadImageDataToTexture(GLContext* gl,
                          unsigned char* aData,
                          int32_t aStride,
                          SurfaceFormat aFormat,
                          const nsIntRegion& aDstRegion,
                          GLuint& aTexture,
+                         size_t* aOutUploadSize,
                          bool aOverwrite,
                          bool aPixelBuffer,
                          GLenum aTextureUnit,
                          GLenum aTextureTarget)
 {
     bool textureInited = aOverwrite ? false : true;
     gl->MakeCurrent();
     gl->fActiveTexture(aTextureUnit);
@@ -500,16 +548,20 @@ UploadImageDataToTexture(GLContext* gl,
         default:
             NS_ASSERTION(false, "Unhandled image surface format!");
     }
 
 
     // Top left point of the region's bounding rectangle.
     IntPoint topLeft = paintRegion.GetBounds().TopLeft();
 
+    if (aOutUploadSize) {
+        *aOutUploadSize = 0;
+    }
+
     for (auto iter = paintRegion.RectIter(); !iter.Done(); iter.Next()) {
         const IntRect& rect = iter.Get();
         // The inital data pointer is at the top left point of the region's
         // bounding rectangle. We need to find the offset of this rect
         // within the region and adjust the data pointer accordingly.
         unsigned char *rectData =
             aData + DataOffset(rect.TopLeft() - topLeft, aStride, aFormat);
 
@@ -539,39 +591,45 @@ UploadImageDataToTexture(GLContext* gl,
                              aStride,
                              pixelSize,
                              0,
                              format,
                              type,
                              rectData);
         }
 
+        if (aOutUploadSize && !textureInited) {
+            uint32_t texelSize = GetBytesPerTexel(internalFormat, type);
+            size_t numTexels = size_t(rect.width) * size_t(rect.height);
+            *aOutUploadSize += texelSize * numTexels;
+        }
     }
 
     return surfaceFormat;
 }
 
 SurfaceFormat
 UploadSurfaceToTexture(GLContext* gl,
-                       DataSourceSurface *aSurface,
+                       DataSourceSurface* aSurface,
                        const nsIntRegion& aDstRegion,
                        GLuint& aTexture,
+                       size_t* aOutUploadSize,
                        bool aOverwrite,
                        const gfx::IntPoint& aSrcPoint,
                        bool aPixelBuffer,
                        GLenum aTextureUnit,
                        GLenum aTextureTarget)
 {
     unsigned char* data = aPixelBuffer ? nullptr : aSurface->GetData();
     int32_t stride = aSurface->Stride();
     SurfaceFormat format = aSurface->GetFormat();
     data += DataOffset(aSrcPoint, stride, format);
     return UploadImageDataToTexture(gl, data, stride, format,
-                                    aDstRegion, aTexture, aOverwrite,
-                                    aPixelBuffer, aTextureUnit,
+                                    aDstRegion, aTexture, aOutUploadSize,
+                                    aOverwrite, aPixelBuffer, aTextureUnit,
                                     aTextureTarget);
 }
 
 bool
 CanUploadNonPowerOfTwo(GLContext* gl)
 {
     if (!gl->WorkAroundDriverBugs())
         return true;
--- a/gfx/gl/GLUploadHelpers.h
+++ b/gfx/gl/GLUploadHelpers.h
@@ -35,16 +35,17 @@ class GLContext;
   * texture memory block allocated.
   *
   * The aDstPoint parameter is ignored if no texture was provided
   * or aOverwrite is true.
   *
   * \param aData Image data to upload.
   * \param aDstRegion Region of texture to upload to.
   * \param aTexture Texture to use, or 0 to have one created for you.
+  * \param aOutUploadSize if set, the number of bytes the texture requires will be returned here
   * \param aOverwrite Over an existing texture with a new one.
   * \param aSrcPoint Offset into aSrc where the region's bound's
   *  TopLeft() sits.
   * \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.
   * \param aTextureUnit, the texture unit used temporarily to upload the
   *  surface. This testure may be overridden, clients should not rely on
@@ -54,29 +55,31 @@ class GLContext;
   */
 gfx::SurfaceFormat
 UploadImageDataToTexture(GLContext* gl,
                          unsigned char* aData,
                          int32_t aStride,
                          gfx::SurfaceFormat aFormat,
                          const nsIntRegion& aDstRegion,
                          GLuint& aTexture,
+                         size_t* aOutUploadSize = nullptr,
                          bool aOverwrite = false,
                          bool aPixelBuffer = false,
                          GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
                          GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
 
 /**
   * Convenience wrapper around UploadImageDataToTexture for gfx::DataSourceSurface's.
   */
 gfx::SurfaceFormat
 UploadSurfaceToTexture(GLContext* gl,
                        gfx::DataSourceSurface *aSurface,
                        const nsIntRegion& aDstRegion,
                        GLuint& aTexture,
+                       size_t* aOutUploadSize = nullptr,
                        bool aOverwrite = false,
                        const gfx::IntPoint& aSrcPoint = gfx::IntPoint(0, 0),
                        bool aPixelBuffer = false,
                        GLenum aTextureUnit = LOCAL_GL_TEXTURE0,
                        GLenum aTextureTarget = LOCAL_GL_TEXTURE_2D);
 
 bool CanUploadSubTextures(GLContext* gl);
 bool CanUploadNonPowerOfTwo(GLContext* gl);
--- a/gfx/gl/GfxTexturesReporter.cpp
+++ b/gfx/gl/GfxTexturesReporter.cpp
@@ -1,99 +1,26 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /* vim: set ts=8 sts=4 et sw=4 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "GfxTexturesReporter.h"
-#include "GLDefs.h"
 
 using namespace mozilla;
 using namespace mozilla::gl;
 
 NS_IMPL_ISUPPORTS(GfxTexturesReporter, nsIMemoryReporter)
 
-Atomic<int32_t> GfxTexturesReporter::sAmount(0);
-Atomic<int32_t> GfxTexturesReporter::sTileWasteAmount(0);
-
-static uint32_t
-GetBitsPerTexel(GLenum format, GLenum type)
-{
-    // If there is no defined format or type, we're not taking up any memory
-    if (!format || !type) {
-        return 0;
-    }
-
-    if (format == LOCAL_GL_DEPTH_COMPONENT) {
-        if (type == LOCAL_GL_UNSIGNED_SHORT)
-            return 2*8;
-        else if (type == LOCAL_GL_UNSIGNED_INT)
-            return 4*8;
-    } else if (format == LOCAL_GL_DEPTH_STENCIL) {
-        if (type == LOCAL_GL_UNSIGNED_INT_24_8_EXT)
-            return 4*8;
-    }
-
-    if (type == LOCAL_GL_UNSIGNED_BYTE || type == LOCAL_GL_FLOAT) {
-        uint32_t multiplier = type == LOCAL_GL_FLOAT ? 32 : 8;
-        switch (format) {
-            case LOCAL_GL_ALPHA:
-            case LOCAL_GL_LUMINANCE:
-                return 1 * multiplier;
-            case LOCAL_GL_LUMINANCE_ALPHA:
-                return 2 * multiplier;
-            case LOCAL_GL_RGB:
-                return 3 * multiplier;
-            case LOCAL_GL_RGBA:
-                return 4 * multiplier;
-            case LOCAL_GL_COMPRESSED_RGB_PVRTC_2BPPV1:
-            case LOCAL_GL_COMPRESSED_RGBA_PVRTC_2BPPV1:
-                return 2;
-            case LOCAL_GL_COMPRESSED_RGB_S3TC_DXT1_EXT:
-            case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT1_EXT:
-            case LOCAL_GL_ATC_RGB:
-            case LOCAL_GL_COMPRESSED_RGB_PVRTC_4BPPV1:
-            case LOCAL_GL_COMPRESSED_RGBA_PVRTC_4BPPV1:
-            case LOCAL_GL_ETC1_RGB8_OES:
-            case LOCAL_GL_COMPRESSED_RGB8_ETC2:
-            case LOCAL_GL_COMPRESSED_SRGB8_ETC2:
-            case LOCAL_GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-            case LOCAL_GL_COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2:
-            case LOCAL_GL_COMPRESSED_R11_EAC:
-            case LOCAL_GL_COMPRESSED_SIGNED_R11_EAC:
-                return 4;
-            case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT3_EXT:
-            case LOCAL_GL_COMPRESSED_RGBA_S3TC_DXT5_EXT:
-            case LOCAL_GL_ATC_RGBA_EXPLICIT_ALPHA:
-            case LOCAL_GL_ATC_RGBA_INTERPOLATED_ALPHA:
-            case LOCAL_GL_COMPRESSED_RGBA8_ETC2_EAC:
-            case LOCAL_GL_COMPRESSED_SRGB8_ALPHA8_ETC2_EAC:
-            case LOCAL_GL_COMPRESSED_RG11_EAC:
-            case LOCAL_GL_COMPRESSED_SIGNED_RG11_EAC:
-                return 8;
-            default:
-                break;
-        }
-    } else if (type == LOCAL_GL_UNSIGNED_SHORT_4_4_4_4 ||
-               type == LOCAL_GL_UNSIGNED_SHORT_5_5_5_1 ||
-               type == LOCAL_GL_UNSIGNED_SHORT_5_6_5)
-    {
-        return 2*8;
-    }
-
-    MOZ_ASSERT(false);
-    return 0;
-}
+Atomic<size_t> GfxTexturesReporter::sAmount(0);
+Atomic<size_t> GfxTexturesReporter::sTileWasteAmount(0);
 
 /* static */ void
-GfxTexturesReporter::UpdateAmount(MemoryUse action, GLenum format,
-                                  GLenum type, int32_t tileWidth,
-                                  int32_t tileHeight)
+GfxTexturesReporter::UpdateAmount(MemoryUse action, size_t amount)
 {
-    int64_t bitsPerTexel = GetBitsPerTexel(format, type);
-    int64_t bytes = int64_t(tileWidth) * int64_t(tileHeight) * bitsPerTexel/8;
     if (action == MemoryFreed) {
-        sAmount -= bytes;
+        MOZ_RELEASE_ASSERT(amount <= sAmount);
+        sAmount -= amount;
     } else {
-        sAmount += bytes;
+        sAmount += amount;
     }
 }
--- a/gfx/gl/GfxTexturesReporter.h
+++ b/gfx/gl/GfxTexturesReporter.h
@@ -36,38 +36,37 @@ public:
         // when memory being allocated is reported to a memory reporter
         MemoryAllocated,
         // when memory being freed is reported to a memory reporter
         MemoryFreed
     };
 
     // When memory is used/freed for tile textures, call this method to update
     // the value reported by this memory reporter.
-    static void UpdateAmount(MemoryUse action, GLenum format, GLenum type,
-                             int32_t tileWidth, int32_t tileHeight);
+    static void UpdateAmount(MemoryUse action, size_t amount);
 
-    static void UpdateWasteAmount(int32_t delta) {
+    static void UpdateWasteAmount(size_t delta) {
       sTileWasteAmount += delta;
     }
 
     NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
                               nsISupports* aData, bool aAnonymize) override
     {
         MOZ_COLLECT_REPORT("gfx-tiles-waste", KIND_OTHER, UNITS_BYTES,
-            sTileWasteAmount,
+            int64_t(sTileWasteAmount),
             "Memory lost due to tiles extending past content boundaries");
         return MOZ_COLLECT_REPORT(
-            "gfx-textures", KIND_OTHER, UNITS_BYTES, sAmount,
+            "gfx-textures", KIND_OTHER, UNITS_BYTES, int64_t(sAmount),
             "Memory used for storing GL textures.");
     }
 
 private:
-    static Atomic<int32_t> sAmount;
+    static Atomic<size_t> sAmount;
     // Count the amount of memory lost to tile waste
-    static Atomic<int32_t> sTileWasteAmount;
+    static Atomic<size_t> sTileWasteAmount;
 };
 
 class GfxTextureWasteTracker {
 public:
   GfxTextureWasteTracker()
     : mBytes(0)
   {
     MOZ_COUNT_CTOR(GfxTextureWasteTracker);
--- a/gfx/gl/TextureImageEGL.cpp
+++ b/gfx/gl/TextureImageEGL.cpp
@@ -202,24 +202,29 @@ TextureImageEGL::DirectUpdate(gfx::DataS
     nsIntRegion region;
     if (mTextureState != Valid) {
         bounds = gfx::IntRect(0, 0, mSize.width, mSize.height);
         region = nsIntRegion(bounds);
     } else {
         region = aRegion;
     }
 
+    size_t uploadSize = 0;
     mTextureFormat =
       UploadSurfaceToTexture(mGLContext,
                              aSurf,
                              region,
                              mTexture,
+                             &uploadSize,
                              mTextureState == Created,
                              bounds.TopLeft() + gfx::IntPoint(aFrom.x, aFrom.y),
                              false);
+    if (uploadSize > 0) {
+        UpdateUploadSize(uploadSize);
+    }
 
     mTextureState = Valid;
     return true;
 }
 
 void
 TextureImageEGL::BindTexture(GLenum aTextureUnit)
 {
--- a/widget/cocoa/nsChildView.mm
+++ b/widget/cocoa/nsChildView.mm
@@ -48,16 +48,17 @@
 
 #include "gfxContext.h"
 #include "gfxQuartzSurface.h"
 #include "gfxUtils.h"
 #include "nsRegion.h"
 #include "Layers.h"
 #include "ClientLayerManager.h"
 #include "mozilla/layers/LayerManagerComposite.h"
+#include "GfxTexturesReporter.h"
 #include "GLTextureImage.h"
 #include "GLContextProvider.h"
 #include "GLContextCGL.h"
 #include "GLUploadHelpers.h"
 #include "ScopedGLHelpers.h"
 #include "HeapCopyOfStackArray.h"
 #include "mozilla/layers/APZCTreeManager.h"
 #include "mozilla/layers/APZThreadUtils.h"
@@ -2979,21 +2980,23 @@ RectTextureImage::EndUpdate(bool aKeepSu
   gfx::IntPoint srcPoint = updateRegion.GetBounds().TopLeft().ToUnknownPoint();
   gfx::SurfaceFormat format = mUpdateDrawTarget->GetFormat();
   int bpp = gfx::BytesPerPixel(format);
   int32_t stride = mBufferSize.width * bpp;
   unsigned char* data = mUpdateDrawTargetData.get();
   data += srcPoint.y * stride + srcPoint.x * bpp;
 
   UploadImageDataToTexture(mGLContext, data, stride, format,
-                           updateRegion.ToUnknownRegion(), mTexture,
+                           updateRegion.ToUnknownRegion(), mTexture, nullptr,
                            overwriteTexture, /* aPixelBuffer = */ false,
                            LOCAL_GL_TEXTURE0,
                            LOCAL_GL_TEXTURE_RECTANGLE_ARB);
 
+
+
   if (!aKeepSurface) {
     mUpdateDrawTarget = nullptr;
     mUpdateDrawTargetData = nullptr;
   }
 
   mInUpdate = false;
 }