add picture-record option to speedup complex clips
remove hack that stopped picture-playback from culling on clipPath() result
git-svn-id: http://skia.googlecode.com/svn/trunk@92 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/core/SkPicture.cpp b/src/core/SkPicture.cpp
index 07cb0a6..343ca2b 100644
--- a/src/core/SkPicture.cpp
+++ b/src/core/SkPicture.cpp
@@ -146,7 +146,8 @@
///////////////////////////////////////////////////////////////////////////////
-SkCanvas* SkPicture::beginRecording(int width, int height) {
+SkCanvas* SkPicture::beginRecording(int width, int height,
+ uint32_t recordingFlags) {
if (fPlayback) {
SkDELETE(fPlayback);
fPlayback = NULL;
@@ -157,7 +158,7 @@
fRecord = NULL;
}
- fRecord = SkNEW(SkPictureRecord);
+ fRecord = SkNEW_ARGS(SkPictureRecord, (recordingFlags));
fWidth = width;
fHeight = height;
diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp
index da17c32..4a3338a 100644
--- a/src/core/SkPicturePlayback.cpp
+++ b/src/core/SkPicturePlayback.cpp
@@ -3,6 +3,11 @@
#include "SkTypeface.h"
#include <new>
+/* Define this to spew out a debug statement whenever we skip the remainder of
+ a save/restore block because a clip... command returned false (empty).
+ */
+#define SPEW_CLIP_SKIPPINGx
+
SkPicturePlayback::SkPicturePlayback() {
this->init();
}
@@ -461,10 +466,31 @@
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
+#ifdef SPEW_CLIP_SKIPPING
+struct SkipClipRec {
+ int fCount;
+ size_t fSize;
+
+ SkipClipRec() {
+ fCount = 0;
+ fSize = 0;
+ }
+
+ void recordSkip(size_t bytes) {
+ fCount += 1;
+ fSize += bytes;
+ }
+};
+#endif
+
void SkPicturePlayback::draw(SkCanvas& canvas) {
#ifdef ENABLE_TIME_DRAW
SkAutoTime at("SkPicture::draw", 50);
#endif
+
+#ifdef SPEW_CLIP_SKIPPING
+ SkipClipRec skipRect, skipRegion, skipPath;
+#endif
TextContainer text;
fReader.rewind();
@@ -476,8 +502,10 @@
SkRegion::Op op = (SkRegion::Op) getInt();
size_t offsetToRestore = getInt();
// HACK (false) until I can handle op==kReplace
- if (!canvas.clipPath(path, op) && false) {
- //SkDebugf("---- skip clipPath for %d bytes\n", offsetToRestore - fReader.offset());
+ if (!canvas.clipPath(path, op)) {
+#ifdef SPEW_CLIP_SKIPPING
+ skipPath.recordSkip(offsetToRestore - fReader.offset());
+#endif
fReader.setOffset(offsetToRestore);
}
} break;
@@ -486,7 +514,9 @@
SkRegion::Op op = (SkRegion::Op) getInt();
size_t offsetToRestore = getInt();
if (!canvas.clipRegion(region, op)) {
- //SkDebugf("---- skip clipDeviceRgn for %d bytes\n", offsetToRestore - fReader.offset());
+#ifdef SPEW_CLIP_SKIPPING
+ skipRegion.recordSkip(offsetToRestore - fReader.offset());
+#endif
fReader.setOffset(offsetToRestore);
}
} break;
@@ -495,7 +525,9 @@
SkRegion::Op op = (SkRegion::Op) getInt();
size_t offsetToRestore = getInt();
if (!canvas.clipRect(*rect, op)) {
- //SkDebugf("---- skip clipRect for %d bytes\n", offsetToRestore - fReader.offset());
+#ifdef SPEW_CLIP_SKIPPING
+ skipRect.recordSkip(offsetToRestore - fReader.offset());
+#endif
fReader.setOffset(offsetToRestore);
}
} break;
@@ -671,6 +703,14 @@
}
}
+#ifdef SPEW_CLIP_SKIPPING
+ {
+ size_t size = skipRect.fSize + skipPath.fSize + skipRegion.fSize;
+ SkDebugf("--- Clip skips %d%% rect:%d path:%d rgn:%d\n",
+ size * 100 / fReader.offset(), skipRect.fCount, skipPath.fCount,
+ skipRegion.fCount);
+ }
+#endif
// this->dumpSize();
}
diff --git a/src/core/SkPictureRecord.cpp b/src/core/SkPictureRecord.cpp
index 4f236d6..c1fadc6 100644
--- a/src/core/SkPictureRecord.cpp
+++ b/src/core/SkPictureRecord.cpp
@@ -4,8 +4,8 @@
#define MIN_WRITER_SIZE 16384
#define HEAP_BLOCK_SIZE 4096
-SkPictureRecord::SkPictureRecord() :
- fHeap(HEAP_BLOCK_SIZE), fWriter(MIN_WRITER_SIZE) {
+SkPictureRecord::SkPictureRecord(uint32_t flags) :
+ fHeap(HEAP_BLOCK_SIZE), fWriter(MIN_WRITER_SIZE), fRecordFlags(flags) {
fBitmapIndex = fMatrixIndex = fPaintIndex = fRegionIndex = 1;
#ifdef SK_DEBUG_SIZE
fPointBytes = fRectBytes = fTextBytes = 0;
@@ -136,7 +136,14 @@
fRestoreOffsetStack.top() = offset;
validate();
- return this->INHERITED::clipPath(path, op);
+
+ if (fRecordFlags & SkPicture::kUsePathBoundsForClip_RecordingFlag) {
+ SkRect bounds;
+ path.computeBounds(&bounds, SkPath::kFast_BoundsType);
+ return this->INHERITED::clipRect(bounds, op);
+ } else {
+ return this->INHERITED::clipPath(path, op);
+ }
}
bool SkPictureRecord::clipRegion(const SkRegion& region, SkRegion::Op op) {
diff --git a/src/core/SkPictureRecord.h b/src/core/SkPictureRecord.h
index b23c747..5325e1e 100644
--- a/src/core/SkPictureRecord.h
+++ b/src/core/SkPictureRecord.h
@@ -11,7 +11,7 @@
class SkPictureRecord : public SkCanvas {
public:
- SkPictureRecord();
+ SkPictureRecord(uint32_t recordFlags);
virtual ~SkPictureRecord();
// overrides from SkCanvas
@@ -171,6 +171,8 @@
SkRefCntRecorder fRCRecorder;
SkRefCntRecorder fTFRecorder;
+ uint32_t fRecordFlags;
+
friend class SkPicturePlayback;
typedef SkCanvas INHERITED;