diff options
-rw-r--r-- | gyp/core.gypi | 2 | ||||
-rw-r--r-- | src/core/SkPictureData.h | 2 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.cpp | 81 | ||||
-rw-r--r-- | src/core/SkPicturePlayback.h | 35 | ||||
-rw-r--r-- | src/core/SkPictureRangePlayback.cpp | 57 | ||||
-rw-r--r-- | src/core/SkPictureRangePlayback.h | 40 | ||||
-rw-r--r-- | src/gpu/SkGpuDevice.cpp | 8 |
7 files changed, 145 insertions, 80 deletions
diff --git a/gyp/core.gypi b/gyp/core.gypi index ae782db053..b1c8cc9e7d 100644 --- a/gyp/core.gypi +++ b/gyp/core.gypi @@ -135,6 +135,8 @@ '<(skia_src_path)/core/SkPictureFlat.h', '<(skia_src_path)/core/SkPicturePlayback.cpp', '<(skia_src_path)/core/SkPicturePlayback.h', + '<(skia_src_path)/core/SkPictureRangePlayback.cpp', + '<(skia_src_path)/core/SkPictureRangePlayback.h', '<(skia_src_path)/core/SkPictureRecord.cpp', '<(skia_src_path)/core/SkPictureRecord.h', '<(skia_src_path)/core/SkPictureRecorder.cpp', diff --git a/src/core/SkPictureData.h b/src/core/SkPictureData.h index 01185d644a..efae974840 100644 --- a/src/core/SkPictureData.h +++ b/src/core/SkPictureData.h @@ -152,6 +152,8 @@ public: bool containsBitmaps() const; + const SkData* opData() const { return fOpData; } + protected: explicit SkPictureData(const SkPictInfo& info); diff --git a/src/core/SkPicturePlayback.cpp b/src/core/SkPicturePlayback.cpp index 7d9d53bf6b..d8ed082690 100644 --- a/src/core/SkPicturePlayback.cpp +++ b/src/core/SkPicturePlayback.cpp @@ -56,28 +56,14 @@ SkPicturePlayback::PlaybackReplacements::lookupByStart(size_t start) { return NULL; } - -class SkAutoResetOpID { -public: - SkAutoResetOpID(SkPicturePlayback* playback) : fPlayback(playback) { } - ~SkAutoResetOpID() { - if (NULL != fPlayback) { - fPlayback->resetOpID(); - } - } - -private: - SkPicturePlayback* fPlayback; -}; - /* -* Read the next op code and chunk size from 'reader'. The returned size -* is the entire size of the chunk (including the opcode). Thus, the -* offset just prior to calling read_op_and_size + 'size' is the offset -* to the next chunk's op code. This also means that the size of a chunk -* with no arguments (just an opcode) will be 4. -*/ -static DrawType read_op_and_size(SkReader32* reader, uint32_t* size) { + * Read the next op code and chunk size from 'reader'. The returned size + * is the entire size of the chunk (including the opcode). Thus, the + * offset just prior to calling ReadOpAndSize + 'size' is the offset + * to the next chunk's op code. This also means that the size of a chunk + * with no arguments (just an opcode) will be 4. + */ +DrawType SkPicturePlayback::ReadOpAndSize(SkReader32* reader, uint32_t* size) { uint32_t temp = reader->readInt(); uint32_t op; if (((uint8_t)temp) == temp) { @@ -121,7 +107,7 @@ static SkBitmap shallow_copy(const SkBitmap& bitmap) { } void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) { - SkAutoResetOpID aroi(this); + AutoResetOpID aroi(this); SkASSERT(0 == fCurOffset); // kDrawComplete will be the signal that we have reached the end of @@ -132,24 +118,19 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) SkAutoTDelete<const SkPicture::OperationList> activeOpsList; const SkTDArray<void*>* activeOps = NULL; - // 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 != fPictureData->fStateTree && NULL != fPictureData->fBoundingHierarchy) { - SkRect clipBounds; - if (canvas->getClipBounds(&clipBounds)) { - SkIRect query; - clipBounds.roundOut(&query); - - activeOpsList.reset(fPictureData->getActiveOps(query)); - if (NULL != activeOpsList.get()) { - if (0 == activeOpsList->numOps()) { - return; // nothing to draw - } + if (fUseBBH && NULL != fPictureData->fStateTree && NULL != fPictureData->fBoundingHierarchy) { + SkRect clipBounds; + if (canvas->getClipBounds(&clipBounds)) { + SkIRect query; + clipBounds.roundOut(&query); - // Since the opList is valid we know it is our derived class - activeOps = &(activeOpsList.get()->fOps); + activeOpsList.reset(fPictureData->getActiveOps(query)); + if (NULL != activeOpsList.get()) { + if (0 == activeOpsList->numOps()) { + return; // nothing to draw } + + activeOps = &(activeOpsList.get()->fOps); } } } @@ -158,14 +139,6 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) SkPictureStateTree::Iterator() : fPictureData->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) { @@ -188,16 +161,6 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) return; } - 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 = @@ -236,7 +199,7 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) if (skipTo <= temp->fStop) { reader.setOffset(skipTo); uint32_t size; - DrawType op = read_op_and_size(&reader, &size); + DrawType op = ReadOpAndSize(&reader, &size); // Since we are relying on the normal SkPictureStateTree // playback we need to convert any nested saveLayer calls // it may issue into saves (so that all its internal @@ -255,7 +218,7 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) } else { reader.setOffset(temp->fStop); uint32_t size; - SkDEBUGCODE(DrawType op = ) read_op_and_size(&reader, &size); + SkDEBUGCODE(DrawType op = ) ReadOpAndSize(&reader, &size); SkASSERT(RESTORE == op); } continue; @@ -264,7 +227,7 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) fCurOffset = reader.offset(); uint32_t size; - DrawType op = read_op_and_size(&reader, &size); + DrawType op = ReadOpAndSize(&reader, &size); size_t skipTo = 0; if (NOOP == op) { // NOOPs are to be ignored - do not propagate them any further diff --git a/src/core/SkPicturePlayback.h b/src/core/SkPicturePlayback.h index 3014b945c1..7966670f6c 100644 --- a/src/core/SkPicturePlayback.h +++ b/src/core/SkPicturePlayback.h @@ -8,7 +8,7 @@ #ifndef SkPicturePlayback_DEFINED #define SkPicturePlayback_DEFINED -#include "SkTypes.h" +#include "SkPictureFlat.h" // for DrawType class SkBitmap; class SkCanvas; @@ -22,13 +22,11 @@ public: : fPictureData(picture->fData.get()) , fCurOffset(0) , fUseBBH(true) - , fStart(0) - , fStop(0) , fReplacements(NULL) { } virtual ~SkPicturePlayback() { } - void draw(SkCanvas* canvas, SkDrawPictureCallback*); + virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*); // Return the ID of the operation currently being executed when playing // back. 0 indicates no call is active. @@ -37,17 +35,6 @@ public: void setUseBBH(bool useBBH) { fUseBBH = useBBH; } - // Limit the opcode playback to be between the offsets 'start' and 'stop'. - // The opcode at 'start' should be a saveLayer while the opcode at - // 'stop' should be a restore. Neither of those commands will be issued. - // Set both start & stop to 0 to disable draw limiting - // Draw limiting cannot be enabled at the same time as draw replacing - void setDrawLimits(size_t start, size_t stop) { - SkASSERT(NULL == fReplacements); - fStart = start; - fStop = stop; - } - // PlaybackReplacements collects op ranges that can be replaced with // a single drawBitmap call (using a precomputed bitmap). class PlaybackReplacements { @@ -91,7 +78,6 @@ public: // the associated drawBitmap call // Draw replacing cannot be enabled at the same time as draw limiting void setReplacements(PlaybackReplacements* replacements) { - SkASSERT(fStart == 0 && fStop == 0); fReplacements = replacements; } @@ -102,8 +88,6 @@ protected: size_t fCurOffset; bool fUseBBH; - size_t fStart; - size_t fStop; PlaybackReplacements* fReplacements; void handleOp(SkReader32* reader, @@ -117,6 +101,21 @@ protected: virtual void postDraw(int opIndex) { } #endif + static DrawType ReadOpAndSize(SkReader32* reader, uint32_t* size); + + class AutoResetOpID { + public: + AutoResetOpID(SkPicturePlayback* playback) : fPlayback(playback) { } + ~AutoResetOpID() { + if (NULL != fPlayback) { + fPlayback->resetOpID(); + } + } + + private: + SkPicturePlayback* fPlayback; + }; + private: typedef SkNoncopyable INHERITED; }; diff --git a/src/core/SkPictureRangePlayback.cpp b/src/core/SkPictureRangePlayback.cpp new file mode 100644 index 0000000000..16473dbfcc --- /dev/null +++ b/src/core/SkPictureRangePlayback.cpp @@ -0,0 +1,57 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#include "SkCanvas.h" +#include "SkPictureData.h" +#include "SkPictureRangePlayback.h" + +void SkPictureRangePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) { + AutoResetOpID aroi(this); + SkASSERT(0 == fCurOffset); + + SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size()); + + if (0 != fStart || 0 != fStop) { + reader.setOffset(fStart); + uint32_t size; + SkDEBUGCODE(DrawType op = ) ReadOpAndSize(&reader, &size); + SkASSERT(SAVE_LAYER == op); + reader.setOffset(fStart + size); + } + + // Record this, so we can concat w/ it if we encounter a setMatrix() + SkMatrix initialMatrix = canvas->getTotalMatrix(); + + SkAutoCanvasRestore acr(canvas, false); + + while (!reader.eof()) { + if (callback && callback->abortDrawing()) { + return; + } + + if (0 != fStart || 0 != fStop) { + size_t offset = reader.offset(); + if (offset >= fStop) { + SkDEBUGCODE(uint32_t size;) + SkDEBUGCODE(DrawType op = ReadOpAndSize(&reader, &size);) + SkASSERT(RESTORE == op); + return; + } + } + + fCurOffset = reader.offset(); + uint32_t size; + DrawType op = ReadOpAndSize(&reader, &size); + if (NOOP == op) { + // NOOPs are to be ignored - do not propagate them any further + reader.setOffset(fCurOffset + size); + continue; + } + + this->handleOp(&reader, op, size, canvas, initialMatrix); + } +} diff --git a/src/core/SkPictureRangePlayback.h b/src/core/SkPictureRangePlayback.h new file mode 100644 index 0000000000..61d10f5d92 --- /dev/null +++ b/src/core/SkPictureRangePlayback.h @@ -0,0 +1,40 @@ +/* + * Copyright 2014 Google Inc. + * + * Use of this source code is governed by a BSD-style license that can be + * found in the LICENSE file. + */ + +#ifndef SkPictureRangePlayback_DEFINED +#define SkPictureRangePlayback_DEFINED + +#include "SkPicturePlayback.h" + +// This version of picture playback plays all the operations between +// a pair of start and stop values. +// The opcode at 'start' should be a saveLayer while the opcode at +// 'stop' should be a restore. Neither of those commands will be issued. +// Since this class never uses the bounding box hierarchy, the base class' +// useBBH setting is ignored. +class SkPictureRangePlayback : public SkPicturePlayback { +public: + // Set both start & stop to 0 to disable draw limiting. Note that disabling + // draw limiting isn't the same as using the base SkPicturePlayback object + // since this class never uses the bounding box hierarchy information. + SkPictureRangePlayback(const SkPicture* picture, size_t start, size_t stop) + : INHERITED(picture) + , fStart(start) + , fStop(stop) { + } + + virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*) SK_OVERRIDE; + +private: + size_t fStart; + size_t fStop; + + typedef SkPicturePlayback INHERITED; +}; + + +#endif diff --git a/src/gpu/SkGpuDevice.cpp b/src/gpu/SkGpuDevice.cpp index cf152fa6e5..42acc9b81c 100644 --- a/src/gpu/SkGpuDevice.cpp +++ b/src/gpu/SkGpuDevice.cpp @@ -31,6 +31,7 @@ #include "SkPicture.h" #include "SkPictureData.h" #include "SkPicturePlayback.h" +#include "SkPictureRangePlayback.h" #include "SkRRect.h" #include "SkStroke.h" #include "SkSurface.h" @@ -2010,9 +2011,10 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi SkIntToScalar(layer->rect().fTop)); } - SkPicturePlayback playback(picture); - playback.setDrawLimits(info.fSaveLayerOpID, info.fRestoreOpID); - playback.draw(canvas, NULL); + SkPictureRangePlayback rangePlayback(picture, + info.fSaveLayerOpID, + info.fRestoreOpID); + rangePlayback.draw(canvas, NULL); canvas->flush(); } |