| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 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 "SkDebugCanvas.h" | 
 | 10 | #include "SkPictureFlat.h" | 
| robertphillips@google.com | 770963f | 2014-04-18 18:04:41 +0000 | [diff] [blame] | 11 | #include "SkPictureRecorder.h" | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 12 |  | 
 | 13 | #define WARN(msg)                                           \ | 
 | 14 |     SkDebugf("%s:%d: %s\n", __FILE__, __LINE__, msg); | 
 | 15 |  | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 16 | // Do the commands in 'input' match the supplied pattern? Note: this is a pretty | 
| skia.committer@gmail.com | 4bb50b2 | 2013-04-13 07:01:15 +0000 | [diff] [blame] | 17 | // heavy-weight operation since we are drawing the picture into a debug canvas | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 18 | // to extract the commands. | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 19 | static bool check_pattern(SkPicture& input, const SkTDArray<DrawType> &pattern) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 20 |     SkDebugCanvas debugCanvas(input.width(), input.height()); | 
 | 21 |     debugCanvas.setBounds(input.width(), input.height()); | 
 | 22 |     input.draw(&debugCanvas); | 
 | 23 |  | 
 | 24 |     if (pattern.count() != debugCanvas.getSize()) { | 
 | 25 |         return false; | 
 | 26 |     } | 
 | 27 |  | 
 | 28 |     for (int i = 0; i < pattern.count(); ++i) { | 
 | 29 |         if (pattern[i] != debugCanvas.getDrawCommandAt(i)->getType()) { | 
 | 30 |             return false; | 
 | 31 |         } | 
 | 32 |     } | 
 | 33 |  | 
 | 34 |     return true; | 
 | 35 | } | 
 | 36 |  | 
 | 37 | // construct the pattern removed by the SkPictureRecord::remove_save_layer1 | 
 | 38 | // optimization, i.e.: | 
 | 39 | //   SAVE_LAYER | 
 | 40 | //       DRAW_BITMAP|DRAW_BITMAP_MATRIX|DRAW_BITMAP_NINE|DRAW_BITMAP_RECT_TO_RECT | 
 | 41 | //   RESTORE | 
 | 42 | // | 
 | 43 | // saveLayerHasPaint - control if the saveLayer has a paint (the optimization | 
 | 44 | //                     takes a different path if this is false) | 
 | 45 | // dbmr2rHasPaint    - control if the dbmr2r has a paint (the optimization | 
 | 46 | //                     takes a different path if this is false) | 
 | 47 | // colorsMatch       - control if the saveLayer and dbmr2r paint colors | 
 | 48 | //                     match (the optimization will fail if they do not) | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 49 | static SkPicture* create_save_layer_opt_1(SkTDArray<DrawType>* preOptPattern, | 
 | 50 |                                           SkTDArray<DrawType>* postOptPattern, | 
 | 51 |                                           const SkBitmap& checkerBoard, | 
 | 52 |                                           bool saveLayerHasPaint, | 
 | 53 |                                           bool dbmr2rHasPaint, | 
 | 54 |                                           bool colorsMatch)  { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 55 |     // Create the pattern that should trigger the optimization | 
 | 56 |     preOptPattern->setCount(5); | 
 | 57 |     (*preOptPattern)[0] = SAVE; | 
 | 58 |     (*preOptPattern)[1] = SAVE_LAYER; | 
 | 59 |     (*preOptPattern)[2] = DRAW_BITMAP_RECT_TO_RECT; | 
 | 60 |     (*preOptPattern)[3] = RESTORE; | 
 | 61 |     (*preOptPattern)[4] = RESTORE; | 
 | 62 |  | 
 | 63 |     if (colorsMatch) { | 
 | 64 |         // Create the pattern that should appear after the optimization | 
 | 65 |         postOptPattern->setCount(5); | 
 | 66 |         (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw | 
 | 67 |         (*postOptPattern)[1] = SAVE; | 
 | 68 |         (*postOptPattern)[2] = DRAW_BITMAP_RECT_TO_RECT; | 
 | 69 |         (*postOptPattern)[3] = RESTORE; | 
 | 70 |         (*postOptPattern)[4] = RESTORE; | 
 | 71 |     } else { | 
 | 72 |         // Create the pattern that appears if the optimization doesn't fire | 
 | 73 |         postOptPattern->setCount(7); | 
 | 74 |         (*postOptPattern)[0] = SAVE; // extra save/restore added by extra draw | 
 | 75 |         (*postOptPattern)[1] = SAVE; | 
 | 76 |         (*postOptPattern)[2] = SAVE_LAYER; | 
 | 77 |         (*postOptPattern)[3] = DRAW_BITMAP_RECT_TO_RECT; | 
 | 78 |         (*postOptPattern)[4] = RESTORE; | 
 | 79 |         (*postOptPattern)[5] = RESTORE; | 
 | 80 |         (*postOptPattern)[6] = RESTORE; | 
 | 81 |     } | 
 | 82 |  | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 83 |     SkPictureRecorder recorder; | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 84 |  | 
| commit-bot@chromium.org | 5fb2ce3 | 2014-04-17 23:35:06 +0000 | [diff] [blame] | 85 |     SkCanvas* canvas = recorder.beginRecording(100, 100, NULL, 0); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 86 |     // have to disable the optimizations while generating the picture | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 87 |     recorder.internalOnly_EnableOpts(false); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 88 |  | 
 | 89 |     SkPaint saveLayerPaint; | 
 | 90 |     saveLayerPaint.setColor(0xCC000000); | 
 | 91 |  | 
 | 92 |     // saveLayer's 'bounds' parameter must be NULL for this optimization | 
 | 93 |     if (saveLayerHasPaint) { | 
 | 94 |         canvas->saveLayer(NULL, &saveLayerPaint); | 
 | 95 |     } else { | 
 | 96 |         canvas->saveLayer(NULL, NULL); | 
 | 97 |     } | 
 | 98 |  | 
 | 99 |     SkRect rect = { 10, 10, 90, 90 }; | 
 | 100 |  | 
 | 101 |     // The dbmr2r's paint must be opaque | 
 | 102 |     SkPaint dbmr2rPaint; | 
 | 103 |     if (colorsMatch) { | 
 | 104 |         dbmr2rPaint.setColor(0xFF000000); | 
 | 105 |     } else { | 
 | 106 |         dbmr2rPaint.setColor(0xFFFF0000); | 
 | 107 |     } | 
 | 108 |  | 
 | 109 |     if (dbmr2rHasPaint) { | 
 | 110 |         canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, &dbmr2rPaint); | 
 | 111 |     } else { | 
 | 112 |         canvas->drawBitmapRectToRect(checkerBoard, NULL, rect, NULL); | 
 | 113 |     } | 
 | 114 |     canvas->restore(); | 
 | 115 |  | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 116 |     return recorder.endRecording(); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 117 | } | 
 | 118 |  | 
 | 119 | // straight-ahead version that is seen in the skps | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 120 | static SkPicture* create_save_layer_opt_1_v1(SkTDArray<DrawType>* preOptPattern, | 
 | 121 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 122 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 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 | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 130 | static SkPicture* create_save_layer_opt_1_v2(SkTDArray<DrawType>* preOptPattern, | 
 | 131 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 132 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 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 applicable | 
 | 137 | } | 
 | 138 |  | 
 | 139 | // alternate version that should still succeed | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 140 | static SkPicture* create_save_layer_opt_1_v3(SkTDArray<DrawType>* preOptPattern, | 
 | 141 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 142 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 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 applicable | 
 | 147 | } | 
 | 148 |  | 
 | 149 | // version in which the optimization fails b.c. the colors don't match | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 150 | static SkPicture* create_save_layer_opt_1_v4(SkTDArray<DrawType>* preOptPattern, | 
 | 151 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 152 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 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_RECT | 
 | 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) | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 174 | static 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)  { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 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 |  | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 217 |     SkPictureRecorder recorder; | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 218 |  | 
| commit-bot@chromium.org | 5fb2ce3 | 2014-04-17 23:35:06 +0000 | [diff] [blame] | 219 |     SkCanvas* canvas = recorder.beginRecording(100, 100, NULL, 0); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 220 |     // have to disable the optimizations while generating the picture | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 221 |     recorder.internalOnly_EnableOpts(false); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 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 |  | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 254 |     return recorder.endRecording(); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 255 | } | 
 | 256 |  | 
 | 257 | // straight-ahead version that is seen in the skps | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 258 | static SkPicture* create_save_layer_opt_2_v1(SkTDArray<DrawType>* preOptPattern, | 
 | 259 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 260 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 261 |     return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard, | 
 | 262 |                                    true,   // saveLayer has a paint | 
 | 263 |                                    true,   // dbmr2r has a paint | 
 | 264 |                                    true);  // and the colors match | 
 | 265 | } | 
 | 266 |  | 
 | 267 | // alternate version that should still succeed | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 268 | static SkPicture* create_save_layer_opt_2_v2(SkTDArray<DrawType>* preOptPattern, | 
 | 269 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 270 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 271 |     return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard, | 
 | 272 |                                    false,  // saveLayer doesn't have a paint! | 
 | 273 |                                    true,   // dbmr2r has a paint | 
 | 274 |                                    true);  // color matching not really applicable | 
 | 275 | } | 
 | 276 |  | 
 | 277 | // alternate version that should still succeed | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 278 | static SkPicture* create_save_layer_opt_2_v3(SkTDArray<DrawType>* preOptPattern, | 
 | 279 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 280 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 281 |     return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard, | 
 | 282 |                                    true,   // saveLayer has a paint | 
 | 283 |                                    false,  // dbmr2r doesn't have a paint! | 
 | 284 |                                    true);  // color matching not really applicable | 
 | 285 | } | 
 | 286 |  | 
 | 287 | // version in which the optimization fails b.c. the colors don't match | 
