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
This commit is contained in:
reed@google.com 2011-08-29 19:02:39 +00:00
parent 574f29dfa7
commit 45482d1d2b
4 changed files with 49 additions and 17 deletions

View File

@ -70,8 +70,6 @@ public:
}
}
virtual bool validForPicture() const { return false; }
protected:
static const int kRows = 5;
@ -79,11 +77,14 @@ protected:
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));

View File

@ -511,8 +511,7 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
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

View File

@ -128,14 +128,47 @@ void SkPictureRecord::setMatrix(const SkMatrix& matrix) {
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 @@ bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op) {
addPath(path);
addInt(op);
size_t offset = fWriter.size();
addInt(fRestoreOffsetStack.top());
fRestoreOffsetStack.top() = offset;
this->recordOffsetForRestore(op);
validate();
@ -164,9 +195,7 @@ bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
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);

View File

@ -182,6 +182,9 @@ private:
uint32_t fRecordFlags;
// helper function to handle save/restore culling offsets
void recordOffsetForRestore(SkRegion::Op op);
friend class SkPicturePlayback;
typedef SkCanvas INHERITED;