Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Unified Diff: src/core/SkPicturePlayback.cpp

Issue 261663003: First pass at pre-rendering saveLayers for GPU (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Reduce size of PlaybackReplacements in SkPicturePlayback.h Created 6 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | src/core/SkPictureStateTree.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/core/SkPicturePlayback.cpp
===================================================================
--- src/core/SkPicturePlayback.cpp (revision 14614)
+++ src/core/SkPicturePlayback.cpp (working copy)
@@ -23,6 +23,33 @@
*/
#define SPEW_CLIP_SKIPPINGx
+SkPicturePlayback::PlaybackReplacements::ReplacementInfo*
+SkPicturePlayback::PlaybackReplacements::push() {
+ SkDEBUGCODE(this->validate());
+ return fReplacements.push();
+}
+
+void SkPicturePlayback::PlaybackReplacements::freeAll() {
+ for (int i = 0; i < fReplacements.count(); ++i) {
+ SkDELETE(fReplacements[i].fBM);
+ }
+ fReplacements.reset();
+}
+
+#ifdef SK_DEBUG
+void SkPicturePlayback::PlaybackReplacements::validate() const {
+ // Check that the ranges are monotonically increasing and non-overlapping
+ if (fReplacements.count() > 0) {
+ SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop);
+
+ for (int i = 1; i < fReplacements.count(); ++i) {
+ SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop);
+ SkASSERT(fReplacements[i-1].fStop < fReplacements[i].fStart);
+ }
+ }
+}
+#endif
+
SkPicturePlayback::SkPicturePlayback(const SkPicture* picture, const SkPictInfo& info)
: fPicture(picture)
, fInfo(info) {
@@ -205,6 +232,10 @@
fStateTree = NULL;
fCachedActiveOps = NULL;
fCurOffset = 0;
+ fUseBBH = true;
+ fStart = 0;
+ fStop = 0;
+ fReplacements = NULL;
}
SkPicturePlayback::~SkPicturePlayback() {
@@ -744,6 +775,21 @@
SkPicturePlayback* fPlayback;
};
+// TODO: Replace with hash or pass in "lastLookedUp" hint
+SkPicturePlayback::PlaybackReplacements::ReplacementInfo*
+SkPicturePlayback::PlaybackReplacements::lookupByStart(size_t start) {
+ SkDEBUGCODE(this->validate());
+ for (int i = 0; i < fReplacements.count(); ++i) {
+ if (start == fReplacements[i].fStart) {
+ return &fReplacements[i];
+ } else if (start < fReplacements[i].fStart) {
+ return NULL; // the ranges are monotonically increasing and non-overlapping
+ }
+ }
+
+ return NULL;
+}
+
void SkPicturePlayback::draw(SkCanvas& canvas, SkDrawPictureCallback* callback) {
SkAutoResetOpID aroi(this);
SkASSERT(0 == fCurOffset);
@@ -769,20 +815,24 @@
TextContainer text;
const SkTDArray<void*>* activeOps = NULL;
- if (NULL != fStateTree && NULL != fBoundingHierarchy) {
- SkRect clipBounds;
- if (canvas.getClipBounds(&clipBounds)) {
- SkIRect query;
- clipBounds.roundOut(&query);
+ // When draw limits are enabled (i.e., 0 != fStart || 0 != fStop) the state
+ // tree isn't used to pick and choose the draw operations
+ if (0 == fStart && 0 == fStop) {
+ if (fUseBBH && NULL != fStateTree && NULL != fBoundingHierarchy) {
+ SkRect clipBounds;
+ if (canvas.getClipBounds(&clipBounds)) {
+ SkIRect query;
+ clipBounds.roundOut(&query);
- const SkPicture::OperationList& activeOpsList = this->getActiveOps(query);
- if (activeOpsList.valid()) {
- if (0 == activeOpsList.numOps()) {
- return; // nothing to draw
+ const SkPicture::OperationList& activeOpsList = this->getActiveOps(query);
+ if (activeOpsList.valid()) {
+ if (0 == activeOpsList.numOps()) {
+ return; // nothing to draw
+ }
+
+ // Since the opList is valid we know it is our derived class
+ activeOps = &((const CachedOperationList&)activeOpsList).fOps;
}
-
- // Since the opList is valid we know it is our derived class
- activeOps = &((const CachedOperationList&)activeOpsList).fOps;
}
}
}
@@ -791,6 +841,14 @@
SkPictureStateTree::Iterator() :
fStateTree->getIterator(*activeOps, &canvas);
+ if (0 != fStart || 0 != fStop) {
+ reader.setOffset(fStart);
+ uint32_t size;
+ SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
+ SkASSERT(SAVE_LAYER == op);
+ reader.setOffset(fStart+size);
+ }
+
if (it.isValid()) {
uint32_t skipTo = it.nextDraw();
if (kDrawComplete == skipTo) {
@@ -821,7 +879,61 @@
return;
}
#endif
+ if (0 != fStart || 0 != fStop) {
+ size_t offset = reader.offset() ;
+ if (offset >= fStop) {
+ uint32_t size;
+ SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
+ SkASSERT(RESTORE == op);
+ return;
+ }
+ }
+ if (NULL != fReplacements) {
+ // Potentially replace a block of operations with a single drawBitmap call
+ SkPicturePlayback::PlaybackReplacements::ReplacementInfo* temp =
+ fReplacements->lookupByStart(reader.offset());
+ if (NULL != temp) {
+ SkASSERT(NULL != temp->fBM);
+ SkASSERT(NULL != temp->fPaint);
+ canvas.drawBitmap(*temp->fBM, temp->fPos.fX, temp->fPos.fY, temp->fPaint);
+
+ if (it.isValid()) {
+ // This save is needed since the BBH will automatically issue
+ // a restore to balanced the saveLayer we're skipping
+ canvas.save();
+ // Note: This skipping only works if the client only issues
+ // well behaved saveLayer calls (i.e., doesn't use
+ // kMatrix_SaveFlag or kClip_SaveFlag in isolation)
+
+ // At this point we know that the PictureStateTree was aiming
+ // for some draw op within temp's saveLayer (although potentially
+ // in a separate saveLayer nested inside it).
+ // We need to skip all the operations inside temp's range
+ // along with all the associated state changes but update
+ // the state tree to the first operation outside temp's range.
+ SkASSERT(it.peekDraw() >= temp->fStart && it.peekDraw() <= temp->fStop);
+
+ while (kDrawComplete != it.peekDraw() && it.peekDraw() <= temp->fStop) {
+ it.skipDraw();
+ }
+
+ if (kDrawComplete == it.peekDraw()) {
+ break;
+ }
+
+ uint32_t skipTo = it.nextDraw();
+ reader.setOffset(skipTo);
+ } else {
+ reader.setOffset(temp->fStop);
+ uint32_t size;
+ SkDEBUGCODE(DrawType op =) read_op_and_size(&reader, &size);
+ SkASSERT(RESTORE == op);
+ }
+ continue;
+ }
+ }
+
#ifdef SPEW_CLIP_SKIPPING
opCount++;
#endif
@@ -915,8 +1027,7 @@
SkRegion::Op regionOp = ClipParams_unpackRegionOp(packed);
bool doAA = ClipParams_unpackDoAA(packed);
size_t offsetToRestore = reader.readInt();
- SkASSERT(!offsetToRestore || \
- offsetToRestore >= reader.offset());
+ SkASSERT(!offsetToRestore || offsetToRestore >= reader.offset());
canvas.clipRRect(rrect, regionOp, doAA);
if (canvas.isClipEmpty() && offsetToRestore) {
#ifdef SPEW_CLIP_SKIPPING
« no previous file with comments | « src/core/SkPicturePlayback.h ('k') | src/core/SkPictureStateTree.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698