Bug 1073984 - Make SVG geometry painting use a Moz2D Path object directly. r=longsonr
authorJonathan Watt <jwatt@jwatt.org>
Mon, 29 Sep 2014 14:26:15 +0100
changeset 207695 89976fb1c8ec080e7bf88be12dbc6a46bee5fed4
parent 207694 4282122a081e2ea3a1c0a5064eec2bd71e0b21f0
child 207696 ab520ec5fed59faff9292a2a8d99f2bb692bebb5
push id27564
push userryanvm@gmail.com
push dateMon, 29 Sep 2014 18:57:04 +0000
treeherdermozilla-central@ce9a0b34225e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslongsonr
bugs1073984
milestone35.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 1073984 - Make SVG geometry painting use a Moz2D Path object directly. r=longsonr
image/test/reftest/downscaling/reftest.list
layout/reftests/svg/as-image/reftest.list
layout/svg/nsSVGPathGeometryFrame.cpp
--- a/image/test/reftest/downscaling/reftest.list
+++ b/image/test/reftest/downscaling/reftest.list
@@ -24,17 +24,17 @@
 # behavior than other platforms, and may require "fuzzy-if(winWidget,...)".
 
 
 # RUN TESTS NOT AFFECTED BY HIGH QUALITY DOWNSCALING:
 # ===================================================
 == downscale-svg-1a.html downscale-svg-1-ref.html?80
 fuzzy(80,468) == downscale-svg-1b.html downscale-svg-1-ref.html?72
 == downscale-svg-1c.html downscale-svg-1-ref.html?64
-fuzzy(17,208) fuzzy-if(B2G,254,207) == downscale-svg-1d.html downscale-svg-1-ref.html?53 # right side is 1 pixel off for B2G, probably regression from 974242
+fuzzy(17,208) fuzzy-if(B2G,255,207) == downscale-svg-1d.html downscale-svg-1-ref.html?53 # right side is 1 pixel off for B2G, probably regression from 974242
 fuzzy(78,216) == downscale-svg-1e.html downscale-svg-1-ref.html?40
 fuzzy(51,90) == downscale-svg-1f.html downscale-svg-1-ref.html?24
 
 # RUN TESTS WITH HIGH QUALITY DOWNSCALING DISABLED:
 # =================================================
 default-preferences pref(image.high_quality_downscaling.enabled,false)
 
 fuzzy-if(winWidget,16,20) fuzzy-if(cocoaWidget,106,31) == downscale-1.html downscale-1-ref.html
--- a/layout/reftests/svg/as-image/reftest.list
+++ b/layout/reftests/svg/as-image/reftest.list
@@ -66,17 +66,17 @@ skip-if(B2G) == img-simple-6.html  lime1
 
 # Test with mix of <html:img> and <svg:image> referring to the same images,
 # with a variety of preserveAspectRatio values in play.
 random == img-and-image-1.html img-and-image-1-ref.svg # bug 645267
 
 # More complex <img> tests
 == img-blobURI-1.html lime100x100-ref.html
 random == img-blobURI-2.html lime100x100-ref.html
-== img-content-outside-viewBox-1.html img-content-outside-viewBox-1-ref.html
+fuzzy-if(d2d,16,10) == img-content-outside-viewBox-1.html img-content-outside-viewBox-1-ref.html # d2d is bug 1074161
 == img-display-none-1.html about:blank
 == img-dyn-1.html img-dyn-1-ref.html
 == img-foreignObject-1.html lime100x100-ref.html
 
 # The following tests check that content embedded via <iframe> and <embed>
 # doesn't load (or execute scripts) in SVG-as-an-image.
 # The "!=" lines are to test that the SVG content, when viewed directly (not as
 # an image), does actually render its external content (making it look
