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;