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

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: Updated 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 "SkImage.h" 9 #include "SkImage.h"
10 #include "SkRecordDraw.h" 10 #include "SkRecordDraw.h"
11 #include "SkRecords.h"
12 #include "SkCanvasPriv.h"
egdaniel 2014/10/01 13:28:12 Alphabetize
robertphillips 2014/10/01 16:04:24 Done.
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
26 void GrReplacements::validate() const {
27 // Check that the ranges are monotonically increasing and non-overlapping
28 if (fReplacements.count() > 0) {
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* 33 const GrReplacements::ReplacementInfo*
40 GrReplacements::lookupByStart(size_t start, int* searchStart) const { 34 GrReplacements::lookupByStart(uint32_t pictureID, size_t start, const SkMatrix& ctm) const {
egdaniel 2014/10/01 13:28:12 is it normal to have a newline between the return
robertphillips 2014/10/01 16:04:24 Done.
41 SkDEBUGCODE(this->validate()); 35 return fReplacementHash.find(ReplacementInfo::Key(pictureID, start, ctm));
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 } 36 }
53 37
54 static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo * ri, 38 static inline void draw_replacement_bitmap(const GrReplacements::ReplacementInfo * ri,
55 SkCanvas* canvas, 39 SkCanvas* canvas,
56 const SkMatrix& initialMatrix) { 40 const SkMatrix& initialMatrix) {
57 SkRect src = SkRect::Make(ri->fSrcRect); 41 SkRect src = SkRect::Make(ri->fSrcRect);
58 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX), 42 SkRect dst = SkRect::MakeXYWH(SkIntToScalar(ri->fPos.fX),
59 SkIntToScalar(ri->fPos.fY), 43 SkIntToScalar(ri->fPos.fY),
60 SkIntToScalar(ri->fSrcRect.width()), 44 SkIntToScalar(ri->fSrcRect.width()),
61 SkIntToScalar(ri->fSrcRect.height())); 45 SkIntToScalar(ri->fSrcRect.height()));
62 46
63 canvas->save(); 47 canvas->save();
64 canvas->setMatrix(initialMatrix); 48 canvas->setMatrix(initialMatrix);
65 canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint); 49 canvas->drawImageRect(ri->fImage, &src, dst, ri->fPaint);
66 canvas->restore(); 50 canvas->restore();
67 } 51 }
68 52
53 // Used by GrRecordReplaceDraw. It intercepts nested drawPicture calls and
54 // also draws them with replaced layers.
55 class ReplaceDraw : public SkRecords::Draw {
56 public:
57 ReplaceDraw(SkCanvas* canvas,
58 const SkPicture* picture,
59 const GrReplacements* replacements,
60 const SkMatrix& initialMatrix,
61 SkDrawPictureCallback* callback)
62 : INHERITED(canvas)
63 , fCanvas(canvas)
64 , fPicture(picture)
65 , fReplacements(replacements)
66 , fInitialMatrix(initialMatrix)
67 , fCallback(callback)
68 , fIndex(0) {
69 }
70
71 void draw() {
72 const SkBBoxHierarchy* bbh = fPicture->fBBH.get();
73 const SkRecord* record = fPicture->fRecord.get();
74 if (NULL == record) {
75 return;
76 }
77
78 fOps.rewind();
79
80 if (bbh) {
81 // Draw only ops that affect pixels in the canvas's current clip.
82 // The SkRecord and BBH were recorded in identity space. This canva s
83 // is not necessarily in that same space. getClipBounds() returns u s
84 // this canvas' clip bounds transformed back into identity space, wh ich
85 // lets us query the BBH.
86 SkRect query = { 0, 0, 0, 0 };
87 (void)fCanvas->getClipBounds(&query);
88
89 bbh->search(query, &fOps);
90
91 for (fIndex = 0; fIndex < fOps.count(); ++fIndex) {
92 if (fCallback && fCallback->abortDrawing()) {
93 return;
94 }
95
96 record->visit<void>((uintptr_t)fOps[fIndex], *this);
97 }
98
99 } else {
100 for (fIndex = 0; fIndex < (int) record->count(); ++fIndex) {
101 if (fCallback && fCallback->abortDrawing()) {
102 return;
103 }
104
105 record->visit<void>(fIndex, *this);
106 }
107 }
108 }
109
110 // Same as Draw for all ops except DrawPicture and SaveLayer.
111 template <typename T> void operator()(const T& r) {
112 this->INHERITED::operator()(r);
113 }
114 void operator()(const SkRecords::DrawPicture& dp) {
115 SkAutoCanvasMatrixPaint acmp(fCanvas, dp.matrix, dp.paint, dp.picture->c ullRect());
116
117 // Draw sub-pictures with the same replacement list but a different pict ure
118 ReplaceDraw draw(fCanvas, dp.picture, fReplacements, fInitialMatrix, fCa llback);
119
120 draw.draw();
121 }
122 void operator()(const SkRecords::SaveLayer& sl) {
123
124 // For a saveLayer command, check if it can be replaced by a drawBitmap
125 // call and, if so, draw it and then update the current op index accordi ngly.
126 size_t startOffset;
127 if (fOps.count()) {
128 startOffset = (uintptr_t)fOps[fIndex];
129 } else {
130 startOffset = fIndex;
131 }
132
133 const GrReplacements::ReplacementInfo* ri = fReplacements->lookupByStart (
134 fPicture->uniqueID() ,
135 startOffset,
136 fCanvas->getTotalMat rix());
137
138 if (ri) {
139 draw_replacement_bitmap(ri, fCanvas, fInitialMatrix);
140
141 if (fPicture->fBBH.get()) {
142 while ((uintptr_t)fOps[fIndex] < ri->fStop) {
143 ++fIndex;
144 }
145 SkASSERT((uintptr_t)fOps[fIndex] == ri->fStop);
146 } else {
147 fIndex = ri->fStop;
148 }
149 return;
150 }
151
152 // This is a fail for layer hoisting
153 this->INHERITED::operator()(sl);
154 }
155
156 private:
157 SkCanvas* fCanvas;
158 const SkPicture* fPicture;
159 const GrReplacements* fReplacements;
160 const SkMatrix fInitialMatrix;
161 SkDrawPictureCallback* fCallback;
162
163 SkTDArray<void*> fOps;
164 int fIndex;
165
166 typedef Draw INHERITED;
167 };
168
69 void GrRecordReplaceDraw(const SkPicture* picture, 169 void GrRecordReplaceDraw(const SkPicture* picture,
70 SkCanvas* canvas, 170 SkCanvas* canvas,
71 const GrReplacements* replacements, 171 const GrReplacements* replacements,
72 const SkMatrix& initialMatrix, 172 const SkMatrix& initialMatrix,
73 SkDrawPictureCallback* callback) { 173 SkDrawPictureCallback* callback) {
74 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/); 174 SkAutoCanvasRestore saveRestore(canvas, true /*save now, restore at exit*/);
75 175
76 const SkBBoxHierarchy* bbh = picture->fBBH.get(); 176 ReplaceDraw draw(canvas, picture, replacements, initialMatrix, callback);
77 const SkRecord* record = picture->fRecord.get();
78 if (NULL == record) {
79 return;
80 }
81 177
82 SkRecords::Draw draw(canvas); 178 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 } 179 }
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