Bug 897409. Use a temporary surface instead of forcing image surfaces (v2). r=mattwoodrow
authorNicholas Cameron <ncameron@mozilla.com>
Thu, 01 Aug 2013 10:17:41 +1200
changeset 140831 88919d816c3295d6757f7fe5ee98054d42ec70d3
parent 140830 b662cd70ea7570309daddcf9d40d81a182904b51
child 140832 2809a0f567cac04b0cb70dd83071bd23fd53248f
push id25042
push userryanvm@gmail.com
push dateThu, 01 Aug 2013 20:34:31 +0000
treeherdermozilla-central@9d9856cf1648 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmattwoodrow
bugs897409
milestone25.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 897409. Use a temporary surface instead of forcing image surfaces (v2). r=mattwoodrow
gfx/layers/CopyableCanvasLayer.cpp
gfx/layers/client/CanvasClient.cpp
--- a/gfx/layers/CopyableCanvasLayer.cpp
+++ b/gfx/layers/CopyableCanvasLayer.cpp
@@ -69,98 +69,77 @@ CopyableCanvasLayer::UpdateSurface(gfxAS
   if (!mGLContext && aDestSurface) {
     nsRefPtr<gfxContext> tmpCtx = new gfxContext(aDestSurface);
     tmpCtx->SetOperator(gfxContext::OPERATOR_SOURCE);
     CopyableCanvasLayer::PaintWithOpacity(tmpCtx, 1.0f, aMaskLayer);
     return;
   }
 
   if (mGLContext) {
-    if (aDestSurface && aDestSurface->GetType() != gfxASurface::SurfaceTypeImage) {
-      MOZ_ASSERT(false, "Destination surface must be ImageSurface type.");
-      return;
-    }
-
     nsRefPtr<gfxImageSurface> readSurf;
-    nsRefPtr<gfxImageSurface> resultSurf;
+    nsRefPtr<gfxASurface> resultSurf;
 
     SharedSurface* sharedSurf = mGLContext->RequestFrame();
     if (!sharedSurf) {
       NS_WARNING("Null frame received.");
       return;
     }
 
     gfxIntSize readSize(sharedSurf->Size());
     gfxImageFormat format = (GetContentFlags() & CONTENT_OPAQUE)
                             ? gfxASurface::ImageFormatRGB24
                             : gfxASurface::ImageFormatARGB32;
 
     if (aDestSurface) {
-      resultSurf = static_cast<gfxImageSurface*>(aDestSurface);
+      resultSurf = aDestSurface;
     } else {
       resultSurf = GetTempSurface(readSize, format);
     }
     MOZ_ASSERT(resultSurf);
     if (resultSurf->CairoStatus() != 0) {
       MOZ_ASSERT(false, "Bad resultSurf->CairoStatus().");
       return;
     }
 
     MOZ_ASSERT(sharedSurf->APIType() == APITypeT::OpenGL);
     SharedSurface_GL* surfGL = SharedSurface_GL::Cast(sharedSurf);
 
     if (surfGL->Type() == SharedSurfaceType::Basic) {
       SharedSurface_Basic* sharedSurf_Basic = SharedSurface_Basic::Cast(surfGL);
       readSurf = sharedSurf_Basic->GetData();
     } else {
-      if (resultSurf->Format() == format &&
-          resultSurf->GetSize() == readSize)
+      if (resultSurf->GetSize() != readSize ||
+          !(readSurf = resultSurf->GetAsImageSurface()) ||
+          readSurf->Format() != format)
       {
-        readSurf = resultSurf;
-      } else {
         readSurf = GetTempSurface(readSize, format);
       }
 
       // Readback handles Flush/MarkDirty.
       mGLContext->Screen()->Readback(surfGL, readSurf);
     }
     MOZ_ASSERT(readSurf);
 
     bool needsPremult = surfGL->HasAlpha() && !mIsGLAlphaPremult;
     if (needsPremult) {
-      gfxImageSurface* sizedReadSurf = nullptr;
-      if (readSurf->Format()  == resultSurf->Format() &&
-          readSurf->GetSize() == resultSurf->GetSize())
-      {
-        sizedReadSurf = readSurf;
-      } else {
-        readSurf->Flush();
-        nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
-        ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
-        ctx->SetSource(readSurf);
-        ctx->Paint();
-
-        sizedReadSurf = resultSurf;
-      }
-      MOZ_ASSERT(sizedReadSurf);
-
       readSurf->Flush();
-      resultSurf->Flush();
-      gfxUtils::PremultiplyImageSurface(readSurf, resultSurf);
-      resultSurf->MarkDirty();
-    } else if (resultSurf != readSurf) {
-      // Didn't need premult, but we do need to blit to resultSurf
+      gfxUtils::PremultiplyImageSurface(readSurf);
+      readSurf->MarkDirty();
+    }
+    
+    if (readSurf != resultSurf) {
       readSurf->Flush();
       nsRefPtr<gfxContext> ctx = new gfxContext(resultSurf);
       ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
       ctx->SetSource(readSurf);
       ctx->Paint();
     }
 
-    // stick our surface into mSurface, so that the Paint() path is the same
+    // If !aDestSurface then we will end up painting using mSurface, so
+    // stick our surface into mSurface, so that the Paint() path is the same.
     if (!aDestSurface) {
       mSurface = resultSurf;
     }
   }
 }
 
 void
 CopyableCanvasLayer::PaintWithOpacity(gfxContext* aContext,
--- a/gfx/layers/client/CanvasClient.cpp
+++ b/gfx/layers/client/CanvasClient.cpp
@@ -61,17 +61,17 @@ CanvasClient2D::Update(gfx::IntSize aSiz
   }
 
   bool isOpaque = (aLayer->GetContentFlags() & Layer::CONTENT_OPAQUE);
   gfxASurface::gfxContentType contentType = isOpaque
                                               ? gfxASurface::CONTENT_COLOR
                                               : gfxASurface::CONTENT_COLOR_ALPHA;
   mDeprecatedTextureClient->EnsureAllocated(aSize, contentType);
 
-  gfxASurface* surface = mDeprecatedTextureClient->LockImageSurface();
+  gfxASurface* surface = mDeprecatedTextureClient->LockSurface();
   aLayer->UpdateSurface(surface);
   mDeprecatedTextureClient->Unlock();
 }
 
 void
 CanvasClientWebGL::Updated()
 {
   mForwarder->UpdateTextureNoSwap(this, 1, mDeprecatedTextureClient->GetDescriptor());