Bug 1279409 - Part 1. Remove mix-blend-mode handling code in nsSVGIntegrationUtils.
authorcku <cku@mozilla.com>
Thu, 29 Sep 2016 11:07:51 +0800
changeset 315856 d48849ef2b8f964e4b68c6bbe82279709aab9c13
parent 315855 ed2554774482c5349fa5aee56c53e22b219ecba3
child 315857 c5b5b2bbba91bde8e3b4f9dee0a5cc653f0e0062
push id20634
push usercbook@mozilla.com
push dateFri, 30 Sep 2016 10:10:13 +0000
treeherderfx-team@afe79b010d13 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1279409
milestone52.0a1
Bug 1279409 - Part 1. Remove mix-blend-mode handling code in nsSVGIntegrationUtils. MozReview-Commit-ID: DRxYU80ClwU
layout/svg/nsSVGIntegrationUtils.cpp
--- a/layout/svg/nsSVGIntegrationUtils.cpp
+++ b/layout/svg/nsSVGIntegrationUtils.cpp
@@ -731,58 +731,16 @@ SetupContextMatrix(nsIFrame* aFrame, con
     nsRect clipRect =
       aParams.frame->GetVisualOverflowRectRelativeToSelf() + toUserSpace;
     context.Clip(NSRectToSnappedRect(clipRect,
                                   aFrame->PresContext()->AppUnitsPerDevPixel(),
                                   *context.GetDrawTarget()));
   }
 }
 
-static already_AddRefed<gfxContext>
-CreateBlendTarget(const PaintFramesParams& aParams, IntPoint& aTargetOffset)
-{
-  MOZ_ASSERT(aParams.frame->StyleEffects()->mMixBlendMode !=
-             NS_STYLE_BLEND_NORMAL);
-
-  // Create a temporary context to draw to so we can blend it back with
-  // another operator.
-  IntRect drawRect = ComputeClipExtsInDeviceSpace(aParams.ctx);
-
-  RefPtr<DrawTarget> targetDT = aParams.ctx.GetDrawTarget()->CreateSimilarDrawTarget(drawRect.Size(), SurfaceFormat::B8G8R8A8);
-  if (!targetDT || !targetDT->IsValid()) {
-    return nullptr;
-  }
-
-  RefPtr<gfxContext> target = gfxContext::CreateOrNull(targetDT);
-  MOZ_ASSERT(target); // already checked the draw target above
-  target->SetMatrix(aParams.ctx.CurrentMatrix() *
-                    gfxMatrix::Translation(-drawRect.TopLeft()));
-  aTargetOffset = drawRect.TopLeft();
-
-  return target.forget();
-}
-
-static void
-BlendToTarget(const PaintFramesParams& aParams, gfxContext* aTarget,
-              const IntPoint& aTargetOffset)
-{
-  MOZ_ASSERT(aParams.frame->StyleEffects()->mMixBlendMode !=
-             NS_STYLE_BLEND_NORMAL);
-
-  RefPtr<DrawTarget> targetDT = aTarget->GetDrawTarget();
-  RefPtr<SourceSurface> targetSurf = targetDT->Snapshot();
-
-  gfxContext& context = aParams.ctx;
-  gfxContextAutoSaveRestore save(&context);
-  context.SetMatrix(gfxMatrix()); // This will be restored right after.
-  RefPtr<gfxPattern> pattern = new gfxPattern(targetSurf, Matrix::Translation(aTargetOffset.x, aTargetOffset.y));
-  context.SetPattern(pattern);
-  context.Paint();
-}
-
 DrawResult
 nsSVGIntegrationUtils::PaintMaskAndClipPath(const PaintFramesParams& aParams)
 {
   MOZ_ASSERT(UsingMaskOrClipPathForFrame(aParams.frame),
              "Should not use this method when no mask or clipPath effect"
              "on this frame");
 
   /* SVG defines the following rendering model:
@@ -853,34 +811,16 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
   bool shouldApplyClipPath = clipPathFrame && isTrivialClip;
   bool shouldApplyBasicShape = !clipPathFrame && svgReset->HasClipPath();
   MOZ_ASSERT_IF(shouldGenerateClipMaskLayer,
                 !shouldApplyClipPath && !shouldApplyBasicShape);
 
   nsPoint offsetToBoundingBox;
   nsPoint offsetToUserSpace;
 
-  // These are used if we require a temporary surface for a custom blend mode.
-  // Clip the source context first, so that we can generate a smaller temporary
-  // surface. (Since we will clip this context in SetupContextMatrix, a pair
-  // of save/restore is needed.)
-  context.Save();
-  SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
-                     offsetToUserSpace, true);
-  IntPoint targetOffset;
-  RefPtr<gfxContext> target =
-    (aParams.frame->StyleEffects()->mMixBlendMode == NS_STYLE_BLEND_NORMAL)
-      ? RefPtr<gfxContext>(&aParams.ctx).forget()
-      : CreateBlendTarget(aParams, targetOffset);
-  context.Restore();
-
-  if (!target) {
-    return DrawResult::TEMPORARY_ERROR;
-  }
-
   bool shouldGenerateMask = (opacity != 1.0f || shouldGenerateClipMaskLayer ||
                              shouldGenerateMaskLayer);
 
   /* Check if we need to do additional operations on this child's
    * rendering, which necessitates rendering into another surface. */
   if (shouldGenerateMask) {
     gfxContextMatrixAutoSaveRestore matSR;
 
@@ -934,17 +874,17 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
     if (!shouldGenerateClipMaskLayer && !shouldGenerateMaskLayer) {
       MOZ_ASSERT(opacity != 1.0f);
 
       matSR.SetContext(&context);
       SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
                          offsetToUserSpace, true);
     }
 
-    target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA,
+    context.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA,
                                   opacityApplied ?  1.0 : opacity,
                                   maskSurface, maskTransform);
   }
 
   /* If this frame has only a trivial clipPath, set up cairo's clipping now so
    * we can just do normal painting and get it clipped appropriately.
    */
   if (shouldApplyClipPath || shouldApplyBasicShape) {
@@ -956,43 +896,38 @@ nsSVGIntegrationUtils::PaintMaskAndClipP
     if (shouldApplyClipPath) {
       clipPathFrame->ApplyClipPath(context, frame, cssPxToDevPxMatrix);
     } else {
       nsCSSClipPathInstance::ApplyBasicShapeClip(context, frame);
     }
   }
 
   /* Paint the child */
