Start tracking the CTM while filling the BBH in SkRecordDraw.
authormtklein <mtklein@chromium.org>
Wed, 13 Aug 2014 20:33:49 +0000 (13:33 -0700)
committerCommit bot <commit-bot@chromium.org>
Wed, 13 Aug 2014 20:33:49 +0000 (13:33 -0700)
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

include/core/SkCanvas.h
src/core/SkCanvas.cpp
src/core/SkRecordDraw.cpp
src/core/SkRecorder.cpp
src/core/SkRecorder.h
src/core/SkRecords.h

index 8afeae6..3b8f17c 100644 (file)
@@ -1020,17 +1020,17 @@ public:
                               const SkColor colors[], SkXfermode* xmode,
                               const uint16_t indices[], int indexCount,
                               const SkPaint& paint);
-    
+
     /**
      Draw a cubic coons patch
-     
+
      @param cubic specifies the 4 bounding cubic bezier curves of a patch with clockwise order
                     starting at the top left corner.
      @param colors specifies the colors for the corners which will be bilerp across the patch,
                     their order is clockwise starting at the top left corner.
-     @param texCoords specifies the texture coordinates that will be bilerp across the patch, 
+     @param texCoords specifies the texture coordinates that will be bilerp across the patch,
                     their order is the same as the colors.
-     @param xmode specifies how are the colors and the textures combined if both of them are 
+     @param xmode specifies how are the colors and the textures combined if both of them are
                     present.
      @param paint Specifies the shader/texture if present.
      */
@@ -1212,6 +1212,7 @@ protected:
         return kFullLayer_SaveLayerStrategy;
     }
     virtual void willRestore() {}
+    virtual void didRestore() {}
     virtual void didConcat(const SkMatrix&) {}
     virtual void didSetMatrix(const SkMatrix&) {}
 
@@ -1230,7 +1231,7 @@ protected:
     virtual void onDrawTextOnPath(const void* text, size_t byteLength,
                                   const SkPath& path, const SkMatrix* matrix,
                                   const SkPaint& paint);
-    
+
     virtual void onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                            const SkPoint texCoords[4], SkXfermode* xmode, const SkPaint& paint);
 
index 240dc9c..7e2609b 100644 (file)
@@ -895,6 +895,7 @@ void SkCanvas::restore() {
     if (fMCStack.count() > 1) {
         this->willRestore();
         this->internalRestore();
+        this->didRestore();
     }
 }
 
@@ -2260,7 +2261,7 @@ void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
     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 @@ void SkCanvas::drawPatch(const SkPoint cubics[12], const SkColor colors[4],
     if (this->quickReject(bounds)) {
         return;
     }
-    
+
     this->onDrawPatch(cubics, colors, texCoords, xmode, paint);
 }
 
@@ -2276,11 +2277,11 @@ void SkCanvas::onDrawPatch(const SkPoint cubics[12], const SkColor colors[4],
                            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 @@ SkAutoCanvasMatrixPaint::SkAutoCanvasMatrixPaint(SkCanvas* canvas, const SkMatri
     } else if (NULL != matrix) {
         canvas->save();
     }
-    
+
     if (NULL != matrix) {
         canvas->concat(*matrix);
     }
index 688d0b6..c9e029b 100644 (file)
@@ -117,6 +117,7 @@ public:
     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 @@ public:
     }
 
     template <typename T> void operator()(const T& r) {
+        this->updateCTM(r);
         this->trackBounds(r);
     }
 
@@ -152,6 +154,11 @@ private:
         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 @@ private:
     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;
index 327a97a..53522c2 100644 (file)
@@ -229,9 +229,9 @@ SkCanvas::SaveLayerStrategy SkRecorder::willSaveLayer(const SkRect* bounds,
     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::didConcat(const SkMatrix& matrix) {
 }
 
 void SkRecorder::didSetMatrix(const SkMatrix& matrix) {
+    SkASSERT(matrix == this->getTotalMatrix());
     APPEND(SetMatrix, matrix);
     INHERITED(didSetMatrix, matrix);
 }
index 2c7234a..97eeb9f 100644 (file)
@@ -64,7 +64,7 @@ public:
 
     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 @@ public:
     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;
index 1efdf28..3d5b190 100644 (file)
@@ -197,7 +197,7 @@ private:
 
 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 @@ struct DrawVertices {
     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 @@ struct DrawPatch {
     , colors(colors)
     , texCoords(texCoords)
     , xmode(SkSafeRef(xmode)) { }
-    
+
     SkPaint paint;
     PODArray<SkPoint> cubics;
     PODArray<SkColor> colors;