Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(253)

Unified Diff: src/gpu/GrRecordReplaceDraw.cpp

Issue 597293002: Fix sub-picture layer rendering bugs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Update to ToT Created 6 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/gpu/GrRecordReplaceDraw.h ('k') | tests/RecordReplaceDrawTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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();
}
}
}
« no previous file with comments | « src/gpu/GrRecordReplaceDraw.h ('k') | tests/RecordReplaceDrawTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698