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

Side by Side Diff: src/effects/SkLayerDrawLooper.cpp

Issue 1362253002: Simplify SkLayerDrawLooper Base URL: https://chromium.googlesource.com/skia.git@flat
Patch Set: Created 5 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 unified diff | Download patch
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2011 Google Inc. 3 * Copyright 2011 Google Inc.
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 #include "SkCanvas.h" 8 #include "SkCanvas.h"
9 #include "SkColor.h" 9 #include "SkColor.h"
10 #include "SkPaint.h"
10 #include "SkReadBuffer.h" 11 #include "SkReadBuffer.h"
11 #include "SkWriteBuffer.h" 12 #include "SkWriteBuffer.h"
12 #include "SkLayerDrawLooper.h" 13 #include "SkLayerDrawLooper.h"
13 #include "SkString.h" 14 #include "SkString.h"
14 #include "SkStringUtils.h" 15 #include "SkStringUtils.h"
15 #include "SkUnPreMultiply.h" 16 #include "SkUnPreMultiply.h"
16 17
17 SkLayerDrawLooper::LayerInfo::LayerInfo() { 18 SkLayerDrawLooper::LayerInfo::LayerInfo() {
18 fPaintBits = 0; // ignore our paint fields 19 fPaintBits = 0; // ignore our paint fields
19 fColorMode = SkXfermode::kDst_Mode; // ignore our color 20 fColorMode = SkXfermode::kDst_Mode; // ignore our color
20 fOffset.set(0, 0); 21 fOffset.set(0, 0);
21 fPostTranslate = false; 22 fPostTranslate = false;
22 } 23 }
23 24
24 SkLayerDrawLooper::SkLayerDrawLooper() 25 SkLayerDrawLooper::SkLayerDrawLooper() : fRecs() {}
25 : fRecs(nullptr),
26 fCount(0) {
27 }
28 26
29 SkLayerDrawLooper::~SkLayerDrawLooper() { 27 SkLayerDrawLooper::~SkLayerDrawLooper() {}
30 Rec* rec = fRecs; 28
31 while (rec) { 29 struct SkLayerDrawLooper::Rec {
32 Rec* next = rec->fNext; 30 explicit Rec(const LayerInfo& info) : fPaint(), fInfo(info) {}
33 delete rec; 31
34 rec = next; 32 SkPaint fPaint;
35 } 33 LayerInfo fInfo;
36 } 34 };
37 35
38 SkLayerDrawLooper::Context* SkLayerDrawLooper::createContext(SkCanvas* canvas, v oid* storage) const { 36 SkLayerDrawLooper::Context* SkLayerDrawLooper::createContext(SkCanvas* canvas, v oid* storage) const {
39 canvas->save(); 37 canvas->save();
40 return new (storage) LayerDrawLooperContext(this); 38 return new (storage) LayerDrawLooperContext(this);
41 } 39 }
42 40
43 static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) { 41 static SkColor xferColor(SkColor src, SkColor dst, SkXfermode::Mode mode) {
44 switch (mode) { 42 switch (mode) {
45 case SkXfermode::kSrc_Mode: 43 case SkXfermode::kSrc_Mode:
46 return src; 44 return src;
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 } 119 }
122 120
123 // Should we add this to canvas? 121 // Should we add this to canvas?
124 static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) { 122 static void postTranslate(SkCanvas* canvas, SkScalar dx, SkScalar dy) {
125 SkMatrix m = canvas->getTotalMatrix(); 123 SkMatrix m = canvas->getTotalMatrix();
126 m.postTranslate(dx, dy); 124 m.postTranslate(dx, dy);
127 canvas->setMatrix(m); 125 canvas->setMatrix(m);
128 } 126 }
129 127
130 SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext( 128 SkLayerDrawLooper::LayerDrawLooperContext::LayerDrawLooperContext(
131 const SkLayerDrawLooper* looper) : fCurrRec(looper->fRecs) {} 129 const SkLayerDrawLooper* looper)
130 : fCurr(looper->fRecs.begin()), fEnd(looper->fRecs.end()) {}
132 131
133 bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas, 132 bool SkLayerDrawLooper::LayerDrawLooperContext::next(SkCanvas* canvas,
134 SkPaint* paint) { 133 SkPaint* paint) {
135 canvas->restore(); 134 canvas->restore();
136 if (nullptr == fCurrRec) { 135 if (fEnd == fCurr) {
137 return false; 136 return false;
138 } 137 }
139 138
140 ApplyInfo(paint, fCurrRec->fPaint, fCurrRec->fInfo); 139 const Rec& rec = *fCurr++;
140 ApplyInfo(paint, rec.fPaint, rec.fInfo);
141 141
142 canvas->save(); 142 canvas->save();
143 if (fCurrRec->fInfo.fPostTranslate) { 143 if (rec.fInfo.fPostTranslate) {
144 postTranslate(canvas, fCurrRec->fInfo.fOffset.fX, 144 postTranslate(canvas, rec.fInfo.fOffset.fX,
145 fCurrRec->fInfo.fOffset.fY); 145 rec.fInfo.fOffset.fY);
146 } else { 146 } else {
147 canvas->translate(fCurrRec->fInfo.fOffset.fX, 147 canvas->translate(rec.fInfo.fOffset.fX,
148 fCurrRec->fInfo.fOffset.fY); 148 rec.fInfo.fOffset.fY);
149 } 149 }
150 fCurrRec = fCurrRec->fNext;
151 150
152 return true; 151 return true;
153 } 152 }
154 153
155 bool SkLayerDrawLooper::asABlurShadow(BlurShadowRec* bsRec) const { 154 bool SkLayerDrawLooper::asABlurShadow(BlurShadowRec* bsRec) const {
156 if (fCount != 2) { 155 if (fRecs.size() != 2) {
157 return false; 156 return false;
158 } 157 }
159 const Rec* rec = fRecs; 158 const Rec* rec = &fRecs[0];
160 159
161 // bottom layer needs to be just blur(maskfilter) 160 // bottom layer needs to be just blur(maskfilter)
162 if ((rec->fInfo.fPaintBits & ~kMaskFilter_Bit)) { 161 if ((rec->fInfo.fPaintBits & ~kMaskFilter_Bit)) {
163 return false; 162 return false;
164 } 163 }
165 if (SkXfermode::kSrc_Mode != rec->fInfo.fColorMode) { 164 if (SkXfermode::kSrc_Mode != rec->fInfo.fColorMode) {
166 return false; 165 return false;
167 } 166 }
168 const SkMaskFilter* mf = rec->fPaint.getMaskFilter(); 167 const SkMaskFilter* mf = rec->fPaint.getMaskFilter();
169 if (nullptr == mf) { 168 if (nullptr == mf) {
170 return false; 169 return false;
171 } 170 }
172 SkMaskFilter::BlurRec maskBlur; 171 SkMaskFilter::BlurRec maskBlur;
173 if (!mf->asABlur(&maskBlur)) { 172 if (!mf->asABlur(&maskBlur)) {
174 return false; 173 return false;
175 } 174 }
176 175
177 rec = rec->fNext; 176 rec = &fRecs[1];
178 // top layer needs to be "plain" 177 // top layer needs to be "plain"
179 if (rec->fInfo.fPaintBits) { 178 if (rec->fInfo.fPaintBits) {
180 return false; 179 return false;
181 } 180 }
182 if (SkXfermode::kDst_Mode != rec->fInfo.fColorMode) { 181 if (SkXfermode::kDst_Mode != rec->fInfo.fColorMode) {
183 return false; 182 return false;
184 } 183 }
185 if (!rec->fInfo.fOffset.equals(0, 0)) { 184 if (!rec->fInfo.fOffset.equals(0, 0)) {
186 return false; 185 return false;
187 } 186 }
188 187
189 if (bsRec) { 188 if (bsRec) {
190 bsRec->fSigma = maskBlur.fSigma; 189 bsRec->fSigma = maskBlur.fSigma;
191 bsRec->fOffset = fRecs->fInfo.fOffset; 190 bsRec->fOffset = fRecs[0].fInfo.fOffset;
192 bsRec->fColor = fRecs->fPaint.getColor(); 191 bsRec->fColor = fRecs[0].fPaint.getColor();
193 bsRec->fStyle = maskBlur.fStyle; 192 bsRec->fStyle = maskBlur.fStyle;
194 bsRec->fQuality = maskBlur.fQuality; 193 bsRec->fQuality = maskBlur.fQuality;
195 } 194 }
196 return true; 195 return true;
197 } 196 }
198 197
199 /////////////////////////////////////////////////////////////////////////////// 198 ///////////////////////////////////////////////////////////////////////////////
200 199
201 void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const { 200 void SkLayerDrawLooper::flatten(SkWriteBuffer& buffer) const {
202 buffer.writeInt(fCount); 201 buffer.writeInt(fRecs.size());
203 202
204 Rec* rec = fRecs; 203 for (const Rec& rec : fRecs) {
205 for (int i = 0; i < fCount; i++) {
206 // Legacy "flagsmask" field -- now ignored, remove when we bump version 204 // Legacy "flagsmask" field -- now ignored, remove when we bump version
207 buffer.writeInt(0); 205 buffer.writeInt(0);
208 206
209 buffer.writeInt(rec->fInfo.fPaintBits); 207 buffer.writeInt(rec.fInfo.fPaintBits);
210 buffer.writeInt(rec->fInfo.fColorMode); 208 buffer.writeInt(rec.fInfo.fColorMode);
211 buffer.writePoint(rec->fInfo.fOffset); 209 buffer.writePoint(rec.fInfo.fOffset);
212 buffer.writeBool(rec->fInfo.fPostTranslate); 210 buffer.writeBool(rec.fInfo.fPostTranslate);
213 buffer.writePaint(rec->fPaint); 211 buffer.writePaint(rec.fPaint);
214 rec = rec->fNext;
215 } 212 }
216 } 213 }
217 214
218 SkFlattenable* SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) { 215 SkFlattenable* SkLayerDrawLooper::CreateProc(SkReadBuffer& buffer) {
219 int count = buffer.readInt(); 216 int count = buffer.readInt();
220 217
221 Builder builder; 218 Builder builder;
219 builder.reserve(count);
222 for (int i = 0; i < count; i++) { 220 for (int i = 0; i < count; i++) {
223 LayerInfo info; 221 LayerInfo info;
224 // Legacy "flagsmask" field -- now ignored, remove when we bump version 222 // Legacy "flagsmask" field -- now ignored, remove when we bump version
225 (void)buffer.readInt(); 223 (void)buffer.readInt();
226 224
227 info.fPaintBits = buffer.readInt(); 225 info.fPaintBits = buffer.readInt();
228 info.fColorMode = (SkXfermode::Mode)buffer.readInt(); 226 info.fColorMode = (SkXfermode::Mode)buffer.readInt();
229 buffer.readPoint(&info.fOffset); 227 buffer.readPoint(&info.fOffset);
230 info.fPostTranslate = buffer.readBool(); 228 info.fPostTranslate = buffer.readBool();
231 buffer.readPaint(builder.addLayerOnTop(info)); 229 buffer.readPaint(builder.addLayerOnTop(info));
232 } 230 }
233 return builder.detachLooper(); 231 return builder.detachLooper();
234 } 232 }
235 233
236 #ifndef SK_IGNORE_TO_STRING 234 #ifndef SK_IGNORE_TO_STRING
237 void SkLayerDrawLooper::toString(SkString* str) const { 235 void SkLayerDrawLooper::toString(SkString* str) const {
238 str->appendf("SkLayerDrawLooper (%d): ", fCount); 236 str->appendf("SkLayerDrawLooper (%zu): ", fRecs.size());
239 237
240 Rec* rec = fRecs; 238 for (size_t i = 0; i < fRecs.size(); i++) {
241 for (int i = 0; i < fCount; i++) { 239 const Rec& rec = fRecs[i];
242 str->appendf("%d: paintBits: (", i); 240 str->appendf("%zu: paintBits: (", i);
243 if (0 == rec->fInfo.fPaintBits) { 241 if (0 == rec.fInfo.fPaintBits) {
244 str->append("None"); 242 str->append("None");
245 } else if (kEntirePaint_Bits == rec->fInfo.fPaintBits) { 243 } else if (kEntirePaint_Bits == rec.fInfo.fPaintBits) {
246 str->append("EntirePaint"); 244 str->append("EntirePaint");
247 } else { 245 } else {
248 bool needSeparator = false; 246 bool needSeparator = false;
249 SkAddFlagToString(str, SkToBool(kStyle_Bit & rec->fInfo.fPaintBits), "Style", 247 SkAddFlagToString(str, SkToBool(kStyle_Bit & rec.fInfo.fPaintBits), "Style",
250 &needSeparator); 248 &needSeparator);
251 SkAddFlagToString(str, SkToBool(kTextSkewX_Bit & rec->fInfo.fPaintBi ts), "TextSkewX", 249 SkAddFlagToString(str, SkToBool(kTextSkewX_Bit & rec.fInfo.fPaintBit s), "TextSkewX",
252 &needSeparator); 250 &needSeparator);
253 SkAddFlagToString(str, SkToBool(kPathEffect_Bit & rec->fInfo.fPaintB its), "PathEffect", 251 SkAddFlagToString(str, SkToBool(kPathEffect_Bit & rec.fInfo.fPaintBi ts), "PathEffect",
254 &needSeparator); 252 &needSeparator);
255 SkAddFlagToString(str, SkToBool(kMaskFilter_Bit & rec->fInfo.fPaintB its), "MaskFilter", 253 SkAddFlagToString(str, SkToBool(kMaskFilter_Bit & rec.fInfo.fPaintBi ts), "MaskFilter",
256 &needSeparator); 254 &needSeparator);
257 SkAddFlagToString(str, SkToBool(kShader_Bit & rec->fInfo.fPaintBits) , "Shader", 255 SkAddFlagToString(str, SkToBool(kShader_Bit & rec.fInfo.fPaintBits), "Shader",
258 &needSeparator); 256 &needSeparator);
259 SkAddFlagToString(str, SkToBool(kColorFilter_Bit & rec->fInfo.fPaint Bits), "ColorFilter", 257 SkAddFlagToString(str, SkToBool(kColorFilter_Bit & rec.fInfo.fPaintB its), "ColorFilter",
260 &needSeparator); 258 &needSeparator);
261 SkAddFlagToString(str, SkToBool(kXfermode_Bit & rec->fInfo.fPaintBit s), "Xfermode", 259 SkAddFlagToString(str, SkToBool(kXfermode_Bit & rec.fInfo.fPaintBits ), "Xfermode",
262 &needSeparator); 260 &needSeparator);
263 } 261 }
264 str->append(") "); 262 str->append(") ");
265 263
266 static const char* gModeStrings[SkXfermode::kLastMode+1] = { 264 static const char* gModeStrings[SkXfermode::kLastMode+1] = {
267 "kClear", "kSrc", "kDst", "kSrcOver", "kDstOver", "kSrcIn", "kDstIn" , 265 "kClear", "kSrc", "kDst", "kSrcOver", "kDstOver", "kSrcIn", "kDstIn" ,
268 "kSrcOut", "kDstOut", "kSrcATop", "kDstATop", "kXor", "kPlus", 266 "kSrcOut", "kDstOut", "kSrcATop", "kDstATop", "kXor", "kPlus",
269 "kMultiply", "kScreen", "kOverlay", "kDarken", "kLighten", "kColorDo dge", 267 "kMultiply", "kScreen", "kOverlay", "kDarken", "kLighten", "kColorDo dge",
270 "kColorBurn", "kHardLight", "kSoftLight", "kDifference", "kExclusion " 268 "kColorBurn", "kHardLight", "kSoftLight", "kDifference", "kExclusion "
271 }; 269 };
272 270
273 str->appendf("mode: %s ", gModeStrings[rec->fInfo.fColorMode]); 271 str->appendf("mode: %s ", gModeStrings[rec.fInfo.fColorMode]);
274 272
275 str->append("offset: ("); 273 str->append("offset: (");
276 str->appendScalar(rec->fInfo.fOffset.fX); 274 str->appendScalar(rec.fInfo.fOffset.fX);
277 str->append(", "); 275 str->append(", ");
278 str->appendScalar(rec->fInfo.fOffset.fY); 276 str->appendScalar(rec.fInfo.fOffset.fY);
279 str->append(") "); 277 str->append(") ");
280 278
281 str->append("postTranslate: "); 279 str->append("postTranslate: ");
282 if (rec->fInfo.fPostTranslate) { 280 if (rec.fInfo.fPostTranslate) {
283 str->append("true "); 281 str->append("true ");
284 } else { 282 } else {
285 str->append("false "); 283 str->append("false ");
286 } 284 }
287 285
288 rec->fPaint.toString(str); 286 rec.fPaint.toString(str);
289 rec = rec->fNext;
290 } 287 }
291 } 288 }
292 #endif 289 #endif
293 290
294 SkLayerDrawLooper::Builder::Builder() 291 SkLayerDrawLooper::Builder::Builder()
295 : fRecs(nullptr), 292 : fRecs() {}
296 fTopRec(nullptr),
297 fCount(0) {
298 }
299 293
300 SkLayerDrawLooper::Builder::~Builder() { 294 SkLayerDrawLooper::Builder::~Builder() {}
301 Rec* rec = fRecs;
302 while (rec) {
303 Rec* next = rec->fNext;
304 delete rec;
305 rec = next;
306 }
307 }
308 295
309 SkPaint* SkLayerDrawLooper::Builder::addLayer(const LayerInfo& info) { 296 void SkLayerDrawLooper::Builder::reserve(size_t n) {
310 fCount += 1; 297 fRecs.reserve(n);
311
312 Rec* rec = new Rec;
313 rec->fNext = fRecs;
314 rec->fInfo = info;
315 fRecs = rec;
316 if (nullptr == fTopRec) {
317 fTopRec = rec;
318 }
319
320 return &rec->fPaint;
321 }
322
323 void SkLayerDrawLooper::Builder::addLayer(SkScalar dx, SkScalar dy) {
324 LayerInfo info;
325
326 info.fOffset.set(dx, dy);
327 (void)this->addLayer(info);
328 } 298 }
329 299
330 SkPaint* SkLayerDrawLooper::Builder::addLayerOnTop(const LayerInfo& info) { 300 SkPaint* SkLayerDrawLooper::Builder::addLayerOnTop(const LayerInfo& info) {
331 fCount += 1; 301 fRecs.push_back(Rec(info));
302 return &fRecs.back().fPaint;
303 }
332 304
333 Rec* rec = new Rec; 305 void SkLayerDrawLooper::Builder::addLayerOnTop(SkScalar dx, SkScalar dy) {
334 rec->fNext = nullptr; 306 LayerInfo info;
335 rec->fInfo = info; 307 info.fOffset.set(dx, dy);
336 if (nullptr == fRecs) { 308 this->addLayerOnTop(info);
337 fRecs = rec;
338 } else {
339 SkASSERT(fTopRec);
340 fTopRec->fNext = rec;
341 }
342 fTopRec = rec;
343
344 return &rec->fPaint;
345 } 309 }
346 310
347 SkLayerDrawLooper* SkLayerDrawLooper::Builder::detachLooper() { 311 SkLayerDrawLooper* SkLayerDrawLooper::Builder::detachLooper() {
348 SkLayerDrawLooper* looper = new SkLayerDrawLooper; 312 SkLayerDrawLooper* looper = new SkLayerDrawLooper;
349 looper->fCount = fCount; 313 fRecs.swap(looper->fRecs);
350 looper->fRecs = fRecs;
351
352 fCount = 0;
353 fRecs = nullptr;
354 fTopRec = nullptr;
355
356 return looper; 314 return looper;
357 } 315 }
OLDNEW
« include/effects/SkLayerDrawLooper.h ('K') | « include/effects/SkLayerDrawLooper.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698