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
This commit is contained in:
parent
9b0390626f
commit
ae814c809e
@ -49,10 +49,28 @@ public:
|
||||
*/
|
||||
void swap(SkPicture& other);
|
||||
|
||||
enum RecordingFlags {
|
||||
/* This flag specifies that when clipPath() is called, the path will
|
||||
be faithfully recorded, but the recording canvas' current clip will
|
||||
only see the path's bounds. This speeds up the recording process
|
||||
without compromising the fidelity of the playback. The only side-
|
||||
effect for recording is that calling getTotalClip() or related
|
||||
clip-query calls will reflect the path's bounds, not the actual
|
||||
path.
|
||||
*/
|
||||
kUsePathBoundsForClip_RecordingFlag = 0x01
|
||||
};
|
||||
|
||||
/** Returns the canvas that records the drawing commands.
|
||||
@param width the base width for the picture, as if the recording
|
||||
canvas' bitmap had this width.
|
||||
@param height the base width for the picture, as if the recording
|
||||
canvas' bitmap had this height.
|
||||
@param recordFlags optional flags that control recording.
|
||||
@return the picture canvas.
|
||||
*/
|
||||
SkCanvas* beginRecording(int width, int height);
|
||||
SkCanvas* beginRecording(int width, int height, uint32_t recordFlags = 0);
|
||||
|
||||
/** Returns the recording canvas if one is active, or NULL if recording is
|
||||
not active. This does not alter the refcnt on the canvas (if present).
|
||||
*/
|
||||
@ -103,9 +121,10 @@ private:
|
||||
|
||||
class SkAutoPictureRecord : SkNoncopyable {
|
||||
public:
|
||||
SkAutoPictureRecord(SkPicture* pict, int width, int height) {
|
||||
SkAutoPictureRecord(SkPicture* pict, int width, int height,
|
||||
uint32_t recordingFlags = 0) {
|
||||
fPicture = pict;
|
||||
fCanvas = pict->beginRecording(width, height);
|
||||
fCanvas = pict->beginRecording(width, height, recordingFlags);
|
||||
}
|
||||
~SkAutoPictureRecord() {
|
||||
fPicture->endRecording();
|
||||
|
@ -146,7 +146,8 @@ void SkPicture::swap(SkPicture& other) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
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 @@ SkCanvas* SkPicture::beginRecording(int width, int height) {
|
||||
fRecord = NULL;
|
||||
}
|
||||
|
||||
fRecord = SkNEW(SkPictureRecord);
|
||||
fRecord = SkNEW_ARGS(SkPictureRecord, (recordingFlags));
|
||||
|
||||
fWidth = width;
|
||||
fHeight = height;
|
||||
|
@ -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 @@ SkPicturePlayback::SkPicturePlayback(SkStream* stream) {
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
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 @@ void SkPicturePlayback::draw(SkCanvas& canvas) {
|
||||
}
|
||||
}
|
||||
|
||||
#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();
|
||||
}
|
||||
|
||||
|
@ -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 @@ bool SkPictureRecord::clipPath(const SkPath& path, SkRegion::Op op) {
|
||||
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) {
|
||||
|
@ -11,7 +11,7 @@
|
||||
|
||||
class SkPictureRecord : public SkCanvas {
|
||||
public:
|
||||
SkPictureRecord();
|
||||
SkPictureRecord(uint32_t recordFlags);
|
||||
virtual ~SkPictureRecord();
|
||||
|
||||
// overrides from SkCanvas
|
||||
@ -171,6 +171,8 @@ private:
|
||||
SkRefCntRecorder fRCRecorder;
|
||||
SkRefCntRecorder fTFRecorder;
|
||||
|
||||
uint32_t fRecordFlags;
|
||||
|
||||
friend class SkPicturePlayback;
|
||||
|
||||
typedef SkCanvas INHERITED;
|
||||
|
Loading…
Reference in New Issue
Block a user