Switch Layer Hoisting over to SkRecord backend
R=bsalomon@google.com TBR=bsalomon@google.com Author: robertphillips@google.com Review URL: https://codereview.chromium.org/540543002
This commit is contained in:
parent
5353bae113
commit
274b4ba6bd
@ -136,13 +136,9 @@
|
|||||||
'<(skia_src_path)/core/SkPictureFlat.h',
|
'<(skia_src_path)/core/SkPictureFlat.h',
|
||||||
'<(skia_src_path)/core/SkPicturePlayback.cpp',
|
'<(skia_src_path)/core/SkPicturePlayback.cpp',
|
||||||
'<(skia_src_path)/core/SkPicturePlayback.h',
|
'<(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.cpp',
|
||||||
'<(skia_src_path)/core/SkPictureRecord.h',
|
'<(skia_src_path)/core/SkPictureRecord.h',
|
||||||
'<(skia_src_path)/core/SkPictureRecorder.cpp',
|
'<(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.cpp',
|
||||||
'<(skia_src_path)/core/SkPictureShader.h',
|
'<(skia_src_path)/core/SkPictureShader.h',
|
||||||
'<(skia_src_path)/core/SkPictureStateTree.cpp',
|
'<(skia_src_path)/core/SkPictureStateTree.cpp',
|
||||||
|
@ -286,6 +286,7 @@ private:
|
|||||||
friend class SkPictureData; // to access OperationList
|
friend class SkPictureData; // to access OperationList
|
||||||
friend class SkPictureRecorder; // just for SkPicture-based constructor
|
friend class SkPictureRecorder; // just for SkPicture-based constructor
|
||||||
friend class SkGpuDevice; // for fData access
|
friend class SkGpuDevice; // for fData access
|
||||||
|
friend class GrLayerHoister; // access to fRecord
|
||||||
friend class CollectLayers; // access to fRecord
|
friend class CollectLayers; // access to fRecord
|
||||||
friend class SkPicturePlayback; // to get fData & OperationList
|
friend class SkPicturePlayback; // to get fData & OperationList
|
||||||
friend class SkPictureReplacementPlayback; // to access OperationList
|
friend class SkPictureReplacementPlayback; // to access OperationList
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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 (NULL != 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,41 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* 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
|
|
@ -1,171 +0,0 @@
|
|||||||
|
|
||||||
/*
|
|
||||||
* 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);
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,86 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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
|
|
@ -7,8 +7,8 @@
|
|||||||
|
|
||||||
#include "GrLayerCache.h"
|
#include "GrLayerCache.h"
|
||||||
#include "GrLayerHoister.h"
|
#include "GrLayerHoister.h"
|
||||||
#include "SkPictureRangePlayback.h"
|
|
||||||
#include "SkCanvas.h"
|
#include "SkCanvas.h"
|
||||||
|
#include "SkRecordDraw.h"
|
||||||
#include "SkSurface.h"
|
#include "SkSurface.h"
|
||||||
|
|
||||||
// Return true if any layers are suitable for hoisting
|
// Return true if any layers are suitable for hoisting
|
||||||
@ -94,10 +94,8 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
|
|||||||
atlasCanvas->translate(bound.fLeft, bound.fTop);
|
atlasCanvas->translate(bound.fLeft, bound.fTop);
|
||||||
atlasCanvas->concat(layer->ctm());
|
atlasCanvas->concat(layer->ctm());
|
||||||
|
|
||||||
SkPictureRangePlayback rangePlayback(picture,
|
SkRecordPartialDraw(*picture->fRecord.get(), atlasCanvas, bound,
|
||||||
layer->start(),
|
layer->start(), layer->stop());
|
||||||
layer->stop());
|
|
||||||
rangePlayback.draw(atlasCanvas, NULL);
|
|
||||||
|
|
||||||
atlasCanvas->restore();
|
atlasCanvas->restore();
|
||||||
}
|
}
|
||||||
@ -111,9 +109,9 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
|
|||||||
|
|
||||||
// Each non-atlased layer has its own GrTexture
|
// Each non-atlased layer has its own GrTexture
|
||||||
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
|
SkAutoTUnref<SkSurface> surface(SkSurface::NewRenderTargetDirect(
|
||||||
layer->texture()->asRenderTarget(),
|
layer->texture()->asRenderTarget(),
|
||||||
SkSurface::kStandard_TextRenderMode,
|
SkSurface::kStandard_TextRenderMode,
|
||||||
SkSurface::kDontClear_RenderTargetFlag));
|
SkSurface::kDontClear_RenderTargetFlag));
|
||||||
|
|
||||||
SkCanvas* layerCanvas = surface->getCanvas();
|
SkCanvas* layerCanvas = surface->getCanvas();
|
||||||
|
|
||||||
@ -130,10 +128,8 @@ void GrLayerHoister::DrawLayers(const SkPicture* picture,
|
|||||||
|
|
||||||
layerCanvas->concat(layer->ctm());
|
layerCanvas->concat(layer->ctm());
|
||||||
|
|
||||||
SkPictureRangePlayback rangePlayback(picture,
|
SkRecordPartialDraw(*picture->fRecord.get(), layerCanvas, bound,
|
||||||
layer->start(),
|
layer->start(), layer->stop());
|
||||||
layer->stop());
|
|
||||||
rangePlayback.draw(layerCanvas, NULL);
|
|
||||||
|
|
||||||
layerCanvas->flush();
|
layerCanvas->flush();
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ void GrRecordReplaceDraw(const SkRecord& record,
|
|||||||
if (NULL != callback && callback->abortDrawing()) {
|
if (NULL != callback && callback->abortDrawing()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ri = replacements->lookupByStart(i, &searchStart);
|
ri = replacements->lookupByStart((uintptr_t)ops[i], &searchStart);
|
||||||
if (NULL != ri) {
|
if (NULL != ri) {
|
||||||
draw_replacement_bitmap(ri, canvas);
|
draw_replacement_bitmap(ri, canvas);
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "GrLayerCache.h"
|
#include "GrLayerCache.h"
|
||||||
#include "GrLayerHoister.h"
|
#include "GrLayerHoister.h"
|
||||||
#include "GrPictureUtils.h"
|
#include "GrPictureUtils.h"
|
||||||
|
#include "GrRecordReplaceDraw.h"
|
||||||
#include "GrStrokeInfo.h"
|
#include "GrStrokeInfo.h"
|
||||||
#include "GrTracing.h"
|
#include "GrTracing.h"
|
||||||
|
|
||||||
@ -31,8 +32,7 @@
|
|||||||
#include "SkPathEffect.h"
|
#include "SkPathEffect.h"
|
||||||
#include "SkPicture.h"
|
#include "SkPicture.h"
|
||||||
#include "SkPictureData.h"
|
#include "SkPictureData.h"
|
||||||
#include "SkPictureRangePlayback.h"
|
#include "SkRecord.h"
|
||||||
#include "SkPictureReplacementPlayback.h"
|
|
||||||
#include "SkRRect.h"
|
#include "SkRRect.h"
|
||||||
#include "SkStroke.h"
|
#include "SkStroke.h"
|
||||||
#include "SkSurface.h"
|
#include "SkSurface.h"
|
||||||
@ -1875,7 +1875,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkPictureReplacementPlayback::PlaybackReplacements replacements;
|
GrReplacements replacements;
|
||||||
|
|
||||||
SkTDArray<GrCachedLayer*> atlased, nonAtlased;
|
SkTDArray<GrCachedLayer*> atlased, nonAtlased;
|
||||||
atlased.setReserve(gpuData->numSaveLayers());
|
atlased.setReserve(gpuData->numSaveLayers());
|
||||||
@ -1890,8 +1890,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
|||||||
info.fRestoreOpID,
|
info.fRestoreOpID,
|
||||||
info.fOriginXform);
|
info.fOriginXform);
|
||||||
|
|
||||||
SkPictureReplacementPlayback::PlaybackReplacements::ReplacementInfo* layerInfo =
|
GrReplacements::ReplacementInfo* layerInfo = replacements.push();
|
||||||
replacements.push();
|
|
||||||
layerInfo->fStart = info.fSaveLayerOpID;
|
layerInfo->fStart = info.fSaveLayerOpID;
|
||||||
layerInfo->fStop = info.fRestoreOpID;
|
layerInfo->fStop = info.fRestoreOpID;
|
||||||
layerInfo->fPos = info.fOffset;
|
layerInfo->fPos = info.fOffset;
|
||||||
@ -1909,11 +1908,12 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
layerInfo->fBM = SkNEW(SkBitmap); // fBM is allocated so ReplacementInfo can be POD
|
SkBitmap bm;
|
||||||
wrap_texture(layer->texture(),
|
wrap_texture(layer->texture(),
|
||||||
!layer->isAtlased() ? desc.fWidth : layer->texture()->width(),
|
!layer->isAtlased() ? desc.fWidth : layer->texture()->width(),
|
||||||
!layer->isAtlased() ? desc.fHeight : layer->texture()->height(),
|
!layer->isAtlased() ? desc.fHeight : layer->texture()->height(),
|
||||||
layerInfo->fBM);
|
&bm);
|
||||||
|
layerInfo->fImage = SkImage::NewTexture(bm);
|
||||||
|
|
||||||
SkASSERT(info.fPaint);
|
SkASSERT(info.fPaint);
|
||||||
layerInfo->fPaint = info.fPaint;
|
layerInfo->fPaint = info.fPaint;
|
||||||
@ -1936,9 +1936,7 @@ bool SkGpuDevice::EXPERIMENTAL_drawPicture(SkCanvas* mainCanvas, const SkPicture
|
|||||||
GrLayerHoister::DrawLayers(picture, atlased, nonAtlased);
|
GrLayerHoister::DrawLayers(picture, atlased, nonAtlased);
|
||||||
|
|
||||||
// Render the entire picture using new layers
|
// Render the entire picture using new layers
|
||||||
SkPictureReplacementPlayback playback(picture, &replacements, NULL);
|
GrRecordReplaceDraw(*picture->fRecord, mainCanvas, picture->fBBH.get(), &replacements, NULL);
|
||||||
|
|
||||||
playback.draw(mainCanvas, NULL);
|
|
||||||
|
|
||||||
GrLayerHoister::UnlockLayers(fContext->getLayerCache(), picture);
|
GrLayerHoister::UnlockLayers(fContext->getLayerCache(), picture);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user