Revert[2] "Remove SkDraw from device-draw methods, and enable device-centric clipping.""
authorMike Reed <reed@google.com>
Fri, 3 Mar 2017 18:58:10 +0000 (13:58 -0500)
committerSkia Commit-Bot <skia-commit-bot@chromium.org>
Fri, 3 Mar 2017 19:39:43 +0000 (19:39 +0000)
passes new (augmented) CanvasClipType unittest
fixed rasterclipstack::setnewsize

This reverts commit ea5e676a7b75600edcde3912886486004ccd7626.

BUG=skia:

Change-Id: I004653e0f4d01454662f8516fccab0046486f273
Reviewed-on: https://skia-review.googlesource.com/9185
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Reed <reed@google.com>

26 files changed:
include/core/SkCanvas.h
src/core/SkBitmapDevice.cpp
src/core/SkBitmapDevice.h
src/core/SkCanvas.cpp
src/core/SkClipStackDevice.cpp
src/core/SkClipStackDevice.h
src/core/SkDevice.cpp
src/core/SkDevice.h
src/core/SkDeviceLooper.cpp
src/core/SkDraw.cpp
src/core/SkDraw.h
src/core/SkRasterClip.cpp
src/core/SkRasterClip.h
src/core/SkRasterClipStack.h
src/gpu/GrRenderTargetOpList.cpp
src/gpu/SkGpuDevice.cpp
src/gpu/SkGpuDevice.h
src/pdf/SkPDFDevice.cpp
src/pdf/SkPDFDevice.h
src/svg/SkSVGDevice.cpp
src/svg/SkSVGDevice.h
src/utils/SkCanvasStateUtils.cpp
src/xps/SkXPSDevice.cpp
src/xps/SkXPSDevice.h
tests/LayerDrawLooperTest.cpp
tools/debugger/SkDebugCanvas.cpp

index 9e9d98a587bcb87914baf2da2efa77ed91fcb47f..3ce4baeb592b82bb6d555a1c9cfaa72bf7511339 100644 (file)
@@ -1359,6 +1359,10 @@ public:
      */
     void temporary_internal_describeTopLayer(SkMatrix* matrix, SkIRect* clip_bounds);
 
+    /**
+     *  Returns the global clip as a region. If the clip contains AA, then only the bounds
+     *  of the clip may be returned.
+     */
     void temporary_internal_getRgnClip(SkRegion*);
 
 protected:
@@ -1523,7 +1527,7 @@ private:
 
         SkBaseDevice*   device() const;
         const SkMatrix& matrix() const;
-        const SkRasterClip& clip() const;
+        void clip(SkRegion*) const;
         const SkPaint&  paint() const;
         int             x() const;
         int             y() const;
@@ -1545,7 +1549,7 @@ private:
 
     static void DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
                                      SkBaseDevice* dst, const SkIPoint& dstOrigin,
