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

Side by Side Diff: src/gpu/GrRecordReplaceDraw.cpp

Issue 607763008: Update GrRecordReplaceDraw to use SkTDynamicHash & add ReplaceDraw (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Re-add missing header Created 6 years, 2 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 unified diff | Download patch
« no previous file with comments | « src/gpu/GrRecordReplaceDraw.h ('k') | tests/RecordReplaceDrawTest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * Copyright 2014 Google Inc. 2 * Copyright 2014 Google Inc.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license that can be 4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file. 5 * found in the LICENSE file.
6 */ 6 */
7 7
8 #include "GrRecordReplaceDraw.h" 8 #include "GrRecordReplaceDraw.h"
9 #include "SkCanvasPriv.h"
9 #include "SkImage.h" 10 #include "SkImage.h"
10 #include "SkRecordDraw.h" 11 #include "SkRecordDraw.h"
12 #include "SkRecords.h"
11 13
12 GrReplacements::ReplacementInfo* GrReplacements::push() { 14 GrReplacements::ReplacementInfo* GrReplacements::newReplacement(uint32_t picture ID,
13 SkDEBUGCODE(this->validate()); 15 unsigned int sta rt,
14 return fReplacements.push(); 16 const SkMatrix& ctm) {
17 ReplacementInfo* replacement = SkNEW_ARGS(ReplacementInfo, (pictureID, start , ctm));
18 fReplacementHash.add(replacement);
19 return replacement;
15 } 20 }
16 21
17 void GrReplacements::freeAll() { 22 void GrReplacements::freeAll() {
18 for (int i = 0; i < fReplacements.count(); ++i) { 23 SkTDynamicHash<ReplacementInfo, ReplacementInfo::Key>::Iter iter(&fReplaceme ntHash);
19 fReplacements[i].fImage->unref(); 24
20 SkDELETE(fReplacements[i].fPaint); 25 for (; !iter.done(); ++iter) {
26 ReplacementInfo* replacement = &(*iter);
27 SkDELETE(replacement);
21 } 28 }
22 fReplacements.reset(); 29
30 fReplacementHash.reset();
23 } 31 }
24 32
25 #ifdef SK_DEBUG 33 const GrReplacements::ReplacementInfo* GrReplacements::lookupByStart(uint32_t pi ctureID,
26 void GrReplacements::validate() const { 34 size_t star t,
27 // Check that the ranges are monotonically increasing and non-overlapping 35 const SkMat rix& ctm) const {
28 if (fReplacements.count() > 0) { 36 return fReplacementHash.find(ReplacementInfo::Key(pictureID, start, ctm));
29 SkASSERT(fReplacements[0].fStart < fReplacements[0].fStop);
30
31 for (int i = 1; i < fReplacements.count(); ++i) {
32 SkASSERT(fReplacements[i].fStart < fReplacements[i].fStop);
33 SkASSERT(fReplacements[i - 1].fStop < fReplacements[i].fStart);
34 }
35 }
36 }
37 #endif
38
39 const GrReplacements::ReplacementInfo*
40 GrReplacements::lookupByStart(size_t start, int* searchStart) const {
41 SkDEBUGCODE(this->validate());
42 for (int i = *searchStart; i < fReplacements.count(); ++i) {
43 if (start == fReplacements[i].fStart) {
44 *searchStart = i + 1;
45 return &fReplacements[i];
46 } else if (start < fReplacements[i].fStart) {
47 return NULL; // the ranges are monotonically increasing and non-ove rlapping
48 }
49 }
50
51 return NULL;
52 } 37 }
53 38
54 static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo * ri, 39 static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo * ri,
55 SkCanvas* canvas, 40 SkCanvas* canvas,
56 const SkMatrix& initialMatrix) { 41 const SkMatrix& initialMatrix) {
57 SkRect src = SkRect::Make(ri->fSrcRect); 42 SkRect src = SkRect::Make(ri->fSrcRect);
58 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX), 43 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
59 SkIntToScalar(ri->fPos.fY), 44 SkIntToScalar(ri->fPos.fY),
60 SkIntToScalar(ri->fSrcRect.width()), 45 SkIntToScalar(ri->fSrcRect.width()),
61 SkIntToScalar(ri->fSrcRect.height())); 46 SkIntToScalar(ri->fSrcRect.height()));
62 47
63 canvas->save(); 48 canvas->save();
64 canvas->setMatrix(initialMatrix); 49 canvas->setMatrix(initialMatrix);
65 canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint); 50 canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
66 canvas->restore(); 51 canvas->restore();
67 } 52 }
68 53
54 // Used by GrRecordReplaceDraw. It intercepts nested drawPicture calls and
55 // also draws them with replaced layers.
56 class ReplaceDraw : public SkRecords::Draw {
57 public:
58 ReplaceDraw(SkCanvas* canvas,
59 const SkPicture* picture,
60 const GrReplacements* replacements,
61 const SkMatrix& initialMatrix,
62 SkDrawPictureCallback* callback)
63 : INHERITED(canvas)
64 , fCanvas(canvas)
65 , fPicture(picture)
66 , fReplacements(replacements)
67 , fInitialMatrix(initialMatrix)
68 , fCallback(callback)
69 , fIndex(0) {
70 }
71
72 void draw() {
73 const SkBBoxHierarchy* bbh = fPicture->fBBH.get();
74 const SkRecord* record = fPicture->fRecord.get();
75 if (NULL == record) {
76 return;
77 }
78
79 fOps.rewind();
80
81 if (bbh) {
82 // Draw only ops that affect pixels in the canvas's current clip.
83 // The SkRecord and BBH were recorded in identity space. This canva s
84 // is not necessarily in that same space. getClipBounds() returns u s
85 // this canvas' clip bounds transformed back into identity space, wh ich
86 // lets us query the BBH.
87 SkRect query = { 0, 0, 0, 0 };
88 (void)fCanvas->getClipBounds(&query);
89
90 bbh->search(query, &fOps);
91
92 for (fIndex = 0; fIndex < fOps.count(); ++fIndex) {
93 if (fCallback && fCallback->abortDrawing()) {
94 return;
95 }
96
97 record->visit<void>((uintptr_t)fOps[fIndex], *this);
98 }
99
100 } else {
101 for (fIndex = 0; fIndex < (int) record->count(); ++fIndex) {
102 if (fCallback && fCallback->abortDrawing()) {
103 return;
104 }
105
106 record->visit<void>(fIndex, *this);
107 }
108 }
109 }
110
111 // Same as Draw for all ops except DrawPicture and SaveLayer.
112 template <typename T> void operator()(const T& r) {
113 this->INHERITED::operator()(r);
114 }
115 void operator()(const SkRecords::DrawPicture& dp) {
116 SkAutoCanvasMatrixPaint acmp(fCanvas, dp.matrix, dp.paint, dp.picture->c ullRect());
117
118 // Draw sub-pictures with the same replacement list but a different pict ure
119 ReplaceDraw draw(fCanvas, dp.picture, fReplacements, fInitialMatrix, fCa llback);
120
121 draw.draw();
122 }
123 void operator()(const SkRecords::SaveLayer& sl) {
124
125 // For a saveLayer command, check if it can be replaced by a drawBitmap
126 // call and, if so, draw it and then update the current op index accordi ngly.
127 size_t startOffset;
128 if (fOps.count()) {
129 startOffset = (uintptr_t)fOps[fIndex];
130 } else {
131 startOffset = fIndex;
132 }
133
134 const GrReplacements::ReplacementInfo* ri = fReplacements->lookupByStart (
135 fPicture->uniqueID() ,
136 startOffset,
137 fCanvas->getTotalMat rix());
138
139 if (ri) {
140 draw_replacement_bitmap(ri, fCanvas, fInitialMatrix);
141
142 if (fPicture->fBBH.get()) {
143 while ((uintptr_t)fOps[fIndex] < ri->fStop) {
144 ++fIndex;
145 }
146 SkASSERT((uintptr_t)fOps[fIndex] == ri->fStop);
147 } else {
148 fIndex = ri->fStop;
149 }
150 return;
151 }
152
153 // This is a fail for layer hoisting
154 this->INHERITED::operator()(sl);
155 }
156
157 private:
158 SkCanvas* fCanvas;
159 const SkPicture* fPicture;
160 const GrReplacements* fReplacements;
161 const SkMatrix fInitialMatrix;
162 SkDrawPictureCallback* fCallback;
163
164 SkTDArray<void*> fOps;
165 int fIndex;
166
167 typedef Draw INHERITED;
168 };
169
69 void GrRecordReplaceDraw(const SkPicture* picture, 170 void GrRecordReplaceDraw(const SkPicture* picture,
70 SkCanvas* canvas, 171 SkCanvas* canvas,
71 const GrReplacements* replacements, 172 const GrReplacements* replacements,
72 const SkMatrix& initialMatrix, 173 const SkMatrix& initialMatrix,
73 SkDrawPictureCallback* callback) { 174 SkDrawPictureCallback* callback) {
74 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); 175 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
75 176
76 const SkBBoxHierarchy* bbh = picture->fBBH.get(); 177 ReplaceDraw draw(canvas, picture, replacements, initialMatrix, callback);
77 const SkRecord* record = picture->fRecord.get();
78 if (NULL == record) {
79 return;
80 }
81 178
82 SkRecords::Draw draw(canvas); 179 draw.draw();
83 const GrReplacements::ReplacementInfo* ri = NULL;
84 int searchStart = 0;
85
86 if (bbh) {
87 // Draw only ops that affect pixels in the canvas's current clip.
88 // The SkRecord and BBH were recorded in identity space. This canvas
89 // is not necessarily in that same space. getClipBounds() returns us
90 // this canvas' clip bounds transformed back into identity space, which
91 // lets us query the BBH.
92 SkRect query = { 0, 0, 0, 0 };
93 (void)canvas->getClipBounds(&query);
94
95 SkTDArray<void*> ops;
96 bbh->search(query, &ops);
97
98 for (int i = 0; i < ops.count(); i++) {
99 if (callback && callback->abortDrawing()) {
100 return;
101 }
102 ri = replacements->lookupByStart((uintptr_t)ops[i], &searchStart);
103 if (ri) {
104 draw_replacement_bitmap(ri, canvas, initialMatrix);
105
106 while ((uintptr_t)ops[i] < ri->fStop) {
107 ++i;
108 }
109 SkASSERT((uintptr_t)ops[i] == ri->fStop);
110 continue;
111 }
112
113 record->visit<void>((uintptr_t)ops[i], draw);
114 }
115 } else {
116 for (unsigned int i = 0; i < record->count(); ++i) {
117 if (callback && callback->abortDrawing()) {
118 return;
119 }
120 ri = replacements->lookupByStart(i, &searchStart);
121 if (ri) {
122 draw_replacement_bitmap(ri, canvas, initialMatrix);
123 i = ri->fStop;
124 continue;
125 }
126
127 record->visit<void>(i, draw);
128 }
129 }
130 } 180 }
OLDNEW
« 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