| commit-bot@chromium.org | 6c4e71a | 2013-11-20 21:32:10 +0000 | [diff] [blame] | 288 | static SkPicture* create_save_layer_opt_2_v4(SkTDArray<DrawType>* preOptPattern, | 
 | 289 |                                              SkTDArray<DrawType>* postOptPattern, | 
 | 290 |                                              const SkBitmap& checkerBoard) { | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 291 |     return create_save_layer_opt_2(preOptPattern, postOptPattern, checkerBoard, | 
 | 292 |                                    true,   // saveLayer has a paint | 
 | 293 |                                    true,   // dbmr2r has a paint | 
 | 294 |                                    false); // and the colors don't match! | 
 | 295 | } | 
 | 296 |  | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 297 | // As our .skp optimizations get folded into the captured skps our code will | 
 | 298 | // no longer be locally exercised. This GM manually constructs the patterns | 
 | 299 | // our optimizations will remove to test them. It acts as both a GM and a unit | 
 | 300 | // test | 
 | 301 | class OptimizationsGM : public skiagm::GM { | 
 | 302 | public: | 
 | 303 |     OptimizationsGM() { | 
 | 304 |         this->makeCheckerboard(); | 
 | 305 |     } | 
 | 306 |  | 
 | 307 |     static const int kWidth = 800; | 
 | 308 |     static const int kHeight = 800; | 
 | 309 |  | 
 | 310 | protected: | 
| commit-bot@chromium.org | 96ab95f4 | 2014-01-09 16:45:38 +0000 | [diff] [blame] | 311 |     uint32_t onGetFlags() const SK_OVERRIDE { | 
 | 312 |         // One optimization changes the color drawn slightly in a 565 target. | 
 | 313 |         // We've decided it's innocuous, so we disable this GM when targeting 565. | 
 | 314 |         // Revisit this if we get finer-grained control: it'd be nice to keep drawing directly. | 
 | 315 |         // For more, see skia:1994. | 
 | 316 |         return skiagm::GM::kSkip565_Flag; | 
 | 317 |     } | 
 | 318 |  | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 319 |     SkString onShortName() { | 
 | 320 |         return SkString("optimizations"); | 
 | 321 |     } | 
 | 322 |  | 
 | 323 |     SkISize onISize() { return SkISize::Make(kWidth, kHeight); } | 
 | 324 |  | 
 | 325 |     typedef SkPicture* (*PFCreateOpt)(SkTDArray<DrawType> *preOptPattern, | 
 | 326 |                                       SkTDArray<DrawType> *postOptPattern, | 
 | 327 |                                       const SkBitmap& checkerBoard); | 
 | 328 |  | 
 | 329 |     virtual void onDraw(SkCanvas* canvas) { | 
 | 330 |  | 
 | 331 |         PFCreateOpt gOpts[] = { | 
 | 332 |             create_save_layer_opt_1_v1, | 
 | 333 |             create_save_layer_opt_1_v2, | 
 | 334 |             create_save_layer_opt_1_v3, | 
 | 335 |             create_save_layer_opt_1_v4, | 
 | 336 |             create_save_layer_opt_2_v1, | 
 | 337 |             create_save_layer_opt_2_v2, | 
 | 338 |             create_save_layer_opt_2_v3, | 
 | 339 |             create_save_layer_opt_2_v4, | 
 | 340 |         }; | 
 | 341 |  | 
 | 342 |         SkTDArray<DrawType> prePattern, postPattern; | 
 | 343 |         int xPos = 0, yPos = 0; | 
 | 344 |  | 
 | 345 |         for (size_t i = 0; i < SK_ARRAY_COUNT(gOpts); ++i) { | 
 | 346 |             SkAutoTUnref<SkPicture> pre((*gOpts[i])(&prePattern, &postPattern, fCheckerboard)); | 
 | 347 |  | 
 | 348 |             if (!(check_pattern(*pre, prePattern))) { | 
 | 349 |                 WARN("Pre optimization pattern mismatch"); | 
 | 350 |                 SkASSERT(0); | 
 | 351 |             } | 
 | 352 |  | 
 | 353 |             canvas->save(); | 
 | 354 |                 canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos)); | 
 | 355 |                 pre->draw(canvas); | 
 | 356 |                 xPos += pre->width(); | 
 | 357 |             canvas->restore(); | 
 | 358 |  | 
 | 359 |             // re-render the 'pre' picture and thus 'apply' the optimization | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 360 |             SkPictureRecorder recorder; | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 361 |  | 
| commit-bot@chromium.org | 5fb2ce3 | 2014-04-17 23:35:06 +0000 | [diff] [blame] | 362 |             SkCanvas* recordCanvas = recorder.beginRecording(pre->width(), pre->height(), NULL, 0); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 363 |  | 
 | 364 |             pre->draw(recordCanvas); | 
 | 365 |  | 
| robertphillips@google.com | 84b18c7 | 2014-04-13 19:09:42 +0000 | [diff] [blame] | 366 |             SkAutoTUnref<SkPicture> post(recorder.endRecording()); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 367 |  | 
 | 368 |             if (!(check_pattern(*post, postPattern))) { | 
 | 369 |                 WARN("Post optimization pattern mismatch"); | 
 | 370 |                 SkASSERT(0); | 
 | 371 |             } | 
 | 372 |  | 
 | 373 |             canvas->save(); | 
 | 374 |                 canvas->translate(SkIntToScalar(xPos), SkIntToScalar(yPos)); | 
 | 375 |                 post->draw(canvas); | 
 | 376 |                 xPos += post->width(); | 
 | 377 |             canvas->restore(); | 
 | 378 |  | 
 | 379 |             if (xPos >= kWidth) { | 
 | 380 |                 // start a new line | 
 | 381 |                 xPos = 0; | 
 | 382 |                 yPos += post->height(); | 
 | 383 |             } | 
 | 384 |  | 
 | 385 |             // TODO: we could also render the pre and post pictures to bitmaps | 
 | 386 |             // and manually compare them in this method | 
 | 387 |         } | 
 | 388 |     } | 
 | 389 |  | 
 | 390 | private: | 
 | 391 |     void makeCheckerboard() { | 
 | 392 |         static const unsigned int kCheckerboardWidth = 16; | 
 | 393 |         static const unsigned int kCheckerboardHeight = 16; | 
 | 394 |  | 
| reed@google.com | eb9a46c | 2014-01-25 16:46:20 +0000 | [diff] [blame] | 395 |         fCheckerboard.allocN32Pixels(kCheckerboardWidth, kCheckerboardHeight); | 
| robertphillips@google.com | ad7d481 | 2013-04-12 15:13:35 +0000 | [diff] [blame] | 396 |         for (unsigned int y = 0; y < kCheckerboardHeight; y += 2) { | 
 | 397 |             SkPMColor* scanline = fCheckerboard.getAddr32(0, y); | 
 | 398 |             for (unsigned int x = 0; x < kCheckerboardWidth; x += 2) { | 
 | 399 |                 *scanline++ = 0xFFFFFFFF; | 
 | 400 |                 *scanline++ = 0xFF000000; | 
 | 401 |             } | 
 | 402 |             scanline = fCheckerboard.getAddr32(0, y + 1); | 
 | 403 |             for (unsigned int x = 0; x < kCheckerboardWidth; x += 2) { | 
 | 404 |                 *scanline++ = 0xFF000000; | 
 | 405 |                 *scanline++ = 0xFFFFFFFF; | 
 | 406 |             } | 
 | 407 |         } | 
 | 408 |     } | 
 | 409 |  | 
 | 410 |     SkBitmap fCheckerboard; | 
 | 411 |  | 
 | 412 |     typedef skiagm::GM INHERITED; | 
 | 413 | }; | 
 | 414 |  | 
 | 415 | ////////////////////////////////////////////////////////////////////////////// | 
 | 416 |  | 
 | 417 | DEF_GM( return new OptimizationsGM; ) |