Bug 1034528, part 3 - Remove the Thebes backed gfxContext propagating code from nsFilterInstance. r=Bas
authorJonathan Watt <jwatt@jwatt.org>
Mon, 07 Jul 2014 09:05:16 +0100
changeset 192533 3a090599c39ef7d6ef0c66af45d55cb163c06f4f
parent 192532 aadf68ef25b2bb6c4836269b66ea2a16d8d09e8e
child 192534 699348fd356b06788e6dadf11c32b947270b071f
child 192665 01356babaefc0c0f5c1401ebe29ee9122cd7065d
push id27088
push usercbook@mozilla.com
push dateMon, 07 Jul 2014 12:19:04 +0000
treeherdermozilla-central@699348fd356b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersBas
bugs1034528
milestone33.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 1034528, part 3 - Remove the Thebes backed gfxContext propagating code from nsFilterInstance. r=Bas
layout/svg/nsFilterInstance.cpp
layout/svg/nsFilterInstance.h
--- a/layout/svg/nsFilterInstance.cpp
+++ b/layout/svg/nsFilterInstance.cpp
@@ -293,40 +293,28 @@ nsFilterInstance::ComputeNeededBoxes()
 
   mSourceGraphic.mNeededBounds = sourceGraphicNeededRegion.GetBounds();
   mFillPaint.mNeededBounds = fillPaintNeededRegion.GetBounds();
   mStrokePaint.mNeededBounds = strokePaintNeededRegion.GetBounds();
 }
 
 nsresult
 nsFilterInstance::BuildSourcePaint(SourceInfo *aSource,
-                                   gfxASurface* aTargetSurface,
                                    DrawTarget* aTargetDT)
 {
   nsIntRect neededRect = aSource->mNeededBounds;
 
-  RefPtr<DrawTarget> offscreenDT;
-  nsRefPtr<gfxASurface> offscreenSurface;
-  nsRefPtr<gfxContext> ctx;
-  if (aTargetSurface) {
-    offscreenSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(
-      neededRect.Size().ToIntSize(), gfxContentType::COLOR_ALPHA);
-    if (!offscreenSurface || offscreenSurface->CairoStatus()) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenSurface);
-  } else {
-    offscreenDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+  RefPtr<DrawTarget> offscreenDT =
+    gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
       ToIntSize(neededRect.Size()), SurfaceFormat::B8G8R8A8);
-    if (!offscreenDT) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenDT);
+  if (!offscreenDT) {
+    return NS_ERROR_OUT_OF_MEMORY;
   }
 
+  nsRefPtr<gfxContext> ctx = new gfxContext(offscreenDT);
   ctx->Translate(-neededRect.TopLeft());
 
   nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext());
   tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
 
   gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
   gfxContext *gfx = tmpCtx->ThebesContext();
   gfx->Multiply(deviceToFilterSpace);
@@ -343,73 +331,56 @@ nsFilterInstance::BuildSourcePaint(Sourc
          nsSVGUtils::SetupCairoFillPaint(mTargetFrame, gfx)) ||
         (aSource == &mStrokePaint &&
          nsSVGUtils::SetupCairoStrokePaint(mTargetFrame, gfx))) {
       gfx->Fill();
     }
   }
   gfx->Restore();
 
-  if (offscreenSurface) {
-    aSource->mSourceSurface =
-      gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTargetDT, offscreenSurface);
-  } else {
-    aSource->mSourceSurface = offscreenDT->Snapshot();
-  }
+
+  aSource->mSourceSurface = offscreenDT->Snapshot();
   aSource->mSurfaceRect = ToIntRect(neededRect);
 
   return NS_OK;
 }
 
 nsresult
