Chromium Code Reviews| Index: src/gpu/GrRecordReplaceDraw.cpp |
| diff --git a/src/gpu/GrRecordReplaceDraw.cpp b/src/gpu/GrRecordReplaceDraw.cpp |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..143d77630b2677f01e5c6d31cb03e87de3e2239a |
| --- /dev/null |
| +++ b/src/gpu/GrRecordReplaceDraw.cpp |
| @@ -0,0 +1,122 @@ |
| +/* |
| + * 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 "SkRecordDraw.h" |
| + |
| +GrReplacements::ReplacementInfo* GrReplacements::push() { |
| + SkDEBUGCODE(this->validate()); |
| + return fReplacements.push(); |
| +} |
| + |
| +void GrReplacements::freeAll() { |
| + for (int i = 0; i < fReplacements.count(); ++i) { |
| + SkDELETE(fReplacements[i].fBM); |
| + } |
| + 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, |
| + SkRecords::Draw* draw) { |
| + 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())); |
| + SkRecords::DrawBitmapRectToRect dbmr2r(const_cast<SkPaint*>(ri->fPaint), |
|
mtklein
2014/09/03 15:46:11
Hrm. This isn't going to work. dbmr2r will destr
|
| + *ri->fBM, |
| + &src, |
| + dst, |
| + SkCanvas::kNone_DrawBitmapRectFlag); |
| + (*draw)(dbmr2r); |
|
mtklein
2014/09/03 15:49:14
Wait a sec, maybe that's still even too complicate
robertphillips
2014/09/03 17:36:24
Done.
|
| +} |
| + |
| +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, &draw); |
| + |
| + for (; (uintptr_t)ops[i] < ri->fStop; ++i) |
|
bsalomon
2014/09/03 15:43:50
while ((uintptr_t)ops[i] < ri->fStop) {
++i;
}
w
robertphillips
2014/09/03 17:36:24
Done.
|
| + ; |
| + 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, &draw); |
| + |
| + i = ri->fStop; |
| + continue; |
| + } |
| + |
| + record.visit<void>(i, draw); |
| + } |
| + } |
| +} |