-  target->SetMatrix(matrixAutoSaveRestore.Matrix());
+  context.SetMatrix(matrixAutoSaveRestore.Matrix());
   BasicLayerManager* basic = static_cast<BasicLayerManager*>(aParams.layerManager);
   RefPtr<gfxContext> oldCtx = basic->GetTarget();
-  basic->SetTarget(target);
+  basic->SetTarget(&context);
   aParams.layerManager->EndTransaction(FrameLayerBuilder::DrawPaintedLayer,
                                        aParams.builder);
   basic->SetTarget(oldCtx);
 
   if (shouldApplyClipPath || shouldApplyBasicShape) {
     context.Restore();
   }
 
   if (shouldGenerateMask) {
-    target->PopGroupAndBlend();
+    context.PopGroupAndBlend();
 
     if (!shouldGenerateClipMaskLayer && !shouldGenerateMaskLayer) {
       MOZ_ASSERT(opacity != 1.0f);
       // Pop the clip push by SetupContextMatrix
       context.PopClip();
     }
   }
 
-  if (aParams.frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
-    MOZ_ASSERT(target != &aParams.ctx);
-    BlendToTarget(aParams, target, targetOffset);
-  }
-
   return result;
 }
 
 DrawResult
 nsSVGIntegrationUtils::PaintFilter(const PaintFramesParams& aParams)
 {
   MOZ_ASSERT(!aParams.builder->IsForGenerateGlyphMask(),
              "Filter effect is discarded while generating glyph mask.");
@@ -1021,53 +956,35 @@ nsSVGIntegrationUtils::PaintFilter(const
   if (!effectProperties.HasValidFilter()) {
     return DrawResult::NOT_READY;
   }
 
   gfxContext& context = aParams.ctx;
   nsPoint offsetToBoundingBox;
   nsPoint offsetToUserSpace;
 
-  // These are used if we require a temporary surface for a custom blend mode.
-  // Clip the source context first, so that we can generate a smaller temporary
-  // surface. (Since we will clip this context in SetupContextMatrix, a pair
-  // of save/restore is needed.)
   gfxContextAutoSaveRestore autoSR(&context);
   SetupContextMatrix(firstFrame, aParams, offsetToBoundingBox,
                      offsetToUserSpace, true);
-  IntPoint targetOffset;
-  RefPtr<gfxContext> target =
-    (aParams.frame->StyleEffects()->mMixBlendMode == NS_STYLE_BLEND_NORMAL)
-    ? RefPtr<gfxContext>(&aParams.ctx).forget()
-    : CreateBlendTarget(aParams, targetOffset);
-  if (!target) {
-    context.Restore();
-    return DrawResult::TEMPORARY_ERROR;
-  }
 
   if (opacity != 1.0f) {
-    target->PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity,
+    context.PushGroupForBlendBack(gfxContentType::COLOR_ALPHA, opacity,
                                   nullptr, Matrix());
   }
 
   /* Paint the child and apply filters */
   RegularFramePaintCallback callback(aParams.builder, aParams.layerManager,
                                      offsetToUserSpace);
   nsRegion dirtyRegion = aParams.dirtyRect - offsetToBoundingBox;
   gfxMatrix tm = nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(frame);
-  nsFilterInstance::PaintFilteredFrame(frame, target->GetDrawTarget(),
+  nsFilterInstance::PaintFilteredFrame(frame, context.GetDrawTarget(),
                                        tm, &callback, &dirtyRegion);
 
   if (opacity != 1.0f) {
-    target->PopGroupAndBlend();
-  }
-
-  if (aParams.frame->StyleEffects()->mMixBlendMode != NS_STYLE_BLEND_NORMAL) {
-    MOZ_ASSERT(target != &aParams.ctx);
-    BlendToTarget(aParams, target, targetOffset);
+    context.PopGroupAndBlend();
   }
 
   return result;
 }
 
 gfxMatrix
 nsSVGIntegrationUtils::GetCSSPxToDevPxMatrix(nsIFrame* aNonSVGFrame)
 {