| Index: src/gpu/GrRecordReplaceDraw.cpp
|
| diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..8291ccb82866e68aa19f3d8e88afbaee51caa164
|
| --- /dev/null
|
| +++ b/src/gpu/GrRecordReplaceDraw.cpp
|
| @@ -0,0 +1,119 @@
|
| +/*
|
| + * 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 "GrRecordReplaceDraw.h"
|
| +#include "SkImage.h"
|
| +#include "SkRecordDraw.h"
|
| +
|
| +GrReplacements::ReplacementInfo* GrReplacements::push() {
|
| + SkDEBUGCODE(this->validate());
|
| + return fReplacements.push();
|
| +}
|
| +
|
| +void GrReplacements::freeAll() {
|
| + for (int i = 0; i < fReplacements.count(); ++i) {
|
| + fReplacements[i].fImage->unref();
|
| + }
|
| + fReplacements.reset();
|
| +}
|
| +
|
| +#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);
|
| + }
|
| + }
|
| +}
|
| +#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;
|
| +}
|
| +
|
| +static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo* ri,
|
| + SkCanvas* canvas) {
|
| + SkRect src = SkRect::Make(ri->fSrcRect);
|
| + SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
|
| + SkIntToScalar(ri->fPos.fY),
|
| + SkIntToScalar(ri->fSrcRect.width()),
|
| + SkIntToScalar(ri->fSrcRect.height()));
|
| + ri->fImage->draw(canvas, &src, dst, ri->fPaint);
|
| +}
|
| +
|
| +void GrRecordReplaceDraw(const SkRecord& record,
|
| + SkCanvas* canvas,
|
| + const SkBBoxHierarchy* bbh,
|
| + const GrReplacements* replacements,
|
| + SkDrawPictureCallback* callback) {
|
| + SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
|
| +
|
| + SkRecords::Draw draw(canvas);
|
| + const GrReplacements::ReplacementInfo* ri = NULL;
|
| + int searchStart = 0;
|
| +
|
| + if (NULL != bbh) {
|
| + // Draw only ops that affect pixels in the canvas's current clip.
|
| + // The SkRecord and BBH were recorded in identity space. This canvas
|
| + // is not necessarily in that same space. getClipBounds() returns us
|
| + // this canvas' clip bounds transformed back into identity space, which
|
| + // lets us query the BBH.
|
| + SkRect query = { 0, 0, 0, 0 };
|
| + (void)canvas->getClipBounds(&query);
|
| +
|
| + SkTDArray<void*> ops;
|
| + bbh->search(query, &ops);
|
| +
|
| + for (int i = 0; i < ops.count(); i++) {
|
| + if (NULL != callback && callback->abortDrawing()) {
|
| + return;
|
| + }
|
| + ri = replacements->lookupByStart(i, &searchStart);
|
| + if (NULL != ri) {
|
| + draw_replacement_bitmap(ri, canvas);
|
| +
|
| + while ((uintptr_t)ops[i] < ri->fStop) {
|
| + ++i;
|
| + }
|
| + SkASSERT((uintptr_t)ops[i] == ri->fStop);
|
| + continue;
|
| + }
|
| +
|
| + record.visit<void>((uintptr_t)ops[i], draw);
|
| + }
|
| + } else {
|
| + for (unsigned int i = 0; i < record.count(); ++i) {
|
| + if (NULL != callback && callback->abortDrawing()) {
|
| + return;
|
| + }
|
| + ri = replacements->lookupByStart(i, &searchStart);
|
| + if (NULL != ri) {
|
| + draw_replacement_bitmap(ri, canvas);
|
| +
|
| + i = ri->fStop;
|
| + continue;
|
| + }
|
| +
|
| + record.visit<void>(i, draw);
|
| + }
|
| + }
|
| +}
|
|
|