add virtuals in prep for device-clipping

Build flag available for backends to begin testing their impl.

Need to formalize save/restore, and how to forward these to device but not on picture canvases.

BUG=skia:6214

Change-Id: Ic5c0afba3e8c84fcf124567e63fe2f5880b623e7
Reviewed-on: https://skia-review.googlesource.com/8183
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index eb81bd7..64ef348 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -387,6 +387,16 @@
     typedef SkDraw INHERITED;
 };
 
+#define FOR_EACH_TOP_DEVICE( code )                 \
+    do {                                            \
+        DeviceCM* layer = fMCRec->fTopLayer;        \
+        while (layer) {                             \
+            SkBaseDevice* device = layer->fDevice;  \
+            code;                                   \
+            layer = layer->fNext;                   \
+        }                                           \
+    } while (0)
+
 /////////////////////////////////////////////////////////////////////////////
 
 static SkPaint* set_if_needed(SkLazyPaint* lazy, const SkPaint& orig) {
@@ -999,6 +1009,9 @@
     SkASSERT(fMCRec->fDeferredSaveCount > 0);
     fMCRec->fDeferredSaveCount -= 1;
     this->internalSave();
+#ifdef SK_USE_DEVICE_CLIPPING
+    FOR_EACH_TOP_DEVICE(device->save());
+#endif
 }
 
 void SkCanvas::restore() {
@@ -1014,6 +1027,9 @@
             fSaveCount -= 1;
             this->internalRestore();
             this->didRestore();
+#ifdef SK_USE_DEVICE_CLIPPING
+            FOR_EACH_TOP_DEVICE(device->restore(fMCRec->fMatrix));
+#endif
         }
     }
 }
@@ -1456,6 +1472,11 @@
     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);
 }
 
@@ -1505,6 +1526,11 @@
 
 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,
@@ -1542,6 +1568,11 @@
     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);
@@ -1579,7 +1610,11 @@
 
     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;
@@ -1602,6 +1637,10 @@
 }
 
 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;