| Index: src/gpu/GrRecordReplaceDraw.cpp
|
| diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
|
| index acdc63fb849c519f6c12995a02b8f83c0fee5342..f44baa7a00499c212655fdd080515bafe268ff55 100644
|
| --- a/src/gpu/GrRecordReplaceDraw.cpp
|
| +++ b/src/gpu/GrRecordReplaceDraw.cpp
|
| @@ -8,47 +8,31 @@
|
| #include "GrRecordReplaceDraw.h"
|
| #include "SkImage.h"
|
| #include "SkRecordDraw.h"
|
| -
|
| -GrReplacements::ReplacementInfo* GrReplacements::push() {
|
| - SkDEBUGCODE(this->validate());
|
| - return fReplacements.push();
|
| +#include "SkRecords.h"
|
| +#include "SkCanvasPriv.h"
|
| +
|
| +GrReplacements::ReplacementInfo* GrReplacements::newReplacement(uint32_t pictureID,
|
| + unsigned int start,
|
| + const SkMatrix& ctm) {
|
| + ReplacementInfo* replacement = SkNEW_ARGS(ReplacementInfo, (pictureID, start, ctm, true));
|
| + fReplacementHash.add(replacement);
|
| + return replacement;
|
| }
|
|
|
| void GrReplacements::freeAll() {
|
| - for (int i = 0; i < fReplacements.count(); ++i) {
|
| - fReplacements[i].fImage->unref();
|
| - SkDELETE(fReplacements[i].fPaint);
|
| - }
|
| - fReplacements.reset();
|
| -}
|
| + SkTDynamicHash<ReplacementInfo, ReplacementInfo::Key>::Iter iter(&fReplacementHash);
|
|
|
| -#ifdef SK_DEBUG
|
| -void GrReplacements::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);
|
| - }
|
| + for (; !iter.done(); ++iter) {
|
| + ReplacementInfo* replacement = &(*iter);
|
| + SkDELETE(replacement);
|
| }
|
| +
|
| + fReplacementHash.reset();
|
| }
|
| -#endif
|
|
|
| const GrReplacements::ReplacementInfo*
|
| -GrReplacements::lookupByStart(size_t start, int* searchStart) const {
|
| - SkDEBUGCODE(this->validate());
|
| - for (int i = *searchStart; i < fReplacements.count(); ++i) {
|
| - if (start == fReplacements[i].fStart) {
|
| - *searchStart = i + 1;
|
| - return &fReplacements[i];
|
| - } else if (start < fReplacements[i].fStart) {
|
| - return NULL; // the ranges are monotonically increasing and non-overlapping
|
| - }
|
| - }
|
| -
|
| - return NULL;
|
| +GrReplacements::lookupByStart(uint32_t pictureID, size_t start, const SkMatrix& ctm) const {
|
| + return fReplacementHash.find(ReplacementInfo::Key(pictureID, start, ctm, true));
|
| }
|
|
|
| static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri,
|
| @@ -66,6 +50,68 @@ static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo
|
| canvas->restore();
|
| }
|
|
|
| +// Used by GrRecordReplaceDraw. It intercepts nested drawPicture calls and
|
| +// also draws them with replaced layers.
|
| +class ReplaceDraw : public SkRecords::Draw {
|
| +public:
|
| + ReplaceDraw(SkCanvas* canvas,
|
| + const GrReplacements* replacements,
|
| + const SkMatrix& initialMatrix,
|
| + SkDrawPictureCallback* callback,
|
| + const SkRecord* record,
|
| + uint32_t pictureID)
|
| + : INHERITED(canvas)
|
| + , fCanvas(canvas)
|
| + , fReplacements(replacements)
|
| + , fInitialMatrix(initialMatrix)
|
| + , fCallback(callback)
|
| + , fIndex(0)
|
| + , fRecord(record)
|
| + , fPictureID(pictureID) {
|
| + }
|
| +
|
| + bool done() const { return fIndex >= fRecord->count(); }
|
| + void drawCur() { fRecord->visit<void>(fIndex, *this); fIndex++; }
|
| +
|
| + // Same as Draw for all ops except DrawPicture.
|
| + template <typename T> void operator()(const T& r) {
|
| + this->INHERITED::operator()(r);
|
| + }
|
| + void operator()(const SkRecords::DrawPicture& dp) {
|
| + SkAutoCanvasMatrixPaint acmp(fCanvas, dp.matrix, dp.paint, dp.picture->cullRect());
|
| +
|
| + GrRecordReplaceDraw(dp.picture,
|
| + fCanvas,
|
| + fReplacements,
|
| + fInitialMatrix,
|
| + fCallback);
|
| + }
|
| + void operator()(const SkRecords::SaveLayer& sl) {
|
| + const GrReplacements::ReplacementInfo* ri;
|
| +
|
| + ri = fReplacements->lookupByStart(fPictureID, fIndex, fCanvas->getTotalMatrix());
|
| + if (ri) {
|
| + draw_replacement_bitmap(ri, fCanvas, fInitialMatrix);
|
| + fIndex = ri->fStop;
|
| + return;
|
| + }
|
| +
|
| + // This is a fail for layer hoisting
|
| + this->INHERITED::operator()(sl);
|
| + }
|
| +
|
| +private:
|
| + SkCanvas* fCanvas;
|
| + const GrReplacements* fReplacements;
|
| + const SkMatrix fInitialMatrix;
|
| + SkDrawPictureCallback* fCallback;
|
| + unsigned int fIndex;
|
| + const SkRecord* fRecord;
|
| + uint32_t fPictureID;
|
| +
|
| + typedef Draw INHERITED;
|
| +};
|
| +
|
| void GrRecordReplaceDraw(const SkPicture* picture,
|
| SkCanvas* canvas,
|
| const GrReplacements* replacements,
|
| @@ -79,9 +125,8 @@ void GrRecordReplaceDraw(const SkPicture* picture,
|
| return;
|
| }
|
|
|
| - SkRecords::Draw draw(canvas);
|
| + ReplaceDraw draw(canvas, replacements, initialMatrix, callback, record, picture->uniqueID());
|
| const GrReplacements::ReplacementInfo* ri = NULL;
|
| - int searchStart = 0;
|
|
|
| if (bbh) {
|
| // Draw only ops that affect pixels in the canvas's current clip.
|
| @@ -99,7 +144,9 @@ void GrRecordReplaceDraw(const SkPicture* picture,
|
| if (callback && callback->abortDrawing()) {
|
| return;
|
| }
|
| - ri = replacements->lookupByStart((uintptr_t)ops[i], &searchStart);
|
| + ri = replacements->lookupByStart(picture->uniqueID(),
|
| + (uintptr_t)ops[i],
|
| + canvas->getTotalMatrix());
|
| if (ri) {
|
| draw_replacement_bitmap(ri, canvas, initialMatrix);
|
|
|
| @@ -113,18 +160,12 @@ void GrRecordReplaceDraw(const SkPicture* picture,
|
| record->visit<void>((uintptr_t)ops[i], draw);
|
| }
|
| } else {
|
| - for (unsigned int i = 0; i < record->count(); ++i) {
|
| + while (!draw.done()) {
|
| if (callback && callback->abortDrawing()) {
|
| return;
|
| }
|
| - ri = replacements->lookupByStart(i, &searchStart);
|
| - if (ri) {
|
| - draw_replacement_bitmap(ri, canvas, initialMatrix);
|
| - i = ri->fStop;
|
| - continue;
|
| - }
|
|
|
| - record->visit<void>(i, draw);
|
| + draw.drawCur();
|
| }
|
| }
|
| }
|
|
|