aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--gyp/core.gypi2
-rw-r--r--src/core/SkPictureData.h2
-rw-r--r--src/core/SkPicturePlayback.cpp81
-rw-r--r--src/core/SkPicturePlayback.h35
-rw-r--r--src/core/SkPictureRangePlayback.cpp57
-rw-r--r--src/core/SkPictureRangePlayback.h40
-rw-r--r--src/gpu/SkGpuDevice.cpp8
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();
}