aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core
diff options
context:
space:
mode:
Diffstat (limited to 'src/core')
-rw-r--r--src/core/SkCanvas.cpp54
-rw-r--r--src/core/SkPictureRecord.cpp17
2 files changed, 54 insertions, 17 deletions
diff --git a/src/core/SkCanvas.cpp b/src/core/SkCanvas.cpp
index cd2065bd30..787d89d184 100644
--- a/src/core/SkCanvas.cpp
+++ b/src/core/SkCanvas.cpp
@@ -1162,6 +1162,60 @@ void SkCanvas::onPopCull() {
}
/////////////////////////////////////////////////////////////////////////////
+#ifdef SK_DEBUG
+// Ensure that cull rects are monotonically nested in device space.
+void SkCanvas::validateCull(const SkIRect& devCull) {
+ if (fCullStack.isEmpty()
+ || devCull.isEmpty()
+ || fCullStack.top().contains(devCull)) {
+ return;
+ }
+
+ SkDEBUGF(("Invalid cull: [%d %d %d %d] (previous cull: [%d %d %d %d])\n",
+ devCull.x(), devCull.y(), devCull.right(), devCull.bottom(),
+ fCullStack.top().x(), fCullStack.top().y(),
+ fCullStack.top().right(), fCullStack.top().bottom()));
+
+#ifdef ASSERT_NESTED_CULLING
+ SkDEBUGFAIL("Invalid cull.");
+#endif
+}
+#endif
+
+void SkCanvas::pushCull(const SkRect& cullRect) {
+ ++fCullCount;
+ this->onPushCull(cullRect);
+
+#ifdef SK_DEBUG
+ // Map the cull rect into device space.
+ SkRect mappedCull;
+ this->getTotalMatrix().mapRect(&mappedCull, cullRect);
+
+ // Take clipping into account.
+ SkIRect devClip, devCull;
+ mappedCull.roundOut(&devCull);
+ this->getClipDeviceBounds(&devClip);
+ if (!devCull.intersect(devClip)) {
+ devCull.setEmpty();
+ }
+
+ this->validateCull(devCull);
+ fCullStack.push(devCull); // balanced in popCull
+#endif
+}
+
+void SkCanvas::popCull() {
+ SkASSERT(fCullStack.count() == fCullCount);
+
+ if (fCullCount > 0) {
+ --fCullCount;
+ this->onPopCull();
+
+ SkDEBUGCODE(fCullStack.pop());
+ }
+}
+
+/////////////////////////////////////////////////////////////////////////////
void SkCanvas::internalDrawBitmap(const SkBitmap& bitmap,
const SkMatrix& matrix, const SkPaint* paint) {
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 55670baa73..ce21d955dd 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -1559,18 +1559,6 @@ void SkPictureRecord::endCommentGroup() {
// [op/size] [rect] [skip offset]
static const uint32_t kPushCullOpSize = 2 * kUInt32Size + sizeof(SkRect);
void SkPictureRecord::onPushCull(const SkRect& cullRect) {
- // Skip identical cull rects.
- if (!fCullOffsetStack.isEmpty()) {
- const SkRect& prevCull = fWriter.readTAt<SkRect>(fCullOffsetStack.top() - sizeof(SkRect));
- if (prevCull == cullRect) {
- // Skipped culls are tracked on the stack, but they point to the previous offset.
- fCullOffsetStack.push(fCullOffsetStack.top());
- return;
- }
-
- SkASSERT(prevCull.contains(cullRect));
- }
-
uint32_t size = kPushCullOpSize;
size_t initialOffset = this->addDraw(PUSH_CULL, &size);
// PUSH_CULL's size should stay constant (used to rewind).
@@ -1588,11 +1576,6 @@ void SkPictureRecord::onPopCull() {
uint32_t cullSkipOffset = fCullOffsetStack.top();
fCullOffsetStack.pop();
- // Skipped push, do the same for pop.
- if (!fCullOffsetStack.isEmpty() && cullSkipOffset == fCullOffsetStack.top()) {
- return;
- }
-
// Collapse empty push/pop pairs.
if ((size_t)(cullSkipOffset + kUInt32Size) == fWriter.bytesWritten()) {
SkASSERT(fWriter.bytesWritten() >= kPushCullOpSize);