override SkRasterPipelineBlitter::blitRect()

Now that we can natively do 2D blits, it's time to invert the blitH() /
blitRect() who-implements-whom relationship.  blitRect() is our more
fundamental blit.

Change-Id: Ia0ae4a3cd75c7bbfc7bd5b08ff429193ce09a73b
Reviewed-on: https://skia-review.googlesource.com/25361
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Mike Klein <mtklein@chromium.org>
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index da536e4..993d735 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -43,6 +43,7 @@
     void blitAntiH (int x, int y, const SkAlpha[], const int16_t[]) override;
     void blitAntiH2(int x, int y, U8CPU a0, U8CPU a1)               override;
     void blitMask  (const SkMask&, const SkIRect& clip)             override;
+    void blitRect  (int x, int y, int width, int height)            override;
 
     // TODO: The default implementations of the other blits look fine,
     // but some of them like blitV could probably benefit from custom
@@ -67,12 +68,12 @@
                        fDstPtr       = {nullptr,0},  // Always points to the top-left of fDst.
                        fMaskPtr      = {nullptr,0};  // Updated each call to blitMask().
 
-    // We may be able to specialize blitH() into a memset.
-    bool     fCanMemsetInBlitH = false;
+    // We may be able to specialize blitH() or blitRect() into a memset.
+    bool     fCanMemsetInBlitRect = false;
     uint64_t fMemsetColor      = 0;     // Big enough for largest dst format, F16.
 
     // Built lazily on first use.
-    std::function<void(size_t, size_t, size_t, size_t)> fBlitH,
+    std::function<void(size_t, size_t, size_t, size_t)> fBlitRect,
                                                         fBlitAntiH,
                                                         fBlitMaskA8,
                                                         fBlitMaskLCD16;
@@ -218,7 +219,7 @@
         blitter->append_store(&p);
         p.run(0,0,1,1);
 
-        blitter->fCanMemsetInBlitH = true;
+        blitter->fCanMemsetInBlitRect = true;
     }
 
     blitter->fDstPtr = SkJumper_MemoryCtx{
@@ -292,17 +293,24 @@
 }
 
 void SkRasterPipelineBlitter::blitH(int x, int y, int w) {
-    if (fCanMemsetInBlitH) {
-        switch (fDst.shiftPerPixel()) {
-            case 0:    memset  (fDst.writable_addr8 (x,y), fMemsetColor, w); return;
-            case 1: sk_memset16(fDst.writable_addr16(x,y), fMemsetColor, w); return;
-            case 2: sk_memset32(fDst.writable_addr32(x,y), fMemsetColor, w); return;
-            case 3: sk_memset64(fDst.writable_addr64(x,y), fMemsetColor, w); return;
-            default: break;
+    this->blitRect(x,y,w,1);
+}
+
+void SkRasterPipelineBlitter::blitRect(int x, int y, int w, int h) {
+    if (fCanMemsetInBlitRect) {
+        for (int ylimit = y+h; y < ylimit; y++) {
+            switch (fDst.shiftPerPixel()) {
+                case 0:    memset  (fDst.writable_addr8 (x,y), fMemsetColor, w); break;
+                case 1: sk_memset16(fDst.writable_addr16(x,y), fMemsetColor, w); break;
+                case 2: sk_memset32(fDst.writable_addr32(x,y), fMemsetColor, w); break;
+                case 3: sk_memset64(fDst.writable_addr64(x,y), fMemsetColor, w); break;
+                default: break;
+            }
         }
+        return;
     }
 
-    if (!fBlitH) {
+    if (!fBlitRect) {
         SkRasterPipeline p(fAlloc);
         p.extend(fColorPipeline);
         if (fBlend == SkBlendMode::kSrcOver
@@ -319,12 +327,19 @@
             }
             this->append_store(&p);
         }
-        fBlitH = p.compile();
+        fBlitRect = p.compile();
     }
+
     if (fBurstCtx) {
-        this->burst_shade(x,y,w);
+        // We can only burst shade one row at a time.
+        for (int ylimit = y+h; y < ylimit; y++) {
+            this->burst_shade(x,y,w);
+            fBlitRect(x,y, w,1);
+        }
+    } else {
+        // If not bursting we can blit the entire rect at once.
+        fBlitRect(x,y,w,h);
     }
-    fBlitH(x,y,w,1);
 }
 
 void SkRasterPipelineBlitter::blitAntiH(int x, int y, const SkAlpha aa[], const int16_t runs[]) {