Start tracking the CTM while filling the BBH in SkRecordDraw.

Depends on https://codereview.chromium.org/475473002/

BUG=skia:
R=robertphillips@google.com, reed@google.com, mtklein@google.com

Author: mtklein@chromium.org

Review URL: https://codereview.chromium.org/468193003
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index 240dc9c..7e2609b 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -895,6 +895,7 @@
     if (fMCStack.count() > 1) {
         this->willRestore();
         this->internalRestore();
+        this->didRestore();
     }
 }
 
@@ -2260,7 +2261,7 @@
     if (NULL == cubics) {
         return;
     }
-    
+
     // Since a patch is always within the convex hull of the control points, we discard it when its
     // bounding rectangle is completely outside the current clip.
     SkRect bounds;
@@ -2268,7 +2269,7 @@
     if (this->quickReject(bounds)) {
         return;
     }
-    
+
     this->onDrawPatch(cubics, colors, texCoords, xmode, paint);
 }
 
@@ -2276,11 +2277,11 @@
                            const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint) {
 
     LOOPER_BEGIN(paint, SkDrawFilter::kPath_Type, NULL)
-    
+
     while (iter.next()) {
         iter.fDevice->drawPatch(iter, cubics, colors, texCoords, xmode, paint);
     }
-    
+
     LOOPER_END
 }
 
@@ -2550,7 +2551,7 @@
     } else if (NULL != matrix) {
         canvas->save();
     }
-    
+
     if (NULL != matrix) {
         canvas->concat(*matrix);
     }
diff --git a/src/core/SkRecordDraw.cpp b/src/core/SkRecordDraw.cpp
index 688d0b6..c9e029b 100644
--- a/src/core/SkRecordDraw.cpp
+++ b/src/core/SkRecordDraw.cpp
@@ -117,6 +117,7 @@
     FillBounds(const SkRecord& record, SkBBoxHierarchy* bbh) : fBounds(record.count()) {
         // Calculate bounds for all ops.  This won't go quite in order, so we'll need
         // to store the bounds separately then feed them in to the BBH later in order.
+        fCTM.setIdentity();
         for (fCurrentOp = 0; fCurrentOp < record.count(); fCurrentOp++) {
             record.visit<void>(fCurrentOp, *this);
         }
@@ -143,6 +144,7 @@
     }
 
     template <typename T> void operator()(const T& r) {
+        this->updateCTM(r);
         this->trackBounds(r);
     }
 
@@ -152,6 +154,11 @@
         SkIRect bounds;  // Bounds of everything in the block.
     };
 
+    template <typename T> void updateCTM(const T&) { /* most ops don't change the CTM */ }
+    void updateCTM(const Restore& r)   { fCTM = r.matrix; }
+    void updateCTM(const SetMatrix& r) { fCTM = r.matrix; }
+    void updateCTM(const Concat& r)    { fCTM.preConcat(r.matrix); }
+
     // The bounds of these ops must be calculated when we hit the Restore
     // from the bounds of the ops in the same Save block.
     void trackBounds(const Save&)       { this->pushSaveBlock(); }
@@ -219,6 +226,7 @@
     SkIRect bounds(const NoOp&) { return SkIRect::MakeEmpty(); }  // NoOps don't draw anywhere.
 
     SkAutoTMalloc<SkIRect> fBounds;  // One for each op in the record.
+    SkMatrix fCTM;
     unsigned fCurrentOp;
     SkTDArray<SaveBounds> fSaveStack;
     SkTDArray<unsigned>   fControlIndices;
diff --git a/src/core/SkRecorder.cpp b/src/core/SkRecorder.cpp
index 327a97a..53522c2 100644
--- a/src/core/SkRecorder.cpp
+++ b/src/core/SkRecorder.cpp
@@ -229,9 +229,9 @@
     return SkCanvas::kNoLayer_SaveLayerStrategy;
 }
 
-void SkRecorder::willRestore() {
-    APPEND(Restore);
-    INHERITED(willRestore);
+void SkRecorder::didRestore() {
+    APPEND(Restore, this->getTotalMatrix());
+    INHERITED(didRestore);
 }
 
 void SkRecorder::onPushCull(const SkRect& rect) {
@@ -248,6 +248,7 @@
 }
 
 void SkRecorder::didSetMatrix(const SkMatrix& matrix) {
+    SkASSERT(matrix == this->getTotalMatrix());
     APPEND(SetMatrix, matrix);
     INHERITED(didSetMatrix, matrix);
 }
diff --git a/src/core/SkRecorder.h b/src/core/SkRecorder.h
index 2c7234a..97eeb9f 100644
--- a/src/core/SkRecorder.h
+++ b/src/core/SkRecorder.h
@@ -64,7 +64,7 @@
 
     void willSave() SK_OVERRIDE;
     SaveLayerStrategy willSaveLayer(const SkRect*, const SkPaint*, SkCanvas::SaveFlags) SK_OVERRIDE;
-    void willRestore() SK_OVERRIDE;
+    void didRestore() SK_OVERRIDE;
 
     void didConcat(const SkMatrix&) SK_OVERRIDE;
     void didSetMatrix(const SkMatrix&) SK_OVERRIDE;
@@ -92,7 +92,7 @@
     void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                      const SkPoint texCoords[4], SkXfermode* xmode,
                      const SkPaint& paint) SK_OVERRIDE;
-    
+
     void onClipRect(const SkRect& rect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
     void onClipRRect(const SkRRect& rrect, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
     void onClipPath(const SkPath& path, SkRegion::Op op, ClipEdgeStyle edgeStyle) SK_OVERRIDE;
diff --git a/src/core/SkRecords.h b/src/core/SkRecords.h
index 1efdf28..3d5b190 100644
--- a/src/core/SkRecords.h
+++ b/src/core/SkRecords.h
@@ -197,7 +197,7 @@
 
 RECORD0(NoOp);
 
-RECORD0(Restore);
+RECORD1(Restore, SkMatrix, matrix);
 RECORD0(Save);
 RECORD3(SaveLayer, Optional<SkRect>, bounds, Optional<SkPaint>, paint, SkCanvas::SaveFlags, flags);
 
@@ -291,10 +291,10 @@
     PODArray<uint16_t> indices;
     int indexCount;
 };
-    
+
 struct DrawPatch {
     static const Type kType = DrawPatch_Type;
-    
+
     DrawPatch(const SkPaint& paint, SkPoint cubics[12], SkColor colors[4],
               SkPoint texCoords[4], SkXfermode* xmode)
     : paint(paint)
@@ -302,7 +302,7 @@
     , colors(colors)
     , texCoords(texCoords)
     , xmode(SkSafeRef(xmode)) { }
-    
+
     SkPaint paint;
     PODArray<SkPoint> cubics;
     PODArray<SkColor> colors;