Bug 1316654 - Fix the DrawTargetSkia::CreateSimilarDrawTarget check for non-raster backed SkCanvas to be more robust. r=lsalzman, a=jcristau
authorJonathan Watt <jwatt@jwatt.org>
Mon, 09 Jan 2017 16:08:49 +0000
changeset 353442 b7a454e513ffc0dc1df147a0559332cee17f2c4c
parent 353441 ae40c9ff8660cbe0239161cff7ec3db1faa4c468
child 353443 35faa0cd51d5425962a07e3c488884223de0aed7
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerslsalzman, jcristau
bugs1316654
milestone52.0a2
Bug 1316654 - Fix the DrawTargetSkia::CreateSimilarDrawTarget check for non-raster backed SkCanvas to be more robust. r=lsalzman, a=jcristau
gfx/2d/DrawTargetSkia.cpp
gfx/2d/HelpersSkia.h
--- a/gfx/2d/DrawTargetSkia.cpp
+++ b/gfx/2d/DrawTargetSkia.cpp
@@ -1564,21 +1564,21 @@ DrawTargetSkia::CreateSimilarDrawTarget(
     if (target->InitWithGrContext(mGrContext.get(), aSize, aFormat, true)) {
       return target.forget();
     }
     // Otherwise, just fall back to a software draw target.
   }
 #endif
 
 #ifdef DEBUG
-  // Check that our SkCanvas isn't backed by vector storage such as PDF.  If it
-  // is then we want similar storage to avoid losing fidelity (if and when this
-  // DrawTarget is Snapshot()'ed, drawning a raster back into this DrawTarget
-  // will lose fidelity).
-  if (mCanvas->imageInfo().colorType() != kUnknown_SkColorType) {
+  if (!IsBackedByPixels(mCanvas.get())) {
+    // If our canvas is backed by vector storage such as PDF then we want to
+    // create a new DrawTarget with similar storage to avoid losing fidelity
+    // (fidelity will be lost if the returned DT is Snapshot()'ed and drawn
+    // back onto us since a raster will be drawn instead of vector commands).
     NS_WARNING("Not backed by pixels - we need to handle PDF backed SkCanvas");
   }
 #endif
 
   if (!target->Init(aSize, aFormat)) {
     return nullptr;
   }
   return target.forget();
@@ -1769,19 +1769,17 @@ bool
 DrawTargetSkia::Init(SkCanvas* aCanvas)
 {
   mCanvas = sk_ref_sp(aCanvas);
 
   SkImageInfo imageInfo = mCanvas->imageInfo();
 
   // If the canvas is backed by pixels we clear it to be on the safe side.  If
   // it's not (for example, for PDF output) we don't.
-  bool isBackedByPixels = imageInfo.colorType() != kUnknown_SkColorType;
-  if (isBackedByPixels) {
-    // Note for PDF backed SkCanvas |alphaType == kUnknown_SkAlphaType|.
+  if (IsBackedByPixels(mCanvas.get())) {
     SkColor clearColor = imageInfo.isOpaque() ? SK_ColorBLACK : SK_ColorTRANSPARENT;
     mCanvas->clear(clearColor);
   }
 
   SkISize size = mCanvas->getBaseLayerSize();
   mSize.width = size.width();
   mSize.height = size.height();
   mFormat = SkiaColorTypeToGfxFormat(imageInfo.colorType(),
--- a/gfx/2d/HelpersSkia.h
+++ b/gfx/2d/HelpersSkia.h
@@ -366,12 +366,31 @@ static inline FillRule GetFillRule(SkPat
   default:
     NS_WARNING("Unsupported fill type\n");
     break;
   }
 
   return FillRule::FILL_EVEN_ODD;
 }
 
+/**
+ * Returns true if the canvas is backed by pixels.  Returns false if the canvas
+ * wraps an SkPDFDocument, for example.
+ *
+ * Note: It is not clear whether the test used to implement this function may
+ * result in it returning false in some circumstances even when the canvas
+ * _is_ pixel backed.  In other words maybe it is possible for such a canvas to
+ * have kUnknown_SkPixelGeometry?
+ */
+static inline bool IsBackedByPixels(const SkCanvas* aCanvas)
+{
+  SkSurfaceProps props(0, kUnknown_SkPixelGeometry);
+  if (!aCanvas->getProps(&props) ||
+      props.pixelGeometry() == kUnknown_SkPixelGeometry) {
+    return false;
+  }
+  return true;
+}
+
 } // namespace gfx
 } // namespace mozilla
 
 #endif /* MOZILLA_GFX_HELPERSSKIA_H_ */