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:
parent
55fad7af61
commit
1ad00e4b24
@ -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',
|
||||
|
@ -152,6 +152,8 @@ public:
|
||||
|
||||
bool containsBitmaps() const;
|
||||
|
||||
const SkData* opData() const { return fOpData; }
|
||||
|
||||
protected:
|
||||
explicit SkPictureData(const SkPictInfo& info);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
57
src/core/SkPictureRangePlayback.cpp
Normal file
57
src/core/SkPictureRangePlayback.cpp
Normal 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);
|
||||
}
|
||||
}
|
40
src/core/SkPictureRangePlayback.h
Normal file
40
src/core/SkPictureRangePlayback.h
Normal 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
|
@ -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();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user