-nsFilterInstance::BuildSourcePaints(gfxASurface* aTargetSurface,
-                                    DrawTarget* aTargetDT)
+nsFilterInstance::BuildSourcePaints(DrawTarget* aTargetDT)
 {
   nsresult rv = NS_OK;
 
   if (!mFillPaint.mNeededBounds.IsEmpty()) {
-    rv = BuildSourcePaint(&mFillPaint, aTargetSurface, aTargetDT);
+    rv = BuildSourcePaint(&mFillPaint, aTargetDT);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   if (!mStrokePaint.mNeededBounds.IsEmpty()) {
-    rv = BuildSourcePaint(&mStrokePaint, aTargetSurface, aTargetDT);
+    rv = BuildSourcePaint(&mStrokePaint, aTargetDT);
     NS_ENSURE_SUCCESS(rv, rv);
   }
   return  rv;
 }
 
 nsresult
-nsFilterInstance::BuildSourceImage(gfxASurface* aTargetSurface,
-                                   DrawTarget* aTargetDT)
+nsFilterInstance::BuildSourceImage(DrawTarget* aTargetDT)
 {
   nsIntRect neededRect = mSourceGraphic.mNeededBounds;
   if (neededRect.IsEmpty()) {
     return NS_OK;
   }
 
-  RefPtr<DrawTarget> offscreenDT;
-  nsRefPtr<gfxASurface> offscreenSurface;
-  nsRefPtr<gfxContext> ctx;
-  if (aTargetSurface) {
-    offscreenSurface = gfxPlatform::GetPlatform()->CreateOffscreenSurface(
-      neededRect.Size().ToIntSize(), gfxContentType::COLOR_ALPHA);
-    if (!offscreenSurface || offscreenSurface->CairoStatus()) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenSurface);
-  } else {
-    offscreenDT = gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
+  RefPtr<DrawTarget> offscreenDT =
+    gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(
       ToIntSize(neededRect.Size()), SurfaceFormat::B8G8R8A8);
-    if (!offscreenDT) {
-      return NS_ERROR_OUT_OF_MEMORY;
-    }
-    ctx = new gfxContext(offscreenDT);
+  if (!offscreenDT) {
+    return NS_ERROR_OUT_OF_MEMORY;
   }
 
+  nsRefPtr<gfxContext> ctx = new gfxContext(offscreenDT);
   ctx->Translate(-neededRect.TopLeft());
 
   nsRefPtr<nsRenderingContext> tmpCtx(new nsRenderingContext());
   tmpCtx->Init(mTargetFrame->PresContext()->DeviceContext(), ctx);
 
   gfxRect r = FilterSpaceToUserSpace(neededRect);
   r.RoundOut();
   nsIntRect dirty;
@@ -426,93 +397,59 @@ nsFilterInstance::BuildSourceImage(gfxAS
   // (since that would eliminate the transform multiplications from user
   // space to device space and back again). However, that would make the
   // code more complex while being hard to get right without introducing
   // subtle bugs, and in practice it probably makes no real difference.)
   gfxMatrix deviceToFilterSpace = GetFilterSpaceToDeviceSpaceTransform().Invert();
   tmpCtx->ThebesContext()->Multiply(deviceToFilterSpace);
   mPaintCallback->Paint(tmpCtx, mTargetFrame, &dirty, mTransformRoot);
 
-  RefPtr<SourceSurface> sourceGraphicSource;
-
-  if (offscreenSurface) {
-    sourceGraphicSource =
-      gfxPlatform::GetPlatform()->GetSourceSurfaceForSurface(aTargetDT, offscreenSurface);
-  } else {
-    sourceGraphicSource = offscreenDT->Snapshot();
-  }
-
-  mSourceGraphic.mSourceSurface = sourceGraphicSource;
+  mSourceGraphic.mSourceSurface = offscreenDT->Snapshot();
   mSourceGraphic.mSurfaceRect = ToIntRect(neededRect);
    
   return NS_OK;
 }
 
 nsresult
 nsFilterInstance::Render(gfxContext* aContext)
 {
   nsIntRect filterRect = mPostFilterDirtyRegion.GetBounds().Intersect(mFilterSpaceBounds);
   gfxMatrix ctm = GetFilterSpaceToDeviceSpaceTransform();
 
   if (filterRect.IsEmpty() || ctm.IsSingular()) {
     return NS_OK;
   }
 
   Matrix oldDTMatrix;
-  nsRefPtr<gfxASurface> resultImage;
-  RefPtr<DrawTarget> dt;
-  if (aContext->IsCairo()) {
-    resultImage =
-      gfxPlatform::GetPlatform()->CreateOffscreenSurface(filterRect.Size().ToIntSize(),
-                                                         gfxContentType::COLOR_ALPHA);
-    if (!resultImage || resultImage->CairoStatus())
-      return NS_ERROR_OUT_OF_MEMORY;
-
-    // Create a Cairo DrawTarget around resultImage.
-    dt = gfxPlatform::GetPlatform()->CreateDrawTargetForSurface(
-           resultImage, ToIntSize(filterRect.Size()));
-  } else {
-    // When we have a DrawTarget-backed context, we can call DrawFilter
-    // directly on the target DrawTarget and don't need a temporary DT.
-    dt = aContext->GetDrawTarget();
-    oldDTMatrix = dt->GetTransform();
-    Matrix matrix = ToMatrix(ctm);
-    matrix.Translate(filterRect.x, filterRect.y);
-    dt->SetTransform(matrix * oldDTMatrix);
-  }
+  RefPtr<DrawTarget> dt = aContext->GetDrawTarget();
+  oldDTMatrix = dt->GetTransform();
+  Matrix matrix = ToMatrix(ctm);
+  matrix.Translate(filterRect.x, filterRect.y);
+  dt->SetTransform(matrix * oldDTMatrix);
 
   ComputeNeededBoxes();
 
-  nsresult rv = BuildSourceImage(resultImage, dt);
+  nsresult rv = BuildSourceImage(dt);
   if (NS_FAILED(rv))
     return rv;
-  rv = BuildSourcePaints(resultImage, dt);
+  rv = BuildSourcePaints(dt);
   if (NS_FAILED(rv))
     return rv;
 
   IntRect filterSpaceBounds = ToIntRect(mFilterSpaceBounds);
   FilterDescription filter(mPrimitiveDescriptions, filterSpaceBounds);
 
   FilterSupport::RenderFilterDescription(
     dt, filter, ToRect(filterRect),
     mSourceGraphic.mSourceSurface, mSourceGraphic.mSurfaceRect,
     mFillPaint.mSourceSurface, mFillPaint.mSurfaceRect,
     mStrokePaint.mSourceSurface, mStrokePaint.mSurfaceRect,
     mInputImages);
 
-  if (resultImage) {
-    aContext->Save();
-    aContext->Multiply(ctm);
-    aContext->Translate(filterRect.TopLeft());
-    aContext->SetSource(resultImage);
-    aContext->Paint();
-    aContext->Restore();
-  } else {
-    dt->SetTransform(oldDTMatrix);
-  }
+  dt->SetTransform(oldDTMatrix);
 
   return NS_OK;
 }
 
 nsresult
 nsFilterInstance::ComputePostFilterDirtyRegion(nsRegion* aPostFilterDirtyRegion)
 {
   *aPostFilterDirtyRegion = nsRegion();
--- a/layout/svg/nsFilterInstance.h
+++ b/layout/svg/nsFilterInstance.h
@@ -178,33 +178,30 @@ private:
     IntRect mSurfaceRect;
   };
 
   /**
    * Creates a SourceSurface for either the FillPaint or StrokePaint graph
    * nodes
    */
   nsresult BuildSourcePaint(SourceInfo *aPrimitive,
-                            gfxASurface* aTargetSurface,
                             DrawTarget* aTargetDT);
 
   /**
    * Creates a SourceSurface for either the FillPaint and StrokePaint graph
    * nodes, fills its contents and assigns it to mFillPaint.mSourceSurface and
    * mStrokePaint.mSourceSurface respectively.
    */
-  nsresult BuildSourcePaints(gfxASurface* aTargetSurface,
-                             DrawTarget* aTargetDT);
+  nsresult BuildSourcePaints(DrawTarget* aTargetDT);
 
   /**
    * Creates the SourceSurface for the SourceGraphic graph node, paints its
    * contents, and assigns it to mSourceGraphic.mSourceSurface.
    */
-  nsresult BuildSourceImage(gfxASurface* aTargetSurface,
-                            DrawTarget* aTargetDT);
+  nsresult BuildSourceImage(DrawTarget* aTargetDT);
 
   /**
    * Build the list of FilterPrimitiveDescriptions that describes the filter's
    * filter primitives and their connections. This populates
    * mPrimitiveDescriptions and mInputImages.
    */
   nsresult BuildPrimitives();