clipShader -- raster implementation

1. pass shader+op down to device
2. bitmapdevice pass it down to rasterclip
3. rasterclip only ever stores at most one shader
   - if there is a ctm, fold that into (another) shader
   - if the op is difference, invert the sense of alpha
   - if there was a previous shader, compose with it
4. pass through to rasterpipelineblitter
5. it prepends the colorPipeline with the clipShader, and stashes its
   results in a buffer (fClipShaderBuffer)
6. in each blit, scale/lerp from the buffer before storing the result

Change-Id: I07c7a8a20b9ae95cdcc9954237d115e63819f7c1
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/275798
Commit-Queue: Mike Reed <reed@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
Reviewed-by: Florin Malita <fmalita@chromium.org>
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index e9cf7e3..17c8a27 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1649,6 +1649,20 @@
     fDeviceClipBounds = qr_clip_bounds(fMCRec->fRasterClip.getBounds());
 }
 
+void SkCanvas::clipShader(sk_sp<SkShader> sh, SkClipOp op) {
+    if (sh) {
+        this->onClipShader(std::move(sh), op);
+    }
+}
+
+void SkCanvas::onClipShader(sk_sp<SkShader> sh, SkClipOp op) {
+    AutoValidateClip avc(this);
+
+    FOR_EACH_TOP_DEVICE(device->clipShader(sh, op));
+
+    // we don't know how to mutate our conservative bounds, so we don't
+}
+
 void SkCanvas::clipRegion(const SkRegion& rgn, SkClipOp op) {
     this->checkForDeferredSave();
     this->onClipRegion(rgn, op);