Split SkPictureReplacementPlayback out of SkPicturePlayback
R=mtklein@google.com, reed@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/383733002
This commit is contained in:
parent
67a3271f0d
commit
c26d991bf2
@ -140,6 +140,8 @@
|
||||
'<(skia_src_path)/core/SkPictureRecord.cpp',
|
||||
'<(skia_src_path)/core/SkPictureRecord.h',
|
||||
'<(skia_src_path)/core/SkPictureRecorder.cpp',
|
||||
'<(skia_src_path)/core/SkPictureReplacementPlayback.cpp',
|
||||
'<(skia_src_path)/core/SkPictureReplacementPlayback.h',
|
||||
'<(skia_src_path)/core/SkPictureShader.cpp',
|
||||
'<(skia_src_path)/core/SkPictureShader.h',
|
||||
'<(skia_src_path)/core/SkPictureStateTree.cpp',
|
||||
|
@ -288,6 +288,7 @@ private:
|
||||
friend class GrGatherDevice;
|
||||
friend class SkDebugCanvas;
|
||||
friend class SkPicturePlayback; // to get fData
|
||||
friend class SkPictureReplacementPlayback; // to access OperationList
|
||||
|
||||
typedef SkRefCnt INHERITED;
|
||||
|
||||
|
@ -14,48 +14,6 @@
|
||||
#include "SkTDArray.h"
|
||||
#include "SkTypes.h"
|
||||
|
||||
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
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
@ -137,79 +95,6 @@ bool SkPicturePlayback::initIterator(SkPictureStateTree::Iterator* iter,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SkPicturePlayback::replaceOps(SkPictureStateTree::Iterator* iter,
|
||||
SkReader32* reader,
|
||||
SkCanvas* canvas,
|
||||
const SkMatrix& initialMatrix) {
|
||||
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->save();
|
||||
canvas->setMatrix(initialMatrix);
|
||||
SkRect src = SkRect::Make(temp->fSrcRect);
|
||||
SkRect dst = SkRect::MakeXYWH(temp->fPos.fX, temp->fPos.fY,
|
||||
temp->fSrcRect.width(),
|
||||
temp->fSrcRect.height());
|
||||
canvas->drawBitmapRectToRect(*temp->fBM, &src, dst, temp->fPaint);
|
||||
canvas->restore();
|
||||
|
||||
if (iter->isValid()) {
|
||||
// This save is needed since the BBH will automatically issue
|
||||
// a restore to balanced the saveLayer we're skipping
|
||||
canvas->save();
|
||||
|
||||
// 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.
|
||||
|
||||
uint32_t skipTo;
|
||||
do {
|
||||
skipTo = iter->nextDraw();
|
||||
if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (skipTo <= temp->fStop) {
|
||||
reader->setOffset(skipTo);
|
||||
uint32_t 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
|
||||
// restores will be balanced).
|
||||
if (SAVE_LAYER == op) {
|
||||
canvas->save();
|
||||
}
|
||||
}
|
||||
} while (skipTo <= temp->fStop);
|
||||
|
||||
if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
|
||||
reader->setOffset(reader->size()); // skip to end
|
||||
return true;
|
||||
}
|
||||
|
||||
reader->setOffset(skipTo);
|
||||
} else {
|
||||
reader->setOffset(temp->fStop);
|
||||
uint32_t size;
|
||||
SkDEBUGCODE(DrawType op = ) ReadOpAndSize(reader, &size);
|
||||
SkASSERT(RESTORE == op);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// If 'iter' is valid use it to skip forward through the picture.
|
||||
void SkPicturePlayback::StepIterator(SkPictureStateTree::Iterator* iter, SkReader32* reader) {
|
||||
if (iter->isValid()) {
|
||||
@ -270,10 +155,6 @@ void SkPicturePlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback)
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->replaceOps(&it, &reader, canvas, initialMatrix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
fCurOffset = reader.offset();
|
||||
uint32_t size;
|
||||
DrawType op = ReadOpAndSize(&reader, &size);
|
||||
|
@ -17,71 +17,29 @@ class SkDrawPictureCallback;
|
||||
class SkPaint;
|
||||
class SkPictureData;
|
||||
|
||||
// The basic picture playback class replays the provided picture into a canvas.
|
||||
// If the picture was generated with a BBH it is used to accelerate drawing
|
||||
// unless disabled via setUseBBH.
|
||||
class SkPicturePlayback : SkNoncopyable {
|
||||
public:
|
||||
SkPicturePlayback(const SkPicture* picture)
|
||||
: fPictureData(picture->fData.get())
|
||||
, fCurOffset(0)
|
||||
, fUseBBH(true)
|
||||
, fReplacements(NULL) {
|
||||
, fUseBBH(true) {
|
||||
}
|
||||
virtual ~SkPicturePlayback() { }
|
||||
|
||||
virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*);
|
||||
|
||||
// TODO: remove the curOp calls after cleaning up GrGatherDevice
|
||||
// Return the ID of the operation currently being executed when playing
|
||||
// back. 0 indicates no call is active.
|
||||
size_t curOpID() const { return fCurOffset; }
|
||||
void resetOpID() { fCurOffset = 0; }
|
||||
|
||||
// TODO: remove setUseBBH after cleaning up GrGatherCanvas
|
||||
void setUseBBH(bool useBBH) { fUseBBH = useBBH; }
|
||||
|
||||
// PlaybackReplacements collects op ranges that can be replaced with
|
||||
// a single drawBitmap call (using a precomputed bitmap).
|
||||
class PlaybackReplacements {
|
||||
public:
|
||||
// All the operations between fStart and fStop (inclusive) will be replaced with
|
||||
// a single drawBitmap call using fPos, fBM and fPaint.
|
||||
// fPaint will be NULL if the picture's paint wasn't copyable
|
||||
struct ReplacementInfo {
|
||||
size_t fStart;
|
||||
size_t fStop;
|
||||
SkIPoint fPos;
|
||||
SkBitmap* fBM; // fBM is allocated so ReplacementInfo can remain POD
|
||||
const SkPaint* fPaint; // Note: this object doesn't own the paint
|
||||
|
||||
SkIRect fSrcRect;
|
||||
};
|
||||
|
||||
~PlaybackReplacements() { this->freeAll(); }
|
||||
|
||||
// Add a new replacement range. The replacement ranges should be
|
||||
// sorted in increasing order and non-overlapping (esp. no nested
|
||||
// saveLayers).
|
||||
ReplacementInfo* push();
|
||||
|
||||
private:
|
||||
friend class SkPicturePlayback; // for access to lookupByStart
|
||||
|
||||
// look up a replacement range by its start offset
|
||||
ReplacementInfo* lookupByStart(size_t start);
|
||||
|
||||
void freeAll();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const;
|
||||
#endif
|
||||
|
||||
SkTDArray<ReplacementInfo> fReplacements;
|
||||
};
|
||||
|
||||
// Replace all the draw ops in the replacement ranges in 'replacements' with
|
||||
// the associated drawBitmap call
|
||||
// Draw replacing cannot be enabled at the same time as draw limiting
|
||||
void setReplacements(PlaybackReplacements* replacements) {
|
||||
fReplacements = replacements;
|
||||
}
|
||||
|
||||
protected:
|
||||
const SkPictureData* fPictureData;
|
||||
|
||||
@ -89,7 +47,6 @@ protected:
|
||||
size_t fCurOffset;
|
||||
|
||||
bool fUseBBH;
|
||||
PlaybackReplacements* fReplacements;
|
||||
|
||||
void handleOp(SkReader32* reader,
|
||||
DrawType op,
|
||||
@ -104,10 +61,6 @@ protected:
|
||||
static void StepIterator(SkPictureStateTree::Iterator* iter, SkReader32* reader);
|
||||
static void SkipIterTo(SkPictureStateTree::Iterator* iter,
|
||||
SkReader32* reader, uint32_t skipTo);
|
||||
bool replaceOps(SkPictureStateTree::Iterator* iter,
|
||||
SkReader32* reader,
|
||||
SkCanvas* canvas,
|
||||
const SkMatrix& initialMatrix);
|
||||
|
||||
static DrawType ReadOpAndSize(SkReader32* reader, uint32_t* size);
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
|
||||
/*
|
||||
* Copyright 2014 Google Inc.
|
||||
*
|
||||
|
171
src/core/SkPictureReplacementPlayback.cpp
Normal file
171
src/core/SkPictureReplacementPlayback.cpp
Normal file
@ -0,0 +1,171 @@
|
||||
|
||||
/*
|
||||
* 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 "SkPicture.h"
|
||||
#include "SkPictureData.h"
|
||||
#include "SkPictureReplacementPlayback.h"
|
||||
|
||||
|
||||
SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
|
||||
SkPictureReplacementPlayback::PlaybackReplacements::push() {
|
||||
SkDEBUGCODE(this->validate());
|
||||
return fReplacements.push();
|
||||
}
|
||||
|
||||
void SkPictureReplacementPlayback::PlaybackReplacements::freeAll() {
|
||||
for (int i = 0; i < fReplacements.count(); ++i) {
|
||||
SkDELETE(fReplacements[i].fBM);
|
||||
}
|
||||
fReplacements.reset();
|
||||
}
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void SkPictureReplacementPlayback::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
|
||||
|
||||
// TODO: Replace with hash or pass in "lastLookedUp" hint
|
||||
SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo*
|
||||
SkPictureReplacementPlayback::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;
|
||||
}
|
||||
|
||||
bool SkPictureReplacementPlayback::replaceOps(SkPictureStateTree::Iterator* iter,
|
||||
SkReader32* reader,
|
||||
SkCanvas* canvas,
|
||||
const SkMatrix& initialMatrix) {
|
||||
if (NULL != fReplacements) {
|
||||
// Potentially replace a block of operations with a single drawBitmap call
|
||||
PlaybackReplacements::ReplacementInfo* temp =
|
||||
fReplacements->lookupByStart(reader->offset());
|
||||
if (NULL != temp) {
|
||||
SkASSERT(NULL != temp->fBM);
|
||||
SkASSERT(NULL != temp->fPaint);
|
||||
canvas->save();
|
||||
canvas->setMatrix(initialMatrix);
|
||||
SkRect src = SkRect::Make(temp->fSrcRect);
|
||||
SkRect dst = SkRect::MakeXYWH(temp->fPos.fX, temp->fPos.fY,
|
||||
temp->fSrcRect.width(),
|
||||
temp->fSrcRect.height());
|
||||
canvas->drawBitmapRectToRect(*temp->fBM, &src, dst, temp->fPaint);
|
||||
canvas->restore();
|
||||
|
||||
if (iter->isValid()) {
|
||||
// This save is needed since the BBH will automatically issue
|
||||
// a restore to balanced the saveLayer we're skipping
|
||||
canvas->save();
|
||||
|
||||
// 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.
|
||||
|
||||
uint32_t skipTo;
|
||||
do {
|
||||
skipTo = iter->nextDraw();
|
||||
if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (skipTo <= temp->fStop) {
|
||||
reader->setOffset(skipTo);
|
||||
uint32_t 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
|
||||
// restores will be balanced).
|
||||
if (SAVE_LAYER == op) {
|
||||
canvas->save();
|
||||
}
|
||||
}
|
||||
} while (skipTo <= temp->fStop);
|
||||
|
||||
if (SkPictureStateTree::Iterator::kDrawComplete == skipTo) {
|
||||
reader->setOffset(reader->size()); // skip to end
|
||||
return true;
|
||||
}
|
||||
|
||||
reader->setOffset(skipTo);
|
||||
} else {
|
||||
reader->setOffset(temp->fStop);
|
||||
uint32_t size;
|
||||
SkDEBUGCODE(DrawType op = ) ReadOpAndSize(reader, &size);
|
||||
SkASSERT(RESTORE == op);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void SkPictureReplacementPlayback::draw(SkCanvas* canvas, SkDrawPictureCallback* callback) {
|
||||
AutoResetOpID aroi(this);
|
||||
SkASSERT(0 == fCurOffset);
|
||||
|
||||
SkPictureStateTree::Iterator it;
|
||||
|
||||
if (!this->initIterator(&it, canvas, fActiveOpsList)) {
|
||||
return; // nothing to draw
|
||||
}
|
||||
|
||||
SkReader32 reader(fPictureData->opData()->bytes(), fPictureData->opData()->size());
|
||||
|
||||
StepIterator(&it, &reader);
|
||||
|
||||
// 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 (NULL != callback && callback->abortDrawing()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->replaceOps(&it, &reader, canvas, initialMatrix)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
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
|
||||
SkipIterTo(&it, &reader, fCurOffset + size);
|
||||
continue;
|
||||
}
|
||||
|
||||
this->handleOp(&reader, op, size, canvas, initialMatrix);
|
||||
|
||||
StepIterator(&it, &reader);
|
||||
}
|
||||
}
|
86
src/core/SkPictureReplacementPlayback.h
Normal file
86
src/core/SkPictureReplacementPlayback.h
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* 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 SkPictureReplacementPlayback_DEFINED
|
||||
#define SkPictureReplacementPlayback_DEFINED
|
||||
|
||||
#include "SkPicturePlayback.h"
|
||||
|
||||
// This playback class replaces complete "saveLayer ... restore" runs with a
|
||||
// single drawBitmap call.
|
||||
class SkPictureReplacementPlayback : public SkPicturePlayback {
|
||||
public:
|
||||
// PlaybackReplacements collects op ranges that can be replaced with
|
||||
// a single drawBitmap call (using a precomputed bitmap).
|
||||
class PlaybackReplacements {
|
||||
public:
|
||||
// All the operations between fStart and fStop (inclusive) will be replaced with
|
||||
// a single drawBitmap call using fPos, fBM and fPaint.
|
||||
// fPaint will be NULL if the picture's paint wasn't copyable
|
||||
struct ReplacementInfo {
|
||||
size_t fStart;
|
||||
size_t fStop;
|
||||
SkIPoint fPos;
|
||||
SkBitmap* fBM; // fBM is allocated so ReplacementInfo can remain POD
|
||||
const SkPaint* fPaint; // Note: this object doesn't own the paint
|
||||
|
||||
SkIRect fSrcRect;
|
||||
};
|
||||
|
||||
~PlaybackReplacements() { this->freeAll(); }
|
||||
|
||||
// Add a new replacement range. The replacement ranges should be
|
||||
// sorted in increasing order and non-overlapping (esp. no nested
|
||||
// saveLayers).
|
||||
ReplacementInfo* push();
|
||||
|
||||
// look up a replacement range by its start offset
|
||||
ReplacementInfo* lookupByStart(size_t start);
|
||||
|
||||
private:
|
||||
SkTDArray<ReplacementInfo> fReplacements;
|
||||
|
||||
void freeAll();
|
||||
|
||||
#ifdef SK_DEBUG
|
||||
void validate() const;
|
||||
#endif
|
||||
};
|
||||
|
||||
// This class doesn't take ownership of either 'replacements' or 'activeOpsList'
|
||||
// The caller must guarantee they exist across any calls to 'draw'.
|
||||
// 'activeOpsList' can be NULL but in that case BBH acceleration will not
|
||||
// be used ('replacements' can be NULL too but that defeats the purpose
|
||||
// of using this class).
|
||||
SkPictureReplacementPlayback(const SkPicture* picture,
|
||||
PlaybackReplacements* replacements,
|
||||
const SkPicture::OperationList* activeOpsList)
|
||||
: INHERITED(picture)
|
||||
, fReplacements(replacements)
|
||||
, fActiveOpsList(activeOpsList) {
|
||||
}
|
||||
|
||||
virtual void draw(SkCanvas* canvas, SkDrawPictureCallback*) SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
PlaybackReplacements* fReplacements;
|
||||
const SkPicture::OperationList* fActiveOpsList;
|
||||
|
||||
// This method checks if the current op pointed at by 'iter' and 'reader'
|
||||
// is within a replacement range. If so, it issues the drawBitmap call,
|
||||
// updates 'iter' and 'reader' to be after the restore operation, and
|
||||
// returns true. If the operation is not in a replacement range (and thus
|
||||
// needs to be drawn normally) false is returned.
|
||||
bool replaceOps(SkPictureStateTree::Iterator* iter,
|
||||
SkReader32* reader,
|
||||
SkCanvas* canvas,
|
||||
const SkMatrix& initialMatrix);
|
||||
|
||||
typedef SkPicturePlayback INHERITED;
|
||||
};
|
||||
|
||||
#endif
|
@ -30,8 +30,8 @@
|
||||
#include "SkPathEffect.h"
|
||||
#include "SkPicture.h"
|
||||
#include "SkPictureData.h"
|
||||
#include "SkPicturePlayback.h"
|
||||
#include "SkPictureRangePlayback.h"
|
||||
#include "SkPictureReplacementPlayback.h"
|
||||
#include "SkRRect.h"
|
||||
#include "SkStroke.h"
|
||||
#include "SkSurface.h"
|
||||
@ -1938,7 +1938,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi
|
||||
}
|
||||
}
|
||||
|
||||
SkPicturePlayback::PlaybackReplacements replacements;
|
||||
SkPictureReplacementPlayback::PlaybackReplacements replacements;
|
||||
|
||||
// Generate the layer and/or ensure it is locked
|
||||
for (int i = 0; i < gpuData->numSaveLayers(); ++i) {
|
||||
@ -1947,7 +1947,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi
|
||||
|
||||
const GPUAccelData::SaveLayerInfo& info = gpuData->saveLayerInfo(i);
|
||||
|
||||
SkPicturePlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
|
||||
SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
|
||||
replacements.push();
|
||||
layerInfo->fStart = info.fSaveLayerOpID;
|
||||
layerInfo->fStop = info.fRestoreOpID;
|
||||
@ -2030,9 +2030,8 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* canvas, const SkPicture* pi
|
||||
}
|
||||
|
||||
// Playback using new layers
|
||||
SkPicturePlayback playback(picture);
|
||||
SkPictureReplacementPlayback playback(picture, &replacements, ops.get());
|
||||
|
||||
playback.setReplacements(&replacements);
|
||||
playback.draw(canvas, NULL);
|
||||
|
||||
// unlock the layers
|
||||
|
Loading…
Reference in New Issue
Block a user