Bug 1467552 - make VectorImage::Show force OP_OVER. r=bas
authorLee Salzman <lsalzman@mozilla.com>
Fri, 08 Jun 2018 12:38:13 -0400
changeset 422024 7f5ff1e7158b39524f142e368b458a4b9dbffa0e
parent 422023 43bd7e809560b7866ca9b253ce660e17c5f010ea
child 422025 ee8699581c1666e449ee5a2fc15ea6ecf664e97a
push id34114
push userbtara@mozilla.com
push dateSat, 09 Jun 2018 15:31:58 +0000
treeherdermozilla-central@e02a5155d815 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbas
bugs1467552
milestone62.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 1467552 - make VectorImage::Show force OP_OVER. r=bas
gfx/thebes/gfxUtils.cpp
gfx/thebes/gfxUtils.h
image/VectorImage.cpp
layout/svg/crashtests/1467552-1.html
layout/svg/crashtests/crashtests.list
--- a/gfx/thebes/gfxUtils.cpp
+++ b/gfx/thebes/gfxUtils.cpp
@@ -297,17 +297,18 @@ OptimalFillOp()
 }
 
 // EXTEND_PAD won't help us here; we have to create a temporary surface to hold
 // the subimage of pixels we're allowed to sample.
 static already_AddRefed<gfxDrawable>
 CreateSamplingRestrictedDrawable(gfxDrawable* aDrawable,
                                  gfxContext* aContext,
                                  const ImageRegion& aRegion,
-                                 const SurfaceFormat aFormat)
+                                 const SurfaceFormat aFormat,
+                                 bool aUseOptimalFillOp)
 {
     AUTO_PROFILER_LABEL("CreateSamplingRestrictedDrawable", GRAPHICS);
 
     DrawTarget* destDrawTarget = aContext->GetDrawTarget();
     if (destDrawTarget->GetBackendType() == BackendType::DIRECT2D1_1) {
       return nullptr;
     }
 
@@ -333,17 +334,19 @@ CreateSamplingRestrictedDrawable(gfxDraw
       gfxPlatform::GetPlatform()->CreateOffscreenContentDrawTarget(size, aFormat);
     if (!target || !target->IsValid()) {
       return nullptr;
     }
 
     RefPtr<gfxContext> tmpCtx = gfxContext::CreateOrNull(target);
     MOZ_ASSERT(tmpCtx); // already checked the target above
 
-    tmpCtx->SetOp(OptimalFillOp());
+    if (aUseOptimalFillOp) {
+        tmpCtx->SetOp(OptimalFillOp());
+    }
     aDrawable->Draw(tmpCtx, needed - needed.TopLeft(), ExtendMode::REPEAT,
                     SamplingFilter::LINEAR,
                     1.0, gfxMatrix::Translation(needed.TopLeft()));
     RefPtr<SourceSurface> surface = target->Snapshot();
 
     RefPtr<gfxDrawable> drawable = new gfxSurfaceDrawable(surface, size, gfxMatrix::Translation(-needed.TopLeft()));
     return drawable.forget();
 }
@@ -519,17 +522,18 @@ PrescaleAndTileDrawable(gfxDrawable* aDr
 /* static */ void
 gfxUtils::DrawPixelSnapped(gfxContext*         aContext,
                            gfxDrawable*        aDrawable,
                            const gfxSize&      aImageSize,
                            const ImageRegion&  aRegion,
                            const SurfaceFormat aFormat,
                            SamplingFilter      aSamplingFilter,
                            uint32_t            aImageFlags,
-                           gfxFloat            aOpacity)
+                           gfxFloat            aOpacity,
+                           bool                aUseOptimalFillOp)
 {
     AUTO_PROFILER_LABEL("gfxUtils::DrawPixelSnapped", GRAPHICS);
 
     gfxRect imageRect(gfxPoint(0, 0), aImageSize);
     gfxRect region(aRegion.Rect());
     ExtendMode extendMode = aRegion.GetExtendMode();
 
     RefPtr<gfxDrawable> drawable = aDrawable;
@@ -566,17 +570,18 @@ gfxUtils::DrawPixelSnapped(gfxContext*  
 #endif
 
             // On Mobile, we don't ever want to do this; it has the potential for
             // allocating very large temporary surfaces, especially since we'll
             // do full-page snapshots often (see bug 749426).
 #if !defined(MOZ_GFX_OPTIMIZE_MOBILE)
             RefPtr<gfxDrawable> restrictedDrawable =
               CreateSamplingRestrictedDrawable(aDrawable, aContext,
-                                               aRegion, aFormat);
+                                               aRegion, aFormat,
+                                               aUseOptimalFillOp);
             if (restrictedDrawable) {
               drawable.swap(restrictedDrawable);
 
               // We no longer need to tile: Either we never needed to, or we already
               // filled a surface with the tiled pattern; this surface can now be
               // drawn without tiling.
               extendMode = ExtendMode::CLAMP;
             }
--- a/gfx/thebes/gfxUtils.h
+++ b/gfx/thebes/gfxUtils.h
@@ -88,17 +88,18 @@ public:
      */
     static void DrawPixelSnapped(gfxContext*        aContext,
                                  gfxDrawable*       aDrawable,
                                  const gfxSize&     aImageSize,
                                  const ImageRegion& aRegion,
                                  const mozilla::gfx::SurfaceFormat aFormat,
                                  mozilla::gfx::SamplingFilter aSamplingFilter,
                                  uint32_t           aImageFlags = imgIContainer::FLAG_NONE,
-                                 gfxFloat           aOpacity = 1.0);
+                                 gfxFloat           aOpacity = 1.0,
+                                 bool               aUseOptimalFillOp = true);
 
     /**
      * Clip aContext to the region aRegion.
      */
     static void ClipToRegion(gfxContext* aContext, const nsIntRegion& aRegion);
 
     /**
      * Clip aTarget to the region aRegion.
--- a/image/VectorImage.cpp
+++ b/image/VectorImage.cpp
@@ -1208,17 +1208,17 @@ void
 VectorImage::Show(gfxDrawable* aDrawable, const SVGDrawingParameters& aParams)
 {
   MOZ_ASSERT(aDrawable, "Should have a gfxDrawable by now");
   gfxUtils::DrawPixelSnapped(aParams.context, aDrawable,
                              SizeDouble(aParams.size),
                              aParams.region,
                              SurfaceFormat::B8G8R8A8,
                              aParams.samplingFilter,
-                             aParams.flags, aParams.opacity);
+                             aParams.flags, aParams.opacity, false);
 
 #ifdef DEBUG
   NotifyDrawingObservers();
 #endif
 
   MOZ_ASSERT(mRenderingObserver, "Should have a rendering observer by now");
   mRenderingObserver->ResumeHonoringInvalidations();
 }
new file mode 100644
--- /dev/null
+++ b/layout/svg/crashtests/1467552-1.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html>
+<meta charset="UTF-8">
+<html>
+<style>
+fieldset {
+  mask: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciLz4=),
+        padding-box;
+  margin-right: 75px;
+}
+span {
+  vertical-align: 672in;
+}
+</style>
+<fieldset><span><video></video></span></fieldset>
+</html>
--- a/layout/svg/crashtests/crashtests.list
+++ b/layout/svg/crashtests/crashtests.list
@@ -203,12 +203,13 @@ load 1322852.html
 load 1348564.svg
 load 1402109.html
 load 1402124.html
 load 1402486.html
 load 1421807-1.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1421807-2.html
 load 1422226.html
 load 1443092.html
+load 1467552-1.html
 load conditional-outer-svg-nondirty-reflow-assert.xhtml
 load extref-test-1.xhtml
 load blob-merging-and-retained-display-list.html
 load grouping-empty-bounds.html