fix pictures to not skip-over clip ops that might expand the clip
git-svn-id: http://skia.googlecode.com/svn/trunk@2187 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/gm/complexclip2.cpp b/gm/complexclip2.cpp
index 1c64698..44a8935 100644
--- a/gm/complexclip2.cpp
+++ b/gm/complexclip2.cpp
@@ -70,8 +70,6 @@
}
}
- virtual bool validForPicture() const { return false; }
-
protected:
static const int kRows = 5;
@@ -79,11 +77,14 @@
static const int kPadX = 20;
static const int kPadY = 20;
- SkString onShortName() {
+ virtual SkString onShortName() {
return SkString("complexclip2");
}
- SkISize onISize() { return make_isize(fTotalWidth, fTotalHeight); }
+ virtual SkISize onISize() {
+ return make_isize(SkScalarRoundToInt(fTotalWidth),
+ SkScalarRoundToInt(fTotalHeight));
+ }
void drawBG(SkCanvas* canvas) {
canvas->drawColor(SkColorSetRGB(0xDD,0xA0,0xDD));
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index 514a76b..34d785b 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -511,8 +511,7 @@
const SkPath& path = getPath();
SkRegion::Op op = (SkRegion::Op) getInt();
size_t offsetToRestore = getInt();
- // HACK (false) until I can handle op==kReplace
- if (!canvas.clipPath(path, op)) {
+ if (!canvas.clipPath(path, op) && offsetToRestore) {
#ifdef SPEW_CLIP_SKIPPING
skipPath.recordSkip(offsetToRestore - fReader.offset());
#endif
@@ -523,7 +522,7 @@
const SkRegion& region = getRegion();
SkRegion::Op op = (SkRegion::Op) getInt();
size_t offsetToRestore = getInt();
- if (!canvas.clipRegion(region, op)) {
+ if (!canvas.clipRegion(region, op) && offsetToRestore) {
#ifdef SPEW_CLIP_SKIPPING
skipRegion.recordSkip(offsetToRestore - fReader.offset());
#endif
@@ -534,7 +533,7 @@
const SkRect* rect = fReader.skipRect();
SkRegion::Op op = (SkRegion::Op) getInt();
size_t offsetToRestore = getInt();
- if (!canvas.clipRect(*rect, op)) {
+ if (!canvas.clipRect(*rect, op) && offsetToRestore) {
#ifdef SPEW_CLIP_SKIPPING
skipRect.recordSkip(offsetToRestore - fReader.offset());
#endif
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 5d35f74..d78c13a 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -128,14 +128,47 @@
this->INHERITED::setMatrix(matrix);
}
+static bool regionOpExpands(SkRegion::Op op) {
+ switch (op) {
+ case SkRegion::kUnion_Op:
+ case SkRegion::kXOR_Op:
+ case SkRegion::kReverseDifference_Op:
+ case SkRegion::kReplace_Op:
+ return true;
+ case SkRegion::kIntersect_Op:
+ case SkRegion::kDifference_Op:
+ return false;
+ default:
+ SkASSERT(!"unknown region op");
+ return false;
+ }
+}
+
+void SkPictureRecord::recordOffsetForRestore(SkRegion::Op op) {
+ if (regionOpExpands(op)) {
+ // Run back through any previous clip ops, and mark their offset to
+ // be 0, disabling their ability to trigger a jump-to-restore, otherwise
+ // they could hide this clips ability to expand the clip (i.e. go from
+ // empty to non-empty).
+ uint32_t offset = fRestoreOffsetStack.top();
+ while (offset) {
+ uint32_t* peek = fWriter.peek32(offset);
+ offset = *peek;
+ *peek = 0;
+ }
+ }
+
+ size_t offset = fWriter.size();
+ addInt(fRestoreOffsetStack.top());
+ fRestoreOffsetStack.top() = offset;
+}
+
bool SkPictureRecord::clipRect(const SkRect& rect, SkRegion::Op op) {
addDraw(CLIP_RECT);
addRect(rect);
addInt(op);
- size_t offset = fWriter.size();
- addInt(fRestoreOffsetStack.top());
- fRestoreOffsetStack.top() = offset;
+ this->recordOffsetForRestore(op);
validate();
return this->INHERITED::clipRect(rect, op);
@@ -146,9 +179,7 @@
addPath(path);
addInt(op);
- size_t offset = fWriter.size();
- addInt(fRestoreOffsetStack.top());
- fRestoreOffsetStack.top() = offset;
+ this->recordOffsetForRestore(op);
validate();
@@ -164,9 +195,7 @@
addRegion(region);
addInt(op);
- size_t offset = fWriter.size();
- addInt(fRestoreOffsetStack.top());
- fRestoreOffsetStack.top() = offset;
+ this->recordOffsetForRestore(op);
validate();
return this->INHERITED::clipRegion(region, op);
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index 1e6cb9d..eb0d654 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -182,6 +182,9 @@
uint32_t fRecordFlags;
+ // helper function to handle save/restore culling offsets
+ void recordOffsetForRestore(SkRegion::Op op);
+
friend class SkPicturePlayback;
typedef SkCanvas INHERITED;