-                                     const SkMatrix& ctm, const SkClipStack* clipStack);
+                                     const SkMatrix& ctm);
 
     enum ShaderOverrideOpacity {
         kNone_ShaderOverrideOpacity,        //!< there is no overriding shader (bitmap or image)
@@ -1567,7 +1571,6 @@ private:
 
     class MCRec;
 
-    sk_sp<SkClipStack> fClipStack;
     SkDeque     fMCStack;
     // points to top of stack
     MCRec*      fMCRec;
@@ -1595,9 +1598,7 @@ private:
     friend class SkSurface_Base;
     friend class SkSurface_Gpu;
 
-    bool fDeviceCMDirty;            // cleared by updateDeviceCMCache()
     SkIRect fClipRestrictionRect = SkIRect::MakeEmpty();
-    void updateDeviceCMCache();
 
     void doSave();
     void checkForDeferredSave();
@@ -1667,14 +1668,11 @@ private:
      */
     bool canDrawBitmapAsSprite(SkScalar x, SkScalar y, int w, int h, const SkPaint&);
 
-    /** Return the clip stack. The clip stack stores all the individual
-     *  clips organized by the save/restore frame in which they were
-     *  added.
-     *  @return the current clip stack ("list" of individual clip elements)
+    /**
+     *  Returns true if the clip (for any active layer) contains antialiasing.
+     *  If the clip is empty, this will return false.
      */
-    const SkClipStack* getClipStack() const {
-        return fClipStack.get();
-    }
+    bool androidFramework_isClipAA() const;
 
     /**
      *  Keep track of the device clip bounds and if the matrix is scale-translate.  This allows
@@ -1685,7 +1683,6 @@ private:
 
     bool fAllowSoftClip;
     bool fAllowSimplifyClip;
-    const bool fConservativeRasterClip;
 
     class AutoValidateClip : ::SkNoncopyable {
     public:
index 77ff706f4f4af54d93ad9845ccfb80d3bb1e2320..89a02651322570f9548c0d102813db9be9645385 100644 (file)
@@ -190,63 +190,63 @@ bool SkBitmapDevice::onReadPixels(const SkImageInfo& dstInfo, void* dstPixels, s
 
 ///////////////////////////////////////////////////////////////////////////////
 
-#ifdef SK_USE_DEVICE_CLIPPING
-class ModifiedDraw : public SkDraw {
+class SkBitmapDevice::BDDraw : public SkDraw {
 public:
-    ModifiedDraw(const SkMatrix& cmt, const SkRasterClip& rc, const SkDraw& draw) : SkDraw(draw) {
-        SkASSERT(cmt == *draw.fMatrix);
-        fRC = &rc;
+    BDDraw(SkBitmapDevice* dev) {
+        // we need fDst to be set, and if we're actually drawing, to dirty the genID
+        if (!dev->accessPixels(&fDst)) {
+            // NoDrawDevice uses us (why?) so we have to catch this case w/ no pixels
+            fDst.reset(dev->imageInfo(), nullptr, 0);
+        }
+        fMatrix = &dev->ctm();
+        fRC = &dev->fRCStack.rc();
     }
 };
-#define PREPARE_DRAW(draw)  ModifiedDraw(this->ctm(), fRCStack.rc(), draw)
-#else
-#define PREPARE_DRAW(draw)  draw
-#endif
 
-void SkBitmapDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
-    PREPARE_DRAW(draw).drawPaint(paint);
+void SkBitmapDevice::drawPaint(const SkPaint& paint) {
+    BDDraw(this).drawPaint(paint);
 }
 
-void SkBitmapDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
+void SkBitmapDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
                                 const SkPoint pts[], const SkPaint& paint) {
-    PREPARE_DRAW(draw).drawPoints(mode, count, pts, paint, nullptr);
+    BDDraw(this).drawPoints(mode, count, pts, paint, nullptr);
 }
 
-void SkBitmapDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
-    PREPARE_DRAW(draw).drawRect(r, paint);
+void SkBitmapDevice::drawRect(const SkRect& r, const SkPaint& paint) {
+    BDDraw(this).drawRect(r, paint);
 }
 
-void SkBitmapDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
+void SkBitmapDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
     SkPath path;
     path.addOval(oval);
     // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
     // required to override drawOval.
-    this->drawPath(draw, path, paint, nullptr, true);
+    this->drawPath(path, paint, nullptr, true);
 }
 
-void SkBitmapDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
+void SkBitmapDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
 #ifdef SK_IGNORE_BLURRED_RRECT_OPT
     SkPath  path;
 
     path.addRRect(rrect);
     // call the VIRTUAL version, so any subclasses who do handle drawPath aren't
     // required to override drawRRect.
-    this->drawPath(draw, path, paint, nullptr, true);
+    this->drawPath(path, paint, nullptr, true);
 #else
-    PREPARE_DRAW(draw).drawRRect(rrect, paint);
+    BDDraw(this).drawRRect(rrect, paint);
 #endif
 }
 
-void SkBitmapDevice::drawPath(const SkDraw& draw, const SkPath& path,
+void SkBitmapDevice::drawPath(const SkPath& path,
                               const SkPaint& paint, const SkMatrix* prePathMatrix,
                               bool pathIsMutable) {
-    PREPARE_DRAW(draw).drawPath(path, paint, prePathMatrix, pathIsMutable);
+    BDDraw(this).drawPath(path, paint, prePathMatrix, pathIsMutable);
 }
 
-void SkBitmapDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBitmapDevice::drawBitmap(const SkBitmap& bitmap,
                                 const SkMatrix& matrix, const SkPaint& paint) {
-    LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
-    PREPARE_DRAW(draw).drawBitmap(bitmap, matrix, nullptr, paint);
+    LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
+    BDDraw(this).drawBitmap(bitmap, matrix, nullptr, paint);
 }
 
 static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& paint) {
@@ -258,7 +258,7 @@ static inline bool CanApplyDstMatrixAsCTM(const SkMatrix& m, const SkPaint& pain
     return m.getType() <= SkMatrix::kTranslate_Mask;
 }
 
-void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBitmapDevice::drawBitmapRect(const SkBitmap& bitmap,
                                     const SkRect* src, const SkRect& dst,
                                     const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
     SkMatrix    matrix;
@@ -275,7 +275,7 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
     }
     matrix.setRectToRect(tmpSrc, dst, SkMatrix::kFill_ScaleToFit);
 
-    LogDrawScaleFactor(SkMatrix::Concat(*draw.fMatrix, matrix), paint.getFilterQuality());
+    LogDrawScaleFactor(SkMatrix::Concat(this->ctm(), matrix), paint.getFilterQuality());
 
     const SkRect* dstPtr = &dst;
     const SkBitmap* bitmapPtr = &bitmap;
@@ -335,7 +335,7 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
         // matrix with the CTM, and try to call drawSprite if it can. If not,
         // it will make a shader and call drawRect, as we do below.
         if (CanApplyDstMatrixAsCTM(matrix, paint)) {
-            PREPARE_DRAW(draw).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
+            BDDraw(this).drawBitmap(*bitmapPtr, matrix, dstPtr, paint);
             return;
         }
     }
@@ -360,45 +360,43 @@ void SkBitmapDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
 
     // Call ourself, in case the subclass wanted to share this setup code
     // but handle the drawRect code themselves.
-    this->drawRect(draw, *dstPtr, paintWithShader);
+    this->drawRect(*dstPtr, paintWithShader);
 }
 
-void SkBitmapDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBitmapDevice::drawSprite(const SkBitmap& bitmap,
                                 int x, int y, const SkPaint& paint) {
-    PREPARE_DRAW(draw).drawSprite(bitmap, x, y, paint);
+    BDDraw(this).drawSprite(bitmap, x, y, paint);
 }
 
-void SkBitmapDevice::drawText(const SkDraw& draw, const void* text, size_t len,
+void SkBitmapDevice::drawText(const void* text, size_t len,
                               SkScalar x, SkScalar y, const SkPaint& paint) {
-    PREPARE_DRAW(draw).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
+    BDDraw(this).drawText((const char*)text, len, x, y, paint, &fSurfaceProps);
 }
 
-void SkBitmapDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
-                                 const SkScalar xpos[], int scalarsPerPos,
-                                 const SkPoint& offset, const SkPaint& paint) {
-    PREPARE_DRAW(draw).drawPosText((const char*)text, len, xpos, scalarsPerPos, offset,
-                                   paint, &fSurfaceProps);
+void SkBitmapDevice::drawPosText(const void* text, size_t len, const SkScalar xpos[],
+                                 int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) {
+    BDDraw(this).drawPosText((const char*)text, len, xpos, scalarsPerPos, offset, paint, &fSurfaceProps);
 }
 
-void SkBitmapDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
+void SkBitmapDevice::drawVertices(SkCanvas::VertexMode vmode,
                                   int vertexCount,
                                   const SkPoint verts[], const SkPoint textures[],
                                   const SkColor colors[], SkBlendMode bmode,
                                   const uint16_t indices[], int indexCount,
                                   const SkPaint& paint) {
-    PREPARE_DRAW(draw).drawVertices(vmode, vertexCount, verts, textures, colors, bmode,
-                      indices, indexCount, paint);
+    BDDraw(this).drawVertices(vmode, vertexCount, verts, textures, colors, bmode, indices,
+                              indexCount, paint);
 }
 
-void SkBitmapDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
+void SkBitmapDevice::drawDevice(SkBaseDevice* device,
                                 int x, int y, const SkPaint& paint) {
     SkASSERT(!paint.getImageFilter());
-    PREPARE_DRAW(draw).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
+    BDDraw(this).drawSprite(static_cast<SkBitmapDevice*>(device)->fBitmap, x, y, paint);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
+void SkBitmapDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
                                  const SkPaint& paint) {
     SkASSERT(!srcImg->isTextureBacked());
 
@@ -407,9 +405,9 @@ void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int
     SkImageFilter* filter = paint.getImageFilter();
     if (filter) {
         SkIPoint offset = SkIPoint::Make(0, 0);
-        SkMatrix matrix = *draw.fMatrix;
+        SkMatrix matrix = this->ctm();
         matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
-        const SkIRect clipBounds = draw.fRC->getBounds().makeOffset(-x, -y);
+        const SkIRect clipBounds = fRCStack.rc().getBounds().makeOffset(-x, -y);
         sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
         SkImageFilter::OutputProperties outputProperties(fBitmap.colorSpace());
         SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
@@ -419,12 +417,12 @@ void SkBitmapDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int
             SkPaint tmpUnfiltered(paint);
             tmpUnfiltered.setImageFilter(nullptr);
             if (resultImg->getROPixels(&resultBM)) {
-                this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
+                this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
             }
         }
     } else {
         if (srcImg->getROPixels(&resultBM)) {
-            this->drawSprite(draw, resultBM, x, y, paint);
+            this->drawSprite(resultBM, x, y, paint);
         }
     }
 }
@@ -511,9 +509,34 @@ void SkBitmapDevice::onSetDeviceClipRestriction(SkIRect* mutableClipRestriction)
     }
 }
 
+bool SkBitmapDevice::onClipIsAA() const {
+    const SkRasterClip& rc = fRCStack.rc();
+    return !rc.isEmpty() && rc.isAA();
+}
+
+void SkBitmapDevice::onAsRgnClip(SkRegion* rgn) const {
+    const SkRasterClip& rc = fRCStack.rc();
+    if (rc.isAA()) {
+        rgn->setRect(rc.getBounds());
+    } else {
+        *rgn = rc.bwRgn();
+    }
+}
+
 void SkBitmapDevice::validateDevBounds(const SkIRect& drawClipBounds) {
 #ifdef SK_DEBUG
     const SkIRect& stackBounds = fRCStack.rc().getBounds();
     SkASSERT(drawClipBounds == stackBounds);
 #endif
 }
+
+SkBaseDevice::ClipType SkBitmapDevice::onGetClipType() const {
+    const SkRasterClip& rc = fRCStack.rc();
+    if (rc.isEmpty()) {
+        return kEmpty_ClipType;
+    } else if (rc.isRect()) {
+        return kRect_ClipType;
+    } else {
+        return kComplex_ClipType;
+    }
+}
index 266b2d9513c4e329cc99e6896283f3b1b210c976..a97ad01457ca45a8b6ef43784d9bbc09c7054208 100644 (file)
@@ -21,7 +21,6 @@
 #include "SkSize.h"
 #include "SkSurfaceProps.h"
 
-class SkDraw;
 class SkImageFilterCache;
 class SkMatrix;
 class SkPaint;
@@ -70,12 +69,12 @@ protected:
      and are handling any looping from the paint, and any effects from the
      DrawFilter.
      */
-    void drawPaint(const SkDraw&, const SkPaint& paint) override;
-    void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+    void drawPaint(const SkPaint& paint) override;
+    void drawPoints(SkCanvas::PointMode mode, size_t count,
                             const SkPoint[], const SkPaint& paint) override;
-    void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
-    void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
-    void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
+    void drawRect(const SkRect& r, const SkPaint& paint) override;
+    void drawOval(const SkRect& oval, const SkPaint& paint) override;
+    void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
 
     /**
      *  If pathIsMutable, then the implementation is allowed to cast path to a
@@ -88,34 +87,34 @@ protected:
      *  affect the geometry/rasterization, then the pre matrix can just be
      *  pre-concated with the current matrix.
      */
-    void drawPath(const SkDraw&, const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
+    void drawPath(const SkPath&, const SkPaint&, const SkMatrix* prePathMatrix,
                           bool pathIsMutable) override;
-    void drawBitmap(const SkDraw&, const SkBitmap&, const SkMatrix&, const SkPaint&) override;
-    void drawSprite(const SkDraw&, const SkBitmap&, int x, int y, const SkPaint&) override;
+    void drawBitmap(const SkBitmap&, const SkMatrix&, const SkPaint&) override;
+    void drawSprite(const SkBitmap&, int x, int y, const SkPaint&) override;
 
     /**
      *  The default impl. will create a bitmap-shader from the bitmap,
      *  and call drawRect with it.
      */
-    void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect*, const SkRect&,
+    void drawBitmapRect(const SkBitmap&, const SkRect*, const SkRect&,
                         const SkPaint&, SkCanvas::SrcRectConstraint) override;
 
     /**
      *  Does not handle text decoration.
      *  Decorations (underline and stike-thru) will be handled by SkCanvas.
      */
-    void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y,
+    void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
                   const SkPaint&) override;
-    void drawPosText(const SkDraw&, const void* text, size_t len, const SkScalar pos[],
+    void drawPosText(const void* text, size_t len, const SkScalar pos[],
                      int scalarsPerPos, const SkPoint& offset, const SkPaint& paint) override;
-    void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
+    void drawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
                       const SkPoint texs[], const SkColor colors[], SkBlendMode,
                       const uint16_t indices[], int indexCount, const SkPaint&) override;
-    void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
+    void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
 
     ///////////////////////////////////////////////////////////////////////////
     
-    void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override;
+    void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
     sk_sp<SkSpecialImage> snapSpecial() override;
@@ -134,7 +133,10 @@ protected:
     void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
     void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
     void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override;
+    bool onClipIsAA() const override;
+    void onAsRgnClip(SkRegion*) const override;
     void validateDevBounds(const SkIRect& r) override;
+    ClipType onGetClipType() const override;
 
 private:
     friend class SkCanvas;
@@ -142,9 +144,10 @@ private:
     friend class SkDraw;
     friend class SkDrawIter;
     friend class SkDeviceFilteredPaint;
-
     friend class SkSurface_Raster;
 
+    class BDDraw;
+
     // used to change the backend's pixels (and possibly config/rowbytes)
     // but cannot change the width/height, so there should be no change to
     // any clip information.
index 5c7039fc50e3bf050469003022b9577916ff7ffc..0e8e7e5644120ed9f010dbc9d96163d79d37f29f 100644 (file)
@@ -75,9 +75,13 @@ bool SkCanvas::wouldOverwriteEntireSurface(const SkRect* rect, const SkPaint* pa
 
     const SkISize size = this->getBaseLayerSize();
     const SkRect bounds = SkRect::MakeIWH(size.width(), size.height());
+
+#if 0
+    // Replace with device method?
     if (!this->getClipStack()->quickContains(bounds)) {
         return false;
     }
+#endif
 
     if (rect) {
         if (!this->getTotalMatrix().isScaleTranslate()) {
@@ -192,10 +196,8 @@ struct DeviceCM {
     SkMatrix            fMatrixStorage;
     SkMatrix            fStashedMatrix; // original CTM; used by imagefilter in saveLayer
 
-    DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas,
-             bool conservativeRasterClip, const SkMatrix& stashed)
+    DeviceCM(SkBaseDevice* device, const SkPaint* paint, SkCanvas* canvas, const SkMatrix& stashed)
         : fNext(nullptr)
-        , fClip(conservativeRasterClip)
         , fStashedMatrix(stashed)
     {
         SkSafeRef(device);
@@ -214,48 +216,6 @@ struct DeviceCM {
         SkASSERT(fDevice);
         fClip.setRect(bounds);
     }
-
-    void updateMC(const SkMatrix& totalMatrix, const SkRasterClip& totalClip,
-                  SkRasterClip* updateClip) {
-        int x = fDevice->getOrigin().x();
-        int y = fDevice->getOrigin().y();
-        int width = fDevice->width();
-        int height = fDevice->height();
-
-        if ((x | y) == 0) {
-            fMatrix = &totalMatrix;
-            fClip = totalClip;
-        } else {
-            fMatrixStorage = totalMatrix;
-            fMatrixStorage.postTranslate(SkIntToScalar(-x),
-                                         SkIntToScalar(-y));
-            fMatrix = &fMatrixStorage;
-            totalClip.translate(-x, -y, &fClip);
-        }
-
-        fClip.op(SkIRect::MakeWH(width, height), SkRegion::kIntersect_Op);
-
-#ifdef SK_USE_DEVICE_CLIPPING
-        SkASSERT(*fMatrix == fDevice->ctm());
-        // TODO: debug tiles-rt-8888 so we can enable this all the time
-//        fDevice->validateDevBounds(fClip.getBounds());
-#endif
-
-        // intersect clip, but don't translate it (yet)
-
-        if (updateClip) {
-            updateClip->op(SkIRect::MakeXYWH(x, y, width, height),
-                           SkRegion::kDifference_Op);
-        }
-
-#ifdef SK_DEBUG
-        if (!fClip.isEmpty()) {
-            SkIRect deviceR;
-            deviceR.set(0, 0, width, height);
-            SkASSERT(deviceR.contains(fClip.getBounds()));
-        }
-#endif
-    }
 };
 
 /*  This is the record we keep for each save/restore level in the stack.
@@ -275,15 +235,15 @@ public:
         reference counted, since the real owner is either our fLayer field,
         or a previous one in a lower level.)
     */
-    DeviceCM*       fTopLayer;
-    SkRasterClip    fRasterClip;
-    SkMatrix        fMatrix;
-    int             fDeferredSaveCount;
+    DeviceCM*           fTopLayer;
+    SkConservativeClip  fRasterClip;
+    SkMatrix            fMatrix;
+    int                 fDeferredSaveCount;
 
     // This is the current cumulative depth (aggregate of all done translateZ calls)
     SkScalar        fCurDrawDepth;
 
-    MCRec(bool conservativeRasterClip) : fRasterClip(conservativeRasterClip) {
+    MCRec() {
         fFilter     = nullptr;
         fLayer      = nullptr;
         fTopLayer   = nullptr;
@@ -320,70 +280,26 @@ public:
     }
 };
 
-static SkIRect compute_device_bounds(SkBaseDevice* device) {
-    return SkIRect::MakeXYWH(device->getOrigin().x(), device->getOrigin().y(),
-                             device->width(), device->height());
-}
-
-class SkDrawIter : public SkDraw {
+class SkDrawIter {
 public:
-    SkDrawIter(SkCanvas* canvas) : fDevice(nullptr) {
-        canvas->updateDeviceCMCache();
-
-        fClipStack = canvas->getClipStack();
-        fCurrLayer = canvas->fMCRec->fTopLayer;
-
-        fMultiDeviceCS = nullptr;
-        if (fCurrLayer->fNext) {
-            fMultiDeviceCS = canvas->fClipStack.get();
-            fMultiDeviceCS->save();
-        }
-#ifdef SK_USE_DEVICE_CLIPPING
-        fClipStack = nullptr;   // for testing
-#endif
-    }
-
-    ~SkDrawIter() {
-        if (fMultiDeviceCS) {
-            fMultiDeviceCS->restore();
-        }
-    }
+    SkDrawIter(SkCanvas* canvas)
+        : fDevice(nullptr), fCurrLayer(canvas->fMCRec->fTopLayer), fPaint(nullptr)
+    {}
 
     bool next() {
-        if (fMultiDeviceCS && fDevice) {
-            // remove the previous device's bounds
-            fMultiDeviceCS->clipDevRect(compute_device_bounds(fDevice), kDifference_SkClipOp);
-        }
-
-        // skip over recs with empty clips
-        while (fCurrLayer && fCurrLayer->fClip.isEmpty()) {
-            fCurrLayer = fCurrLayer->fNext;
-        }
-
         const DeviceCM* rec = fCurrLayer;
         if (rec && rec->fDevice) {
-
-            fMatrix = rec->fMatrix;
-            fRC     = &rec->fClip;
             fDevice = rec->fDevice;
-            if (!fDevice->accessPixels(&fDst)) {
-                fDst.reset(fDevice->imageInfo(), nullptr, 0);
-            }
             fPaint  = rec->fPaint;
-            SkDEBUGCODE(this->validate();)
-
             fCurrLayer = rec->fNext;
             // fCurrLayer may be nullptr now
-
             return true;
         }
         return false;
     }
 
-    const SkRasterClip& getClip() const { return *fRC; }
     int getX() const { return fDevice->getOrigin().x(); }
     int getY() const { return fDevice->getOrigin().y(); }
-    const SkMatrix& getMatrix() const { return *fMatrix; }
     const SkPaint* getPaint() const { return fPaint; }
 
     SkBaseDevice*   fDevice;
@@ -391,9 +307,6 @@ public:
 private:
     const DeviceCM* fCurrLayer;
     const SkPaint*  fPaint;     // May be null.
-    SkClipStack*    fMultiDeviceCS;
-
-    typedef SkDraw INHERITED;
 };
 
 #define FOR_EACH_TOP_DEVICE( code )                 \
@@ -657,7 +570,6 @@ static inline SkRect qr_clip_bounds(const SkIRect& bounds) {
 
 void SkCanvas::resetForNextPicture(const SkIRect& bounds) {
     this->restoreToCount(1);
-    fClipStack->reset();
     fMCRec->reset(bounds);
 
     // We're peering through a lot of structs here.  Only at this scope do we
@@ -671,29 +583,22 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
     if (device && device->forceConservativeRasterClip()) {
         flags = InitFlags(flags | kConservativeRasterClip_InitFlag);
     }
-    // Since init() is only called once by our constructors, it is safe to perform this
-    // const-cast.
-    *const_cast<bool*>(&fConservativeRasterClip) = SkToBool(flags & kConservativeRasterClip_InitFlag);
 
     fAllowSimplifyClip = false;
-    fDeviceCMDirty = true;
     fSaveCount = 1;
     fMetaData = nullptr;
 #ifdef SK_EXPERIMENTAL_SHADOWING
     fLights = nullptr;
 #endif
 
-    fClipStack.reset(new SkClipStack);
-
     fMCRec = (MCRec*)fMCStack.push_back();
-    new (fMCRec) MCRec(fConservativeRasterClip);
+    new (fMCRec) MCRec;
     fMCRec->fRasterClip.setDeviceClipRestriction(&fClipRestrictionRect);
     fIsScaleTranslate = true;
 
     SkASSERT(sizeof(DeviceCM) <= sizeof(fDeviceCMStorage));
     fMCRec->fLayer = (DeviceCM*)fDeviceCMStorage;
-    new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fConservativeRasterClip,
-                                    fMCRec->fMatrix);
+    new (fDeviceCMStorage) DeviceCM(nullptr, nullptr, nullptr, fMCRec->fMatrix);
 
     fMCRec->fTopLayer = fMCRec->fLayer;
 
@@ -706,9 +611,7 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
         fMCRec->fRasterClip.setRect(device->getGlobalBounds());
         fDeviceClipBounds = qr_clip_bounds(device->getGlobalBounds());
 
-#ifdef SK_USE_DEVICE_CLIPPING
         device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
-#endif
     }
 
     return device;
@@ -717,7 +620,6 @@ SkBaseDevice* SkCanvas::init(SkBaseDevice* device, InitFlags flags) {
 SkCanvas::SkCanvas()
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
-    , fConservativeRasterClip(false)
 {
     inc_canvas();
 
@@ -746,7 +648,6 @@ private:
 SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(SkSurfacePropsCopyOrDefault(props))
-    , fConservativeRasterClip(false)
 {
     inc_canvas();
 
@@ -757,7 +658,6 @@ SkCanvas::SkCanvas(int width, int height, const SkSurfaceProps* props)
 SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
-    , fConservativeRasterClip(false)
 {
     inc_canvas();
 
@@ -767,7 +667,6 @@ SkCanvas::SkCanvas(const SkIRect& bounds, InitFlags flags)
 SkCanvas::SkCanvas(SkBaseDevice* device)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(device->surfaceProps())
-    , fConservativeRasterClip(false)
 {
     inc_canvas();
 
@@ -777,7 +676,6 @@ SkCanvas::SkCanvas(SkBaseDevice* device)
 SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(device->surfaceProps())
-    , fConservativeRasterClip(false)
 {
     inc_canvas();
 
@@ -787,7 +685,6 @@ SkCanvas::SkCanvas(SkBaseDevice* device, InitFlags flags)
 SkCanvas::SkCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props)
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(props)
-    , fConservativeRasterClip(false)
 {
     inc_canvas();
 
@@ -800,7 +697,6 @@ SkCanvas::SkCanvas(const SkBitmap& bitmap, std::unique_ptr<SkRasterHandleAllocat
     : fMCStack(sizeof(MCRec), fMCRecStorage, sizeof(fMCRecStorage))
     , fProps(SkSurfaceProps::kLegacyFontHost_InitType)
     , fAllocator(std::move(alloc))
-    , fConservativeRasterClip(false)
 {
     inc_canvas();
 
@@ -967,26 +863,6 @@ bool SkCanvas::writePixels(const SkImageInfo& srcInfo, const void* pixels, size_
 
 //////////////////////////////////////////////////////////////////////////////
 
-void SkCanvas::updateDeviceCMCache() {
-    if (fDeviceCMDirty) {
-        const SkMatrix& totalMatrix = this->getTotalMatrix();
-        const SkRasterClip& totalClip = fMCRec->fRasterClip;
-        DeviceCM*       layer = fMCRec->fTopLayer;
-
-        if (nullptr == layer->fNext) {   // only one layer
-            layer->updateMC(totalMatrix, totalClip, nullptr);
-        } else {
-            SkRasterClip clip(totalClip);
-            do {
-                layer->updateMC(totalMatrix, clip, &clip);
-            } while ((layer = layer->fNext) != nullptr);
-        }
-        fDeviceCMDirty = false;
-    }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
 void SkCanvas::checkForDeferredSave() {
     if (fMCRec->fDeferredSaveCount > 0) {
         this->doSave();
@@ -1057,10 +933,7 @@ void SkCanvas::internalSave() {
     new (newTop) MCRec(*fMCRec);    // balanced in restore()
     fMCRec = newTop;
 
-    fClipStack->save();
-#ifdef SK_USE_DEVICE_CLIPPING
     FOR_EACH_TOP_DEVICE(device->save());
-#endif
 }
 
 bool SkCanvas::BoundsAffectsClip(SaveLayerFlags saveLayerFlags) {
@@ -1091,6 +964,7 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
         // early exit if the layer's bounds are clipped out
         if (!ir.intersect(clipBounds)) {
             if (BoundsAffectsClip(saveLayerFlags)) {
+                fMCRec->fTopLayer->fDevice->clipRegion(SkRegion(), SkClipOp::kIntersect); // empty
                 fMCRec->fRasterClip.setEmpty();
                 fDeviceClipBounds.setEmpty();
             }
@@ -1103,7 +977,6 @@ bool SkCanvas::clipRectBounds(const SkRect* bounds, SaveLayerFlags saveLayerFlag
 
     if (BoundsAffectsClip(saveLayerFlags)) {
         // Simplify the current clips since they will be applied properly during restore()
-        fClipStack->clipDevRect(ir, kReplace_SkClipOp);
         fMCRec->fRasterClip.setRect(ir);
         fDeviceClipBounds = qr_clip_bounds(ir);
     }
@@ -1136,7 +1009,7 @@ int SkCanvas::saveLayer(const SaveLayerRec& origRec) {
 
 void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filter,
                                     SkBaseDevice* dst, const SkIPoint& dstOrigin,
-                                    const SkMatrix& ctm, const SkClipStack* clipStack) {
+                                    const SkMatrix& ctm) {
     SkDraw draw;
     SkRasterClip rc;
     rc.setRect(SkIRect::MakeWH(dst->width(), dst->height()));
@@ -1145,7 +1018,6 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
     }
     draw.fMatrix = &SkMatrix::I();
     draw.fRC = &rc;
-    draw.fClipStack = clipStack;
 
     SkPaint p;
     if (filter) {
@@ -1156,7 +1028,7 @@ void SkCanvas::DrawDeviceWithFilter(SkBaseDevice* src, const SkImageFilter* filt
     int y = src->getOrigin().y() - dstOrigin.y();
     auto special = src->snapSpecial();
     if (special) {
-        dst->drawSpecial(draw, special.get(), x, y, p);
+        dst->drawSpecial(special.get(), x, y, p);
     }
 }
 
@@ -1220,8 +1092,6 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
     // that would invoke a possibly overridden virtual
     this->internalSave();
 
-    fDeviceCMDirty = true;
-
     SkIRect ir;
     if (!this->clipRectBounds(bounds, saveLayerFlags, &ir, imageFilter)) {
         return;
@@ -1265,12 +1135,8 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
             return;
         }
     }
-#ifndef SK_USE_DEVICE_CLIPPING
-    newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
-#endif
-
     DeviceCM* layer =
-            new DeviceCM(newDevice.get(), paint, this, fConservativeRasterClip, stashedMatrix);
+            new DeviceCM(newDevice.get(), paint, this, stashedMatrix);
 
     // only have a "next" if this new layer doesn't affect the clip (rare)
     layer->fNext = BoundsAffectsClip(saveLayerFlags) ? nullptr : fMCRec->fTopLayer;
@@ -1279,10 +1145,9 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
 
     if ((rec.fSaveLayerFlags & kInitWithPrevious_SaveLayerFlag) || rec.fBackdrop) {
         DrawDeviceWithFilter(priorDevice, rec.fBackdrop, newDevice.get(), { ir.fLeft, ir.fTop },
-                             fMCRec->fMatrix, this->getClipStack());
+                             fMCRec->fMatrix);
     }
 
-#ifdef SK_USE_DEVICE_CLIPPING
     newDevice->setOrigin(fMCRec->fMatrix, ir.fLeft, ir.fTop);
 
     newDevice->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect);
@@ -1295,7 +1160,6 @@ void SkCanvas::internalSaveLayer(const SaveLayerRec& rec, SaveLayerStrategy stra
             layer->fDevice->clipRegion(hole, SkClipOp::kDifference);
         } while (layer->fNext);
     }
-#endif
 }
 
 int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
@@ -1311,10 +1175,6 @@ int SkCanvas::saveLayerAlpha(const SkRect* bounds, U8CPU alpha) {
 void SkCanvas::internalRestore() {
     SkASSERT(fMCStack.count() != 0);
 
-    fDeviceCMDirty = true;
-
-    fClipStack->restore();
-
     // reserve our layer (if any)
     DeviceCM* layer = fMCRec->fLayer;   // may be null
     // now detach it from fMCRec so we can pop(). Gets freed after its drawn
@@ -1325,11 +1185,9 @@ void SkCanvas::internalRestore() {
     fMCStack.pop_back();
     fMCRec = (MCRec*)fMCStack.back();
 
-#ifdef SK_USE_DEVICE_CLIPPING
     if (fMCRec) {
         FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix));
     }
-#endif
 
     /*  Time to draw the layer's offscreen. We can't call the public drawSprite,
         since if we're being recorded, we don't want to record this (the
@@ -1342,7 +1200,6 @@ void SkCanvas::internalRestore() {
             // restore what we smashed in internalSaveLayer
             fMCRec->fMatrix = layer->fStashedMatrix;
             // reset this, since internalDrawDevice will have set it to true
-            fDeviceCMDirty = true;
             delete layer;
         } else {
             // we're at the root
@@ -1448,10 +1305,10 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
         if (filter) {
             sk_sp<SkSpecialImage> specialImage = srcDev->snapSpecial();
             if (specialImage) {
-                dstDev->drawSpecial(iter, specialImage.get(), pos.x(), pos.y(), *paint);
+                dstDev->drawSpecial(specialImage.get(), pos.x(), pos.y(), *paint);
             }
         } else {
-            dstDev->drawDevice(iter, srcDev, pos.x(), pos.y(), *paint);
+            dstDev->drawDevice(srcDev, pos.x(), pos.y(), *paint);
         }
     }
 
@@ -1463,15 +1320,12 @@ void SkCanvas::internalDrawDevice(SkBaseDevice* srcDev, int x, int y, const SkPa
 void SkCanvas::translate(SkScalar dx, SkScalar dy) {
     if (dx || dy) {
         this->checkForDeferredSave();
-        fDeviceCMDirty = true;
         fMCRec->fMatrix.preTranslate(dx,dy);
 
         // Translate shouldn't affect the is-scale-translateness of the matrix.
         SkASSERT(fIsScaleTranslate == fMCRec->fMatrix.isScaleTranslate());
 
-#ifdef SK_USE_DEVICE_CLIPPING
         FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
-#endif
 
         this->didTranslate(dx,dy);
     }
@@ -1507,25 +1361,19 @@ void SkCanvas::concat(const SkMatrix& matrix) {
     }
 
     this->checkForDeferredSave();
-    fDeviceCMDirty = true;
     fMCRec->fMatrix.preConcat(matrix);
     fIsScaleTranslate = fMCRec->fMatrix.isScaleTranslate();
 
-#ifdef SK_USE_DEVICE_CLIPPING
     FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
-#endif
 
     this->didConcat(matrix);
 }
 
 void SkCanvas::internalSetMatrix(const SkMatrix& matrix) {
-    fDeviceCMDirty = true;
     fMCRec->fMatrix = matrix;
     fIsScaleTranslate = matrix.isScaleTranslate();
 
-#ifdef SK_USE_DEVICE_CLIPPING
     FOR_EACH_TOP_DEVICE(device->setGlobalCTM(fMCRec->fMatrix));
-#endif
 }
 
 void SkCanvas::setMatrix(const SkMatrix& matrix) {
@@ -1569,36 +1417,25 @@ void SkCanvas::clipRect(const SkRect& rect, SkClipOp op, bool doAA) {
 void SkCanvas::onClipRect(const SkRect& rect, SkClipOp op, ClipEdgeStyle edgeStyle) {
     const bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
 
-#ifdef SK_USE_DEVICE_CLIPPING
     FOR_EACH_TOP_DEVICE(device->clipRect(rect, op, isAA));
-#endif
 
     AutoValidateClip avc(this);
-    fClipStack->clipRect(rect, fMCRec->fMatrix, op, isAA);
     fMCRec->fRasterClip.op(rect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
                            isAA);
-    fDeviceCMDirty = true;
     fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
 }
 
 void SkCanvas::androidFramework_setDeviceClipRestriction(const SkIRect& rect) {
     fClipRestrictionRect = rect;
-    fClipStack->setDeviceClipRestriction(fClipRestrictionRect);
     if (fClipRestrictionRect.isEmpty()) {
         // we notify the device, but we *dont* resolve deferred saves (since we're just
         // removing the restriction if the rect is empty. how I hate this api.
-#ifdef SK_USE_DEVICE_CLIPPING
         FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
-#endif
     } else {
         this->checkForDeferredSave();
-#ifdef SK_USE_DEVICE_CLIPPING
         FOR_EACH_TOP_DEVICE(device->androidFramework_setDeviceClipRestriction(&fClipRestrictionRect));
-#endif
         AutoValidateClip avc(this);
-        fClipStack->clipDevRect(fClipRestrictionRect, kIntersect_SkClipOp);
         fMCRec->fRasterClip.op(fClipRestrictionRect, SkRegion::kIntersect_Op);
-        fDeviceCMDirty = true;
         fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
     }
 }
@@ -1616,19 +1453,13 @@ void SkCanvas::clipRRect(const SkRRect& rrect, SkClipOp op, bool doAA) {
 void SkCanvas::onClipRRect(const SkRRect& rrect, SkClipOp op, ClipEdgeStyle edgeStyle) {
     AutoValidateClip avc(this);
 
-    fDeviceCMDirty = true;
-
     bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
     
-#ifdef SK_USE_DEVICE_CLIPPING
     FOR_EACH_TOP_DEVICE(device->clipRRect(rrect, op, isAA));
-#endif
-    
-    fClipStack->clipRRect(rrect, fMCRec->fMatrix, op, isAA);
+
     fMCRec->fRasterClip.op(rrect, fMCRec->fMatrix, this->getTopLayerBounds(), (SkRegion::Op)op,
                            isAA);
     fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
-    return;
 }
 
 void SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) {
@@ -1659,24 +1490,12 @@ void SkCanvas::clipPath(const SkPath& path, SkClipOp op, bool doAA) {
 void SkCanvas::onClipPath(const SkPath& path, SkClipOp op, ClipEdgeStyle edgeStyle) {
     AutoValidateClip avc(this);
 
-    fDeviceCMDirty = true;
     bool isAA = kSoft_ClipEdgeStyle == edgeStyle;
     
-#ifdef SK_USE_DEVICE_CLIPPING
     FOR_EACH_TOP_DEVICE(device->clipPath(path, op, isAA));
-#endif
-    
-    fClipStack->clipPath(path, fMCRec->fMatrix, op, isAA);
 
     const SkPath* rasterClipPath = &path;
     const SkMatrix* matrix = &fMCRec->fMatrix;
-    SkPath tempPath;
-    if (fAllowSimplifyClip) {
-        isAA = getClipStack()->asPath(&tempPath);
-        rasterClipPath = &tempPath;
-        matrix = &SkMatrix::I();
-        op = kReplace_SkClipOp;
-    }
     fMCRec->fRasterClip.op(*rasterClipPath, *matrix, this->getTopLayerBounds(), (SkRegion::Op)op,
                            isAA);
     fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
@@ -1688,17 +1507,9 @@ void SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) {
 }
 
 void SkCanvas::onClipRegion(const SkRegion& rgn, SkClipOp op) {
-#ifdef SK_USE_DEVICE_CLIPPING
     FOR_EACH_TOP_DEVICE(device->clipRegion(rgn, op));
-#endif
-    
-    AutoValidateClip avc(this);
-
-    fDeviceCMDirty = true;
 
-    // todo: signal fClipStack that we have a region, and therefore (I guess)
-    // we have to ignore it, and use the region directly?
-    fClipStack->clipDevRect(rgn.getBounds(), op);
+    AutoValidateClip avc(this);
 
     fMCRec->fRasterClip.op(rgn, (SkRegion::Op)op);
     fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
@@ -1712,51 +1523,61 @@ void SkCanvas::validateClip() const {
         SkASSERT(this->isClipEmpty());
         return;
     }
-
-    SkIRect ir;
-    ir.set(0, 0, device->width(), device->height());
-    SkRasterClip tmpClip(ir, fConservativeRasterClip);
-
-    SkClipStack::B2TIter                iter(*fClipStack);
-    const SkClipStack::Element* element;
-    while ((element = iter.next()) != nullptr) {
-        switch (element->getType()) {
-            case SkClipStack::Element::kRect_Type:
-                element->getRect().round(&ir);
-                tmpClip.op(ir, (SkRegion::Op)element->getOp());
-                break;
-            case SkClipStack::Element::kEmpty_Type:
-                tmpClip.setEmpty();
-                break;
-            default: {
-                SkPath path;
-                element->asPath(&path);
-                tmpClip.op(path, SkMatrix::I(), this->getTopLayerBounds(),
-                           (SkRegion::Op)element->getOp(), element->isAA());
-                break;
-            }
-        }
-    }
 }
 #endif
 
 void SkCanvas::replayClips(ClipVisitor* visitor) const {
+#if 0
     SkClipStack::B2TIter                iter(*fClipStack);
     const SkClipStack::Element*         element;
 
     while ((element = iter.next()) != nullptr) {
         element->replay(visitor);
     }
+#endif
+}
+
+bool SkCanvas::androidFramework_isClipAA() const {
+    bool containsAA = false;
+
+    FOR_EACH_TOP_DEVICE(containsAA |= device->onClipIsAA());
+
+    return containsAA;
+}
+
+class RgnAccumulator {
+    SkRegion* fRgn;
+public:
+    RgnAccumulator(SkRegion* total) : fRgn(total) {}
+    void accumulate(SkBaseDevice* device, SkRegion* rgn) {
+        SkIPoint origin = device->getOrigin();
+        if (origin.x() | origin.y()) {
+            rgn->translate(origin.x(), origin.y());
+        }
+        fRgn->op(*rgn, SkRegion::kUnion_Op);
+    }
+};
+
+void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) {
+    RgnAccumulator accum(rgn);
+    SkRegion tmp;
+
+    rgn->setEmpty();
+    FOR_EACH_TOP_DEVICE(device->onAsRgnClip(&tmp); accum.accumulate(device, &tmp));
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
 bool SkCanvas::isClipEmpty() const {
-    return fMCRec->fRasterClip.isEmpty();
+    SkBaseDevice* dev = this->getTopDevice();
+    // if no device we return true
+    return !dev || dev->onGetClipType() == SkBaseDevice::kEmpty_ClipType;
 }
 
 bool SkCanvas::isClipRect() const {
-    return fMCRec->fRasterClip.isRect();
+    SkBaseDevice* dev = this->getTopDevice();
+    // if no device we return false
+    return dev && dev->onGetClipType() == SkBaseDevice::kRect_ClipType;
 }
 
 static inline bool is_nan_or_clipped(const Sk4f& devRect, const Sk4f& devClip) {
@@ -1857,38 +1678,13 @@ SkRect SkCanvas::onGetLocalClipBounds() const {
 }
 
 SkIRect SkCanvas::onGetDeviceClipBounds() const {
-    const SkRasterClip& clip = fMCRec->fRasterClip;
-    if (clip.isEmpty()) {
-        return SkIRect::MakeEmpty();
-    }
-    return clip.getBounds();
+    return fMCRec->fRasterClip.getBounds();
 }
 
 const SkMatrix& SkCanvas::getTotalMatrix() const {
     return fMCRec->fMatrix;
 }
 
-void SkCanvas::temporary_internal_getRgnClip(SkRegion* rgn) {
-    // we know that ganesh doesn't track the rgn, so ask for its clipstack
-    if (this->getGrContext()) {
-        const SkClipStack* cs = this->getClipStack();
-        SkClipStack::BoundsType boundType;
-        bool isIntersectionOfRects;
-        SkRect bounds;
-        cs->getBounds(&bounds, &boundType, &isIntersectionOfRects);
-        if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
-            rgn->setRect(bounds.round());
-            return;
-        }
-        SkPath path;
-        cs->asPath(&path);
-        SkISize size = this->getBaseLayerSize();
-        rgn->setPath(path, SkRegion(SkIRect::MakeWH(size.width(), size.height())));
-    } else {
-        *rgn = fMCRec->fRasterClip.forceGetBW();
-    }
-}
-
 GrRenderTargetContext* SkCanvas::internal_private_accessTopLayerRenderTargetContext() {
     SkBaseDevice* dev = this->getTopDevice();
     return dev ? dev->accessRenderTargetContext() : nullptr;
@@ -2158,7 +1954,7 @@ void SkCanvas::internalDrawPaint(const SkPaint& paint) {
     LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kPaint_Type, nullptr, false)
 
     while (iter.next()) {
-        iter.fDevice->drawPaint(iter, looper.paint());
+        iter.fDevice->drawPaint(looper.paint());
     }
 
     LOOPER_END
@@ -2192,7 +1988,7 @@ void SkCanvas::onDrawPoints(PointMode mode, size_t count, const SkPoint pts[],
     LOOPER_BEGIN(paint, SkDrawFilter::kPoint_Type, bounds)
 
     while (iter.next()) {
-        iter.fDevice->drawPoints(iter, mode, count, pts, looper.paint());
+        iter.fDevice->drawPoints(mode, count, pts, looper.paint());
     }
 
     LOOPER_END
@@ -2224,7 +2020,7 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
         LOOPER_BEGIN_CHECK_COMPLETE_OVERWRITE(paint, SkDrawFilter::kRect_Type, &r, false)
 
         while (iter.next()) {
-            iter.fDevice->drawRect(iter, r, looper.paint());
+            iter.fDevice->drawRect(r, looper.paint());
         }
 
         LOOPER_END
@@ -2232,7 +2028,7 @@ void SkCanvas::onDrawRect(const SkRect& r, const SkPaint& paint) {
         this->predrawNotify(&r, &paint, false);
         SkDrawIter iter(this);
         while (iter.next()) {
-            iter.fDevice->drawRect(iter, r, paint);
+            iter.fDevice->drawRect(r, paint);
         }
     }
 }
@@ -2249,7 +2045,7 @@ void SkCanvas::onDrawRegion(const SkRegion& region, const SkPaint& paint) {
     LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, &regionRect)
 
     while (iter.next()) {
-        iter.fDevice->drawRegion(iter, region, looper.paint());
+        iter.fDevice->drawRegion(region, looper.paint());
     }
 
     LOOPER_END
@@ -2267,7 +2063,7 @@ void SkCanvas::onDrawOval(const SkRect& oval, const SkPaint& paint) {
     LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
 
     while (iter.next()) {
-        iter.fDevice->drawOval(iter, oval, looper.paint());
+        iter.fDevice->drawOval(oval, looper.paint());
     }
 
     LOOPER_END
@@ -2288,7 +2084,7 @@ void SkCanvas::onDrawArc(const SkRect& oval, SkScalar startAngle,
     LOOPER_BEGIN(paint, SkDrawFilter::kOval_Type, &oval)
 
     while (iter.next()) {
-        iter.fDevice->drawArc(iter, oval, startAngle, sweepAngle, useCenter, looper.paint());
+        iter.fDevice->drawArc(oval, startAngle, sweepAngle, useCenter, looper.paint());
     }
 
     LOOPER_END
@@ -2316,7 +2112,7 @@ void SkCanvas::onDrawRRect(const SkRRect& rrect, const SkPaint& paint) {
     LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &rrect.getBounds())
 
     while (iter.next()) {
-        iter.fDevice->drawRRect(iter, rrect, looper.paint());
+        iter.fDevice->drawRRect(rrect, looper.paint());
     }
 
     LOOPER_END
@@ -2333,7 +2129,7 @@ void SkCanvas::onDrawDRRect(const SkRRect& outer, const SkRRect& inner, const Sk
     LOOPER_BEGIN(paint, SkDrawFilter::kRRect_Type, &outer.getBounds())
 
     while (iter.next()) {
-        iter.fDevice->drawDRRect(iter, outer, inner, looper.paint());
+        iter.fDevice->drawDRRect(outer, inner, looper.paint());
     }
 
     LOOPER_END
@@ -2363,7 +2159,7 @@ void SkCanvas::onDrawPath(const SkPath& path, const SkPaint& paint) {
     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, &pathBounds)
 
     while (iter.next()) {
-        iter.fDevice->drawPath(iter, path, looper.paint());
+        iter.fDevice->drawPath(path, looper.paint());
     }
 
     LOOPER_END
@@ -2425,12 +2221,12 @@ void SkCanvas::onDrawImage(const SkImage* image, SkScalar x, SkScalar y, const S
         const SkPaint& pnt = looper.paint();
         if (special) {
             SkPoint pt;
-            iter.fMatrix->mapXY(x, y, &pt);
-            iter.fDevice->drawSpecial(iter, special.get(),
+            iter.fDevice->ctm().mapXY(x, y, &pt);
+            iter.fDevice->drawSpecial(special.get(),
                                       SkScalarRoundToInt(pt.fX),
                                       SkScalarRoundToInt(pt.fY), pnt);
         } else {
-            iter.fDevice->drawImage(iter, image, x, y, pnt);
+            iter.fDevice->drawImage(image, x, y, pnt);
         }
     }
 
@@ -2458,7 +2254,7 @@ void SkCanvas::onDrawImageRect(const SkImage* image, const SkRect* src, const Sk
                                           image->isOpaque())
 
     while (iter.next()) {
-        iter.fDevice->drawImageRect(iter, image, src, dst, looper.paint(), constraint);
+        iter.fDevice->drawImageRect(image, src, dst, looper.paint(), constraint);
     }
 
     LOOPER_END
@@ -2506,12 +2302,12 @@ void SkCanvas::onDrawBitmap(const SkBitmap& bitmap, SkScalar x, SkScalar y, cons
         const SkPaint& pnt = looper.paint();
         if (special) {
             SkPoint pt;
-            iter.fMatrix->mapXY(x, y, &pt);
-            iter.fDevice->drawSpecial(iter, special.get(),
+            iter.fDevice->ctm().mapXY(x, y, &pt);
+            iter.fDevice->drawSpecial(special.get(),
                                       SkScalarRoundToInt(pt.fX),
                                       SkScalarRoundToInt(pt.fY), pnt);
         } else {
-            iter.fDevice->drawBitmap(iter, bitmap, matrix, looper.paint());
+            iter.fDevice->drawBitmap(bitmap, matrix, looper.paint());
         }
     }
 
@@ -2542,7 +2338,7 @@ void SkCanvas::internalDrawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
                                           bitmap.isOpaque())
 
     while (iter.next()) {
-        iter.fDevice->drawBitmapRect(iter, bitmap, src, dst, looper.paint(), constraint);
+        iter.fDevice->drawBitmapRect(bitmap, src, dst, looper.paint(), constraint);
     }
 
     LOOPER_END
@@ -2574,7 +2370,7 @@ void SkCanvas::onDrawImageNine(const SkImage* image, const SkIRect& center, cons
     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
 
     while (iter.next()) {
-        iter.fDevice->drawImageNine(iter, image, center, dst, looper.paint());
+        iter.fDevice->drawImageNine(image, center, dst, looper.paint());
     }
 
     LOOPER_END
@@ -2600,7 +2396,7 @@ void SkCanvas::onDrawBitmapNine(const SkBitmap& bitmap, const SkIRect& center, c
     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
 
     while (iter.next()) {
-        iter.fDevice->drawBitmapNine(iter, bitmap, center, dst, looper.paint());
+        iter.fDevice->drawBitmapNine(bitmap, center, dst, looper.paint());
     }
 
     LOOPER_END
@@ -2623,7 +2419,7 @@ void SkCanvas::onDrawImageLattice(const SkImage* image, const Lattice& lattice,
     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
 
     while (iter.next()) {
-        iter.fDevice->drawImageLattice(iter, image, lattice, dst, looper.paint());
+        iter.fDevice->drawImageLattice(image, lattice, dst, looper.paint());
     }
 
     LOOPER_END
@@ -2646,7 +2442,7 @@ void SkCanvas::onDrawBitmapLattice(const SkBitmap& bitmap, const Lattice& lattic
     LOOPER_BEGIN(*paint, SkDrawFilter::kBitmap_Type, &dst)
 
     while (iter.next()) {
-        iter.fDevice->drawBitmapLattice(iter, bitmap, lattice, dst, looper.paint());
+        iter.fDevice->drawBitmapLattice(bitmap, lattice, dst, looper.paint());
     }
 
     LOOPER_END
@@ -2678,7 +2474,7 @@ void SkCanvas::onDrawText(const void* text, size_t byteLength, SkScalar x, SkSca
 
     while (iter.next()) {
         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
-        iter.fDevice->drawText(iter, text, byteLength, x, y, dfp.paint());
+        iter.fDevice->drawText(text, byteLength, x, y, dfp.paint());
     }
 
     LOOPER_END
@@ -2692,7 +2488,7 @@ void SkCanvas::onDrawPosText(const void* text, size_t byteLength, const SkPoint
 
     while (iter.next()) {
         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
-        iter.fDevice->drawPosText(iter, text, byteLength, &pos->fX, 2, textOffset,
+        iter.fDevice->drawPosText(text, byteLength, &pos->fX, 2, textOffset,
                                   dfp.paint());
     }
 
@@ -2708,7 +2504,7 @@ void SkCanvas::onDrawPosTextH(const void* text, size_t byteLength, const SkScala
 
     while (iter.next()) {
         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
-        iter.fDevice->drawPosText(iter, text, byteLength, xpos, 1, textOffset,
+        iter.fDevice->drawPosText(text, byteLength, xpos, 1, textOffset,
                                   dfp.paint());
     }
 
@@ -2720,7 +2516,7 @@ void SkCanvas::onDrawTextOnPath(const void* text, size_t byteLength, const SkPat
     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
 
     while (iter.next()) {
-        iter.fDevice->drawTextOnPath(iter, text, byteLength, path,
+        iter.fDevice->drawTextOnPath(text, byteLength, path,
                                      matrix, looper.paint());
     }
 
@@ -2736,7 +2532,7 @@ void SkCanvas::onDrawTextRSXform(const void* text, size_t byteLength, const SkRS
     LOOPER_BEGIN(paint, SkDrawFilter::kText_Type, nullptr)
 
     while (iter.next()) {
-        iter.fDevice->drawTextRSXform(iter, text, byteLength, xform, looper.paint());
+        iter.fDevice->drawTextRSXform(text, byteLength, xform, looper.paint());
     }
 
     LOOPER_END
@@ -2765,7 +2561,7 @@ void SkCanvas::onDrawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
 
     while (iter.next()) {
         SkDeviceFilteredPaint dfp(iter.fDevice, looper.paint());
-        iter.fDevice->drawTextBlob(iter, blob, x, y, dfp.paint(), drawFilter);
+        iter.fDevice->drawTextBlob(blob, x, y, dfp.paint(), drawFilter);
     }
 
     LOOPER_END
@@ -2825,7 +2621,7 @@ void SkCanvas::onDrawVertices(VertexMode vmode, int vertexCount,
     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
 
     while (iter.next()) {
-        iter.fDevice->drawVertices(iter, vmode, vertexCount, verts, texs,
+        iter.fDevice->drawVertices(vmode, vertexCount, verts, texs,
                                    colors, bmode, indices, indexCount,
                                    looper.paint());
     }
@@ -2840,7 +2636,7 @@ void SkCanvas::onDrawVerticesObject(sk_sp<SkVertices> vertices, SkBlendMode bmod
 
     while (iter.next()) {
         // In the common case of one iteration we could std::move vertices here.
-        iter.fDevice->drawVerticesObject(iter, vertices, bmode, looper.paint(), flags);
+        iter.fDevice->drawVerticesObject(vertices, bmode, looper.paint(), flags);
     }
 
     LOOPER_END
@@ -2880,7 +2676,7 @@ void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, nullptr)
 
     while (iter.next()) {
-        iter.fDevice->drawPatch(iter, cubics, colors, texCoords, bmode, paint);
+        iter.fDevice->drawPatch(cubics, colors, texCoords, bmode, paint);
     }
 
     LOOPER_END
@@ -2924,7 +2720,7 @@ void SkCanvas::onDrawAtlas(const SkImage* atlas, const SkRSXform xform[], const
 
     LOOPER_BEGIN(pnt, SkDrawFilter::kPath_Type, nullptr)
     while (iter.next()) {
-        iter.fDevice->drawAtlas(iter, atlas, xform, tex, colors, count, bmode, pnt);
+        iter.fDevice->drawAtlas(atlas, xform, tex, colors, count, bmode, pnt);
     }
     LOOPER_END
 }
@@ -2935,7 +2731,7 @@ void SkCanvas::onDrawAnnotation(const SkRect& rect, const char key[], SkData* va
     SkPaint paint;
     LOOPER_BEGIN(paint, SkDrawFilter::kRect_Type, nullptr)
     while (iter.next()) {
-        iter.fDevice->drawAnnotation(iter, rect, key, value);
+        iter.fDevice->drawAnnotation(rect, key, value);
     }
     LOOPER_END
 }
@@ -3310,7 +3106,7 @@ SkBaseDevice* SkCanvas::LayerIter::device() const {
 }
 
 const SkMatrix& SkCanvas::LayerIter::matrix() const {
-    return fImpl->getMatrix();
+    return fImpl->fDevice->ctm();
 }
 
 const SkPaint& SkCanvas::LayerIter::paint() const {
@@ -3321,7 +3117,10 @@ const SkPaint& SkCanvas::LayerIter::paint() const {
     return *paint;
 }
 
-const SkRasterClip& SkCanvas::LayerIter::clip() const { return fImpl->getClip(); }
+void SkCanvas::LayerIter::clip(SkRegion* rgn) const {
+    return fImpl->fDevice->onAsRgnClip(rgn);
+}
+
 int SkCanvas::LayerIter::x() const { return fImpl->getX(); }
 int SkCanvas::LayerIter::y() const { return fImpl->getY(); }
 
index 799850b83929fb151c942670038aaf9eab959b70..dd5118d319c0572a618ff4dc4277696efbc46b46 100644 (file)
@@ -9,6 +9,16 @@
 #include "SkDraw.h"
 #include "SkRasterClip.h"
 
+SkIRect SkClipStackDevice::devClipBounds() const {
+    SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
+    if (!r.isEmpty()) {
+        SkASSERT(this->imageInfo().bounds().contains(r));
+    }
+    return r;
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 void SkClipStackDevice::onSave() {
     fClipStack.save();
 }
@@ -52,13 +62,47 @@ void SkClipStackDevice::onSetDeviceClipRestriction(SkIRect* clipRestriction) {
     }
 }
 
-SkIRect SkClipStackDevice::devClipBounds(const SkDraw& draw) const {
-#ifdef SK_USE_DEVICE_CLIPPING
-    SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
-    SkASSERT(this->imageInfo().bounds().contains(r));
-    SkASSERT(draw.fRC->getBounds().contains(r));
-    return r;
-#else
-    return draw.fRC->getBounds();
-#endif
+bool SkClipStackDevice::onClipIsAA() const {
+    SkClipStack::B2TIter        iter(fClipStack);
+    const SkClipStack::Element* element;
+
+    while ((element = iter.next()) != nullptr) {
+        if (element->isAA()) {
+            return true;
+        }
+    }
+    return false;
+}
+
+void SkClipStackDevice::onAsRgnClip(SkRegion* rgn) const {
+    SkClipStack::BoundsType boundType;
+    bool isIntersectionOfRects;
+    SkRect bounds;
+    fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
+    if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
+        rgn->setRect(bounds.round());
+    } else {
+        SkPath path;
+        fClipStack.asPath(&path);
+        rgn->setPath(path, SkRegion(SkIRect::MakeWH(this->width(), this->height())));
+    }
+}
+
+SkBaseDevice::ClipType SkClipStackDevice::onGetClipType() const {
+    if (fClipStack.isWideOpen()) {
+        return kRect_ClipType;
+    }
+    if (fClipStack.isEmpty(SkIRect::MakeWH(this->width(), this->height()))) {
+        return kEmpty_ClipType;
+    } else {
+        SkClipStack::BoundsType boundType;
+        bool isIntersectionOfRects;
+        SkRect bounds;
+        fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
+        if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
+            return kRect_ClipType;
+        } else {
+            return kComplex_ClipType;
+        }
+    }
 }
index 1836821fc0574aa7ddbdf9fe54b85fb54ae44054..1f1c7d6e422f78947c08a81f81a15a91b9994639 100644 (file)
@@ -19,7 +19,7 @@ public:
 
     const SkClipStack& cs() const { return fClipStack; }
 
-    SkIRect devClipBounds(const SkDraw&) const;
+    SkIRect devClipBounds() const;
 
 protected:
     void onSave() override;
@@ -29,6 +29,9 @@ protected:
     void onClipPath(const SkPath& path, SkClipOp, bool aa) override;
     void onClipRegion(const SkRegion& deviceRgn, SkClipOp) override;
     void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) override;
+    bool onClipIsAA() const override;
+    void onAsRgnClip(SkRegion*) const override;
+    ClipType onGetClipType() const override;
 
 private:
     SkClipStack fClipStack;
index cd3bf502c74f72a7db14c6e4ca6a42c76f21bde7..fad73e9961014acfa11de907690643399c7f4262 100644 (file)
@@ -71,35 +71,36 @@ static inline bool is_int(float x) {
     return x == (float) sk_float_round2int(x);
 }
 
-void SkBaseDevice::drawRegion(const SkDraw& draw, const SkRegion& region, const SkPaint& paint) {
-    bool isNonTranslate = draw.fMatrix->getType() & ~(SkMatrix::kTranslate_Mask);
+void SkBaseDevice::drawRegion(const SkRegion& region, const SkPaint& paint) {
+    const SkMatrix& ctm = this->ctm();
+    bool isNonTranslate = ctm.getType() & ~(SkMatrix::kTranslate_Mask);
     bool complexPaint = paint.getStyle() != SkPaint::kFill_Style || paint.getMaskFilter() ||
                         paint.getPathEffect();
-    bool antiAlias = paint.isAntiAlias() && (!is_int(draw.fMatrix->getTranslateX()) ||
-                                             !is_int(draw.fMatrix->getTranslateY()));
+    bool antiAlias = paint.isAntiAlias() && (!is_int(ctm.getTranslateX()) ||
+                                             !is_int(ctm.getTranslateY()));
     if (isNonTranslate || complexPaint || antiAlias) {
         SkPath path;
         region.getBoundaryPath(&path);
-        return this->drawPath(draw, path, paint, nullptr, false);
+        return this->drawPath(path, paint, nullptr, false);
     }
 
     SkRegion::Iterator it(region);
     while (!it.done()) {
-        this->drawRect(draw, SkRect::Make(it.rect()), paint);
+        this->drawRect(SkRect::Make(it.rect()), paint);
         it.next();
     }
 }
 
-void SkBaseDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle,
+void SkBaseDevice::drawArc(const SkRect& oval, SkScalar startAngle,
                            SkScalar sweepAngle, bool useCenter, const SkPaint& paint) {
     SkPath path;
     bool isFillNoPathEffect = SkPaint::kFill_Style == paint.getStyle() && !paint.getPathEffect();
     SkPathPriv::CreateDrawArcPath(&path, oval, startAngle, sweepAngle, useCenter,
                                   isFillNoPathEffect);
-    this->drawPath(draw, path, paint);
+    this->drawPath(path, paint);
 }
 
-void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
+void SkBaseDevice::drawDRRect(const SkRRect& outer,
                               const SkRRect& inner, const SkPaint& paint) {
     SkPath path;
     path.addRRect(outer);
@@ -109,25 +110,25 @@ void SkBaseDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
 
     const SkMatrix* preMatrix = nullptr;
     const bool pathIsMutable = true;
-    this->drawPath(draw, path, paint, preMatrix, pathIsMutable);
+    this->drawPath(path, paint, preMatrix, pathIsMutable);
 }
 
-void SkBaseDevice::drawPatch(const SkDraw& draw, const SkPoint cubics[12], const SkColor colors[4],
+void SkBaseDevice::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
                              const SkPoint texCoords[4], SkBlendMode bmode, const SkPaint& paint) {
     SkPatchUtils::VertexData data;
 
-    SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, draw.fMatrix);
+    SkISize lod = SkPatchUtils::GetLevelOfDetail(cubics, &this->ctm());
 
     // It automatically adjusts lodX and lodY in case it exceeds the number of indices.
     // If it fails to generate the vertices, then we do not draw.
     if (SkPatchUtils::getVertexData(&data, cubics, colors, texCoords, lod.width(), lod.height())) {
-        this->drawVertices(draw, SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
+        this->drawVertices(SkCanvas::kTriangles_VertexMode, data.fVertexCount, data.fPoints,
                            data.fTexCoords, data.fColors, bmode, data.fIndices, data.fIndexCount,
                            paint);
     }
 }
 
-void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
+void SkBaseDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                 const SkPaint &paint, SkDrawFilter* drawFilter) {
 
     SkPaint runPaint = paint;
@@ -150,14 +151,14 @@ void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
 
         switch (it.positioning()) {
         case SkTextBlob::kDefault_Positioning:
-            this->drawText(draw, it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
+            this->drawText(it.glyphs(), textLen, x + offset.x(), y + offset.y(), runPaint);
             break;
         case SkTextBlob::kHorizontal_Positioning:
-            this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 1,
+            this->drawPosText(it.glyphs(), textLen, it.pos(), 1,
                               SkPoint::Make(x, y + offset.y()), runPaint);
             break;
         case SkTextBlob::kFull_Positioning:
-            this->drawPosText(draw, it.glyphs(), textLen, it.pos(), 2,
+            this->drawPosText(it.glyphs(), textLen, it.pos(), 2,
                               SkPoint::Make(x, y), runPaint);
             break;
         default:
@@ -171,66 +172,66 @@ void SkBaseDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSc
     }
 }
 
-void SkBaseDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
+void SkBaseDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
                              const SkPaint& paint) {
     SkBitmap bm;
     if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
-        this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
+        this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
     }
 }
 
-void SkBaseDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
+void SkBaseDevice::drawImageRect(const SkImage* image, const SkRect* src,
                                  const SkRect& dst, const SkPaint& paint,
                                  SkCanvas::SrcRectConstraint constraint) {
     SkBitmap bm;
     if (as_IB(image)->getROPixels(&bm, this->imageInfo().colorSpace())) {
-        this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
+        this->drawBitmapRect(bm, src, dst, paint, constraint);
     }
 }
 
-void SkBaseDevice::drawImageNine(const SkDraw& draw, const SkImage* image, const SkIRect& center,
+void SkBaseDevice::drawImageNine(const SkImage* image, const SkIRect& center,
                                  const SkRect& dst, const SkPaint& paint) {
     SkLatticeIter iter(image->width(), image->height(), center, dst);
 
     SkRect srcR, dstR;
     while (iter.next(&srcR, &dstR)) {
-        this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+        this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
     }
 }
 
-void SkBaseDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
+void SkBaseDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                                   const SkRect& dst, const SkPaint& paint) {
     SkLatticeIter iter(bitmap.width(), bitmap.height(), center, dst);
 
     SkRect srcR, dstR;
     while (iter.next(&srcR, &dstR)) {
-        this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+        this->drawBitmapRect(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
     }
 }
 
-void SkBaseDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
+void SkBaseDevice::drawImageLattice(const SkImage* image,
                                     const SkCanvas::Lattice& lattice, const SkRect& dst,
                                     const SkPaint& paint) {
     SkLatticeIter iter(lattice, dst);
 
     SkRect srcR, dstR;
     while (iter.next(&srcR, &dstR)) {
-        this->drawImageRect(draw, image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+        this->drawImageRect(image, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
     }
 }
 
-void SkBaseDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
+void SkBaseDevice::drawBitmapLattice(const SkBitmap& bitmap,
                                      const SkCanvas::Lattice& lattice, const SkRect& dst,
                                      const SkPaint& paint) {
     SkLatticeIter iter(lattice, dst);
 
     SkRect srcR, dstR;
     while (iter.next(&srcR, &dstR)) {
-        this->drawBitmapRect(draw, bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
+        this->drawBitmapRect(bitmap, &srcR, dstR, paint, SkCanvas::kStrict_SrcRectConstraint);
     }
 }
 
-void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
+void SkBaseDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
                              const SkRect tex[], const SkColor colors[], int count,
                              SkBlendMode mode, const SkPaint& paint) {
     SkPath path;
@@ -260,23 +261,23 @@ void SkBaseDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkR
         path.rewind();
         path.addPoly(quad, 4, true);
         path.setConvexity(SkPath::kConvex_Convexity);
-        this->drawPath(draw, path, pnt, nullptr, true);
+        this->drawPath(path, pnt, nullptr, true);
     }
 }
 
-void SkBaseDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> vertices,
+void SkBaseDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
                                       SkBlendMode mode, const SkPaint& paint, uint32_t flags) {
     const SkPoint* texs =
             (flags & SkCanvas::kIgnoreTexCoords_VerticesFlag) ? nullptr : vertices->texCoords();
     const SkColor* colors =
             (flags & SkCanvas::kIgnoreColors_VerticesFlag) ? nullptr : vertices->colors();
-    this->drawVertices(draw, vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
+    this->drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(), texs,
                        colors, mode, vertices->indices(), vertices->indexCount(), paint);
 }
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-void SkBaseDevice::drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) {}
+void SkBaseDevice::drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) {}
 sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkBitmap&) { return nullptr; }
 sk_sp<SkSpecialImage> SkBaseDevice::makeSpecial(const SkImage*) { return nullptr; }
 sk_sp<SkSpecialImage> SkBaseDevice::snapSpecial() { return nullptr; }
@@ -392,13 +393,13 @@ static void morphpath(SkPath* dst, const SkPath& src, SkPathMeasure& meas,
     }
 }
 
-void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t byteLength,
+void SkBaseDevice::drawTextOnPath(const void* text, size_t byteLength,
                                   const SkPath& follow, const SkMatrix* matrix,
                                   const SkPaint& paint) {
     SkASSERT(byteLength == 0 || text != nullptr);
 
     // nothing to draw
-    if (text == nullptr || byteLength == 0 || draw.fRC->isEmpty()) {
+    if (text == nullptr || byteLength == 0) {
         return;
     }
 
@@ -433,7 +434,7 @@ void SkBaseDevice::drawTextOnPath(const SkDraw& draw, const void* text, size_t b
                 m.postConcat(*matrix);
             }
             morphpath(&tmp, *iterPath, meas, m);
-            this->drawPath(draw, tmp, iter.getPaint(), nullptr, true);
+            this->drawPath(tmp, iter.getPaint(), nullptr, true);
         }
     }
 }
@@ -448,7 +449,7 @@ static int count_utf16(const char* text) {
 static int return_4(const char* text) { return 4; }
 static int return_2(const char* text) { return 2; }
 
-void SkBaseDevice::drawTextRSXform(const SkDraw& draw, const void* text, size_t len,
+void SkBaseDevice::drawTextRSXform(const void* text, size_t len,
                                    const SkRSXform xform[], const SkPaint& paint) {
     CountTextProc proc = nullptr;
     switch (paint.getTextEncoding()) {
@@ -466,19 +467,15 @@ void SkBaseDevice::drawTextRSXform(const SkDraw& draw, const void* text, size_t
             break;
     }
 
-    SkDraw localD(draw);
     SkMatrix localM, currM;
     const void* stopText = (const char*)text + len;
     while ((const char*)text < (const char*)stopText) {
         localM.setRSXform(*xform++);
-        currM.setConcat(*draw.fMatrix, localM);
-        localD.fMatrix = &currM;
-#ifdef SK_USE_DEVICE_CLIPPING
+        currM.setConcat(this->ctm(), localM);
         SkAutoDeviceCTMRestore adc(this, currM);
-#endif
 
         int subLen = proc((const char*)text);
-        this->drawText(localD, text, subLen, 0, 0, paint);
+        this->drawText(text, subLen, 0, 0, paint);
         text = (const char*)text + subLen;
     }
 }
index cd0e1d01ea28412b43aca3539b9b65dc49a2bb31..481d46a008274c64bb4afd3e5e680f02b72abbab 100644 (file)
@@ -14,7 +14,6 @@
 #include "SkSurfaceProps.h"
 
 class SkBitmap;
-class SkDraw;
 class SkDrawFilter;
 class SkImageFilterCache;
 struct SkIRect;
@@ -150,29 +149,37 @@ protected:
     virtual void onClipPath(const SkPath& path, SkClipOp, bool aa) {}
     virtual void onClipRegion(const SkRegion& deviceRgn, SkClipOp) {}
     virtual void onSetDeviceClipRestriction(SkIRect* mutableClipRestriction) {}
+    virtual bool onClipIsAA() const = 0;
+    virtual void onAsRgnClip(SkRegion*) const = 0;
+    enum ClipType {
+        kEmpty_ClipType,
+        kRect_ClipType,
+        kComplex_ClipType
+    };
+    virtual ClipType onGetClipType() const = 0;
 
     /** These are called inside the per-device-layer loop for each draw call.
      When these are called, we have already applied any saveLayer operations,
      and are handling any looping from the paint, and any effects from the
      DrawFilter.
      */
-    virtual void drawPaint(const SkDraw&, const SkPaint& paint) = 0;
-    virtual void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+    virtual void drawPaint(const SkPaint& paint) = 0;
+    virtual void drawPoints(SkCanvas::PointMode mode, size_t count,
                             const SkPoint[], const SkPaint& paint) = 0;
-    virtual void drawRect(const SkDraw&, const SkRect& r,
+    virtual void drawRect(const SkRect& r,
                           const SkPaint& paint) = 0;
-    virtual void drawRegion(const SkDraw&, const SkRegion& r,
+    virtual void drawRegion(const SkRegion& r,
                             const SkPaint& paint);
-    virtual void drawOval(const SkDraw&, const SkRect& oval,
+    virtual void drawOval(const SkRect& oval,
                           const SkPaint& paint) = 0;
     /** By the time this is called we know that abs(sweepAngle) is in the range [0, 360). */
-    virtual void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle,
+    virtual void drawArc(const SkRect& oval, SkScalar startAngle,
                          SkScalar sweepAngle, bool useCenter, const SkPaint& paint);
-    virtual void drawRRect(const SkDraw&, const SkRRect& rr,
+    virtual void drawRRect(const SkRRect& rr,
                            const SkPaint& paint) = 0;
 
     // Default impl calls drawPath()
-    virtual void drawDRRect(const SkDraw&, const SkRRect& outer,
+    virtual void drawDRRect(const SkRRect& outer,
                             const SkRRect& inner, const SkPaint&);
 
     /**
@@ -186,77 +193,77 @@ protected:
      *  affect the geometry/rasterization, then the pre matrix can just be
      *  pre-concated with the current matrix.
      */
-    virtual void drawPath(const SkDraw&, const SkPath& path,
+    virtual void drawPath(const SkPath& path,
                           const SkPaint& paint,
                           const SkMatrix* prePathMatrix = NULL,
                           bool pathIsMutable = false) = 0;
-    virtual void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+    virtual void drawBitmap(const SkBitmap& bitmap,
                             const SkMatrix& matrix, const SkPaint& paint) = 0;
-    virtual void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+    virtual void drawSprite(const SkBitmap& bitmap,
                             int x, int y, const SkPaint& paint) = 0;
 
     /**
      *  The default impl. will create a bitmap-shader from the bitmap,
      *  and call drawRect with it.
      */
-    virtual void drawBitmapRect(const SkDraw&, const SkBitmap&,
+    virtual void drawBitmapRect(const SkBitmap&,
                                 const SkRect* srcOrNull, const SkRect& dst,
                                 const SkPaint& paint,
                                 SkCanvas::SrcRectConstraint) = 0;
-    virtual void drawBitmapNine(const SkDraw&, const SkBitmap&, const SkIRect& center,
+    virtual void drawBitmapNine(const SkBitmap&, const SkIRect& center,
                                 const SkRect& dst, const SkPaint&);
-    virtual void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
+    virtual void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
                                    const SkRect& dst, const SkPaint&);
 
-    virtual void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
-    virtual void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
+    virtual void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&);
+    virtual void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
                                const SkPaint&, SkCanvas::SrcRectConstraint);
-    virtual void drawImageNine(const SkDraw&, const SkImage*, const SkIRect& center,
+    virtual void drawImageNine(const SkImage*, const SkIRect& center,
                                const SkRect& dst, const SkPaint&);
-    virtual void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
+    virtual void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
                                   const SkRect& dst, const SkPaint&);
 
     /**
      *  Does not handle text decoration.
      *  Decorations (underline and stike-thru) will be handled by SkCanvas.
      */
-    virtual void drawText(const SkDraw&, const void* text, size_t len,
+    virtual void drawText(const void* text, size_t len,
                           SkScalar x, SkScalar y, const SkPaint& paint) = 0;
-    virtual void drawPosText(const SkDraw&, const void* text, size_t len,
+    virtual void drawPosText(const void* text, size_t len,
                              const SkScalar pos[], int scalarsPerPos,
                              const SkPoint& offset, const SkPaint& paint) = 0;
-    virtual void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+    virtual void drawVertices(SkCanvas::VertexMode, int vertexCount,
                               const SkPoint verts[], const SkPoint texs[],
                               const SkColor colors[], SkBlendMode,
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint) = 0;
-    virtual void drawVerticesObject(const SkDraw&, sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
+    virtual void drawVerticesObject(sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
                                     uint32_t flags);
     // default implementation unrolls the blob runs.
-    virtual void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
+    virtual void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
                               const SkPaint& paint, SkDrawFilter* drawFilter);
     // default implementation calls drawVertices
-    virtual void drawPatch(const SkDraw&, const SkPoint cubics[12], const SkColor colors[4],
+    virtual void drawPatch(const SkPoint cubics[12], const SkColor colors[4],
                            const SkPoint texCoords[4], SkBlendMode, const SkPaint& paint);
 
     // default implementation calls drawPath
-    virtual void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
+    virtual void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
                            const SkColor[], int count, SkBlendMode, const SkPaint&);
 
-    virtual void drawAnnotation(const SkDraw&, const SkRect&, const char[], SkData*) {}
+    virtual void drawAnnotation(const SkRect&, const char[], SkData*) {}
 
     /** The SkDevice passed will be an SkDevice which was returned by a call to
         onCreateDevice on this device with kNeverTile_TileExpectation.
      */
-    virtual void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+    virtual void drawDevice(SkBaseDevice*, int x, int y,
                             const SkPaint&) = 0;
 
-    virtual void drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath&,
+    virtual void drawTextOnPath(const void* text, size_t len, const SkPath&,
                                 const SkMatrix*, const SkPaint&);
-    virtual void drawTextRSXform(const SkDraw&, const void* text, size_t len, const SkRSXform[],
+    virtual void drawTextRSXform(const void* text, size_t len, const SkRSXform[],
                                  const SkPaint&);
 
-    virtual void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&);
+    virtual void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&);
     virtual sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&);
     virtual sk_sp<SkSpecialImage> makeSpecial(const SkImage*);
     virtual sk_sp<SkSpecialImage> snapSpecial();
index c4e401361c177827d8d33746d9eb9ced43a85000..cea92704ef035fefdb9c6b4b4546758c2608bbfa 100644 (file)
@@ -11,7 +11,6 @@ SkDeviceLooper::SkDeviceLooper(const SkPixmap& base, const SkRasterClip& rc, con
                                bool aa)
     : fBaseDst(base)
     , fBaseRC(rc)
-    , fSubsetRC(rc.isForceConservativeRects())
     , fDelta(aa ? kAA_Delta : kBW_Delta)
 {
     // sentinels that next() has not yet been called, and so our mapper functions
index 683d5e139e6e01a023a830d76576b94d7d676b05..03ca87eb9fb80b1e1c0a83b15977acb05d9d22d3 100644 (file)
@@ -578,11 +578,9 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
                         // then path then
                         path.setIsVolatile((count-1) == i);
                         if (device) {
-                            device->drawPath(*this, path, newPaint, &preMatrix,
-                                              (count-1) == i);
+                            device->drawPath(path, newPaint, &preMatrix, (count-1) == i);
                         } else {
-                            this->drawPath(path, newPaint, &preMatrix,
-                                           (count-1) == i);
+                            this->drawPath(path, newPaint, &preMatrix, (count-1) == i);
                         }
                     }
                 } else {
@@ -594,7 +592,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
                         r.fRight = r.fLeft + width;
                         r.fBottom = r.fTop + width;
                         if (device) {
-                            device->drawRect(*this, r, newPaint);
+                            device->drawRect(r, newPaint);
                         } else {
                             this->drawRect(r, newPaint);
                         }
@@ -625,7 +623,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
 
                         if (!pointData.fFirst.isEmpty()) {
                             if (device) {
-                                device->drawPath(*this, pointData.fFirst, newP);
+                                device->drawPath(pointData.fFirst, newP);
                             } else {
                                 this->drawPath(pointData.fFirst, newP);
                             }
@@ -633,7 +631,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
 
                         if (!pointData.fLast.isEmpty()) {
                             if (device) {
-                                device->drawPath(*this, pointData.fLast, newP);
+                                device->drawPath(pointData.fLast, newP);
                             } else {
                                 this->drawPath(pointData.fLast, newP);
                             }
@@ -650,11 +648,10 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
                             }
 
                             if (device) {
-                                device->drawPoints(*this,
-                                                    SkCanvas::kPoints_PointMode,
-                                                    pointData.fNumPoints,
-                                                    pointData.fPoints,
-                                                    newP);
+                                device->drawPoints(SkCanvas::kPoints_PointMode,
+                                                   pointData.fNumPoints,
+                                                   pointData.fPoints,
+                                                   newP);
                             } else {
                                 this->drawPoints(SkCanvas::kPoints_PointMode,
                                                  pointData.fNumPoints,
@@ -676,7 +673,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
                                       pointData.fPoints[i].fX + pointData.fSize.fX,
                                       pointData.fPoints[i].fY + pointData.fSize.fY);
                                 if (device) {
-                                    device->drawRect(*this, r, newP);
+                                    device->drawRect(r, newP);
                                 } else {
                                     this->drawRect(r, newP);
                                 }
@@ -698,7 +695,7 @@ void SkDraw::drawPoints(SkCanvas::PointMode mode, size_t count,
                     path.moveTo(pts[i]);
                     path.lineTo(pts[i+1]);
                     if (device) {
-                        device->drawPath(*this, path, p, nullptr, true);
+                        device->drawPath(path, p, nullptr, true);
                     } else {
                         this->drawPath(path, p, nullptr, true);
                     }
@@ -1423,8 +1420,7 @@ void SkDraw::drawText_asPaths(const char text[], size_t byteLength, SkScalar x,
     while (iter.next(&iterPath, &xpos)) {
         matrix.postTranslate(xpos - prevXPos, 0);
         if (iterPath) {
-            const SkPaint& pnt = iter.getPaint();
-            this->drawPath(*iterPath, pnt, &matrix, false);
+            this->drawPath(*iterPath, iter.getPaint(), &matrix, false);
         }
         prevXPos = xpos;
     }
index 534333984bacc33b0fbfbf194c69dfc74a244da9..0b29468d8eca41a25ab013cb6fc1412af87ee093 100644 (file)
@@ -149,7 +149,6 @@ public:
     SkPixmap        fDst;
     const SkMatrix* fMatrix;        // required
     const SkRasterClip* fRC;        // required
-    const SkClipStack* fClipStack;  // optional, may be null
 
 #ifdef SK_DEBUG
     void validate() const;
index a9e043f84fe63569f91924fa2ba8413cfde2e621..f43d14e483578138af7f3179c895a20bd2d31ac7 100644 (file)
 #include "SkRasterClip.h"
 #include "SkPath.h"
 
+enum MutateResult {
+    kDoNothing_MutateResult,
+    kReplaceClippedAgainstGlobalBounds_MutateResult,
+    kContinue_MutateResult,
+};
+
+static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
+    if (inverseFilled) {
+        switch (*op) {
+            case SkRegion::kIntersect_Op:
+            case SkRegion::kDifference_Op:
+                // These ops can only shrink the current clip. So leaving
+                // the clip unchanged conservatively respects the contract.
+                return kDoNothing_MutateResult;
+            case SkRegion::kUnion_Op:
+            case SkRegion::kReplace_Op:
+            case SkRegion::kReverseDifference_Op:
+            case SkRegion::kXOR_Op: {
+                // These ops can grow the current clip up to the extents of
+                // the input clip, which is inverse filled, so we just set
+                // the current clip to the device bounds.
+                *op = SkRegion::kReplace_Op;
+                return kReplaceClippedAgainstGlobalBounds_MutateResult;
+            }
+        }
+    } else {
+        // Not inverse filled
+        switch (*op) {
+            case SkRegion::kIntersect_Op:
+            case SkRegion::kUnion_Op:
+            case SkRegion::kReplace_Op:
+                return kContinue_MutateResult;
+            case SkRegion::kDifference_Op:
+                // Difference can only shrink the current clip.
+                // Leaving clip unchanged conservatively fullfills the contract.
+                return kDoNothing_MutateResult;
+            case SkRegion::kReverseDifference_Op:
+                // To reverse, we swap in the bounds with a replace op.
+                // As with difference, leave it unchanged.
+                *op = SkRegion::kReplace_Op;
+                return kContinue_MutateResult;
+            case SkRegion::kXOR_Op:
+                // Be conservative, based on (A XOR B) always included in (A union B),
+                // which is always included in (bounds(A) union bounds(B))
+                *op = SkRegion::kUnion_Op;
+                return kContinue_MutateResult;
+        }
+    }
+    SkFAIL("should not get here");
+    return kDoNothing_MutateResult;
+}
+
+void SkConservativeClip::op(const SkRect& localRect, const SkMatrix& ctm, const SkIRect& devBounds,
+                            SkRegion::Op op, bool doAA) {
+    SkRect devRect;
+
+    SkIRect bounds(devBounds);
+    this->applyClipRestriction(op, &bounds);
+    SkIRect ir;
+    switch (mutate_conservative_op(&op, false)) {
+        case kDoNothing_MutateResult:
+            return;
+        case kReplaceClippedAgainstGlobalBounds_MutateResult:
+            ir = bounds;
+            break;
+        case kContinue_MutateResult:
+            ctm.mapRect(&devRect, localRect);
+            ir = doAA ? devRect.roundOut() : devRect.round();
+            break;
+    }
+    this->op(ir, op);
+}
+
+void SkConservativeClip::op(const SkRRect& rrect, const SkMatrix& ctm, const SkIRect& devBounds,
+                            SkRegion::Op op, bool doAA) {
+    SkIRect bounds(devBounds);
+    this->applyClipRestriction(op, &bounds);
+    this->op(rrect.getBounds(), ctm, bounds, op, doAA);
+}
+
+void SkConservativeClip::op(const SkPath& path, const SkMatrix& ctm, const SkIRect& devBounds,
+                            SkRegion::Op op, bool doAA) {
+    SkIRect bounds(devBounds);
+    this->applyClipRestriction(op, &bounds);
+
+    SkIRect ir;
+    switch (mutate_conservative_op(&op, path.isInverseFillType())) {
+        case kDoNothing_MutateResult:
+            return;
+        case kReplaceClippedAgainstGlobalBounds_MutateResult:
+            ir = bounds;
+            break;
+        case kContinue_MutateResult: {
+            SkRect bounds = path.getBounds();
+            ctm.mapRect(&bounds);
+            ir = bounds.roundOut();
+            break;
+        }
+    }
+    return this->op(ir, op);
+}
+
+void SkConservativeClip::op(const SkRegion& rgn, SkRegion::Op op) {
+    this->op(rgn.getBounds(), op);
+}
+
+void SkConservativeClip::op(const SkIRect& devRect, SkRegion::Op op) {
+    // This may still create a complex region (which we would then take the bounds
+    // Perhaps we should inline the op-logic directly to never create the rgn...
+    SkRegion result;
+    result.op(SkRegion(fBounds), SkRegion(devRect), op);
+    fBounds = result.getBounds();
+}
+
+///////////////////////////////////////////////////////////////////////////////////////////////////
+
 SkRasterClip::SkRasterClip(const SkRasterClip& src) {
     AUTO_RASTERCLIP_VALIDATE(src);
 
-    fForceConservativeRects = src.fForceConservativeRects;
     fIsBW = src.fIsBW;
     if (fIsBW) {
         fBW = src.fBW;
@@ -26,23 +141,20 @@ SkRasterClip::SkRasterClip(const SkRasterClip& src) {
 }
 
 SkRasterClip::SkRasterClip(const SkRegion& rgn) : fBW(rgn) {
-    fForceConservativeRects = false;
     fIsBW = true;
     fIsEmpty = this->computeIsEmpty();  // bounds might be empty, so compute
     fIsRect = !fIsEmpty;
     SkDEBUGCODE(this->validate();)
 }
 
-SkRasterClip::SkRasterClip(const SkIRect& bounds, bool forceConservativeRects) : fBW(bounds) {
-    fForceConservativeRects = forceConservativeRects;
+SkRasterClip::SkRasterClip(const SkIRect& bounds) : fBW(bounds) {
     fIsBW = true;
     fIsEmpty = this->computeIsEmpty();  // bounds might be empty, so compute
     fIsRect = !fIsEmpty;
     SkDEBUGCODE(this->validate();)
 }
 
-SkRasterClip::SkRasterClip(bool forceConservativeRects) {
-    fForceConservativeRects = forceConservativeRects;
+SkRasterClip::SkRasterClip() {
     fIsBW = true;
     fIsEmpty = true;
     fIsRect = false;
@@ -54,8 +166,6 @@ SkRasterClip::~SkRasterClip() {
 }
 
 bool SkRasterClip::operator==(const SkRasterClip& other) const {
-    // This impl doesn't care if fForceConservativeRects is the same in both, only the current state
-
     if (fIsBW != other.fIsBW) {
         return false;
     }
@@ -114,65 +224,9 @@ bool SkRasterClip::setConservativeRect(const SkRect& r, const SkIRect& clipR, bo
 
 /////////////////////////////////////////////////////////////////////////////////////
 
-enum MutateResult {
-    kDoNothing_MutateResult,
-    kReplaceClippedAgainstGlobalBounds_MutateResult,
-    kContinue_MutateResult,
-};
-
-static MutateResult mutate_conservative_op(SkRegion::Op* op, bool inverseFilled) {
-    if (inverseFilled) {
-        switch (*op) {
-            case SkRegion::kIntersect_Op:
-            case SkRegion::kDifference_Op:
-                // These ops can only shrink the current clip. So leaving
-                // the clip unchanged conservatively respects the contract.
-                return kDoNothing_MutateResult;
-            case SkRegion::kUnion_Op:
-            case SkRegion::kReplace_Op:
-            case SkRegion::kReverseDifference_Op:
-            case SkRegion::kXOR_Op: {
-                // These ops can grow the current clip up to the extents of
-                // the input clip, which is inverse filled, so we just set
-                // the current clip to the device bounds.
-                *op = SkRegion::kReplace_Op;
-                return kReplaceClippedAgainstGlobalBounds_MutateResult;
-            }
-        }
-    } else {
-        // Not inverse filled
-        switch (*op) {
-            case SkRegion::kIntersect_Op:
-            case SkRegion::kUnion_Op:
-            case SkRegion::kReplace_Op:
-                return kContinue_MutateResult;
-            case SkRegion::kDifference_Op:
-                // Difference can only shrink the current clip.
-                // Leaving clip unchanged conservatively fullfills the contract.
-                return kDoNothing_MutateResult;
-            case SkRegion::kReverseDifference_Op:
-                // To reverse, we swap in the bounds with a replace op.
-                // As with difference, leave it unchanged.
-                *op = SkRegion::kReplace_Op;
-                return kContinue_MutateResult;
-            case SkRegion::kXOR_Op:
-                // Be conservative, based on (A XOR B) always included in (A union B),
-                // which is always included in (bounds(A) union bounds(B))
-                *op = SkRegion::kUnion_Op;
-                return kContinue_MutateResult;
-        }
-    }
-    SkFAIL("should not get here");
-    return kDoNothing_MutateResult;
-}
-
 bool SkRasterClip::setPath(const SkPath& path, const SkRegion& clip, bool doAA) {
     AUTO_RASTERCLIP_VALIDATE(*this);
 
-    if (fForceConservativeRects) {
-        return this->setConservativeRect(path.getBounds(), clip.getBounds(), path.isInverseFillType());
-    }
-
     if (this->isBW() && !doAA) {
         (void)fBW.setPath(path, clip);
     } else {
@@ -190,9 +244,6 @@ bool SkRasterClip::op(const SkRRect& rrect, const SkMatrix& matrix, const SkIRec
                       SkRegion::Op op, bool doAA) {
     SkIRect bounds(devBounds);
     this->applyClipRestriction(op, &bounds);
-    if (fForceConservativeRects) {
-        return this->op(rrect.getBounds(), matrix, bounds, op, doAA);
-    }
 
     SkPath path;
     path.addRRect(rrect);
@@ -206,24 +257,6 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
     SkIRect bounds(devBounds);
     this->applyClipRestriction(op, &bounds);
 
-    if (fForceConservativeRects) {
-        SkIRect ir;
-        switch (mutate_conservative_op(&op, path.isInverseFillType())) {
-            case kDoNothing_MutateResult:
-                return !this->isEmpty();
-            case kReplaceClippedAgainstGlobalBounds_MutateResult:
-                ir = bounds;
-                break;
-            case kContinue_MutateResult: {
-                SkRect bounds = path.getBounds();
-                matrix.mapRect(&bounds);
-                ir = bounds.roundOut();
-                break;
-            }
-        }
-        return this->op(ir, op);
-    }
-
     // base is used to limit the size (and therefore memory allocation) of the
     // region that results from scan converting devPath.
     SkRegion base;
@@ -246,7 +279,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
             return this->setPath(devPath, this->bwRgn(), doAA);
         } else {
             base.setRect(this->getBounds());
-            SkRasterClip clip(fForceConservativeRects);
+            SkRasterClip clip;
             clip.setPath(devPath, base, doAA);
             return this->op(clip, op);
         }
@@ -256,7 +289,7 @@ bool SkRasterClip::op(const SkPath& path, const SkMatrix& matrix, const SkIRect&
         if (SkRegion::kReplace_Op == op) {
             return this->setPath(devPath, base, doAA);
         } else {
-            SkRasterClip clip(fForceConservativeRects);
+            SkRasterClip clip;
             clip.setPath(devPath, base, doAA);
             return this->op(clip, op);
         }
@@ -331,23 +364,6 @@ bool SkRasterClip::op(const SkRect& localRect, const SkMatrix& matrix, const SkI
     AUTO_RASTERCLIP_VALIDATE(*this);
     SkRect devRect;
 
-    if (fForceConservativeRects) {
-        SkIRect bounds(devBounds);
-        this->applyClipRestriction(op, &bounds);
-        SkIRect ir;
-        switch (mutate_conservative_op(&op, false)) {
-            case kDoNothing_MutateResult:
-                return !this->isEmpty();
-            case kReplaceClippedAgainstGlobalBounds_MutateResult:
-                ir = bounds;
-                break;
-            case kContinue_MutateResult:
-                matrix.mapRect(&devRect, localRect);
-                ir = devRect.roundOut();
-                break;
-        }
-        return this->op(ir, op);
-    }
     const bool isScaleTrans = matrix.isScaleTranslate();
     if (!isScaleTrans) {
         SkPath path;
@@ -427,8 +443,6 @@ const SkRegion& SkRasterClip::forceGetBW() {
 void SkRasterClip::convertToAA() {
     AUTO_RASTERCLIP_VALIDATE(*this);
 
-    SkASSERT(!fForceConservativeRects);
-
     SkASSERT(fIsBW);
     fAA.setRegion(fBW);
     fIsBW = false;
index 0dc84e491faa79c2165bf7ad4030aa2f86deb52c..1e50e0453928dbbd04164f798175b6b0453dbc4e 100644 (file)
 
 class SkRRect;
 
+class SkConservativeClip {
+    SkIRect         fBounds;
+    const SkIRect*  fClipRestrictionRect;
+
+    inline void applyClipRestriction(SkRegion::Op op, SkIRect* bounds) {
+        if (op >= SkRegion::kUnion_Op && fClipRestrictionRect
+            && !fClipRestrictionRect->isEmpty()) {
+            if (!bounds->intersect(*fClipRestrictionRect)) {
+                bounds->setEmpty();
+            }
+        }
+    }
+
+public:
+    SkConservativeClip() : fBounds(SkIRect::MakeEmpty()), fClipRestrictionRect(nullptr) {}
+
+    bool isEmpty() const { return fBounds.isEmpty(); }
+    bool isRect() const { return true; }
+    const SkIRect& getBounds() const { return fBounds; }
+
+    void setEmpty() { fBounds.setEmpty(); }
+    void setRect(const SkIRect& r) { fBounds = r; }
+    void setDeviceClipRestriction(const SkIRect* rect) {
+        fClipRestrictionRect = rect;
+    }
+
+    void op(const SkRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
+    void op(const SkRRect&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
+    void op(const SkPath&, const SkMatrix&, const SkIRect& limit, SkRegion::Op, bool isAA);
+    void op(const SkRegion&, SkRegion::Op);
+    void op(const SkIRect&, SkRegion::Op);
+};
+
 /**
  *  Wraps a SkRegion and SkAAClip, so we have a single object that can represent either our
  *  BW or antialiased clips.
@@ -24,8 +57,8 @@ class SkRRect;
  */
 class SkRasterClip {
 public:
-    SkRasterClip(bool forceConservativeRects = false);
-    SkRasterClip(const SkIRect&, bool forceConservativeRects = false);
+    SkRasterClip();
+    SkRasterClip(const SkIRect&);
     SkRasterClip(const SkRegion&);
     SkRasterClip(const SkRasterClip&);
     ~SkRasterClip();
@@ -37,8 +70,6 @@ public:
         return !(*this == other);
     }
 
-    bool isForceConservativeRects() const { return fForceConservativeRects; }
-
     bool isBW() const { return fIsBW; }
     bool isAA() const { return !fIsBW; }
     const SkRegion& bwRgn() const { SkASSERT(fIsBW); return fBW; }
@@ -101,7 +132,6 @@ public:
 private:
     SkRegion    fBW;
     SkAAClip    fAA;
-    bool        fForceConservativeRects;
     bool        fIsBW;
     // these 2 are caches based on querying the right obj based on fIsBW
     bool        fIsEmpty;
index d553f241411a69cbe1b7dc18aa1e20c2f71a201b..f3e3b17df78c82139a096133643038a36c5979bd 100644 (file)
@@ -73,8 +73,12 @@ public:
     }
 
     void setNewSize(int w, int h) {
-        SkASSERT(fStack.count() == 1);
         fRootBounds.setXYWH(0, 0, w, h);
+
+        SkASSERT(fStack.count() == 1);
+        Rec& rec = fStack.top();
+        SkASSERT(rec.fDeferredCount == 0);
+        rec.fRC.setRect(fRootBounds);
     }
 
     const SkRasterClip& rc() const { return fStack.top().fRC; }
index 4fc898c3ac9b875f30131d5773042e91a71b8dfe..c95fe6af7ae0c2336d72e090bdde4e3f2d88bece 100644 (file)
@@ -547,10 +547,10 @@ void GrRenderTargetOpList::forwardCombine() {
             if (j == i +1) {
                 // We assume op would have combined with candidate when the candidate was added
                 // via backwards combining in recordOp.
-#ifndef SK_USE_DEVICE_CLIPPING
+
                 // not sure why this fires with device-clipping in gm/complexclip4.cpp
-                SkASSERT(!op->combineIfPossible(candidate.fOp.get(), *this->caps()));
-#endif
+//                SkASSERT(!op->combineIfPossible(candidate.fOp.get(), *this->caps()));
+
             } else if (op->combineIfPossible(candidate.fOp.get(), *this->caps())) {
                 GrOP_INFO("\t\tCombining with (%s, B%u)\n", candidate.fOp->name(),
                           candidate.fOp->uniqueID());
index 0b5f14c45cfd8ae4884ae7563f0b312fd31612a5..bcc2930821f1e3509689d13e027af6fce26c12eb 100644 (file)
 
 #if 0
     extern bool (*gShouldDrawProc)();
-    #define CHECK_SHOULD_DRAW(draw)                             \
+    #define CHECK_SHOULD_DRAW()                                 \
         do {                                                    \
             if (gShouldDrawProc && !gShouldDrawProc()) return;  \
-            this->prepareDraw(draw);                            \
+            this->prepareDraw();                                \
         } while (0)
 #else
-    #define CHECK_SHOULD_DRAW(draw) this->prepareDraw(draw)
+    #define CHECK_SHOULD_DRAW() this->prepareDraw()
 #endif
 
 ///////////////////////////////////////////////////////////////////////////////
@@ -174,17 +174,16 @@ sk_sp<GrRenderTargetContext> SkGpuDevice::MakeRenderTargetContext(
                                     origin, surfaceProps, budgeted);
 }
 
-sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(const SkDraw& draw,
-                                                 SkSpecialImage* srcImg,
+sk_sp<SkSpecialImage> SkGpuDevice::filterTexture(SkSpecialImage* srcImg,
                                                  int left, int top,
                                                  SkIPoint* offset,
                                                  const SkImageFilter* filter) {
     SkASSERT(srcImg->isTextureBacked());
     SkASSERT(filter);
 
-    SkMatrix matrix = *draw.fMatrix;
+    SkMatrix matrix = this->ctm();
     matrix.postTranslate(SkIntToScalar(-left), SkIntToScalar(-top));
-    const SkIRect clipBounds = this->devClipBounds(draw).makeOffset(-left, -top);
+    const SkIRect clipBounds = this->devClipBounds().makeOffset(-left, -top);
     sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
     SkImageFilter::OutputProperties outputProperties(fRenderTargetContext->getColorSpace());
     SkImageFilter::Context ctx(matrix, clipBounds, cache.get(), outputProperties);
@@ -233,15 +232,10 @@ bool SkGpuDevice::onAccessPixels(SkPixmap* pmap) {
 
 // call this every draw call, to ensure that the context reflects our state,
 // and not the state from some other canvas/device
-void SkGpuDevice::prepareDraw(const SkDraw& draw) {
+void SkGpuDevice::prepareDraw() {
     ASSERT_SINGLE_OWNER
 
-#ifdef SK_USE_DEVICE_CLIPPING
-    SkASSERT(*draw.fMatrix == this->ctm());
     fClip.reset(&this->cs(), nullptr);
-#else
-    fClip.reset(draw.fClipStack, &this->getOrigin());
-#endif
 }
 
 GrRenderTargetContext* SkGpuDevice::accessRenderTargetContext() {
@@ -285,18 +279,18 @@ void SkGpuDevice::replaceRenderTargetContext(bool shouldRetainContent) {
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
+void SkGpuDevice::drawPaint(const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPaint", fContext.get());
 
     GrPaint grPaint;
-    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                           &grPaint)) {
         return;
     }
 
-    fRenderTargetContext->drawPaint(fClip, std::move(grPaint), *draw.fMatrix);
+    fRenderTargetContext->drawPaint(fClip, std::move(grPaint), this->ctm());
 }
 
 // must be in SkCanvas::PointMode order
@@ -333,11 +327,11 @@ static bool needs_antialiasing(SkCanvas::PointMode mode, size_t count, const SkP
     return true;
 }
 
-void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
+void SkGpuDevice::drawPoints(SkCanvas::PointMode mode,
                              size_t count, const SkPoint pts[], const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPoints", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     SkScalar width = paint.getStrokeWidth();
     if (width < 0) {
@@ -347,7 +341,7 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
     if (paint.getPathEffect() && 2 == count && SkCanvas::kLines_PointMode == mode) {
         GrStyle style(paint, SkPaint::kStroke_Style);
         GrPaint grPaint;
-        if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+        if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                               &grPaint)) {
             return;
         }
@@ -356,25 +350,31 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
         path.moveTo(pts[0]);
         path.lineTo(pts[1]);
         fRenderTargetContext->drawPath(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
-                                       *draw.fMatrix, path, style);
+                                       this->ctm(), path, style);
         return;
     }
 
     SkScalar scales[2];
-    bool isHairline = (0 == width) || (1 == width && draw.fMatrix->getMinMaxScales(scales) &&
+    bool isHairline = (0 == width) || (1 == width && this->ctm().getMinMaxScales(scales) &&
                                        SkScalarNearlyEqual(scales[0], 1.f) &&
                                        SkScalarNearlyEqual(scales[1], 1.f));
     // we only handle non-antialiased hairlines and paints without path effects or mask filters,
     // else we let the SkDraw call our drawPath()
     if (!isHairline || paint.getPathEffect() || paint.getMaskFilter() ||
-        (paint.isAntiAlias() && needs_antialiasing(mode, count, pts, *draw.fMatrix))) {
+        (paint.isAntiAlias() && needs_antialiasing(mode, count, pts, this->ctm())))
+    {
+        SkRasterClip rc(this->devClipBounds());
+        SkDraw draw;
+        draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(this->width(), this->height()), nullptr, 0);
+        draw.fMatrix = &this->ctm();
+        draw.fRC = &rc;
         draw.drawPoints(mode, count, pts, paint, this);
         return;
     }
 
     GrPrimitiveType primitiveType = gPointMode2PrimitiveType[mode];
 
-    const SkMatrix* viewMatrix = draw.fMatrix;
+    const SkMatrix* viewMatrix = &this->ctm();
 #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
     // This offsetting in device space matches the expectations of the Android framework for non-AA
     // points and lines.
@@ -407,10 +407,10 @@ void SkGpuDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode,
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint& paint) {
+void SkGpuDevice::drawRect(const SkRect& rect, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRect", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
 
     // A couple reasons we might need to call drawPath.
@@ -420,37 +420,37 @@ void SkGpuDevice::drawRect(const SkDraw& draw, const SkRect& rect, const SkPaint
         path.addRect(rect);
         GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
                                             fClip, path, paint,
-                                            *draw.fMatrix, nullptr,
-                                            this->devClipBounds(draw), true);
+                                            this->ctm(), nullptr,
+                                            this->devClipBounds(), true);
         return;
     }
 
     GrPaint grPaint;
-    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                           &grPaint)) {
         return;
     }
 
     GrStyle style(paint);
     fRenderTargetContext->drawRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
-                                   *draw.fMatrix, rect, &style);
+                                   this->ctm(), rect, &style);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPaint& paint) {
+void SkGpuDevice::drawRRect(const SkRRect& rrect, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawRRect", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     GrPaint grPaint;
-    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                           &grPaint)) {
         return;
     }
 
     SkMaskFilter* mf = paint.getMaskFilter();
-    if (mf && mf->asFragmentProcessor(nullptr, nullptr, *draw.fMatrix)) {
+    if (mf && mf->asFragmentProcessor(nullptr, nullptr, this->ctm())) {
         mf = nullptr; // already handled in SkPaintToGrPaint
     }
 
@@ -459,19 +459,19 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPa
         // try to hit the fast path for drawing filtered round rects
 
         SkRRect devRRect;
-        if (rrect.transform(*draw.fMatrix, &devRRect)) {
+        if (rrect.transform(this->ctm(), &devRRect)) {
             if (devRRect.allCornersCircular()) {
                 SkRect maskRect;
-                if (mf->canFilterMaskGPU(devRRect, this->devClipBounds(draw),
-                                         *draw.fMatrix, &maskRect)) {
+                if (mf->canFilterMaskGPU(devRRect, this->devClipBounds(),
+                                         this->ctm(), &maskRect)) {
                     SkIRect finalIRect;
                     maskRect.roundOut(&finalIRect);
-                    if (draw.fRC->quickReject(finalIRect)) {
-                        // clipped out
-                        return;
-                    }
+
+                    // we used to test finalIRect for quickReject, but that seems unlikely
+                    // given that the original shape was not rejected...
+
                     if (mf->directFilterRRectMaskGPU(fContext.get(), fRenderTargetContext.get(),
-                                                     std::move(grPaint), fClip, *draw.fMatrix,
+                                                     std::move(grPaint), fClip, this->ctm(),
                                                      style.strokeRec(), rrect, devRRect)) {
                         return;
                     }
@@ -490,43 +490,43 @@ void SkGpuDevice::drawRRect(const SkDraw& draw, const SkRRect& rrect, const SkPa
         path.addRRect(rrect);
         GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
                                             fClip, path, paint,
-                                            *draw.fMatrix, nullptr,
-                                            this->devClipBounds(draw), true);
+                                            this->ctm(), nullptr,
+                                            this->devClipBounds(), true);
         return;
     }
 
     SkASSERT(!style.pathEffect());
 
     fRenderTargetContext->drawRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
-                                    *draw.fMatrix, rrect, style);
+                                    this->ctm(), rrect, style);
 }
 
 
-void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
+void SkGpuDevice::drawDRRect(const SkRRect& outer,
                              const SkRRect& inner, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDRRect", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     if (outer.isEmpty()) {
        return;
     }
 
     if (inner.isEmpty()) {
-        return this->drawRRect(draw, outer, paint);
+        return this->drawRRect(outer, paint);
     }
 
     SkStrokeRec stroke(paint);
 
     if (stroke.isFillStyle() && !paint.getMaskFilter() && !paint.getPathEffect()) {
         GrPaint grPaint;
-        if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+        if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                               &grPaint)) {
             return;
         }
 
         fRenderTargetContext->drawDRRect(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
-                                         *draw.fMatrix, outer, inner);
+                                         this->ctm(), outer, inner);
         return;
     }
 
@@ -538,78 +538,78 @@ void SkGpuDevice::drawDRRect(const SkDraw& draw, const SkRRect& outer,
 
     GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
                                         fClip, path, paint,
-                                        *draw.fMatrix, nullptr,
-                                        this->devClipBounds(draw), true);
+                                        this->ctm(), nullptr,
+                                        this->devClipBounds(), true);
 }
 
 
 /////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::drawRegion(const SkDraw& draw, const SkRegion& region, const SkPaint& paint) {
+void SkGpuDevice::drawRegion(const SkRegion& region, const SkPaint& paint) {
     if (paint.getMaskFilter()) {
         SkPath path;
         region.getBoundaryPath(&path);
-        return this->drawPath(draw, path, paint, nullptr, false);
+        return this->drawPath(path, paint, nullptr, false);
     }
 
     GrPaint grPaint;
-    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                           &grPaint)) {
         return;
     }
 
     fRenderTargetContext->drawRegion(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
-                                     *draw.fMatrix, region, GrStyle(paint));
+                                     this->ctm(), region, GrStyle(paint));
 }
 
-void SkGpuDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
+void SkGpuDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawOval", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     // Presumably the path effect warps this to something other than an oval
     if (paint.getPathEffect()) {
         SkPath path;
         path.setIsVolatile(true);
         path.addOval(oval);
-        this->drawPath(draw, path, paint, nullptr, true);
+        this->drawPath(path, paint, nullptr, true);
         return;
     }
 
     if (paint.getMaskFilter()) {
         // The RRect path can handle special case blurring
         SkRRect rr = SkRRect::MakeOval(oval);
-        return this->drawRRect(draw, rr, paint);
+        return this->drawRRect(rr, paint);
     }
 
     GrPaint grPaint;
-    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                           &grPaint)) {
         return;
     }
 
     fRenderTargetContext->drawOval(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
-                                   *draw.fMatrix, oval, GrStyle(paint));
+                                   this->ctm(), oval, GrStyle(paint));
 }
 
-void SkGpuDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar startAngle,
+void SkGpuDevice::drawArc(const SkRect& oval, SkScalar startAngle,
                           SkScalar sweepAngle, bool useCenter, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawArc", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     if (paint.getMaskFilter()) {
-        this->INHERITED::drawArc(draw, oval, startAngle, sweepAngle, useCenter, paint);
+        this->INHERITED::drawArc(oval, startAngle, sweepAngle, useCenter, paint);
         return;
     }
     GrPaint grPaint;
-    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, *draw.fMatrix,
+    if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), paint, this->ctm(),
                           &grPaint)) {
         return;
     }
 
     fRenderTargetContext->drawArc(fClip, std::move(grPaint), GrBoolToAA(paint.isAntiAlias()),
-                                  *draw.fMatrix, oval, startAngle, sweepAngle, useCenter,
+                                  this->ctm(), oval, startAngle, sweepAngle, useCenter,
                                   GrStyle(paint));
 }
 
@@ -617,11 +617,10 @@ void SkGpuDevice::drawArc(const SkDraw& draw, const SkRect& oval, SkScalar start
 
 ///////////////////////////////////////////////////////////////////////////////
 void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
-                                  const SkDraw& draw,
                                   const SkPaint& origPaint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawStrokedLine", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     // Adding support for round capping would require a
     // GrRenderTargetContext::fillRRectWithLocalMatrix entry point
@@ -659,7 +658,7 @@ void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
 
     SkMatrix local = m;
 
-    m.postConcat(*draw.fMatrix);
+    m.postConcat(this->ctm());
 
     GrPaint grPaint;
     if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), newPaint, m, &grPaint)) {
@@ -670,7 +669,7 @@ void SkGpuDevice::drawStrokedLine(const SkPoint points[2],
             fClip, std::move(grPaint), GrBoolToAA(newPaint.isAntiAlias()), m, rect, local);
 }
 
-void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
+void SkGpuDevice::drawPath(const SkPath& origSrcPath,
                            const SkPaint& paint, const SkMatrix* prePathMatrix,
                            bool pathIsMutable) {
     ASSERT_SINGLE_OWNER
@@ -678,40 +677,40 @@ void SkGpuDevice::drawPath(const SkDraw& draw, const SkPath& origSrcPath,
         SkPoint points[2];
         if (SkPaint::kStroke_Style == paint.getStyle() && paint.getStrokeWidth() > 0 &&
             !paint.getMaskFilter() && SkPaint::kRound_Cap != paint.getStrokeCap() &&
-            draw.fMatrix->preservesRightAngles() && origSrcPath.isLine(points)) {
+            this->ctm().preservesRightAngles() && origSrcPath.isLine(points)) {
             // Path-based stroking looks better for thin rects
-            SkScalar strokeWidth = draw.fMatrix->getMaxScale() * paint.getStrokeWidth();
+            SkScalar strokeWidth = this->ctm().getMaxScale() * paint.getStrokeWidth();
             if (strokeWidth >= 1.0f) {
                 // Round capping support is currently disabled b.c. it would require a RRect
                 // GrDrawOp that takes a localMatrix.
-                this->drawStrokedLine(points, draw, paint);
+                this->drawStrokedLine(points, paint);
                 return;
             }
         }
         bool isClosed;
         SkRect rect;
         if (origSrcPath.isRect(&rect, &isClosed) && isClosed) {
-            this->drawRect(draw, rect, paint);
+            this->drawRect(rect, paint);
             return;
         }
         if (origSrcPath.isOval(&rect)) {
-            this->drawOval(draw, rect, paint);
+            this->drawOval(rect, paint);
             return;
         }
         SkRRect rrect;
         if (origSrcPath.isRRect(&rrect)) {
-            this->drawRRect(draw, rrect, paint);
+            this->drawRRect(rrect, paint);
             return;
         }
     }
 
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPath", fContext.get());
 
     GrBlurUtils::drawPathWithMaskFilter(fContext.get(), fRenderTargetContext.get(),
                                         fClip, origSrcPath, paint,
-                                        *draw.fMatrix, prePathMatrix,
-                                        this->devClipBounds(draw), pathIsMutable);
+                                        this->ctm(), prePathMatrix,
+                                        this->devClipBounds(), pathIsMutable);
 }
 
 static const int kBmpSmallTileSize = 1 << 10;
@@ -857,14 +856,13 @@ bool SkGpuDevice::shouldTileImage(const SkImage* image, const SkRect* srcRectPtr
                                    &outClippedSrcRect);
 }
 
-void SkGpuDevice::drawBitmap(const SkDraw& origDraw,
-                             const SkBitmap& bitmap,
+void SkGpuDevice::drawBitmap(const SkBitmap& bitmap,
                              const SkMatrix& m,
                              const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(origDraw);
+    CHECK_SHOULD_DRAW();
     SkMatrix viewMatrix;
-    viewMatrix.setConcat(*origDraw.fMatrix, m);
+    viewMatrix.setConcat(this->ctm(), m);
 
     int maxTileSize = fContext->caps()->maxTileSize();
 
@@ -1121,10 +1119,10 @@ void SkGpuDevice::drawBitmapTile(const SkBitmap& bitmap,
     fRenderTargetContext->drawRect(fClip, std::move(grPaint), aa, viewMatrix, dstRect);
 }
 
-void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
+void SkGpuDevice::drawSprite(const SkBitmap& bitmap,
                              int left, int top, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSprite", fContext.get());
 
     if (fContext->abandoned()) {
@@ -1136,23 +1134,22 @@ void SkGpuDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
         return;
     }
 
-    this->drawSpecial(draw, srcImg.get(), left, top, paint);
+    this->drawSpecial(srcImg.get(), left, top, paint);
 }
 
 
-void SkGpuDevice::drawSpecial(const SkDraw& draw,
-                              SkSpecialImage* special1,
+void SkGpuDevice::drawSpecial(SkSpecialImage* special1,
                               int left, int top,
                               const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawSpecial", fContext.get());
 
     SkIPoint offset = { 0, 0 };
 
     sk_sp<SkSpecialImage> result;
     if (paint.getImageFilter()) {
-        result = this->filterTexture(draw, special1, left, top,
+        result = this->filterTexture(special1, left, top,
                                       &offset,
                                       paint.getImageFilter());
         if (!result) {
@@ -1204,11 +1201,11 @@ void SkGpuDevice::drawSpecial(const SkDraw& draw,
             SkRect::Make(subset));
 }
 
-void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
+void SkGpuDevice::drawBitmapRect(const SkBitmap& bitmap,
                                  const SkRect* src, const SkRect& origDst,
                                  const SkPaint& paint, SkCanvas::SrcRectConstraint constraint) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     // The src rect is inferred to be the bmp bounds if not provided. Otherwise, the src rect must
     // be clipped to the bmp bounds. To determine tiling parameters we need the filter mode which
@@ -1256,7 +1253,7 @@ void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
         GrSamplerParams params;
         bool doBicubic;
         GrSamplerParams::FilterMode textureFilterMode =
-            GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, srcToDstMatrix,
+            GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), this->ctm(), srcToDstMatrix,
                                             &doBicubic);
 
         int tileFilterPad;
@@ -1271,16 +1268,16 @@ void SkGpuDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap,
         params.setFilterMode(textureFilterMode);
 
         int maxTileSizeForFilter = fContext->caps()->maxTileSize() - 2 * tileFilterPad;
-        if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), *draw.fMatrix,
+        if (this->shouldTileImageID(bitmap.getGenerationID(), bitmap.getSubset(), this->ctm(),
                                     srcToDstMatrix, params, src, maxTileSizeForFilter, &tileSize,
                                     &clippedSrcRect)) {
-            this->drawTiledBitmap(bitmap, *draw.fMatrix, srcToDstMatrix, *src, clippedSrcRect,
+            this->drawTiledBitmap(bitmap, this->ctm(), srcToDstMatrix, *src, clippedSrcRect,
                                   params, paint, constraint, tileSize, doBicubic);
             return;
         }
     }
     GrBitmapTextureMaker maker(fContext.get(), bitmap);
-    this->drawTextureProducer(&maker, src, dst, constraint, *draw.fMatrix, fClip, paint);
+    this->drawTextureProducer(&maker, src, dst, constraint, this->ctm(), fClip, paint);
 }
 
 sk_sp<SkSpecialImage> SkGpuDevice::makeSpecial(const SkBitmap& bitmap) {
@@ -1349,7 +1346,7 @@ sk_sp<SkSpecialImage> SkGpuDevice::snapSpecial() {
                                                &this->surfaceProps());
 }
 
-void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
+void SkGpuDevice::drawDevice(SkBaseDevice* device,
                              int left, int top, const SkPaint& paint) {
     SkASSERT(!paint.getImageFilter());
 
@@ -1358,7 +1355,7 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawDevice", fContext.get());
 
     // drawDevice is defined to be in device coords.
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     SkGpuDevice* dev = static_cast<SkGpuDevice*>(device);
     sk_sp<SkSpecialImage> srcImg(dev->snapSpecial());
@@ -1366,17 +1363,17 @@ void SkGpuDevice::drawDevice(const SkDraw& draw, SkBaseDevice* device,
         return;
     }
 
-    this->drawSpecial(draw, srcImg.get(), left, top, paint);
+    this->drawSpecial(srcImg.get(), left, top, paint);
 }
 
-void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x, SkScalar y,
+void SkGpuDevice::drawImage(const SkImage* image, SkScalar x, SkScalar y,
                             const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
-    SkMatrix viewMatrix = *draw.fMatrix;
+    SkMatrix viewMatrix = this->ctm();
     viewMatrix.preTranslate(x, y);
     uint32_t pinnedUniqueID;
     if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
-        CHECK_SHOULD_DRAW(draw);
+        CHECK_SHOULD_DRAW();
         GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
                                    as_IB(image)->onImageInfo().colorSpace());
         this->drawTextureProducer(&adjuster, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint,
@@ -1385,66 +1382,66 @@ void SkGpuDevice::drawImage(const SkDraw& draw, const SkImage* image, SkScalar x
     } else {
         SkBitmap bm;
         if (this->shouldTileImage(image, nullptr, SkCanvas::kFast_SrcRectConstraint,
-                                  paint.getFilterQuality(), *draw.fMatrix, SkMatrix::I())) {
+                                  paint.getFilterQuality(), this->ctm(), SkMatrix::I())) {
             // only support tiling as bitmap at the moment, so force raster-version
             if (!as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
                 return;
             }
-            this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
+            this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
         } else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
-            CHECK_SHOULD_DRAW(draw);
+            CHECK_SHOULD_DRAW();
             GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
             this->drawTextureProducer(&maker, nullptr, nullptr, SkCanvas::kFast_SrcRectConstraint,
                                       viewMatrix, fClip, paint);
         } else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
-            this->drawBitmap(draw, bm, SkMatrix::MakeTrans(x, y), paint);
+            this->drawBitmap(bm, SkMatrix::MakeTrans(x, y), paint);
         }
     }
 }
 
-void SkGpuDevice::drawImageRect(const SkDraw& draw, const SkImage* image, const SkRect* src,
+void SkGpuDevice::drawImageRect(const SkImage* image, const SkRect* src,
                                 const SkRect& dst, const SkPaint& paint,
                                 SkCanvas::SrcRectConstraint constraint) {
     ASSERT_SINGLE_OWNER
     uint32_t pinnedUniqueID;
     if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
-        CHECK_SHOULD_DRAW(draw);
+        CHECK_SHOULD_DRAW();
         GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
                                    as_IB(image)->onImageInfo().colorSpace());
-        this->drawTextureProducer(&adjuster, src, &dst, constraint, *draw.fMatrix, fClip, paint);
+        this->drawTextureProducer(&adjuster, src, &dst, constraint, this->ctm(), fClip, paint);
         return;
     }
     SkBitmap bm;
     SkMatrix srcToDstRect;
     srcToDstRect.setRectToRect((src ? *src : SkRect::MakeIWH(image->width(), image->height())),
                                dst, SkMatrix::kFill_ScaleToFit);
-    if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), *draw.fMatrix,
+    if (this->shouldTileImage(image, src, constraint, paint.getFilterQuality(), this->ctm(),
                               srcToDstRect)) {
         // only support tiling as bitmap at the moment, so force raster-version
         if (!as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
             return;
         }
-        this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
+        this->drawBitmapRect(bm, src, dst, paint, constraint);
     } else if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
-        CHECK_SHOULD_DRAW(draw);
+        CHECK_SHOULD_DRAW();
         GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
-        this->drawTextureProducer(&maker, src, &dst, constraint, *draw.fMatrix, fClip, paint);
+        this->drawTextureProducer(&maker, src, &dst, constraint, this->ctm(), fClip, paint);
     } else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
-        this->drawBitmapRect(draw, bm, src, dst, paint, constraint);
+        this->drawBitmapRect(bm, src, dst, paint, constraint);
     }
 }
 
-void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* producer,
+void SkGpuDevice::drawProducerNine(GrTextureProducer* producer,
                                    const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerNine", fContext.get());
 
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     bool useFallback = paint.getMaskFilter() || paint.isAntiAlias() ||
                        fRenderTargetContext->isUnifiedMultisampled();
     bool doBicubic;
     GrSamplerParams::FilterMode textureFilterMode =
-        GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), *draw.fMatrix, SkMatrix::I(),
+        GrSkFilterQualityToGrFilterMode(paint.getFilterQuality(), this->ctm(), SkMatrix::I(),
                                         &doBicubic);
     if (useFallback || doBicubic || GrSamplerParams::kNone_FilterMode != textureFilterMode) {
         SkLatticeIter iter(producer->width(), producer->height(), center, dst);
@@ -1452,7 +1449,7 @@ void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* produc
         SkRect srcR, dstR;
         while (iter.next(&srcR, &dstR)) {
             this->drawTextureProducer(producer, &srcR, &dstR, SkCanvas::kStrict_SrcRectConstraint,
-                                      *draw.fMatrix, fClip, paint);
+                                      this->ctm(), fClip, paint);
         }
         return;
     }
@@ -1465,51 +1462,51 @@ void SkGpuDevice::drawProducerNine(const SkDraw& draw, GrTextureProducer* produc
                                           &kMode, fRenderTargetContext->getColorSpace()));
     GrPaint grPaint;
     if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext.get(), paint,
-                                     *draw.fMatrix, std::move(fp), producer->isAlphaOnly(),
+                                     this->ctm(), std::move(fp), producer->isAlphaOnly(),
                                      &grPaint)) {
         return;
     }
 
     std::unique_ptr<SkLatticeIter> iter(
             new SkLatticeIter(producer->width(), producer->height(), center, dst));
-    fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
+    fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), this->ctm(),
                                            producer->width(), producer->height(), std::move(iter),
                                            dst);
 }
 
-void SkGpuDevice::drawImageNine(const SkDraw& draw, const SkImage* image,
+void SkGpuDevice::drawImageNine(const SkImage* image,
                                 const SkIRect& center, const SkRect& dst, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     uint32_t pinnedUniqueID;
     if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
-        CHECK_SHOULD_DRAW(draw);
+        CHECK_SHOULD_DRAW();
         GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
                                    as_IB(image)->onImageInfo().colorSpace());
-        this->drawProducerNine(draw, &adjuster, center, dst, paint);
+        this->drawProducerNine(&adjuster, center, dst, paint);
     } else {
         SkBitmap bm;
         if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
             GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
-            this->drawProducerNine(draw, &maker, center, dst, paint);
+            this->drawProducerNine(&maker, center, dst, paint);
         } else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
-            this->drawBitmapNine(draw, bm, center, dst, paint);
+            this->drawBitmapNine(bm, center, dst, paint);
         }
     }
 }
 
-void SkGpuDevice::drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
+void SkGpuDevice::drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                                  const SkRect& dst, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GrBitmapTextureMaker maker(fContext.get(), bitmap);
-    this->drawProducerNine(draw, &maker, center, dst, paint);
+    this->drawProducerNine(&maker, center, dst, paint);
 }
 
-void SkGpuDevice::drawProducerLattice(const SkDraw& draw, GrTextureProducer* producer,
+void SkGpuDevice::drawProducerLattice(GrTextureProducer* producer,
                                       const SkCanvas::Lattice& lattice, const SkRect& dst,
                                       const SkPaint& paint) {
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawProducerLattice", fContext.get());
 
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     static const GrSamplerParams::FilterMode kMode = GrSamplerParams::kNone_FilterMode;
     sk_sp<GrFragmentProcessor> fp(
@@ -1519,45 +1516,45 @@ void SkGpuDevice::drawProducerLattice(const SkDraw& draw, GrTextureProducer* pro
                                           &kMode, fRenderTargetContext->getColorSpace()));
     GrPaint grPaint;
     if (!SkPaintToGrPaintWithTexture(this->context(), fRenderTargetContext.get(), paint,
-                                     *draw.fMatrix, std::move(fp), producer->isAlphaOnly(),
+                                     this->ctm(), std::move(fp), producer->isAlphaOnly(),
                                      &grPaint)) {
         return;
     }
 
     std::unique_ptr<SkLatticeIter> iter(
             new SkLatticeIter(lattice, dst));
-    fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), *draw.fMatrix,
+    fRenderTargetContext->drawImageLattice(fClip, std::move(grPaint), this->ctm(),
                                            producer->width(), producer->height(), std::move(iter),
                                            dst);
 }
 
-void SkGpuDevice::drawImageLattice(const SkDraw& draw, const SkImage* image,
+void SkGpuDevice::drawImageLattice(const SkImage* image,
                                    const SkCanvas::Lattice& lattice, const SkRect& dst,
                                    const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     uint32_t pinnedUniqueID;
     if (sk_sp<GrTexture> tex = as_IB(image)->refPinnedTexture(&pinnedUniqueID)) {
-        CHECK_SHOULD_DRAW(draw);
+        CHECK_SHOULD_DRAW();
         GrTextureAdjuster adjuster(tex.get(), image->alphaType(), image->bounds(), pinnedUniqueID,
                                    as_IB(image)->onImageInfo().colorSpace());
-        this->drawProducerLattice(draw, &adjuster, lattice, dst, paint);
+        this->drawProducerLattice(&adjuster, lattice, dst, paint);
     } else {
         SkBitmap bm;
         if (SkImageCacherator* cacher = as_IB(image)->peekCacherator()) {
             GrImageTextureMaker maker(fContext.get(), cacher, image, SkImage::kAllow_CachingHint);
-            this->drawProducerLattice(draw, &maker, lattice, dst, paint);
+            this->drawProducerLattice(&maker, lattice, dst, paint);
         } else if (as_IB(image)->getROPixels(&bm, fRenderTargetContext->getColorSpace())) {
-            this->drawBitmapLattice(draw, bm, lattice, dst, paint);
+            this->drawBitmapLattice(bm, lattice, dst, paint);
         }
     }
 }
 
-void SkGpuDevice::drawBitmapLattice(const SkDraw& draw, const SkBitmap& bitmap,
+void SkGpuDevice::drawBitmapLattice(const SkBitmap& bitmap,
                                     const SkCanvas::Lattice& lattice, const SkRect& dst,
                                     const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GrBitmapTextureMaker maker(fContext.get(), bitmap);
-    this->drawProducerLattice(draw, &maker, lattice, dst, paint);
+    this->drawProducerLattice(&maker, lattice, dst, paint);
 }
 
 bool init_vertices_paint(const SkPaint& skPaint, const SkMatrix& matrix, SkBlendMode bmode,
@@ -1585,14 +1582,14 @@ bool init_vertices_paint(const SkPaint& skPaint, const SkMatrix& matrix, SkBlend
     }
 }
 
-void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
+void SkGpuDevice::drawVertices(SkCanvas::VertexMode vmode,
                               int vertexCount, const SkPoint vertices[],
                               const SkPoint texs[], const SkColor colors[],
                               SkBlendMode bmode,
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVertices", fContext.get());
 
     // If both textures and vertex-colors are nullptr, strokes hairlines with the paint's color.
@@ -1642,7 +1639,7 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
         }
         fRenderTargetContext->drawVertices(fClip,
                                            std::move(grPaint),
-                                           *draw.fMatrix,
+                                           this->ctm(),
                                            kLines_GrPrimitiveType,
                                            vertexCount,
                                            vertices,
@@ -1656,13 +1653,13 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
     GrPrimitiveType primType = SkVertexModeToGrPrimitiveType(vmode);
 
     GrPaint grPaint;
-    if (!init_vertices_paint(paint, *draw.fMatrix, bmode, SkToBool(texs), SkToBool(colors),
+    if (!init_vertices_paint(paint, this->ctm(), bmode, SkToBool(texs), SkToBool(colors),
                              fRenderTargetContext.get(), &grPaint)) {
         return;
     }
     fRenderTargetContext->drawVertices(fClip,
                                        std::move(grPaint),
-                                       *draw.fMatrix,
+                                       this->ctm(),
                                        primType,
                                        vertexCount,
                                        vertices,
@@ -1673,10 +1670,10 @@ void SkGpuDevice::drawVertices(const SkDraw& draw, SkCanvas::VertexMode vmode,
                                        GrRenderTargetContext::ColorArrayType::kSkColor);
 }
 
-void SkGpuDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> vertices,
+void SkGpuDevice::drawVerticesObject(sk_sp<SkVertices> vertices,
                                      SkBlendMode mode, const SkPaint& paint, uint32_t flags) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawVerticesObject", fContext.get());
 
     SkASSERT(vertices);
@@ -1685,30 +1682,30 @@ void SkGpuDevice::drawVerticesObject(const SkDraw& draw, sk_sp<SkVertices> verti
     bool hasTexs = vertices->hasTexCoords() & !(SkCanvas::kIgnoreTexCoords_VerticesFlag & flags);
     if (!hasTexs && !hasColors) {
         // The dreaded wireframe mode. Fallback to drawVertices and go so slooooooow.
-        this->drawVertices(draw, vertices->mode(), vertices->vertexCount(), vertices->positions(),
+        this->drawVertices(vertices->mode(), vertices->vertexCount(), vertices->positions(),
                            nullptr, nullptr, mode, vertices->indices(), vertices->indexCount(),
                            paint);
     }
-    if (!init_vertices_paint(paint, *draw.fMatrix, mode, hasTexs, hasColors,
+    if (!init_vertices_paint(paint, this->ctm(), mode, hasTexs, hasColors,
                              fRenderTargetContext.get(), &grPaint)) {
         return;
     }
-    fRenderTargetContext->drawVertices(fClip, std::move(grPaint), *draw.fMatrix,
+    fRenderTargetContext->drawVertices(fClip, std::move(grPaint), this->ctm(),
                                        std::move(vertices), flags);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRSXform xform[],
+void SkGpuDevice::drawAtlas(const SkImage* atlas, const SkRSXform xform[],
                             const SkRect texRect[], const SkColor colors[], int count,
                             SkBlendMode mode, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     if (paint.isAntiAlias()) {
-        this->INHERITED::drawAtlas(draw, atlas, xform, texRect, colors, count, mode, paint);
+        this->INHERITED::drawAtlas(atlas, xform, texRect, colors, count, mode, paint);
         return;
     }
 
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
 
     SkPaint p(paint);
@@ -1717,58 +1714,58 @@ void SkGpuDevice::drawAtlas(const SkDraw& draw, const SkImage* atlas, const SkRS
     GrPaint grPaint;
     if (colors) {
         if (!SkPaintToGrPaintWithXfermode(this->context(), fRenderTargetContext.get(), p,
-                                          *draw.fMatrix, (SkBlendMode)mode, true, &grPaint)) {
+                                          this->ctm(), (SkBlendMode)mode, true, &grPaint)) {
             return;
         }
     } else {
-        if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), p, *draw.fMatrix,
+        if (!SkPaintToGrPaint(this->context(), fRenderTargetContext.get(), p, this->ctm(),
                               &grPaint)) {
             return;
         }
     }
 
     SkDEBUGCODE(this->validate();)
-    fRenderTargetContext->drawAtlas(fClip, std::move(grPaint), *draw.fMatrix, count, xform, texRect,
+    fRenderTargetContext->drawAtlas(fClip, std::move(grPaint), this->ctm(), count, xform, texRect,
                                     colors);
 }
 
 ///////////////////////////////////////////////////////////////////////////////
 
-void SkGpuDevice::drawText(const SkDraw& draw, const void* text,
+void SkGpuDevice::drawText(const void* text,
                            size_t byteLength, SkScalar x, SkScalar y,
                            const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawText", fContext.get());
     SkDEBUGCODE(this->validate();)
 
-    fRenderTargetContext->drawText(fClip, paint, *draw.fMatrix,
-                                   (const char*)text, byteLength, x, y, this->devClipBounds(draw));
+    fRenderTargetContext->drawText(fClip, paint, this->ctm(),
+                                   (const char*)text, byteLength, x, y, this->devClipBounds());
 }
 
-void SkGpuDevice::drawPosText(const SkDraw& draw, const void* text, size_t byteLength,
+void SkGpuDevice::drawPosText(const void* text, size_t byteLength,
                               const SkScalar pos[], int scalarsPerPos,
                               const SkPoint& offset, const SkPaint& paint) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawPosText", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
     SkDEBUGCODE(this->validate();)
 
-    fRenderTargetContext->drawPosText(fClip, paint, *draw.fMatrix,
+    fRenderTargetContext->drawPosText(fClip, paint, this->ctm(),
                                       (const char*)text, byteLength, pos, scalarsPerPos, offset,
-                                      this->devClipBounds(draw));
+                                      this->devClipBounds());
 }
 
-void SkGpuDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
+void SkGpuDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                const SkPaint& paint, SkDrawFilter* drawFilter) {
     ASSERT_SINGLE_OWNER
     GR_CREATE_TRACE_MARKER_CONTEXT("SkGpuDevice", "drawTextBlob", fContext.get());
-    CHECK_SHOULD_DRAW(draw);
+    CHECK_SHOULD_DRAW();
 
     SkDEBUGCODE(this->validate();)
 
-    fRenderTargetContext->drawTextBlob(fClip, paint, *draw.fMatrix,
-                                       blob, x, y, drawFilter, this->devClipBounds(draw));
+    fRenderTargetContext->drawTextBlob(fClip, paint, this->ctm(),
+                                       blob, x, y, drawFilter, this->devClipBounds());
 }
 
 ///////////////////////////////////////////////////////////////////////////////
index 31ade05f4c761f19d0b08903c5052d7539471dd9..655724ca9061c733e5a5f3f00d8d94306a08b158 100644 (file)
@@ -65,55 +65,55 @@ public:
 
     GrRenderTargetContext* accessRenderTargetContext() override;
 
-    void drawPaint(const SkDraw&, const SkPaint& paint) override;
-    void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count, const SkPoint[],
+    void drawPaint(const SkPaint& paint) override;
+    void drawPoints(SkCanvas::PointMode mode, size_t count, const SkPoint[],
                     const SkPaint& paint) override;
-    void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
-    void drawRRect(const SkDraw&, const SkRRect& r, const SkPaint& paint) override;
-    void drawDRRect(const SkDraw& draw, const SkRRect& outer, const SkRRect& inner,
+    void drawRect(const SkRect& r, const SkPaint& paint) override;
+    void drawRRect(const SkRRect& r, const SkPaint& paint) override;
+    void drawDRRect(const SkRRect& outer, const SkRRect& inner,
                     const SkPaint& paint) override;
-    void drawRegion(const SkDraw&, const SkRegion& r, const SkPaint& paint) override;
-    void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
-    void drawArc(const SkDraw&, const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
+    void drawRegion(const SkRegion& r, const SkPaint& paint) override;
+    void drawOval(const SkRect& oval, const SkPaint& paint) override;
+    void drawArc(const SkRect& oval, SkScalar startAngle, SkScalar sweepAngle,
                  bool useCenter, const SkPaint& paint) override;
-    void drawPath(const SkDraw&, const SkPath& path, const SkPaint& paint,
+    void drawPath(const SkPath& path, const SkPaint& paint,
                   const SkMatrix* prePathMatrix, bool pathIsMutable) override;
-    void drawBitmap(const SkDraw&, const SkBitmap& bitmap, const SkMatrix&,
+    void drawBitmap(const SkBitmap& bitmap, const SkMatrix&,
                     const SkPaint&) override;
-    void drawBitmapRect(const SkDraw&, const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst,
+    void drawBitmapRect(const SkBitmap&, const SkRect* srcOrNull, const SkRect& dst,
                         const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
-    void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
+    void drawSprite(const SkBitmap& bitmap, int x, int y,
                     const SkPaint& paint) override;
-    void drawText(const SkDraw&, const void* text, size_t len, SkScalar x, SkScalar y,
+    void drawText(const void* text, size_t len, SkScalar x, SkScalar y,
                   const SkPaint&) override;
-    void drawPosText(const SkDraw&, const void* text, size_t len, const SkScalar pos[],
+    void drawPosText(const void* text, size_t len, const SkScalar pos[],
                      int scalarsPerPos, const SkPoint& offset, const SkPaint&) override;
-    void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
+    void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
                       const SkPaint& paint, SkDrawFilter* drawFilter) override;
-    void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
+    void drawVertices(SkCanvas::VertexMode, int vertexCount, const SkPoint verts[],
                       const SkPoint texs[], const SkColor colors[], SkBlendMode,
                       const uint16_t indices[], int indexCount, const SkPaint&) override;
-    void drawVerticesObject(const SkDraw&, sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
+    void drawVerticesObject(sk_sp<SkVertices>, SkBlendMode, const SkPaint&,
                             uint32_t flags) override;
-    void drawAtlas(const SkDraw&, const SkImage* atlas, const SkRSXform[], const SkRect[],
+    void drawAtlas(const SkImage* atlas, const SkRSXform[], const SkRect[],
                    const SkColor[], int count, SkBlendMode, const SkPaint&) override;
-    void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y, const SkPaint&) override;
+    void drawDevice(SkBaseDevice*, int x, int y, const SkPaint&) override;
 
-    void drawImage(const SkDraw&, const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;
-    void drawImageRect(const SkDraw&, const SkImage*, const SkRect* src, const SkRect& dst,
+    void drawImage(const SkImage*, SkScalar x, SkScalar y, const SkPaint&) override;
+    void drawImageRect(const SkImage*, const SkRect* src, const SkRect& dst,
                        const SkPaint&, SkCanvas::SrcRectConstraint) override;
 
-    void drawImageNine(const SkDraw& draw, const SkImage* image, const SkIRect& center,
+    void drawImageNine(const SkImage* image, const SkIRect& center,
                        const SkRect& dst, const SkPaint& paint) override;
-    void drawBitmapNine(const SkDraw& draw, const SkBitmap& bitmap, const SkIRect& center,
+    void drawBitmapNine(const SkBitmap& bitmap, const SkIRect& center,
                         const SkRect& dst, const SkPaint& paint) override;
 
-    void drawImageLattice(const SkDraw&, const SkImage*, const SkCanvas::Lattice&,
+    void drawImageLattice(const SkImage*, const SkCanvas::Lattice&,
                           const SkRect& dst, const SkPaint&) override;
-    void drawBitmapLattice(const SkDraw&, const SkBitmap&, const SkCanvas::Lattice&,
+    void drawBitmapLattice(const SkBitmap&, const SkCanvas::Lattice&,
                            const SkRect& dst, const SkPaint&) override;
 
-    void drawSpecial(const SkDraw&, SkSpecialImage*,
+    void drawSpecial(SkSpecialImage*,
                      int left, int top, const SkPaint& paint) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
@@ -157,7 +157,7 @@ private:
     bool forceConservativeRasterClip() const override { return true; }
 
     // sets the render target and clip on context
-    void prepareDraw(const SkDraw&);
+    void prepareDraw();
 
     /**
      * Helper functions called by drawBitmapCommon. By the time these are called the SkDraw's
@@ -179,8 +179,7 @@ private:
                          SkCanvas::SrcRectConstraint constraint, SkFilterQuality quality,
                          const SkMatrix& viewMatrix, const SkMatrix& srcToDstRect) const;
 
-    sk_sp<SkSpecialImage> filterTexture(const SkDraw&,
-                                        SkSpecialImage*,
+    sk_sp<SkSpecialImage> filterTexture(SkSpecialImage*,
                                         int left, int top,
                                         SkIPoint* offset,
                                         const SkImageFilter* filter);
@@ -228,14 +227,14 @@ private:
     bool drawFilledDRRect(const SkMatrix& viewMatrix, const SkRRect& outer,
                           const SkRRect& inner, const SkPaint& paint);
 
-    void drawProducerNine(const SkDraw&, GrTextureProducer*, const SkIRect& center,
+    void drawProducerNine(GrTextureProducer*, const SkIRect& center,
                           const SkRect& dst, const SkPaint&);
 
-    void drawProducerLattice(const SkDraw&, GrTextureProducer*, const SkCanvas::Lattice& lattice,
+    void drawProducerLattice(GrTextureProducer*, const SkCanvas::Lattice& lattice,
                              const SkRect& dst, const SkPaint&);
 
     bool drawDashLine(const SkPoint pts[2], const SkPaint& paint);
-    void drawStrokedLine(const SkPoint pts[2], const SkDraw&, const SkPaint&);
+    void drawStrokedLine(const SkPoint pts[2], const SkPaint&);
 
     static sk_sp<GrRenderTargetContext> MakeRenderTargetContext(GrContext*,
                                                                 SkBudgeted,
index d54441e92dedc10cd7d04b594c94b415abc88af2..26dd09fcd9d853706fda2b65d89ccebeb10ab722 100644 (file)
 
 // Utility functions
 
+static void draw_points(SkCanvas::PointMode mode,
+                        size_t count,
+                        const SkPoint* points,
+                        const SkPaint& paint,
+                        const SkIRect& bounds,
+                        const SkMatrix& ctm,
+                        SkBaseDevice* device) {
+    SkRasterClip rc(bounds);
+    SkDraw draw;
+    draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(bounds.right(), bounds.bottom()), nullptr, 0);
+    draw.fMatrix = &ctm;
+    draw.fRC = &rc;
+    draw.drawPoints(mode, count, points, paint, device);
+}
+
+static SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; }
+
 // If the paint will definitely draw opaquely, replace kSrc with
 // kSrcOver.  http://crbug.com/473572
 static void replace_srcmode_on_opaque_paint(SkPaint* paint) {
@@ -381,23 +398,26 @@ SkPDFCanon* SkPDFDevice::getCanon() const { return fDocument->canon(); }
 // drawing method and maintain the state needed between set up and finish.
 class ScopedContentEntry {
 public:
-    ScopedContentEntry(SkPDFDevice* device, const SkDraw& draw,
-                       const SkPaint& paint, bool hasText = false)
-        : fDevice(device),
-          fContentEntry(nullptr),
-          fBlendMode(SkBlendMode::kSrcOver),
-          fDstFormXObject(nullptr) {
-        init(draw.fClipStack, *draw.fMatrix, paint, hasText);
-    }
-    ScopedContentEntry(SkPDFDevice* device, const SkClipStack* clipStack,
+    ScopedContentEntry(SkPDFDevice* device,
+                       const SkClipStack& clipStack,
                        const SkMatrix& matrix,
-                       const SkPaint& paint, bool hasText = false)
-        : fDevice(device),
-          fContentEntry(nullptr),
-          fBlendMode(SkBlendMode::kSrcOver),
-          fDstFormXObject(nullptr) {
-        init(clipStack, matrix, paint, hasText);
+                       const SkPaint& paint,
+                       bool hasText = false)
+        : fDevice(device)
+        , fContentEntry(nullptr)
+        , fBlendMode(SkBlendMode::kSrcOver)
+        , fDstFormXObject(nullptr)
+    {
+        if (matrix.hasPerspective()) {
+            NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
+            return;
+        }
+        fBlendMode = paint.getBlendMode();
+        fContentEntry =
+            fDevice->setUpContentEntry(clipStack, matrix, paint, hasText, &fDstFormXObject);
     }
+    ScopedContentEntry(SkPDFDevice* dev, const SkPaint& paint, bool hasText = false)
+        : ScopedContentEntry(dev, dev->cs(), dev->ctm(), paint, hasText) {}
 
     ~ScopedContentEntry() {
         if (fContentEntry) {
@@ -451,18 +471,6 @@ private:
     SkBlendMode fBlendMode;
     sk_sp<SkPDFObject> fDstFormXObject;
     SkPath fShape;
-
-    void init(const SkClipStack* clipStack,
-              const SkMatrix& matrix, const SkPaint& paint, bool hasText) {
-        // Shape has to be flatten before we get here.
-        if (matrix.hasPerspective()) {
-            NOT_IMPLEMENTED(!matrix.hasPerspective(), false);
-            return;
-        }
-        fBlendMode = paint.getBlendMode();
-        fContentEntry = fDevice->setUpContentEntry(clipStack, matrix, paint, hasText,
-                                                   &fDstFormXObject);
-    }
 };
 
 ////////////////////////////////////////////////////////////////////////////////
@@ -503,25 +511,44 @@ void SkPDFDevice::cleanUp() {
     fShaderResources.unrefAll();
 }
 
-void SkPDFDevice::drawAnnotation(const SkDraw& d, const SkRect& rect, const char key[],
-                                 SkData* value) {
+void SkPDFDevice::drawAnnotation(const SkRect& rect, const char key[], SkData* value) {
     if (!value) {
         return;
     }
     if (rect.isEmpty()) {
-        this->handlePointAnnotation({ rect.x(), rect.y() }, *d.fMatrix, key, value);
-    } else {
-        this->handleRectAnnotation(rect, d, key, value);
+        if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
+            SkPoint transformedPoint;
+            this->ctm().mapXY(rect.x(), rect.y(), &transformedPoint);
+            fNamedDestinations.emplace_back(value, transformedPoint);
+        }
+        return;
+    }
+    // Convert to path to handle non-90-degree rotations.
+    SkPath path;
+    path.addRect(rect);
+    path.transform(this->ctm(), &path);
+    SkPath clip;
+    (void)this->cs().asPath(&clip);
+    Op(clip, path, kIntersect_SkPathOp, &path);
+    // PDF wants a rectangle only.
+    SkRect transformedRect = path.getBounds();
+    if (transformedRect.isEmpty()) {
+        return;
+    }
+    if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
+        fLinkToURLs.emplace_back(transformedRect, value);
+    } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
+        fLinkToDestinations.emplace_back(transformedRect, value);
     }
 }
 
-void SkPDFDevice::drawPaint(const SkDraw& d, const SkPaint& paint) {
+void SkPDFDevice::drawPaint(const SkPaint& paint) {
     SkPaint newPaint = paint;
     replace_srcmode_on_opaque_paint(&newPaint);
 
     newPaint.setStyle(SkPaint::kFill_Style);
-    ScopedContentEntry content(this, d, newPaint);
-    internalDrawPaint(newPaint, content.entry());
+    ScopedContentEntry content(this, newPaint);
+    this->internalDrawPaint(newPaint, content.entry());
 }
 
 void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
@@ -542,8 +569,7 @@ void SkPDFDevice::internalDrawPaint(const SkPaint& paint,
                           &contentEntry->fContent);
 }
 
-void SkPDFDevice::drawPoints(const SkDraw& d,
-                             SkCanvas::PointMode mode,
+void SkPDFDevice::drawPoints(SkCanvas::PointMode mode,
                              size_t count,
                              const SkPoint* points,
                              const SkPaint& srcPaint) {
@@ -558,10 +584,11 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
     // We only use this when there's a path effect because of the overhead
     // of multiple calls to setUpContentEntry it causes.
     if (passedPaint.getPathEffect()) {
-        if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+        if (this->cs().isEmpty(size(*this))) {
             return;
         }
-        d.drawPoints(mode, count, points, passedPaint, this);
+        draw_points(mode, count, points, passedPaint,
+                    this->devClipBounds(), this->ctm(), this);
         return;
     }
 
@@ -581,7 +608,7 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
             for (size_t i = 0; i < count; i++) {
                 SkRect r = SkRect::MakeXYWH(points[i].fX, points[i].fY, 0, 0);
                 r.inset(-halfStroke, -halfStroke);
-                drawRect(d, r, modifiedPaint);
+                this->drawRect(r, modifiedPaint);
             }
             return;
         } else {
@@ -589,7 +616,7 @@ void SkPDFDevice::drawPoints(const SkDraw& d,
         }
     }
 
-    ScopedContentEntry content(this, d, *paint);
+    ScopedContentEntry content(this, *paint);
     if (!content.entry()) {
         return;
     }
@@ -671,8 +698,7 @@ static sk_sp<SkPDFDict> create_link_named_dest(const SkData* nameData,
     return annotation;
 }
 
-void SkPDFDevice::drawRect(const SkDraw& d,
-                           const SkRect& rect,
+void SkPDFDevice::drawRect(const SkRect& rect,
                            const SkPaint& srcPaint) {
     SkPaint paint = srcPaint;
     replace_srcmode_on_opaque_paint(&paint);
@@ -680,16 +706,16 @@ void SkPDFDevice::drawRect(const SkDraw& d,
     r.sort();
 
     if (paint.getPathEffect()) {
-        if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+        if (this->cs().isEmpty(size(*this))) {
             return;
         }
         SkPath path;
         path.addRect(r);
-        drawPath(d, path, paint, nullptr, true);
+        this->drawPath(path, paint, nullptr, true);
         return;
     }
 
-    ScopedContentEntry content(this, d, paint);
+    ScopedContentEntry content(this, paint);
     if (!content.entry()) {
         return;
     }
@@ -698,37 +724,44 @@ void SkPDFDevice::drawRect(const SkDraw& d,
                           &content.entry()->fContent);
 }
 
-void SkPDFDevice::drawRRect(const SkDraw& draw,
-                            const SkRRect& rrect,
+void SkPDFDevice::drawRRect(const SkRRect& rrect,
                             const SkPaint& srcPaint) {
     SkPaint paint = srcPaint;
     replace_srcmode_on_opaque_paint(&paint);
     SkPath  path;
     path.addRRect(rrect);
-    this->drawPath(draw, path, paint, nullptr, true);
+    this->drawPath(path, paint, nullptr, true);
 }
 
-void SkPDFDevice::drawOval(const SkDraw& draw,
-                           const SkRect& oval,
+void SkPDFDevice::drawOval(const SkRect& oval,
                            const SkPaint& srcPaint) {
     SkPaint paint = srcPaint;
     replace_srcmode_on_opaque_paint(&paint);
     SkPath  path;
     path.addOval(oval);
-    this->drawPath(draw, path, paint, nullptr, true);
+    this->drawPath(path, paint, nullptr, true);
 }
 
-void SkPDFDevice::drawPath(const SkDraw& d,
-                           const SkPath& origPath,
+void SkPDFDevice::drawPath(const SkPath& origPath,
                            const SkPaint& srcPaint,
                            const SkMatrix* prePathMatrix,
                            bool pathIsMutable) {
+    this->internalDrawPath(
+            this->cs(), this->ctm(), origPath, srcPaint, prePathMatrix, pathIsMutable);
+}
+
+void SkPDFDevice::internalDrawPath(const SkClipStack& clipStack,
+                                   const SkMatrix& ctm,
+                                   const SkPath& origPath,
+                                   const SkPaint& srcPaint,
+                                   const SkMatrix* prePathMatrix,
+                                   bool pathIsMutable) {
     SkPaint paint = srcPaint;
     replace_srcmode_on_opaque_paint(&paint);
     SkPath modifiedPath;
     SkPath* pathPtr = const_cast<SkPath*>(&origPath);
 
-    SkMatrix matrix = *d.fMatrix;
+    SkMatrix matrix = ctm;
     if (prePathMatrix) {
         if (paint.getPathEffect() || paint.getStyle() != SkPaint::kFill_Style) {
             if (!pathIsMutable) {
@@ -742,7 +775,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
     }
 
     if (paint.getPathEffect()) {
-        if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+        if (clipStack.isEmpty(size(*this))) {
             return;
         }
         if (!pathIsMutable) {
@@ -759,15 +792,15 @@ void SkPDFDevice::drawPath(const SkDraw& d,
             noEffectPaint.setStyle(SkPaint::kStroke_Style);
             noEffectPaint.setStrokeWidth(0);
         }
-        drawPath(d, *pathPtr, noEffectPaint, nullptr, true);
+        this->internalDrawPath(clipStack, ctm, *pathPtr, noEffectPaint, nullptr, true);
         return;
     }
 
-    if (handleInversePath(d, origPath, paint, pathIsMutable, prePathMatrix)) {
+    if (this->handleInversePath(origPath, paint, pathIsMutable, prePathMatrix)) {
         return;
     }
 
-    ScopedContentEntry content(this, d.fClipStack, matrix, paint);
+    ScopedContentEntry content(this, clipStack, matrix, paint);
     if (!content.entry()) {
         return;
     }
@@ -786,8 +819,7 @@ void SkPDFDevice::drawPath(const SkDraw& d,
 }
 
 
-void SkPDFDevice::drawImageRect(const SkDraw& d,
-                                const SkImage* image,
+void SkPDFDevice::drawImageRect(const SkImage* image,
                                 const SkRect* src,
                                 const SkRect& dst,
                                 const SkPaint& srcPaint,
@@ -815,17 +847,15 @@ void SkPDFDevice::drawImageRect(const SkDraw& d,
     if (!imageSubset.isValid()) {
         return;
     }
-    transform.postConcat(*d.fMatrix);
-    this->internalDrawImage(transform, d.fClipStack,
-                            std::move(imageSubset), paint);
+    transform.postConcat(this->ctm());
+    this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
 }
 
-void SkPDFDevice::drawBitmapRect(const SkDraw& d,
-                                 const SkBitmap& bitmap,
+void SkPDFDevice::drawBitmapRect(const SkBitmap& bitmap,
                                  const SkRect* src,
                                  const SkRect& dst,
-                                const SkPaint& srcPaint,
-                                SkCanvas::SrcRectConstraint) {
+                                 const SkPaint& srcPaint,
+                                 SkCanvas::SrcRectConstraint) {
     if (bitmap.drawsNothing()) {
         return;
     }
@@ -853,16 +883,14 @@ void SkPDFDevice::drawBitmapRect(const SkDraw& d,
     if (!imageSubset.isValid()) {
         return;
     }
-    transform.postConcat(*d.fMatrix);
-    this->internalDrawImage(transform, d.fClipStack,
-                            std::move(imageSubset), paint);
+    transform.postConcat(this->ctm());
+    this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
 }
 
-void SkPDFDevice::drawBitmap(const SkDraw& d,
-                             const SkBitmap& bitmap,
+void SkPDFDevice::drawBitmap(const SkBitmap& bitmap,
                              const SkMatrix& matrix,
                              const SkPaint& srcPaint) {
-    if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
+    if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
         return;
     }
     SkPaint paint = srcPaint;
@@ -874,17 +902,15 @@ void SkPDFDevice::drawBitmap(const SkDraw& d,
         return;
     }
     SkMatrix transform = matrix;
-    transform.postConcat(*d.fMatrix);
-    this->internalDrawImage(
-            transform, d.fClipStack, std::move(imageSubset), paint);
+    transform.postConcat(this->ctm());
+    this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
 }
 
-void SkPDFDevice::drawSprite(const SkDraw& d,
-                             const SkBitmap& bitmap,
+void SkPDFDevice::drawSprite(const SkBitmap& bitmap,
                              int x,
                              int y,
                              const SkPaint& srcPaint) {
-    if (bitmap.drawsNothing() || d.fClipStack->isEmpty(this->getGlobalBounds())) {
+    if (bitmap.drawsNothing() || this->cs().isEmpty(size(*this))) {
         return;
     }
     SkPaint paint = srcPaint;
@@ -896,12 +922,10 @@ void SkPDFDevice::drawSprite(const SkDraw& d,
         return;
     }
     SkMatrix transform = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
-    this->internalDrawImage(
-            transform, d.fClipStack, std::move(imageSubset), paint);
+    this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
 }
 
-void SkPDFDevice::drawImage(const SkDraw& draw,
-                            const SkImage* image,
+void SkPDFDevice::drawImage(const SkImage* image,
                             SkScalar x,
                             SkScalar y,
                             const SkPaint& srcPaint) {
@@ -917,9 +941,8 @@ void SkPDFDevice::drawImage(const SkDraw& draw,
         return;
     }
     SkMatrix transform = SkMatrix::MakeTrans(x, y);
-    transform.postConcat(*draw.fMatrix);
-    this->internalDrawImage(
-            transform, draw.fClipStack, std::move(imageSubset), paint);
+    transform.postConcat(this->ctm());
+    this->internalDrawImage(transform, this->cs(), std::move(imageSubset), paint);
 }
 
 namespace {
@@ -1213,7 +1236,7 @@ static void update_font(SkWStream* wStream, int fontIndex, SkScalar textSize) {
 }
 
 void SkPDFDevice::internalDrawText(
-        const SkDraw& d, const void* sourceText, size_t sourceByteCount,
+        const void* sourceText, size_t sourceByteCount,
         const SkScalar pos[], SkTextBlob::GlyphPositioning positioning,
         SkPoint offset, const SkPaint& srcPaint, const uint32_t* clusters,
         uint32_t textByteLength, const char* utf8Text) {
@@ -1297,7 +1320,7 @@ void SkPDFDevice::internalDrawText(
         }
         offset.offset(alignmentFactor * advance, 0);
     }
-    ScopedContentEntry content(this, d, paint, true);
+    ScopedContentEntry content(this, paint, true);
     if (!content.entry()) {
         return;
     }
@@ -1396,20 +1419,20 @@ void SkPDFDevice::internalDrawText(
     }
 }
 
-void SkPDFDevice::drawText(const SkDraw& d, const void* text, size_t len,
+void SkPDFDevice::drawText(const void* text, size_t len,
                            SkScalar x, SkScalar y, const SkPaint& paint) {
-    this->internalDrawText(d, text, len, nullptr, SkTextBlob::kDefault_Positioning,
+    this->internalDrawText(text, len, nullptr, SkTextBlob::kDefault_Positioning,
                            SkPoint{x, y}, paint, nullptr, 0, nullptr);
 }
 
-void SkPDFDevice::drawPosText(const SkDraw& d, const void* text, size_t len,
+void SkPDFDevice::drawPosText(const void* text, size_t len,
                               const SkScalar pos[], int scalarsPerPos,
                               const SkPoint& offset, const SkPaint& paint) {
-    this->internalDrawText(d, text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
+    this->internalDrawText(text, len, pos, (SkTextBlob::GlyphPositioning)scalarsPerPos,
                            offset, paint, nullptr, 0, nullptr);
 }
 
-void SkPDFDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkScalar x, SkScalar y,
+void SkPDFDevice::drawTextBlob(const SkTextBlob* blob, SkScalar x, SkScalar y,
                                const SkPaint &paint, SkDrawFilter* drawFilter) {
     for (SkTextBlobRunIterator it(blob); !it.done(); it.next()) {
         SkPaint runPaint(paint);
@@ -1419,25 +1442,24 @@ void SkPDFDevice::drawTextBlob(const SkDraw& draw, const SkTextBlob* blob, SkSca
         }
         runPaint.setFlags(this->filterTextFlags(runPaint));
         SkPoint offset = it.offset() + SkPoint{x, y};
-        this->internalDrawText(draw, it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
+        this->internalDrawText(it.glyphs(), sizeof(SkGlyphID) * it.glyphCount(),
                                it.pos(), it.positioning(), offset, runPaint,
                                it.clusters(), it.textSize(), it.text());
     }
 }
 
-void SkPDFDevice::drawVertices(const SkDraw& d, SkCanvas::VertexMode,
+void SkPDFDevice::drawVertices(SkCanvas::VertexMode,
                                int vertexCount, const SkPoint verts[],
                                const SkPoint texs[], const SkColor colors[],
                                SkBlendMode, const uint16_t indices[],
                                int indexCount, const SkPaint& paint) {
-    if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+    if (this->cs().isEmpty(size(*this))) {
         return;
     }
     // TODO: implement drawVertices
 }
 
-void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
-                             int x, int y, const SkPaint& paint) {
+void SkPDFDevice::drawDevice(SkBaseDevice* device, int x, int y, const SkPaint& paint) {
     SkASSERT(!paint.getImageFilter());
 
     // Check if the source device is really a bitmapdevice (because that's what we returned
@@ -1446,7 +1468,7 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
     if (device->peekPixels(&pmap)) {
         SkBitmap bitmap;
         bitmap.installPixels(pmap);
-        this->drawSprite(d, bitmap, x, y, paint);
+        this->drawSprite(bitmap, x, y, paint);
         return;
     }
 
@@ -1472,9 +1494,8 @@ void SkPDFDevice::drawDevice(const SkDraw& d, SkBaseDevice* device,
         return;
     }
 
-    SkMatrix matrix;
-    matrix.setTranslate(SkIntToScalar(x), SkIntToScalar(y));
-    ScopedContentEntry content(this, d.fClipStack, matrix, paint);
+    SkMatrix matrix = SkMatrix::MakeTrans(SkIntToScalar(x), SkIntToScalar(y));
+    ScopedContentEntry content(this, this->cs(), matrix, paint);
     if (!content.entry()) {
         return;
     }
@@ -1530,11 +1551,8 @@ std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const {
 
     GraphicStackState gsState(fExistingClipStack, &buffer);
     for (const auto& entry : fContentEntries) {
-        SkPoint translation;
-        translation.iset(this->getOrigin());
-        translation.negate();
         gsState.updateClip(entry.fState.fClipStack,
-                           translation, SkRect::Make(this->getGlobalBounds()));
+                {0, 0}, SkRect::Make(size(*this)));
         gsState.updateMatrix(entry.fState.fMatrix);
         gsState.updateDrawingState(entry.fState);
 
@@ -1555,14 +1573,14 @@ std::unique_ptr<SkStreamAsset> SkPDFDevice::content() const {
  * either as a (incorrect) fallback or because the path was not inverse
  * in the first place.
  */
-bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
+bool SkPDFDevice::handleInversePath(const SkPath& origPath,
                                     const SkPaint& paint, bool pathIsMutable,
                                     const SkMatrix* prePathMatrix) {
     if (!origPath.isInverseFillType()) {
         return false;
     }
 
-    if (d.fClipStack->isEmpty(this->getGlobalBounds())) {
+    if (this->cs().isEmpty(size(*this))) {
         return false;
     }
 
@@ -1582,7 +1600,7 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
             // To be consistent with the raster output, hairline strokes
             // are rendered as non-inverted.
             modifiedPath.toggleInverseFillType();
-            drawPath(d, modifiedPath, paint, nullptr, true);
+            this->drawPath(modifiedPath, paint, nullptr, true);
             return true;
         }
     }
@@ -1590,16 +1608,14 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
     // Get bounds of clip in current transform space
     // (clip bounds are given in device space).
     SkMatrix transformInverse;
-    SkMatrix totalMatrix = *d.fMatrix;
+    SkMatrix totalMatrix = this->ctm();
     if (prePathMatrix) {
         totalMatrix.preConcat(*prePathMatrix);
     }
     if (!totalMatrix.invert(&transformInverse)) {
         return false;
     }
-    SkRect bounds = d.fClipStack->bounds(this->getGlobalBounds());
-    SkIPoint deviceOrigin = this->getOrigin();
-    bounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
+    SkRect bounds = this->cs().bounds(size(*this));
     transformInverse.mapRect(&bounds);
 
     // Extend the bounds by the line width (plus some padding)
@@ -1611,48 +1627,10 @@ bool SkPDFDevice::handleInversePath(const SkDraw& d, const SkPath& origPath,
         return false;
     }
 
-    drawPath(d, modifiedPath, noInversePaint, prePathMatrix, true);
+    this->drawPath(modifiedPath, noInversePaint, prePathMatrix, true);
     return true;
 }
 
-void SkPDFDevice::handlePointAnnotation(const SkPoint& point,
-                                        const SkMatrix& matrix,
-                                        const char key[], SkData* value) {
-    SkASSERT(value);
-    if (!strcmp(SkAnnotationKeys::Define_Named_Dest_Key(), key)) {
-        SkPoint transformedPoint;
-        matrix.mapXY(point.x(), point.y(), &transformedPoint);
-        fNamedDestinations.emplace_back(value, transformedPoint);
-    }
-}
-
-void SkPDFDevice::handleRectAnnotation(const SkRect& rect,
-                                       const SkDraw& d,
-                                       const char key[], SkData* value) {
-    SkASSERT(value);
-    // Convert to path to handle non-90-degree rotations.
-    SkPath path;
-    path.addRect(rect);
-    path.transform(*d.fMatrix, &path);
-    SkPath clip;
-    (void)d.fClipStack->asPath(&clip);
-    SkIPoint deviceOrigin = this->getOrigin();
-    clip.offset(-deviceOrigin.x(), -deviceOrigin.y());
-    // Offset here to make clip and path share coordinates.
-    // We remove the offset in SkPDFDevice::drawDevice().
-    Op(clip, path, kIntersect_SkPathOp, &path);
-    // PDF wants a rectangle only.
-    SkRect transformedRect = path.getBounds();
-
-    if (!transformedRect.isEmpty()) {
-        if (!strcmp(SkAnnotationKeys::URL_Key(), key)) {
-            fLinkToURLs.emplace_back(transformedRect, value);
-        } else if (!strcmp(SkAnnotationKeys::Link_Named_Dest_Key(), key)) {
-            fLinkToDestinations.emplace_back(transformedRect, value);
-        }
-    }
-}
-
 void SkPDFDevice::appendAnnotations(SkPDFArray* array) const {
     array->reserve(fLinkToURLs.count() + fLinkToDestinations.count());
     for (const RectWithData& rectWithURL : fLinkToURLs) {
@@ -1704,10 +1682,10 @@ sk_sp<SkPDFObject> SkPDFDevice::makeFormXObjectFromDevice() {
 
 void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
                                           sk_sp<SkPDFObject> mask,
-                                          const SkClipStack* clipStack,
+                                          const SkClipStack& clipStack,
                                           SkBlendMode mode,
                                           bool invertClip) {
-    if (!invertClip && clipStack->isEmpty(this->getGlobalBounds())) {
+    if (!invertClip && clipStack.isEmpty(size(*this))) {
         return;
     }
 
@@ -1715,11 +1693,9 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
             std::move(mask), invertClip,
             SkPDFGraphicState::kAlpha_SMaskMode, fDocument->canon());
 
-    SkMatrix identity;
-    identity.reset();
     SkPaint paint;
     paint.setBlendMode(mode);
-    ScopedContentEntry content(this, clipStack, identity, paint);
+    ScopedContentEntry content(this, clipStack, SkMatrix::I(), paint);
     if (!content.entry()) {
         return;
     }
@@ -1735,13 +1711,12 @@ void SkPDFDevice::drawFormXObjectWithMask(int xObjectIndex,
                                   &content.entry()->fContent);
 }
 
-SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* clipStack,
+SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack& clipStack,
                                                           const SkMatrix& matrix,
                                                           const SkPaint& paint,
                                                           bool hasText,
                                                           sk_sp<SkPDFObject>* dst) {
     *dst = nullptr;
-    SkASSERT(clipStack);
     SkBlendMode blendMode = paint.getBlendMode();
 
     // For the following modes, we want to handle source and destination
@@ -1781,7 +1756,7 @@ SkPDFDevice::ContentEntry* SkPDFDevice::setUpContentEntry(const SkClipStack* cli
     } else {
         entry = fContentEntries.emplace_front();
     }
-    populateGraphicStateEntryFromPaint(matrix, *clipStack, paint, hasText, &entry->fState);
+    populateGraphicStateEntryFromPaint(matrix, clipStack, paint, hasText, &entry->fState);
     return entry;
 }
 
@@ -1826,8 +1801,6 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
 
     SkClipStack clipStack = fContentEntries.front()->fState.fClipStack;
 
-    SkMatrix identity;
-    identity.reset();
     SkPaint stockPaint;
 
     sk_sp<SkPDFObject> srcFormXObject;
@@ -1839,7 +1812,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
         // reduces to Dst.
         if (shape == nullptr || blendMode == SkBlendMode::kDstOut ||
                 blendMode == SkBlendMode::kSrcATop) {
-            ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
+            ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
             // TODO: addXObjectResource take sk_sp
             SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
                                         &content.entry()->fContent);
@@ -1860,28 +1833,23 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
         // the non-transparent parts of the device and the outlines (shape) of
         // all images and devices drawn.
         drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()), dst,
-                                &fExistingClipStack, SkBlendMode::kSrcOver, true);
+                                fExistingClipStack, SkBlendMode::kSrcOver, true);
     } else {
         if (shape != nullptr) {
             // Draw shape into a form-xobject.
-            SkRasterClip rc;
-            SkDraw d;
-            d.fMatrix = &identity;
-            d.fRC = &rc;
-            d.fClipStack = &clipStack;
             SkPaint filledPaint;
             filledPaint.setColor(SK_ColorBLACK);
             filledPaint.setStyle(SkPaint::kFill_Style);
-            this->drawPath(d, *shape, filledPaint, nullptr, true);
-            drawFormXObjectWithMask(addXObjectResource(dst.get()),
-                                    this->makeFormXObjectFromDevice(),
-                                    &fExistingClipStack,
-                                    SkBlendMode::kSrcOver, true);
-
+            this->internalDrawPath(clipStack, SkMatrix::I(), *shape, filledPaint, nullptr, true);
+            this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
+                                          this->makeFormXObjectFromDevice(),
+                                          fExistingClipStack,
+                                          SkBlendMode::kSrcOver, true);
         } else {
-            drawFormXObjectWithMask(addXObjectResource(dst.get()), srcFormXObject,
-                                    &fExistingClipStack,
-                                    SkBlendMode::kSrcOver, true);
+            this->drawFormXObjectWithMask(this->addXObjectResource(dst.get()),
+                                          srcFormXObject,
+                                          fExistingClipStack,
+                                          SkBlendMode::kSrcOver, true);
         }
     }
 
@@ -1889,7 +1857,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
         return;
     } else if (blendMode == SkBlendMode::kSrc ||
             blendMode == SkBlendMode::kDstATop) {
-        ScopedContentEntry content(this, &fExistingClipStack, identity, stockPaint);
+        ScopedContentEntry content(this, fExistingClipStack, SkMatrix::I(), stockPaint);
         if (content.entry()) {
             SkPDFUtils::DrawFormXObject(
                     this->addXObjectResource(srcFormXObject.get()),
@@ -1899,8 +1867,8 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
             return;
         }
     } else if (blendMode == SkBlendMode::kSrcATop) {
-        ScopedContentEntry content(this, &fExistingClipStack,
-                                   identity, stockPaint);
+        ScopedContentEntry content(this, fExistingClipStack,
+                                   SkMatrix::I(), stockPaint);
         if (content.entry()) {
             SkPDFUtils::DrawFormXObject(this->addXObjectResource(dst.get()),
                                         &content.entry()->fContent);
@@ -1920,7 +1888,7 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
             blendMode == SkBlendMode::kSrcATop) {
         drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
                                 std::move(dst),
-                                &fExistingClipStack,
+                                fExistingClipStack,
                                 SkBlendMode::kSrcOver,
                                 blendMode == SkBlendMode::kSrcOut);
         return;
@@ -1929,12 +1897,12 @@ void SkPDFDevice::finishContentEntry(SkBlendMode blendMode,
         int resourceID = addXObjectResource(dst.get());
         if (blendMode == SkBlendMode::kModulate) {
             drawFormXObjectWithMask(addXObjectResource(srcFormXObject.get()),
-                                    std::move(dst), &fExistingClipStack,
+                                    std::move(dst), fExistingClipStack,
                                     SkBlendMode::kSrcOver, false);
             mode = SkBlendMode::kMultiply;
         }
         drawFormXObjectWithMask(resourceID, std::move(srcFormXObject),
-                                &fExistingClipStack, mode,
+                                fExistingClipStack, mode,
                                 blendMode == SkBlendMode::kDstOut);
         return;
     }
@@ -1986,9 +1954,7 @@ void SkPDFDevice::populateGraphicStateEntryFromPaint(
 
             // PDF doesn't support kClamp_TileMode, so we simulate it by making
             // a pattern the size of the current clip.
-            SkRect clipStackBounds = clipStack.bounds(this->getGlobalBounds());
-            SkIPoint deviceOrigin = this->getOrigin();
-            clipStackBounds.offset(-deviceOrigin.x(), -deviceOrigin.y());
+            SkRect clipStackBounds = clipStack.bounds(size(*this));
 
             // We need to apply the initial transform to bounds in order to get
             // bounds in a consistent coordinate system.
@@ -2095,7 +2061,7 @@ static sk_sp<SkImage> color_filter(const SkImageSubset& imageSubset,
 
 ////////////////////////////////////////////////////////////////////////////////
 void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
-                                    const SkClipStack* clipStack,
+                                    const SkClipStack& clipStack,
                                     SkImageSubset imageSubset,
                                     const SkPaint& paint) {
     if (imageSubset.dimensions().isZero()) {
@@ -2237,8 +2203,8 @@ void SkPDFDevice::internalDrawImage(const SkMatrix& origMatrix,
 #include "SkSpecialImage.h"
 #include "SkImageFilter.h"
 
-void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x, int y,
-                                 const SkPaint& paint) {
+void SkPDFDevice::drawSpecial(SkSpecialImage* srcImg, int x, int y,
+                              const SkPaint& paint) {
     SkASSERT(!srcImg->isTextureBacked());
 
     SkBitmap resultBM;
@@ -2246,10 +2212,10 @@ void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x,
     SkImageFilter* filter = paint.getImageFilter();
     if (filter) {
         SkIPoint offset = SkIPoint::Make(0, 0);
-        SkMatrix matrix = *draw.fMatrix;
+        SkMatrix matrix = this->ctm();
         matrix.postTranslate(SkIntToScalar(-x), SkIntToScalar(-y));
         const SkIRect clipBounds =
-            draw.fClipStack->bounds(this->imageInfo().bounds()).roundOut().makeOffset(-x, -y);
+            this->cs().bounds(this->imageInfo().bounds()).roundOut().makeOffset(-x, -y);
         sk_sp<SkImageFilterCache> cache(this->getImageFilterCache());
         // TODO: Should PDF be operating in a specified color space? For now, run the filter
         // in the same color space as the source (this is different from all other backends).
@@ -2261,12 +2227,12 @@ void SkPDFDevice::drawSpecial(const SkDraw& draw, SkSpecialImage* srcImg, int x,
             SkPaint tmpUnfiltered(paint);
             tmpUnfiltered.setImageFilter(nullptr);
             if (resultImg->getROPixels(&resultBM)) {
-                this->drawSprite(draw, resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
+                this->drawSprite(resultBM, x + offset.x(), y + offset.y(), tmpUnfiltered);
             }
         }
     } else {
         if (srcImg->getROPixels(&resultBM)) {
-            this->drawSprite(draw, resultBM, x, y, paint);
+            this->drawSprite(resultBM, x, y, paint);
         }
     }
 }
index 428e4ad0fc738a45550b8d9f1461280bd6ae52dd..176b8ed1b2de8a79fddb71b9b765cd5a4eb62236 100644 (file)
@@ -79,46 +79,44 @@ public:
      and are handling any looping from the paint, and any effects from the
      DrawFilter.
      */
-    void drawPaint(const SkDraw&, const SkPaint& paint) override;
-    void drawPoints(const SkDraw&, SkCanvas::PointMode mode,
+    void drawPaint(const SkPaint& paint) override;
+    void drawPoints(SkCanvas::PointMode mode,
                     size_t count, const SkPoint[],
                     const SkPaint& paint) override;
-    void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
-    void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
-    void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
-    void drawPath(const SkDraw&, const SkPath& origpath,
+    void drawRect(const SkRect& r, const SkPaint& paint) override;
+    void drawOval(const SkRect& oval, const SkPaint& paint) override;
+    void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
+    void drawPath(const SkPath& origpath,
                   const SkPaint& paint, const SkMatrix* prePathMatrix,
                   bool pathIsMutable) override;
-    void drawBitmapRect(const SkDraw& draw, const SkBitmap& bitmap, const SkRect* src,
+    void drawBitmapRect(const SkBitmap& bitmap, const SkRect* src,
                         const SkRect& dst, const SkPaint&, SkCanvas::SrcRectConstraint) override;
-    void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+    void drawBitmap(const SkBitmap& bitmap,
                     const SkMatrix& matrix, const SkPaint&) override;
-    void drawSprite(const SkDraw&, const SkBitmap& bitmap, int x, int y,
+    void drawSprite(const SkBitmap& bitmap, int x, int y,
                     const SkPaint& paint) override;
-    void drawImage(const SkDraw&,
-                   const SkImage*,
+    void drawImage(const SkImage*,
                    SkScalar x,
                    SkScalar y,
                    const SkPaint&) override;
-    void drawImageRect(const SkDraw&,
-                       const SkImage*,
+    void drawImageRect(const SkImage*,
                        const SkRect* src,
                        const SkRect& dst,
                        const SkPaint&,
                        SkCanvas::SrcRectConstraint) override;
-    void drawText(const SkDraw&, const void* text, size_t len,
+    void drawText(const void* text, size_t len,
                   SkScalar x, SkScalar y, const SkPaint&) override;
-    void drawPosText(const SkDraw&, const void* text, size_t len,
+    void drawPosText(const void* text, size_t len,
                      const SkScalar pos[], int scalarsPerPos,
                      const SkPoint& offset, const SkPaint&) override;
-    void drawTextBlob(const SkDraw&, const SkTextBlob*, SkScalar x, SkScalar y,
+    void drawTextBlob(const SkTextBlob*, SkScalar x, SkScalar y,
                       const SkPaint &, SkDrawFilter*) override;
-    void drawVertices(const SkDraw&, SkCanvas::VertexMode,
+    void drawVertices(SkCanvas::VertexMode,
                       int vertexCount, const SkPoint verts[],
                       const SkPoint texs[], const SkColor colors[],
                       SkBlendMode, const uint16_t indices[],
                       int indexCount, const SkPaint& paint) override;
-    void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+    void drawDevice(SkBaseDevice*, int x, int y,
                     const SkPaint&) override;
 
     // PDF specific methods.
@@ -174,9 +172,9 @@ public:
 protected:
     sk_sp<SkSurface> makeSurface(const SkImageInfo&, const SkSurfaceProps&) override;
 
-    void drawAnnotation(const SkDraw&, const SkRect&, const char key[], SkData* value) override;
+    void drawAnnotation(const SkRect&, const char key[], SkData* value) override;
 
-    void drawSpecial(const SkDraw&, SkSpecialImage*, int x, int y, const SkPaint&) override;
+    void drawSpecial(SkSpecialImage*, int x, int y, const SkPaint&) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkBitmap&) override;
     sk_sp<SkSpecialImage> makeSpecial(const SkImage*) override;
     sk_sp<SkSpecialImage> snapSpecial() override;
@@ -242,7 +240,7 @@ private:
 
     void drawFormXObjectWithMask(int xObjectIndex,
                                  sk_sp<SkPDFObject> mask,
-                                 const SkClipStack* clipStack,
+                                 const SkClipStack& clipStack,
                                  SkBlendMode,
                                  bool invertClip);
 
@@ -250,7 +248,7 @@ private:
     // returns nullptr and does not create a content entry.
     // setUpContentEntry and finishContentEntry can be used directly, but
     // the preferred method is to use the ScopedContentEntry helper class.
-    ContentEntry* setUpContentEntry(const SkClipStack* clipStack,
+    ContentEntry* setUpContentEntry(const SkClipStack& clipStack,
                                     const SkMatrix& matrix,
                                     const SkPaint& paint,
                                     bool hasText,
@@ -269,22 +267,27 @@ private:
     int getFontResourceIndex(SkTypeface* typeface, uint16_t glyphID);
 
 
-    void internalDrawText(const SkDraw&, const void*, size_t, const SkScalar pos[],
+    void internalDrawText( const void*, size_t, const SkScalar pos[],
                           SkTextBlob::GlyphPositioning, SkPoint, const SkPaint&,
                           const uint32_t*, uint32_t, const char*);
 
     void internalDrawPaint(const SkPaint& paint, ContentEntry* contentEntry);
 
     void internalDrawImage(const SkMatrix& origMatrix,
-                           const SkClipStack* clipStack,
+                           const SkClipStack& clipStack,
                            SkImageSubset imageSubset,
                            const SkPaint& paint);
 
-    bool handleInversePath(const SkDraw& d, const SkPath& origPath,
+    void internalDrawPath(const SkClipStack&,
+                          const SkMatrix&,
+                          const SkPath&,
+                          const SkPaint&,
+                          const SkMatrix* prePathMatrix,
+                          bool pathIsMutable);
+
+    bool handleInversePath(const SkPath& origPath,
                            const SkPaint& paint, bool pathIsMutable,
                            const SkMatrix* prePathMatrix = nullptr);
-    void handlePointAnnotation(const SkPoint&, const SkMatrix&, const char key[], SkData* value);
-    void handleRectAnnotation(const SkRect&, const SkDraw& d, const char key[], SkData* value);
 
     typedef SkClipStackDevice INHERITED;
 
index 360bb07d4463e6a0def31768ed871406ae8fe390..7ce616436c97c3b9d685b6e04ed70b82b7610163 100644 (file)
@@ -278,14 +278,9 @@ struct SkSVGDevice::MxCp {
     const SkMatrix* fMatrix;
     const SkClipStack*  fClipStack;
 
-    MxCp(SkSVGDevice* device, const SkDraw& draw) {
-#ifdef SK_USE_DEVICE_CLIPPING
+    MxCp(SkSVGDevice* device) {
         fMatrix = &device->ctm();
         fClipStack = &device->cs();
-#else
-        fMatrix = draw.fMatrix;
-        fClipStack = draw.fClipStack;
-#endif
     }
 };
 
@@ -607,13 +602,13 @@ SkSVGDevice::SkSVGDevice(const SkISize& size, SkXMLWriter* writer)
 SkSVGDevice::~SkSVGDevice() {
 }
 
-void SkSVGDevice::drawPaint(const SkDraw& draw, const SkPaint& paint) {
-    AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+void SkSVGDevice::drawPaint(const SkPaint& paint) {
+    AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this), paint);
     rect.addRectAttributes(SkRect::MakeWH(SkIntToScalar(this->width()),
                                           SkIntToScalar(this->height())));
 }
 
-void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_t count,
+void SkSVGDevice::drawPoints(SkCanvas::PointMode mode, size_t count,
                              const SkPoint pts[], const SkPaint& paint) {
     SkPath path;
 
@@ -628,7 +623,7 @@ void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_
                 path.rewind();
                 path.moveTo(pts[i]);
                 path.lineTo(pts[i+1]);
-                AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+                AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
                 elem.addPathAttributes(path);
             }
             break;
@@ -636,37 +631,37 @@ void SkSVGDevice::drawPoints(const SkDraw& draw, SkCanvas::PointMode mode, size_
             if (count > 1) {
                 path.addPoly(pts, SkToInt(count), false);
                 path.moveTo(pts[0]);
-                AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+                AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
                 elem.addPathAttributes(path);
             }
             break;
     }
 }
 
-void SkSVGDevice::drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) {
-    AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+void SkSVGDevice::drawRect(const SkRect& r, const SkPaint& paint) {
+    AutoElement rect("rect", fWriter, fResourceBucket.get(), MxCp(this), paint);
     rect.addRectAttributes(r);
 }
 
-void SkSVGDevice::drawOval(const SkDraw& draw, const SkRect& oval, const SkPaint& paint) {
-    AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+void SkSVGDevice::drawOval(const SkRect& oval, const SkPaint& paint) {
+    AutoElement ellipse("ellipse", fWriter, fResourceBucket.get(), MxCp(this), paint);
     ellipse.addAttribute("cx", oval.centerX());
     ellipse.addAttribute("cy", oval.centerY());
     ellipse.addAttribute("rx", oval.width() / 2);
     ellipse.addAttribute("ry", oval.height() / 2);
 }
 
-void SkSVGDevice::drawRRect(const SkDraw& draw, const SkRRect& rr, const SkPaint& paint) {
+void SkSVGDevice::drawRRect(const SkRRect& rr, const SkPaint& paint) {
     SkPath path;
     path.addRRect(rr);
 
-    AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+    AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
     elem.addPathAttributes(path);
 }
 
-void SkSVGDevice::drawPath(const SkDraw& draw, const SkPath& path, const SkPaint& paint,
+void SkSVGDevice::drawPath(const SkPath& path, const SkPaint& paint,
                            const SkMatrix* prePathMatrix, bool pathIsMutable) {
-    AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+    AutoElement elem("path", fWriter, fResourceBucket.get(), MxCp(this), paint);
     elem.addPathAttributes(path);
 
     // TODO: inverse fill types?
@@ -711,9 +706,9 @@ void SkSVGDevice::drawBitmapCommon(const MxCp& mc, const SkBitmap& bm, const SkP
     }
 }
 
-void SkSVGDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
+void SkSVGDevice::drawBitmap(const SkBitmap& bitmap,
                              const SkMatrix& matrix, const SkPaint& paint) {
-    MxCp mc(this, draw);
+    MxCp mc(this);
     SkMatrix adjustedMatrix = *mc.fMatrix;
     adjustedMatrix.preConcat(matrix);
     mc.fMatrix = &adjustedMatrix;
@@ -721,9 +716,9 @@ void SkSVGDevice::drawBitmap(const SkDraw& draw, const SkBitmap& bitmap,
     drawBitmapCommon(mc, bitmap, paint);
 }
 
-void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
+void SkSVGDevice::drawSprite(const SkBitmap& bitmap,
                              int x, int y, const SkPaint& paint) {
-    MxCp mc(this, draw);
+    MxCp mc(this);
     SkMatrix adjustedMatrix = *mc.fMatrix;
     adjustedMatrix.preTranslate(SkIntToScalar(x), SkIntToScalar(y));
     mc.fMatrix = &adjustedMatrix;
@@ -731,10 +726,10 @@ void SkSVGDevice::drawSprite(const SkDraw& draw, const SkBitmap& bitmap,
     drawBitmapCommon(mc, bitmap, paint);
 }
 
-void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const SkRect* srcOrNull,
+void SkSVGDevice::drawBitmapRect(const SkBitmap& bm, const SkRect* srcOrNull,
                                  const SkRect& dst, const SkPaint& paint,
                                  SkCanvas::SrcRectConstraint) {
-    MxCp mc(this, draw);
+    MxCp mc(this);
 
     SkClipStack adjustedClipStack;
     if (srcOrNull && *srcOrNull != SkRect::Make(bm.bounds())) {
@@ -754,9 +749,9 @@ void SkSVGDevice::drawBitmapRect(const SkDraw& draw, const SkBitmap& bm, const S
     drawBitmapCommon(mc, bm, paint);
 }
 
-void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
+void SkSVGDevice::drawText(const void* text, size_t len,
                            SkScalar x, SkScalar y, const SkPaint& paint) {
-    AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+    AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this), paint);
     elem.addTextAttributes(paint);
 
     SVGTextBuilder builder(text, len, paint, SkPoint::Make(x, y), 0);
@@ -765,12 +760,12 @@ void SkSVGDevice::drawText(const SkDraw& draw, const void* text, size_t len,
     elem.addText(builder.text());
 }
 
-void SkSVGDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
+void SkSVGDevice::drawPosText(const void* text, size_t len,
                               const SkScalar pos[], int scalarsPerPos, const SkPoint& offset,
                               const SkPaint& paint) {
     SkASSERT(scalarsPerPos == 1 || scalarsPerPos == 2);
 
-    AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this, draw), paint);
+    AutoElement elem("text", fWriter, fResourceBucket.get(), MxCp(this), paint);
     elem.addTextAttributes(paint);
 
     SVGTextBuilder builder(text, len, paint, offset, scalarsPerPos, pos);
@@ -779,7 +774,7 @@ void SkSVGDevice::drawPosText(const SkDraw& draw, const void* text, size_t len,
     elem.addText(builder.text());
 }
 
-void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, const SkPath& path,
+void SkSVGDevice::drawTextOnPath(const void* text, size_t len, const SkPath& path,
                                  const SkMatrix* matrix, const SkPaint& paint) {
     SkString pathID = fResourceBucket->addPath();
 
@@ -816,7 +811,7 @@ void SkSVGDevice::drawTextOnPath(const SkDraw&, const void* text, size_t len, co
     }
 }
 
-void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+void SkSVGDevice::drawVertices(SkCanvas::VertexMode, int vertexCount,
                                const SkPoint verts[], const SkPoint texs[],
                                const SkColor colors[], SkBlendMode,
                                const uint16_t indices[], int indexCount,
@@ -825,7 +820,7 @@ void SkSVGDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCo
     SkDebugf("unsupported operation: drawVertices()\n");
 }
 
-void SkSVGDevice::drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+void SkSVGDevice::drawDevice(SkBaseDevice*, int x, int y,
                              const SkPaint&) {
     // todo
     SkDebugf("unsupported operation: drawDevice()\n");
index 106537e4ed18e0395aaee13b8c5436d8a84e1280..78f4cea8344774598b72a31f9ab5097b0f1f2bb6 100644 (file)
@@ -18,40 +18,40 @@ public:
     static SkBaseDevice* Create(const SkISize& size, SkXMLWriter* writer);
 
 protected:
-    void drawPaint(const SkDraw&, const SkPaint& paint) override;
-    void drawPoints(const SkDraw&, SkCanvas::PointMode mode, size_t count,
+    void drawPaint(const SkPaint& paint) override;
+    void drawPoints(SkCanvas::PointMode mode, size_t count,
                     const SkPoint[], const SkPaint& paint) override;
-    void drawRect(const SkDraw&, const SkRect& r, const SkPaint& paint) override;
-    void drawOval(const SkDraw&, const SkRect& oval, const SkPaint& paint) override;
-    void drawRRect(const SkDraw&, const SkRRect& rr, const SkPaint& paint) override;
-    void drawPath(const SkDraw&, const SkPath& path,
+    void drawRect(const SkRect& r, const SkPaint& paint) override;
+    void drawOval(const SkRect& oval, const SkPaint& paint) override;
+    void drawRRect(const SkRRect& rr, const SkPaint& paint) override;
+    void drawPath(const SkPath& path,
                   const SkPaint& paint,
                   const SkMatrix* prePathMatrix = nullptr,
                   bool pathIsMutable = false) override;
 
-    void drawBitmap(const SkDraw&, const SkBitmap& bitmap,
+    void drawBitmap(const SkBitmap& bitmap,
                     const SkMatrix& matrix, const SkPaint& paint) override;
-    void drawSprite(const SkDraw&, const SkBitmap& bitmap,
+    void drawSprite(const SkBitmap& bitmap,
                     int x, int y, const SkPaint& paint) override;
-    void drawBitmapRect(const SkDraw&, const SkBitmap&,
+    void drawBitmapRect(const SkBitmap&,
                         const SkRect* srcOrNull, const SkRect& dst,
                         const SkPaint& paint, SkCanvas::SrcRectConstraint) override;
 
-    void drawText(const SkDraw&, const void* text, size_t len,
+    void drawText(const void* text, size_t len,
                   SkScalar x, SkScalar y, const SkPaint& paint) override;
-    void drawPosText(const SkDraw&, const void* text, size_t len,
+    void drawPosText(const void* text, size_t len,
                      const SkScalar pos[], int scalarsPerPos,
                      const SkPoint& offset, const SkPaint& paint) override;
-    void drawTextOnPath(const SkDraw&, const void* text, size_t len,
+    void drawTextOnPath(const void* text, size_t len,
                         const SkPath& path, const SkMatrix* matrix,
                         const SkPaint& paint) override;
-    void drawVertices(const SkDraw&, SkCanvas::VertexMode, int vertexCount,
+    void drawVertices(SkCanvas::VertexMode, int vertexCount,
                       const SkPoint verts[], const SkPoint texs[],
                       const SkColor colors[], SkBlendMode,
                       const uint16_t indices[], int indexCount,
                       const SkPaint& paint) override;
 
-    void drawDevice(const SkDraw&, SkBaseDevice*, int x, int y,
+    void drawDevice(SkBaseDevice*, int x, int y,
                     const SkPaint&) override;
 
 private:
index a78f3435a429190cdd816fa761bea8e8bf4753bd..0c50bad0f6e5b1c2dfd07ad44f2c8016ea2102ca 100644 (file)
@@ -130,28 +130,6 @@ private:
 
 ////////////////////////////////////////////////////////////////////////////////
 
-class ClipValidator : public SkCanvas::ClipVisitor {
-public:
-    ClipValidator() : fFailed(false) {}
-    bool failed() { return fFailed; }
-
-    // ClipVisitor
-    void clipRect(const SkRect& rect, SkClipOp op, bool antialias) override {
-        fFailed |= antialias;
-    }
-
-    void clipRRect(const SkRRect& rrect, SkClipOp op, bool antialias) override {
-        fFailed |= antialias;
-    }
-
-    void clipPath(const SkPath&, SkClipOp, bool antialias) override {
-        fFailed |= antialias;
-    }
-
-private:
-    bool fFailed;
-};
-
 static void setup_MC_state(SkMCState* state, const SkMatrix& matrix, const SkRegion& clip) {
     // initialize the struct
     state->clipRectCount = 0;
@@ -193,9 +171,7 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) {
     SkASSERT(canvas);
 
     // Check the clip can be decomposed into rectangles (i.e. no soft clips).
-    ClipValidator validator;
-    canvas->replayClips(&validator);
-    if (validator.failed()) {
+    if (canvas->androidFramework_isClipAA()) {
         return nullptr;
     }
 
@@ -246,7 +222,9 @@ SkCanvasState* SkCanvasStateUtils::CaptureCanvasState(SkCanvas* canvas) {
         layerState->raster.rowBytes = pmap.rowBytes();
         layerState->raster.pixels = pmap.writable_addr();
 
-        setup_MC_state(&layerState->mcState, layer.matrix(), layer.clip().bwRgn());
+        SkRegion rgn;
+        layer.clip(&rgn);
+        setup_MC_state(&layerState->mcState, layer.matrix(), rgn);
         layerCount++;
     }
 
index bf93302d516ac7d0710dfd9c576b74be8b12eea0..514c9332baab997bbd6a78d438359b7f91d79e6b 100644 (file)
@@ -1139,23 +1139,34 @@ HRESULT SkXPSDevice::createXpsQuad(const SkPoint (&points)[4],
     return S_OK;
 }
 
-void SkXPSDevice::drawPoints(const SkDraw& d, SkCanvas::PointMode mode,
+template <typename F, typename... Args>
+void draw(SkClipStackDevice* dev, F f, Args&&... args) {
+    SkIRect r = dev->devClipBounds();
+    SkRasterClip rc(r);
+    SkDraw draw;
+    draw.fMatrix = &dev->ctm();
+    draw.fDst = SkPixmap(SkImageInfo::MakeUnknown(r.right(), r.bottom()), nullptr, 0);
+    draw.fRC = &rc;
+    (draw.*f)(std::forward<Args>(args)...);
+}
+
+
+void SkXPSDevice::drawPoints(SkCanvas::PointMode mode,
                              size_t count, const SkPoint points[],
                              const SkPaint& paint) {
-    //This will call back into the device to do the drawing.
-    d.drawPoints(mode, count, points, paint, this);
+    draw(this, &SkDraw::drawPoints, mode, count, points, paint, this);
 }
 
-void SkXPSDevice::drawVertices(const SkDraw&, SkCanvas::VertexMode,
+void SkXPSDevice::drawVertices(SkCanvas::VertexMode vertexMode,
                                int vertexCount, const SkPoint verts[],
                                const SkPoint texs[], const SkColor colors[],
-                               SkBlendMode, const uint16_t indices[],
+                               SkBlendMode blendMode, const uint16_t indices[],
                                int indexCount, const SkPaint& paint) {
-    //TODO: override this for XPS
-    SkDEBUGF(("XPS drawVertices not yet implemented."));
+    draw(this, &SkDraw::drawVertices, vertexMode, vertexCount, verts, texs, colors,
+         blendMode, indices, indexCount, paint);
 }
 
-void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& origPaint) {
+void SkXPSDevice::drawPaint(const SkPaint& origPaint) {
     const SkRect r = SkRect::MakeSize(this->fCurrentCanvasSize);
 
     //If trying to paint with a stroke, ignore that and fill.
@@ -1165,39 +1176,38 @@ void SkXPSDevice::drawPaint(const SkDraw& d, const SkPaint& origPaint) {
         paint.writable()->setStyle(SkPaint::kFill_Style);
     }
 
-    this->internalDrawRect(d, r, false, *fillPaint);
+    this->internalDrawRect(r, false, *fillPaint);
 }
 
-void SkXPSDevice::drawRect(const SkDraw& d,
-                           const SkRect& r,
+void SkXPSDevice::drawRect(const SkRect& r,
                            const SkPaint& paint) {
-    this->internalDrawRect(d, r, true, paint);
+    this->internalDrawRect(r, true, paint);
 }
 
-void SkXPSDevice::drawRRect(const SkDraw& d,
-                            const SkRRect& rr,
+void SkXPSDevice::drawRRect(const SkRRect& rr,
                             const SkPaint& paint) {
     SkPath path;
     path.addRRect(rr);
-    this->drawPath(d, path, paint, nullptr, true);
+    this->drawPath(path, paint, nullptr, true);
 }
 
-void SkXPSDevice::internalDrawRect(const SkDraw& d,
-                                   const SkRect& r,
+static SkIRect size(const SkBaseDevice& dev) { return {0, 0, dev.width(), dev.height()}; }
+
+void SkXPSDevice::internalDrawRect(const SkRect& r,
                                    bool transformRect,
                                    const SkPaint& paint) {
     //Exit early if there is nothing to draw.
-    if (d.fRC->isEmpty() ||
+    if (this->cs().isEmpty(size(*this)) ||
         (paint.getAlpha() == 0 && paint.isSrcOver())) {
         return;
     }
 
     //Path the rect if we can't optimize it.
-    if (rect_must_be_pathed(paint, *d.fMatrix)) {
+    if (rect_must_be_pathed(paint, this->ctm())) {
         SkPath tmp;
         tmp.addRect(r);
         tmp.setFillType(SkPath::kWinding_FillType);
-        this->drawPath(d, tmp, paint, nullptr, true);
+        this->drawPath(tmp, paint, nullptr, true);
         return;
     }
 
@@ -1218,13 +1228,13 @@ void SkXPSDevice::internalDrawRect(const SkDraw& d,
     //Set the brushes.
     BOOL fill = FALSE;
     BOOL stroke = FALSE;
-    HRV(this->shadePath(shadedPath.get(), paint, *d.fMatrix, &fill, &stroke));
+    HRV(this->shadePath(shadedPath.get(), paint, this->ctm(), &fill, &stroke));
 
     bool xpsTransformsPath = true;
     //Transform the geometry.
     if (transformRect && xpsTransformsPath) {
         SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
-        HRV(this->createXpsTransform(*d.fMatrix, &xpsTransform));
+        HRV(this->createXpsTransform(this->ctm(), &xpsTransform));
         if (xpsTransform.get()) {
             HRVM(shadedGeometry->SetTransformLocal(xpsTransform.get()),
                  "Could not set transform for rect.");
@@ -1243,7 +1253,7 @@ void SkXPSDevice::internalDrawRect(const SkDraw& d,
             { r.fRight, r.fTop },
         };
         if (!xpsTransformsPath && transformRect) {
-            d.fMatrix->mapPoints(points, SK_ARRAY_COUNT(points));
+            this->ctm().mapPoints(points, SK_ARRAY_COUNT(points));
         }
         HRV(this->createXpsQuad(points, stroke, fill, &rectFigure));
     }
@@ -1257,7 +1267,7 @@ void SkXPSDevice::internalDrawRect(const SkDraw& d,
     HRVM(shadedFigures->Append(rectFigure.get()),
          "Could not add shaded figure for rect.");
 
-    HRV(this->clip(shadedPath.get(), d));
+    HRV(this->clip(shadedPath.get()));
 
     //Add the shaded path to the current visuals.
     SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
@@ -1394,8 +1404,7 @@ void SkXPSDevice::convertToPpm(const SkMaskFilter* filter,
     clipRect.roundOut(clipIRect);
 }
 
-HRESULT SkXPSDevice::applyMask(const SkDraw& d,
-                               const SkMask& mask,
+HRESULT SkXPSDevice::applyMask(const SkMask& mask,
                                const SkVector& ppuScale,
                                IXpsOMPath* shadedPath) {
     //Get the geometry object.
@@ -1434,7 +1443,7 @@ HRESULT SkXPSDevice::applyMask(const SkDraw& d,
     HRM(shadedFigures->Append(shadedFigure.get()),
         "Could not add mask shaded figure.");
 
-    HR(this->clip(shadedPath, d));
+    HR(this->clip(shadedPath));
 
     //Add the path to the active visual collection.
     SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
@@ -1494,15 +1503,14 @@ HRESULT SkXPSDevice::shadePath(IXpsOMPath* shadedPath,
     return S_OK;
 }
 
-void SkXPSDevice::drawPath(const SkDraw& d,
-                           const SkPath& platonicPath,
+void SkXPSDevice::drawPath(const SkPath& platonicPath,
                            const SkPaint& origPaint,
                            const SkMatrix* prePathMatrix,
                            bool pathIsMutable) {
     SkTCopyOnFirstWrite<SkPaint> paint(origPaint);
 
     // nothing to draw
-    if (d.fRC->isEmpty() ||
+    if (this->cs().isEmpty(size(*this)) ||
         (paint->getAlpha() == 0 && paint->isSrcOver())) {
         return;
     }
@@ -1512,7 +1520,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
                                  || paint->getStyle() != SkPaint::kFill_Style;
 
     //Apply pre-path matrix [Platonic-path -> Skeletal-path].
-    SkMatrix matrix = *d.fMatrix;
+    SkMatrix matrix = this->ctm();
     SkPath* skeletalPath = const_cast<SkPath*>(&platonicPath);
     if (prePathMatrix) {
         if (paintHasPathEffect || paint->getRasterizer()) {
@@ -1574,7 +1582,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
     BOOL stroke;
     HRV(this->shadePath(shadedPath.get(),
                         *paint,
-                        *d.fMatrix,
+                        this->ctm(),
                         &fill,
                         &stroke));
 
@@ -1585,7 +1593,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
         this->convertToPpm(filter,
                            &matrix,
                            &ppuScale,
-                           d.fRC->getBounds(),
+                           this->cs().bounds(size(*this)).roundOut(),
                            &clipIRect);
 
         SkMask* mask = nullptr;
@@ -1605,13 +1613,13 @@ void SkXPSDevice::drawPath(const SkDraw& d,
 
             //[Mask -> Mask]
             SkMask filteredMask;
-            if (filter && filter->filterMask(&filteredMask, *mask, *d.fMatrix, nullptr)) {
+            if (filter && filter->filterMask(&filteredMask, *mask, this->ctm(), nullptr)) {
                 mask = &filteredMask;
             }
             SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
 
             //Draw mask.
-            HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
+            HRV(this->applyMask(*mask, ppuScale, shadedPath.get()));
         }
         return;
     }
@@ -1623,7 +1631,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
         this->convertToPpm(filter,
                            &matrix,
                            &ppuScale,
-                           d.fRC->getBounds(),
+                           this->cs().bounds(size(*this)).roundOut(),
                            &clipIRect);
 
         //[Fillable-path -> Pixel-path]
@@ -1659,7 +1667,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
             SkAutoMaskFreeImage filteredAmi(filteredMask.fImage);
 
             //Draw mask.
-            HRV(this->applyMask(d, *mask, ppuScale, shadedPath.get()));
+            HRV(this->applyMask(*mask, ppuScale, shadedPath.get()));
         }
         return;
     }
@@ -1734,7 +1742,7 @@ void SkXPSDevice::drawPath(const SkDraw& d,
     HRV(this->addXpsPathGeometry(shadedFigures.get(),
                                  stroke, fill, *devicePath));
 
-    HRV(this->clip(shadedPath.get(), d));
+    HRV(this->clip(shadedPath.get()));
 
     //Add the path to the active visual collection.
     SkTScopedComPtr<IXpsOMVisualCollection> currentVisuals;
@@ -1744,16 +1752,10 @@ void SkXPSDevice::drawPath(const SkDraw& d,
          "Could not add shaded path to current visuals.");
 }
 
-HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual, const SkDraw& d) {
+HRESULT SkXPSDevice::clip(IXpsOMVisual* xpsVisual) {
     SkPath clipPath;
-    if (d.fRC->isBW()) {
-        SkAssertResult(d.fRC->bwRgn().getBoundaryPath(&clipPath));
-    } else {
-        // Don't have a way to turn a AAClip into a path, so we just use the bounds.
-        // TODO: consider using fClipStack instead?
-        clipPath.addRect(SkRect::Make(d.fRC->getBounds()));
-    }
-
+    // clipPath.addRect(this->cs().bounds(size(*this)));
+    (void)this->cs().asPath(&clipPath);
     return this->clipToPath(xpsVisual, clipPath, XPS_FILL_RULE_EVENODD);
 }
 HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual,
@@ -1782,9 +1784,9 @@ HRESULT SkXPSDevice::clipToPath(IXpsOMVisual* xpsVisual,
     return S_OK;
 }
 
-void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
+void SkXPSDevice::drawBitmap(const SkBitmap& bitmap,
                              const SkMatrix& matrix, const SkPaint& paint) {
-    if (d.fRC->isEmpty()) {
+    if (this->cs().isEmpty(size(*this))) {
         return;
     }
 
@@ -1811,7 +1813,7 @@ void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
          "Could not get the figures for bitmap.");
 
     SkMatrix transform = matrix;
-    transform.postConcat(*d.fMatrix);
+    transform.postConcat(this->ctm());
 
     SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
     HRV(this->createXpsTransform(transform, &xpsTransform));
@@ -1851,12 +1853,10 @@ void SkXPSDevice::drawBitmap(const SkDraw& d, const SkBitmap& bitmap,
     HRVM(currentVisuals->Append(shadedPath.get()),
          "Could not add bitmap to current visuals.");
 
-    HRV(this->clip(shadedPath.get(), d));
+    HRV(this->clip(shadedPath.get()));
 }
 
-void SkXPSDevice::drawSprite(const SkDraw&, const SkBitmap& bitmap,
-                             int x, int y,
-                             const SkPaint& paint) {
+void SkXPSDevice::drawSprite(const SkBitmap& bitmap, int x, int y, const SkPaint& paint) {
     //TODO: override this for XPS
     SkDEBUGF(("XPS drawSprite not yet implemented."));
 }
@@ -1929,8 +1929,7 @@ HRESULT SkXPSDevice::CreateTypefaceUse(const SkPaint& paint,
     return S_OK;
 }
 
-HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
-                               IXpsOMObjectFactory* xpsFactory,
+HRESULT SkXPSDevice::AddGlyphs(IXpsOMObjectFactory* xpsFactory,
                                IXpsOMCanvas* canvas,
                                TypefaceUse* font,
                                LPCWSTR text,
@@ -2001,7 +2000,7 @@ HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
     HRM(canvas->GetVisuals(&visuals), "Could not get glyph canvas visuals.");
 
     if (!useCanvasForClip) {
-        HR(this->clip(glyphs.get(), d));
+        HR(this->clip(glyphs.get()));
         HRM(visuals->Append(glyphs.get()), "Could not add glyphs to canvas.");
     } else {
         SkTScopedComPtr<IXpsOMCanvas> glyphCanvas;
@@ -2014,7 +2013,7 @@ HRESULT SkXPSDevice::AddGlyphs(const SkDraw& d,
 
         HRM(glyphCanvasVisuals->Append(glyphs.get()),
             "Could not add glyphs to page.");
-        HR(this->clip(glyphCanvas.get(), d));
+        HR(this->clip(glyphCanvas.get()));
 
         HRM(visuals->Append(glyphCanvas.get()),
             "Could not add glyph canvas to page.");
@@ -2091,16 +2090,15 @@ private:
     GlyphRun* const fXpsGlyphs;
 };
 
-void SkXPSDevice::drawText(const SkDraw& d,
-                           const void* text, size_t byteLen,
+void SkXPSDevice::drawText(const void* text, size_t byteLen,
                            SkScalar x, SkScalar y,
                            const SkPaint& paint) {
     if (byteLen < 1) return;
 
-    if (text_must_be_pathed(paint, *d.fMatrix)) {
+    if (text_must_be_pathed(paint, this->ctm())) {
         SkPath path;
         paint.getTextPath(text, byteLen, x, y, &path);
-        this->drawPath(d, path, paint, nullptr, true);
+        this->drawPath(path, paint, nullptr, true);
         //TODO: add automation "text"
         return;
     }
@@ -2137,8 +2135,7 @@ void SkXPSDevice::drawText(const SkDraw& d,
     xpsGlyphs[0].horizontalOffset = 0.0f;
     xpsGlyphs[0].verticalOffset = 0.0f;
 
-    HRV(AddGlyphs(d,
-                  this->fXpsFactory.get(),
+    HRV(AddGlyphs(this->fXpsFactory.get(),
                   this->fCurrentXpsCanvas.get(),
                   typeface,
                   nullptr,
@@ -2146,21 +2143,20 @@ void SkXPSDevice::drawText(const SkDraw& d,
                   &origin,
                   SkScalarToFLOAT(paint.getTextSize()),
                   XPS_STYLE_SIMULATION_NONE,
-                  *d.fMatrix,
+                  this->ctm(),
                   paint));
 }
 
-void SkXPSDevice::drawPosText(const SkDraw& d,
-                              const void* text, size_t byteLen,
+void SkXPSDevice::drawPosText(const void* text, size_t byteLen,
                               const SkScalar pos[], int scalarsPerPos,
                               const SkPoint& offset, const SkPaint& paint) {
     if (byteLen < 1) return;
 
-    if (text_must_be_pathed(paint, *d.fMatrix)) {
+    if (text_must_be_pathed(paint, this->ctm())) {
         SkPath path;
         //TODO: make this work, Draw currently does not handle as well.
         //paint.getTextPath(text, byteLength, x, y, &path);
-        //this->drawPath(d, path, paint, nullptr, true);
+        //this->drawPath(path, paint, nullptr, true);
         //TODO: add automation "text"
         return;
     }
@@ -2197,8 +2193,7 @@ void SkXPSDevice::drawPosText(const SkDraw& d,
     xpsGlyphs[0].horizontalOffset = 0.0f;
     xpsGlyphs[0].verticalOffset = 0.0f;
 
-    HRV(AddGlyphs(d,
-                  this->fXpsFactory.get(),
+    HRV(AddGlyphs(this->fXpsFactory.get(),
                   this->fCurrentXpsCanvas.get(),
                   typeface,
                   nullptr,
@@ -2206,24 +2201,18 @@ void SkXPSDevice::drawPosText(const SkDraw& d,
                   &origin,
                   SkScalarToFLOAT(paint.getTextSize()),
                   XPS_STYLE_SIMULATION_NONE,
-                  *d.fMatrix,
+                  this->ctm(),
                   paint));
 }
 
-void SkXPSDevice::drawDevice(const SkDraw& d, SkBaseDevice* dev,
+void SkXPSDevice::drawDevice( SkBaseDevice* dev,
                              int x, int y,
                              const SkPaint&) {
     SkXPSDevice* that = static_cast<SkXPSDevice*>(dev);
 
     SkTScopedComPtr<IXpsOMMatrixTransform> xpsTransform;
-    XPS_MATRIX rawTransform = {
-        1.0f,
-        0.0f,
-        0.0f,
-        1.0f,
-        static_cast<FLOAT>(x),
-        static_cast<FLOAT>(y),
-    };
+    // TODO(halcanary): assert that current transform is identity rather than calling setter.
+    XPS_MATRIX rawTransform = {1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f};
     HRVM(this->fXpsFactory->CreateMatrixTransform(&rawTransform, &xpsTransform),
          "Could not create layer transform.");
     HRVM(that->fCurrentXpsCanvas->SetTransformLocal(xpsTransform.get()),
@@ -2256,18 +2245,17 @@ SkBaseDevice* SkXPSDevice::onCreateDevice(const CreateInfo& info, const SkPaint*
     return dev;
 }
 
-void SkXPSDevice::drawOval(const SkDraw& d, const SkRect& o, const SkPaint& p) {
+void SkXPSDevice::drawOval( const SkRect& o, const SkPaint& p) {
     SkPath path;
     path.addOval(o);
-    this->drawPath(d, path, p, nullptr, true);
+    this->drawPath(path, p, nullptr, true);
 }
 
-void SkXPSDevice::drawBitmapRect(const SkDraw& draw,
-                                  const SkBitmap& bitmap,
-                                  const SkRect* src,
-                                  const SkRect& dst,
-                                  const SkPaint& paint,
-                                  SkCanvas::SrcRectConstraint constraint) {
+void SkXPSDevice::drawBitmapRect(const SkBitmap& bitmap,
+                                 const SkRect* src,
+                                 const SkRect& dst,
+                                 const SkPaint& paint,
+                                 SkCanvas::SrcRectConstraint constraint) {
     SkRect srcBounds = src ? *src : SkRect::Make(bitmap.bounds());
     SkMatrix matrix = SkMatrix::MakeRectToRect(srcBounds, dst, SkMatrix::kFill_ScaleToFit);
 
@@ -2279,6 +2267,6 @@ void SkXPSDevice::drawBitmapRect(const SkDraw& draw,
     SkPaint paintWithShader(paint);
     paintWithShader.setStyle(SkPaint::kFill_Style);
     paintWithShader.setShader(std::move(bitmapShader));
-    this->drawRect(draw, dst, paintWithShader);
+    this->drawRect(dst, paintWithShader);
 }
 #endif//defined(SK_BUILD_FOR_WIN32)
index 0ad993950902288136430ccd66937ad30eb2ea22..a03b2932cacede43bd53aa3fc4a01ddbc3d1d3b8 100644 (file)
 #include <XpsObjectModel.h>
 
 #include "SkAutoCoInitialize.h"
-#include "SkBitmapDevice.h"
 #include "SkBitSet.h"
+#include "SkBitmapDevice.h"
 #include "SkCanvas.h"
+#include "SkClipStackDevice.h"
 #include "SkColor.h"
 #include "SkPaint.h"
 #include "SkPath.h"
@@ -35,7 +36,7 @@
 
     The drawing context for the XPS backend.
 */
-class SkXPSDevice : public SkBaseDevice {
+class SkXPSDevice : public SkClipStackDevice {
 public:
     SK_API SkXPSDevice(SkISize);
     SK_API virtual ~SkXPSDevice();
@@ -73,79 +74,39 @@ public:
     bool endPortfolio();
 
 protected:
-    void drawPaint(const SkDraw&, const SkPaint& paint) override;
-
-    void drawPoints(
-        const SkDraw&,
-        SkCanvas::PointMode mode,
-        size_t count, const SkPoint[],
-        const SkPaint& paint) override;
-
-    void drawRect(
-        const SkDraw&,
-        const SkRect& r,
-        const SkPaint& paint) override;
-
-    void drawRRect(
-        const SkDraw&,
-        const SkRRect&,
-        const SkPaint& paint) override;
-
-    void drawPath(
-        const SkDraw&,
-        const SkPath& platonicPath,
-        const SkPaint& paint,
-        const SkMatrix* prePathMatrix,
-        bool pathIsMutable) override;
-
-    void drawBitmap(
-        const SkDraw&,
-        const SkBitmap& bitmap,
-        const SkMatrix& matrix,
-        const SkPaint& paint) override;
-
-    void drawSprite(
-        const SkDraw&,
-        const SkBitmap& bitmap,
-        int x, int y,
-        const SkPaint& paint) override;
-
-    void drawText(
-        const SkDraw&,
-        const void* text, size_t len,
-        SkScalar x, SkScalar y,
-        const SkPaint& paint) override;
-
-    void drawPosText(
-        const SkDraw&,
-        const void* text, size_t len,
-        const SkScalar pos[], int scalarsPerPos,
-        const SkPoint& offset, const SkPaint& paint) override;
-
-    void drawVertices(
-        const SkDraw&,
-        SkCanvas::VertexMode,
-        int vertexCount, const SkPoint verts[],
-        const SkPoint texs[], const SkColor colors[],
-        SkBlendMode,
-        const uint16_t indices[], int indexCount,
-        const SkPaint& paint) override;
-
-    void drawDevice(
-        const SkDraw&,
-        SkBaseDevice* device,
-        int x, int y,
-        const SkPaint& paint) override;
-
-    void drawOval(const SkDraw&, const SkRect&, const SkPaint&) override;
-
-    void drawBitmapRect(const SkDraw&,
-                        const SkBitmap&,
-                        const SkRect*,
-                        const SkRect&,
-                        const SkPaint&,
+    void drawPaint(const SkPaint& paint) override;
+    void drawPoints(SkCanvas::PointMode mode, size_t count,
+                    const SkPoint[], const SkPaint& paint) override;
+    void drawRect(const SkRect& r,
+                  const SkPaint& paint) override;
+    void drawOval(const SkRect& oval,
+                  const SkPaint& paint) override;
+    void drawRRect(const SkRRect& rr,
+                   const SkPaint& paint) override;
+    void drawPath(const SkPath& path,
+                  const SkPaint& paint,
+                  const SkMatrix* prePathMatrix = NULL,
+                  bool pathIsMutable = false) override;
+    void drawBitmap(const SkBitmap& bitmap,
+                    const SkMatrix& matrix, const SkPaint& paint) override;
+    void drawSprite(const SkBitmap& bitmap,
+                    int x, int y, const SkPaint& paint) override;
+    void drawBitmapRect(const SkBitmap&,
+                        const SkRect* srcOrNull, const SkRect& dst,
+                        const SkPaint& paint,
                         SkCanvas::SrcRectConstraint) override;
-
+    void drawText(const void* text, size_t len,
+                  SkScalar x, SkScalar y, const SkPaint& paint) override;
+    void drawPosText(const void* text, size_t len,
+                     const SkScalar pos[], int scalarsPerPos,
+                     const SkPoint& offset, const SkPaint& paint) override;
+    void drawVertices(SkCanvas::VertexMode, int vertexCount,
+                      const SkPoint verts[], const SkPoint texs[],
+                      const SkColor colors[], SkBlendMode,
+                      const uint16_t indices[], int indexCount,
+                      const SkPaint& paint) override;
+    void drawDevice(SkBaseDevice*, int x, int y,
+                    const SkPaint&) override;
 
 private:
     class TypefaceUse : ::SkNoncopyable {
@@ -198,7 +159,6 @@ private:
         IXpsOMImageResource** image);
 
     void internalDrawRect(
-        const SkDraw&,
         const SkRect& r,
         bool transformRect,
         const SkPaint& paint);
@@ -257,7 +217,6 @@ private:
         TypefaceUse** fontResource);
 
     HRESULT AddGlyphs(
-        const SkDraw& d,
         IXpsOMObjectFactory* xpsFactory,
         IXpsOMCanvas* canvas,
         TypefaceUse* font,
@@ -289,16 +248,14 @@ private:
         const SkColor color,
         IXpsOMVisualCollection* visuals);
 
-    HRESULT clip(
-        IXpsOMVisual* xpsVisual,
-        const SkDraw& d);
+    HRESULT clip(IXpsOMVisual* xpsVisual);
+
     HRESULT clipToPath(
         IXpsOMVisual* xpsVisual,
         const SkPath& clipPath,
         XPS_FILL_RULE fillRule);
 
     HRESULT drawInverseWindingPath(
-        const SkDraw& d,
         const SkPath& devicePath,
         IXpsOMPath* xpsPath);
 
@@ -315,7 +272,6 @@ private:
         const SkIRect& clip, SkIRect* clipIRect);
 
     HRESULT applyMask(
-        const SkDraw& d,
         const SkMask& mask,
         const SkVector& ppuScale,
         IXpsOMPath* shadedPath);
@@ -326,7 +282,7 @@ private:
     SkXPSDevice(const SkXPSDevice&);
     void operator=(const SkXPSDevice&);
 
-    typedef SkBaseDevice INHERITED;
+    typedef SkClipStackDevice INHERITED;
 };
 
 #endif  // SK_BUILD_FOR_WIN
index 2910341be8c8f50ad5c723bcfdfcff0fba882ca9..f3705b77be2bb71878471519921bf7f3c3eac17c 100644 (file)
@@ -30,9 +30,9 @@ public:
     FakeDevice() : INHERITED(make_bm(100, 100), SkSurfaceProps(0, kUnknown_SkPixelGeometry)) {
     }
 
-    void drawRect(const SkDraw& draw, const SkRect& r, const SkPaint& paint) override {
-        fLastMatrix = *draw.fMatrix;
-        this->INHERITED::drawRect(draw, r, paint);
+    void drawRect(const SkRect& r, const SkPaint& paint) override {
+        fLastMatrix = this->ctm();
+        this->INHERITED::drawRect(r, paint);
     }
 
     SkMatrix fLastMatrix;
index c9d18eeca4ce97484543c1fce4d812ccb221b516..522f4edbeba36244fda2c0dde4ed45178ff6ee59 100644 (file)
@@ -307,7 +307,7 @@ void SkDebugCanvas::drawTo(SkCanvas* originalCanvas, int index, int m) {
     }
     if (pathOpsMode) {
         this->resetClipStackData();
-        const SkClipStack* clipStack = filterCanvas.getClipStack();
+        const SkClipStack* clipStack = nullptr;//HACK filterCanvas.getClipStack();
         SkClipStack::Iter iter(*clipStack, SkClipStack::Iter::kBottom_IterStart);
         const SkClipStack::Element* element;
         SkPath devPath;