--- a/layout/svg/nsSVGPathGeometryFrame.cpp
+++ b/layout/svg/nsSVGPathGeometryFrame.cpp
@@ -609,87 +609,90 @@ nsSVGPathGeometryFrame::MarkerProperties
 
 void
 nsSVGPathGeometryFrame::Render(nsRenderingContext *aContext,
                                uint32_t aRenderComponents,
                                const gfxMatrix& aTransform)
 {
   gfxContext *gfx = aContext->ThebesContext();
 
+  gfxMatrix newMatrix =
+    gfx->CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
+  if (newMatrix.IsSingular()) {
+    return;
+  }
+
   uint16_t renderMode = SVGAutoRenderState::GetRenderMode(aContext);
+  FillRule fillRule =
+    nsSVGUtils::ToFillRule(renderMode == SVGAutoRenderState::CLIP_MASK ?
+                             StyleSVG()->mClipRule : StyleSVG()->mFillRule);
+
+  RefPtr<PathBuilder> builder =
+    aContext->GetDrawTarget()->CreatePathBuilder(fillRule);
+  if (!builder) {
+    return;
+  }
+
+  RefPtr<Path> path =
+    static_cast<nsSVGPathGeometryElement*>(mContent)->BuildPath(builder);
+  if (!path) {
+    return;
+  }
 
   switch (StyleSVG()->mShapeRendering) {
   case NS_STYLE_SHAPE_RENDERING_OPTIMIZESPEED:
   case NS_STYLE_SHAPE_RENDERING_CRISPEDGES:
     gfx->SetAntialiasMode(AntialiasMode::NONE);
     break;
   default:
     gfx->SetAntialiasMode(AntialiasMode::SUBPIXEL);
     break;
   }
 
   if (renderMode == SVGAutoRenderState::CLIP_MASK) {
-    FillRule newFillRule = nsSVGUtils::ToFillRule(StyleSVG()->mClipRule);
-    RefPtr<PathBuilder> builder =
-      aContext->GetDrawTarget()->CreatePathBuilder(newFillRule);
-    if (!builder) {
-      return;
-    }
+    FillRule oldFillRule = gfx->CurrentFillRule();
+    gfxContextMatrixAutoSaveRestore autoSaveRestore(gfx);
 
-    RefPtr<Path> path =
-      static_cast<nsSVGPathGeometryElement*>(mContent)->BuildPath(builder);
-    if (!path) {
-      return;
-    }
-
-    gfxMatrix newMatrix =
-      gfx->CurrentMatrix().PreMultiply(aTransform).NudgeToIntegers();
-    if (newMatrix.IsSingular()) {
-      return;
-    }
-    gfxContextMatrixAutoSaveRestore autoSaveRestore(gfx);
     gfx->SetMatrix(newMatrix);
-
-    FillRule oldFillRule = gfx->CurrentFillRule();
-    gfx->SetFillRule(newFillRule);
-
+    gfx->SetFillRule(fillRule);
     gfx->SetColor(gfxRGBA(1.0f, 1.0f, 1.0f, 1.0f));
     gfx->SetPath(path);
     gfx->Fill();
+
     gfx->SetFillRule(oldFillRule);
     gfx->NewPath();
-
     return;
   }
 
   NS_ABORT_IF_FALSE(renderMode == SVGAutoRenderState::NORMAL,
                     "Unknown render mode");
 
   gfxContextAutoSaveRestore autoSaveRestore(gfx);
-
-  GeneratePath(gfx, ToMatrix(aTransform));
+  gfx->SetMatrix(newMatrix);
 
   gfxTextContextPaint *contextPaint =
     (gfxTextContextPaint*)aContext->GetDrawTarget()->GetUserData(&gfxTextContextPaint::sUserDataKey);
 
   if ((aRenderComponents & eRenderFill)) {
     nsRefPtr<gfxPattern> fillPattern =
       nsSVGUtils::MakeFillPatternFor(this, gfx, contextPaint);
     if (fillPattern) {
+      gfx->SetPath(path);
       gfx->SetPattern(fillPattern);
-      gfx->SetFillRule(nsSVGUtils::ToFillRule(StyleSVG()->mFillRule));
+      gfx->SetFillRule(fillRule);
       gfx->Fill();
     }
   }
 
   if ((aRenderComponents & eRenderStroke) &&
       nsSVGUtils::HasStroke(this, contextPaint)) {
     nsRefPtr<gfxPattern> strokePattern =
       nsSVGUtils::MakeStrokePatternFor(this, gfx, contextPaint);
     if (strokePattern) {
+      gfx->SetPath(path);
       nsSVGUtils::SetupCairoStrokeGeometry(this, gfx, contextPaint);
       gfx->SetPattern(strokePattern);
       gfx->Stroke();
     }
   }
 
   gfx->NewPath();
 }