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

Side by Side Diff: gm/optimizations.cpp

Issue 12843028: Add testing of optimizations to GM (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Removed debugging cruft Created 7 years, 8 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | gyp/SampleApp.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
1 /*
2 * Copyright 2013 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "gm.h"
9 #include "..\debugger\SkDebugCanvas.h"
10 #include "SkPictureFlat.h"
11
12 namespace {
13
14 // Do the commands in 'input' match the supplied pattern? Note: this is a pretty
15 // heavy-weight operation since we are drawing the picture into a debug canvas
16 // to extract the commands.
17 bool check_pattern(SkPicture& input, const SkTDArray<DrawType> &pattern) {
18 SkDebugCanvas debugCanvas(input.width(), input.height());
19 debugCanvas.setBounds(input.width(), input.height());
20 input.draw(&debugCanvas);
21
22 if (pattern.count() != debugCanvas.getSize()) {
23 return false;
24 }
25
26 for (int i = 0; i < pattern.count(); ++i) {
27 if (pattern[i] != debugCanvas.getDrawCommandAt(i)->getType()) {
28 return false;
29 }
30 }
31
32 return true;
33 }
34
35 // construct the pattern removed by the SkPictureRecord::remove_save_layer1
36 // optimization, i.e.:
37 // SAVE_LAYER
38 // DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_REC T
39 // RESTORE
40 //
41 // saveLayerHasPaint - control if the saveLayer has a paint (the optimization
42 // takes a different path if this is false)
43 // dbmr2rHasPaint - control if the dbmr2r has a paint (the optimization
44 // takes a different path if this is false)
45 // colorsMatch - control if the saveLayer and dbmr2r paint colors
46 // match (the optimization will fail if they do not)
47 SkPicture* create_save_layer_opt_1(SkTDArray<DrawType> *preOptPattern,
48 SkTDArray<DrawType> *postOptPattern,
49 const SkBitmap& checkerBoard,
50 bool saveLayerHasPaint,
51 bool dbmr2rHasPaint,
52 bool colorsMatch) {
53 // Create the pattern that should trigger the optimization
54 preOptPattern->setCount(5);
55 (*preOptPattern)[0] = SAVE;
56 (*preOptPattern)[1] = SAVE_LAYER;
57 (*preOptPattern)[2] = DRAW_BITMAP_RECT_TO_RECT;
58 (*preOptPattern)[3] = RESTORE;
59 (*preOptPattern)[4] = RESTORE;
60
61 if (colorsMatch) {
62 // Create the pattern that should appear after the optimization
63 postOptPattern->setCount(5);
64 (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw
65 (*postOptPattern)[1] = SAVE;
66 (*postOptPattern)[2] = DRAW_BITMAP_RECT_TO_RECT;
67 (*postOptPattern)[3] = RESTORE;
68 (*postOptPattern)[4] = RESTORE;
69 } else {
70 // Create the pattern that appears if the optimization doesn't fire
71 postOptPattern->setCount(7);
72 (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw
73 (*postOptPattern)[1] = SAVE;
74 (*postOptPattern)[2] = SAVE_LAYER;
75 (*postOptPattern)[3] = DRAW_BITMAP_RECT_TO_RECT;
76 (*postOptPattern)[4] = RESTORE;
77 (*postOptPattern)[5] = RESTORE;
78 (*postOptPattern)[6] = RESTORE;
79 }
80
81 SkPicture* result = new SkPicture;
82
83 // have to disable the optimizations while generating the picture
84 SkCanvas* canvas = result->beginRecording(100, 100,
85 SkPicture::kDisableRecordOptimizations_RecordingFlag);
86
87 SkPaint saveLayerPaint;
88 saveLayerPaint.setColor(0xCC000000);
89
90 // saveLayer's 'bounds' parameter must be NULL for this optimization
91 if (saveLayerHasPaint) {
92 canvas->saveLayer(NULL, &saveLayerPaint);
93 } else {
94 canvas->saveLayer(NULL, NULL);
95 }
96
97 SkRect rect = { 10, 10, 90, 90 };
98
99 // The dbmr2r's paint must be opaque
100 SkPaint dbmr2rPaint;
101 if (colorsMatch) {
102 dbmr2rPaint.setColor(0xFF000000);
103 } else {
104 dbmr2rPaint.setColor(0xFFFF0000);
105 }
106
107 if (dbmr2rHasPaint) {
108 canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, &dbmr2rPaint);
109 } else {
110 canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, NULL);
111 }
112 canvas->restore();
113
114 result->endRecording();
115
116 return result;
117 }
118
119 // straight-ahead version that is seen in the skps
120 SkPicture* create_save_layer_opt_1_v1(SkTDArray<DrawType> *preOptPattern,
121 SkTDArray<DrawType> *postOptPattern,
122 const SkBitmap& checkerBoard) {
123 return create_save_layer_opt_1(preOptPattern, postOptPattern, checkerBoard,
124 true, // saveLayer has a paint
125 true, // dbmr2r has a paint
126 true); // and the colors match
127 }
128
129 // alternate version that should still succeed
130 SkPicture* create_save_layer_opt_1_v2(SkTDArray<DrawType> *preOptPattern,
131 SkTDArray<DrawType> *postOptPattern,
132 const SkBitmap& checkerBoard) {
133 return create_save_layer_opt_1(preOptPattern, postOptPattern, checkerBoard,
134 false, // saveLayer doesn't have a paint!
135 true, // dbmr2r has a paint
136 true); // color matching not really applicab le
137 }
138
139 // alternate version that should still succeed
140 SkPicture* create_save_layer_opt_1_v3(SkTDArray<DrawType> *preOptPattern,
141 SkTDArray<DrawType> *postOptPattern,
142 const SkBitmap& checkerBoard) {
143 return create_save_layer_opt_1(preOptPattern, postOptPattern, checkerBoard,
144 true, // saveLayer has a paint
145 false, // dbmr2r doesn't have a paint!
146 true); // color matching not really applicab le
147 }
148
149 // version in which the optimization fails b.c. the colors don't match
150 SkPicture* create_save_layer_opt_1_v4(SkTDArray<DrawType> *preOptPattern,
151 SkTDArray<DrawType> *postOptPattern,
152 const SkBitmap& checkerBoard) {
153 return create_save_layer_opt_1(preOptPattern, postOptPattern, checkerBoard,
154 true, // saveLayer has a paint
155 true, // dbmr2r has a paint
156 false); // and the colors don't match!
157 }
158
159 // construct the pattern removed by the SkPictureRecord::remove_save_layer2
160 // optimization, i.e.:
161 // SAVE_LAYER (with NULL == bounds)
162 // SAVE
163 // CLIP_RECT
164 // DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_R ECT
165 // RESTORE
166 // RESTORE
167 //
168 // saveLayerHasPaint - control if the saveLayer has a paint (the optimization
169 // takes a different path if this is false)
170 // dbmr2rHasPaint - control if the dbmr2r has a paint (the optimization
171 // takes a different path if this is false)
172 // colorsMatch - control if the saveLayer and dbmr2r paint colors
173 // match (the optimization will fail if they do not)
174 SkPicture* create_save_layer_opt_2(SkTDArray<DrawType> *preOptPattern,
175 SkTDArray<DrawType> *postOptPattern,
176 const SkBitmap& checkerBoard,
177 bool saveLayerHasPaint,
178 bool dbmr2rHasPaint,
179 bool colorsMatch) {
180 // Create the pattern that should trigger the optimization
181 preOptPattern->setCount(8);
182 (*preOptPattern)[0] = SAVE;
183 (*preOptPattern)[1] = SAVE_LAYER;
184 (*preOptPattern)[2] = SAVE;
185 (*preOptPattern)[3] = CLIP_RECT;
186 (*preOptPattern)[4] = DRAW_BITMAP_RECT_TO_RECT;
187 (*preOptPattern)[5] = RESTORE;
188 (*preOptPattern)[6] = RESTORE;
189 (*preOptPattern)[7] = RESTORE;
190
191 if (colorsMatch) {
192 // Create the pattern that should appear after the optimization
193 postOptPattern->setCount(8);
194 (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw
195 (*postOptPattern)[1] = SAVE;
196 (*postOptPattern)[2] = SAVE;
197 (*postOptPattern)[3] = CLIP_RECT;
198 (*postOptPattern)[4] = DRAW_BITMAP_RECT_TO_RECT;
199 (*postOptPattern)[5] = RESTORE;
200 (*postOptPattern)[6] = RESTORE;
201 (*postOptPattern)[7] = RESTORE;
202 } else {
203 // Create the pattern that appears if the optimization doesn't fire
204 postOptPattern->setCount(10);
205 (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw
206 (*postOptPattern)[1] = SAVE;
207 (*postOptPattern)[2] = SAVE_LAYER;
208 (*postOptPattern)[3] = SAVE;
209 (*postOptPattern)[4] = CLIP_RECT;
210 (*postOptPattern)[5] = DRAW_BITMAP_RECT_TO_RECT;
211 (*postOptPattern)[6] = RESTORE;
212 (*postOptPattern)[7] = RESTORE;
213 (*postOptPattern)[8] = RESTORE;
214 (*postOptPattern)[9] = RESTORE;
215 }
216
217 SkPicture* result = new SkPicture;
218
219 // have to disable the optimizations while generating the picture
220 SkCanvas* canvas = result->beginRecording(100, 100,
221 SkPicture::kDisableRecordOptimizations_RecordingFlag);
222
223 SkPaint saveLayerPaint;
224 saveLayerPaint.setColor(0xCC000000);
225
226 // saveLayer's 'bounds' parameter must be NULL for this optimization
227 if (saveLayerHasPaint) {
228 canvas->saveLayer(NULL, &saveLayerPaint);
229 } else {
230 canvas->saveLayer(NULL, NULL);
231 }
232
233 canvas->save();
234
235 SkRect rect = { 10, 10, 90, 90 };
236 canvas->clipRect(rect);
237
238 // The dbmr2r's paint must be opaque
239 SkPaint dbmr2rPaint;
240 if (colorsMatch) {
241 dbmr2rPaint.setColor(0xFF000000);
242 } else {
243 dbmr2rPaint.setColor(0xFFFF0000);
244 }
245
246 if (dbmr2rHasPaint) {
247 canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, &dbmr2rPaint);
248 } else {
249 canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, NULL);
250 }
251 canvas->restore();
252 canvas->restore();
253
254 result->endRecording();
255
256 return result;
257 }
258
259 // straight-ahead version that is seen in the skps
260 SkPicture* create_save_layer_opt_2_v1(SkTDArray<DrawType> *preOptPattern,
261 SkTDArray<DrawType> *postOptPattern,
262 const SkBitmap& checkerBoard) {
263 return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard,
264 true, // saveLayer has a paint
265 true, // dbmr2r has a paint
266 true); // and the colors match
267 }
268
269 // alternate version that should still succeed
270 SkPicture* create_save_layer_opt_2_v2(SkTDArray<DrawType> *preOptPattern,
271 SkTDArray<DrawType> *postOptPattern,
272 const SkBitmap& checkerBoard) {
273 return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard,
274 false, // saveLayer doesn't have a paint!
275 true, // dbmr2r has a paint
276 true); // color matching not really applicab le
277 }
278
279 // alternate version that should still succeed
280 SkPicture* create_save_layer_opt_2_v3(SkTDArray<DrawType> *preOptPattern,
281 SkTDArray<DrawType> *postOptPattern,
282 const SkBitmap& checkerBoard) {
283 return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard,
284 true, // saveLayer has a paint
285 false, // dbmr2r doesn't have a paint!
286 true); // color matching not really applicab le
287 }
288
289 // version in which the optimization fails b.c. the colors don't match
290 SkPicture* create_save_layer_opt_2_v4(SkTDArray<DrawType> *preOptPattern,
291 SkTDArray<DrawType> *postOptPattern,
292 const SkBitmap& checkerBoard) {
293 return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard,
294 true, // saveLayer has a paint
295 true, // dbmr2r has a paint
296 false); // and the colors don't match!
297 }
298
299 };
300
301
302 // As our .skp optimizations get folded into the captured skps our code will
303 // no longer be locally exercised. This GM manually constructs the patterns
304 // our optimizations will remove to test them. It acts as both a GM and a unit
305 // test
306 class OptimizationsGM : public skiagm::GM {
307 public:
308 OptimizationsGM() {
309 this->makeCheckerboard();
310 }
311
312 static const int kWidth = 800;
313 static const int kHeight = 800;
314
315 protected:
316 SkString onShortName() {
317 return SkString("optimizations");
318 }
319
320 SkISize onISize() { return SkISize::Make(kWidth, kHeight); }
321
322 typedef SkPicture* (*PFCreateOpt)(SkTDArray<DrawType> *preOptPattern,
323 SkTDArray<DrawType> *postOptPattern,
324 const SkBitmap& checkerBoard);
325
326 virtual void onDraw(SkCanvas* canvas) {
327
328 PFCreateOpt gOpts[] = {
329 create_save_layer_opt_1_v1,
330 create_save_layer_opt_1_v2,
331 create_save_layer_opt_1_v3,
332 create_save_layer_opt_1_v4,
333 create_save_layer_opt_2_v1,
334 create_save_layer_opt_2_v2,
335 create_save_layer_opt_2_v3,
336 create_save_layer_opt_2_v4,
337 };
338
339 SkTDArray<DrawType> prePattern, postPattern;
340 int xPos = 0, yPos = 0;
341
342 for (int i = 0; i < SK_ARRAY_COUNT(gOpts); ++i) {
343 SkAutoTUnref<SkPicture> pre((*gOpts[i])(&prePattern, &postPattern, f Checkerboard));
344
345 SkASSERT(check_pattern(*pre, prePattern));
Justin Novosad 2013/04/04 15:35:11 SkASSERT? Any way we could report these failures i
robertphillips 2013/04/08 17:57:52 Done.
346
347 canvas->save();
348 canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
349 pre->draw(canvas);
350 xPos += pre->width();
351 canvas->restore();
352
353 // re-render the 'pre' picture and thus 'apply' the optimization
354 SkAutoTUnref<SkPicture> post(new SkPicture);
355
356 SkCanvas* recordCanvas = post->beginRecording(pre->width(), pre->hei ght());
357
358 pre->draw(recordCanvas);
359
360 post->endRecording();
361
362 SkASSERT(check_pattern(*post, postPattern));
363
364 canvas->save();
365 canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos));
366 post->draw(canvas);
367 xPos += post->width();
368 canvas->restore();
369
370 if (xPos >= kWidth) {
371 // start a new line
372 xPos = 0;
373 yPos += post->height();
374 }
375
376 // TODO: we could also render the pre and post pictures to bitmaps
377 // and manually compare them in this method
378 }
379 }
380
381 private:
382 void makeCheckerboard() {
383 static const unsigned int kCheckerboardWidth = 16;
384 static const unsigned int kCheckerboardHeight = 16;
385
386 fCheckerboard.setConfig(SkBitmap::kARGB_8888_Config,
387 kCheckerboardWidth, kCheckerboardHeight);
388 fCheckerboard.allocPixels();
389 SkAutoLockPixels lock(fCheckerboard);
390 for (int y = 0; y < kCheckerboardHeight; y += 2) {
391 SkPMColor* scanline = fCheckerboard.getAddr32(0, y);
392 for (int x = 0; x < kCheckerboardWidth; x += 2) {
393 *scanline++ = 0xFFFFFFFF;
394 *scanline++ = 0xFF000000;
395 }
396 scanline = fCheckerboard.getAddr32(0, y + 1);
397 for (int x = 0; x < kCheckerboardWidth; x += 2) {
398 *scanline++ = 0xFF000000;
399 *scanline++ = 0xFFFFFFFF;
400 }
401 }
402 }
403
404 SkBitmap fCheckerboard;
405
406 typedef skiagm::GM INHERITED;
407 };
408
409 //////////////////////////////////////////////////////////////////////////////
410
411 DEF_GM( return new OptimizationsGM; )
OLDNEW
« no previous file with comments | « no previous file | gyp/SampleApp.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698