Split SkPictureRangePlayback out of SkPicturePlayback

This CL starts cleaning up SkPicturePlayback. Future CLs will:

split out the SkPictureReplacementPlayback
remove the preDraw/postDraw entry points & fix up SkPictureTimedPlayback

R=mtklein@google.com, reed@google.com

Author: robertphillips@google.com

Review URL: https://codereview.chromium.org/374833006
This commit is contained in:
robertphillips 2014-07-08 08:28:08 -07:00 committed by Commit bot
parent 55fad7af61
commit 1ad00e4b24
7 changed files with 145 additions and 80 deletions

View File

@ -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',

View File

@ -152,6 +152,8 @@ public:
bool containsBitmaps() const;
const SkData* opData() const { return fOpData; }
protected:
explicit SkPictureData(const SkPictInfo& info);

View File

@ -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);
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
}
// 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

View File

@ -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;
};

View File

@ -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);
}
}

View File

@ -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

View File

@ -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();
}