| OLD | NEW |
| 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 "gm.h" | 8 #include "gm.h" |
| 9 | 9 |
| 10 #include "SkColorFilter.h" | 10 #include "SkColorFilter.h" |
| 11 #include "SkMultiPictureDraw.h" | 11 #include "SkMultiPictureDraw.h" |
| 12 #include "SkPictureRecorder.h" | 12 #include "SkPictureRecorder.h" |
| 13 #include "SkSurface.h" | 13 #include "SkSurface.h" |
| 14 | 14 |
| 15 static const SkScalar kRoot3Over2 = 0.86602545f; // sin(60) | 15 static const SkScalar kRoot3Over2 = 0.86602545f; // sin(60) |
| 16 static const SkScalar kRoot3 = 1.73205081f; |
| 16 | 17 |
| 17 static const int kHexSide = 30; | 18 static const int kHexSide = 30; |
| 18 static const int kNumHexX = 6; | 19 static const int kNumHexX = 6; |
| 19 static const int kNumHexY = 6; | 20 static const int kNumHexY = 6; |
| 20 static const int kPicWidth = kNumHexX * kHexSide; | 21 static const int kPicWidth = kNumHexX * kHexSide; |
| 21 static const int kPicHeight = SkScalarCeilToInt((kNumHexY - 0.5f) * 2 * kHexSide
* kRoot3Over2); | 22 static const int kPicHeight = SkScalarCeilToInt((kNumHexY - 0.5f) * 2 * kHexSide
* kRoot3Over2); |
| 22 static const SkScalar kInset = 20.0f; | 23 static const SkScalar kInset = 20.0f; |
| 24 static const int kNumPictures = 3; |
| 25 |
| 26 static const int kTriSide = 40; |
| 23 | 27 |
| 24 // Create a hexagon centered at (originX, originY) | 28 // Create a hexagon centered at (originX, originY) |
| 25 static SkPath make_hex_path(SkScalar originX, SkScalar originY) { | 29 static SkPath make_hex_path(SkScalar originX, SkScalar originY) { |
| 26 SkPath hex; | 30 SkPath hex; |
| 27 hex.moveTo(originX-kHexSide, originY); | 31 hex.moveTo(originX-kHexSide, originY); |
| 28 hex.rLineTo(SkScalarHalf(kHexSide), kRoot3Over2 * kHexSide); | 32 hex.rLineTo(SkScalarHalf(kHexSide), kRoot3Over2 * kHexSide); |
| 29 hex.rLineTo(SkIntToScalar(kHexSide), 0); | 33 hex.rLineTo(SkIntToScalar(kHexSide), 0); |
| 30 hex.rLineTo(SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2); | 34 hex.rLineTo(SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2); |
| 31 hex.rLineTo(-SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2); | 35 hex.rLineTo(-SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2); |
| 32 hex.rLineTo(-SkIntToScalar(kHexSide), 0); | 36 hex.rLineTo(-SkIntToScalar(kHexSide), 0); |
| 33 hex.close(); | 37 hex.close(); |
| 34 return hex; | 38 return hex; |
| 35 } | 39 } |
| 36 | 40 |
| 37 // Make a picture that is a tiling of the plane with stroked hexagons where | 41 // Make a picture that is a tiling of the plane with stroked hexagons where |
| 38 // each hexagon is in its own layer. The layers are to exercise Ganesh's | 42 // each hexagon is in its own layer. The layers are to exercise Ganesh's |
| 39 // layer hoisting. | 43 // layer hoisting. |
| 40 static const SkPicture* make_picture(SkColor fillColor) { | 44 static const SkPicture* make_hex_plane_picture(SkColor fillColor) { |
| 41 | 45 |
| 42 // Create a hexagon with its center at the origin | 46 // Create a hexagon with its center at the origin |
| 43 SkPath hex = make_hex_path(0, 0); | 47 SkPath hex = make_hex_path(0, 0); |
| 44 | 48 |
| 45 SkPaint fill; | 49 SkPaint fill; |
| 46 fill.setStyle(SkPaint::kFill_Style); | 50 fill.setStyle(SkPaint::kFill_Style); |
| 47 fill.setColor(fillColor); | 51 fill.setColor(fillColor); |
| 48 | 52 |
| 49 SkPaint stroke; | 53 SkPaint stroke; |
| 50 stroke.setStyle(SkPaint::kStroke_Style); | 54 stroke.setStyle(SkPaint::kStroke_Style); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 69 | 73 |
| 70 xPos += 1.5f * kHexSide; | 74 xPos += 1.5f * kHexSide; |
| 71 } | 75 } |
| 72 | 76 |
| 73 yPos += 2 * kHexSide * kRoot3Over2; | 77 yPos += 2 * kHexSide * kRoot3Over2; |
| 74 } | 78 } |
| 75 | 79 |
| 76 return recorder.endRecording(); | 80 return recorder.endRecording(); |
| 77 } | 81 } |
| 78 | 82 |
| 83 // Make an equilateral triangle path with its top corner at (originX, originY) |
| 84 static SkPath make_tri_path(SkScalar originX, SkScalar originY) { |
| 85 SkPath tri; |
| 86 tri.moveTo(originX, originY); |
| 87 tri.rLineTo(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3); |
| 88 tri.rLineTo(-kTriSide, 0); |
| 89 tri.close(); |
| 90 return tri; |
| 91 } |
| 92 |
| 93 static const SkPicture* make_tri_picture() { |
| 94 SkPath tri = make_tri_path(0, 0); |
| 95 |
| 96 SkPaint fill; |
| 97 fill.setStyle(SkPaint::kFill_Style); |
| 98 fill.setColor(SK_ColorLTGRAY);; |
| 99 |
| 100 SkPaint stroke; |
| 101 stroke.setStyle(SkPaint::kStroke_Style); |
| 102 stroke.setStrokeWidth(3); |
| 103 |
| 104 SkPictureRecorder recorder; |
| 105 |
| 106 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth), |
| 107 SkIntToScalar(kPicHeight)); |
| 108 // The saveLayer/restore block is to exercise layer hoisting |
| 109 canvas->saveLayer(NULL, NULL); |
| 110 canvas->drawPath(tri, fill); |
| 111 canvas->drawPath(tri, stroke); |
| 112 canvas->restore(); |
| 113 |
| 114 return recorder.endRecording(); |
| 115 } |
| 116 |
| 117 static const SkPicture* make_sub_picture(const SkPicture* tri) { |
| 118 SkPictureRecorder recorder; |
| 119 |
| 120 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth), |
| 121 SkIntToScalar(kPicHeight)); |
| 122 |
| 123 canvas->scale(1.0f/2.0f, 1.0f/2.0f); |
| 124 |
| 125 canvas->drawPicture(tri); |
| 126 |
| 127 canvas->save(); |
| 128 canvas->translate(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3); |
| 129 canvas->drawPicture(tri); |
| 130 canvas->restore(); |
| 131 |
| 132 canvas->save(); |
| 133 canvas->translate(-SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3); |
| 134 canvas->drawPicture(tri); |
| 135 canvas->restore(); |
| 136 |
| 137 return recorder.endRecording(); |
| 138 } |
| 139 |
| 140 // Create a Sierpinkski-like picture that starts with a top row with a picture |
| 141 // that just contains a triangle. Subsequent rows take the prior row's picture, |
| 142 // shrinks it and replicates it 3 times then draws and appropriate number of |
| 143 // copies of it. |
| 144 static const SkPicture* make_sierpinski_picture() { |
| 145 SkAutoTUnref<const SkPicture> pic(make_tri_picture()); |
| 146 |
| 147 SkPictureRecorder recorder; |
| 148 |
| 149 SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(kPicWidth), |
| 150 SkIntToScalar(kPicHeight)); |
| 151 |
| 152 static const int kNumLevels = 4; |
| 153 for (int i = 0; i < kNumLevels; ++i) { |
| 154 canvas->save(); |
| 155 canvas->translate(-i*kTriSide / 2.0f, 0); |
| 156 for (int j = 0; j < i+1; ++j) { |
| 157 canvas->drawPicture(pic); |
| 158 canvas->translate(SkIntToScalar(kTriSide), 0); |
| 159 } |
| 160 canvas->restore(); |
| 161 |
| 162 pic.reset(make_sub_picture(pic)); |
| 163 |
| 164 canvas->translate(0, 1.5f * kTriSide / kRoot3); |
| 165 } |
| 166 |
| 167 return recorder.endRecording(); |
| 168 } |
| 169 |
| 79 static SkSurface* create_compat_surface(SkCanvas* canvas, int width, int height)
{ | 170 static SkSurface* create_compat_surface(SkCanvas* canvas, int width, int height)
{ |
| 80 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); | 171 SkImageInfo info = SkImageInfo::MakeN32Premul(width, height); |
| 81 | 172 |
| 82 SkSurface* surface = canvas->newSurface(info); | 173 SkSurface* surface = canvas->newSurface(info); |
| 83 if (NULL == surface) { | 174 if (NULL == surface) { |
| 84 // picture canvas returns NULL so fall back to raster | 175 // picture canvas returns NULL so fall back to raster |
| 85 surface = SkSurface::NewRaster(info); | 176 surface = SkSurface::NewRaster(info); |
| 86 } | 177 } |
| 87 | 178 |
| 88 return surface; | 179 return surface; |
| 89 } | 180 } |
| 90 | 181 |
| 91 // This class stores the information required to compose all the result | 182 // This class stores the information required to compose all the result |
| 92 // fragments potentially generated by the MultiPictureDraw object | 183 // fragments potentially generated by the MultiPictureDraw object |
| 93 class ComposeStep { | 184 class ComposeStep { |
| 94 public: | 185 public: |
| 95 ComposeStep() : fSurf(NULL), fX(0.0f), fY(0.0f), fPaint(NULL) { } | 186 ComposeStep() : fSurf(NULL), fX(0.0f), fY(0.0f), fPaint(NULL) { } |
| 96 ~ComposeStep() { SkSafeUnref(fSurf); SkDELETE(fPaint); } | 187 ~ComposeStep() { SkSafeUnref(fSurf); SkDELETE(fPaint); } |
| 97 | 188 |
| 98 SkSurface* fSurf; | 189 SkSurface* fSurf; |
| 99 SkScalar fX; | 190 SkScalar fX; |
| 100 SkScalar fY; | 191 SkScalar fY; |
| 101 SkPaint* fPaint; | 192 SkPaint* fPaint; |
| 102 }; | 193 }; |
| 103 | 194 |
| 104 typedef void (*PFContentMtd)(SkCanvas* canvas, const SkPicture* pictures[2]); | 195 typedef void (*PFContentMtd)(SkCanvas* canvas, const SkPicture* pictures[kNumPic
tures]); |
| 105 | 196 |
| 106 // Just a single picture with no clip | 197 // Just a single picture with no clip |
| 107 static void no_clip(SkCanvas* canvas, const SkPicture* pictures[2]) { | 198 static void no_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) { |
| 108 canvas->drawPicture(pictures[0]); | 199 canvas->drawPicture(pictures[0]); |
| 109 } | 200 } |
| 110 | 201 |
| 111 // Two pictures with a rect clip on the second one | 202 // Two pictures with a rect clip on the second one |
| 112 static void rect_clip(SkCanvas* canvas, const SkPicture* pictures[2]) { | 203 static void rect_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures])
{ |
| 113 canvas->drawPicture(pictures[0]); | 204 canvas->drawPicture(pictures[0]); |
| 114 | 205 |
| 115 SkRect rect = pictures[0]->cullRect(); | 206 SkRect rect = pictures[0]->cullRect(); |
| 116 rect.inset(kInset, kInset); | 207 rect.inset(kInset, kInset); |
| 117 | 208 |
| 118 canvas->clipRect(rect); | 209 canvas->clipRect(rect); |
| 119 | 210 |
| 120 canvas->drawPicture(pictures[1]); | 211 canvas->drawPicture(pictures[1]); |
| 121 } | 212 } |
| 122 | 213 |
| 123 // Two pictures with a round rect clip on the second one | 214 // Two pictures with a round rect clip on the second one |
| 124 static void rrect_clip(SkCanvas* canvas, const SkPicture* pictures[2]) { | 215 static void rrect_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]
) { |
| 125 canvas->drawPicture(pictures[0]); | 216 canvas->drawPicture(pictures[0]); |
| 126 | 217 |
| 127 SkRect rect = pictures[0]->cullRect(); | 218 SkRect rect = pictures[0]->cullRect(); |
| 128 rect.inset(kInset, kInset); | 219 rect.inset(kInset, kInset); |
| 129 | 220 |
| 130 SkRRect rrect; | 221 SkRRect rrect; |
| 131 rrect.setRectXY(rect, kInset, kInset); | 222 rrect.setRectXY(rect, kInset, kInset); |
| 132 | 223 |
| 133 canvas->clipRRect(rrect); | 224 canvas->clipRRect(rrect); |
| 134 | 225 |
| 135 canvas->drawPicture(pictures[1]); | 226 canvas->drawPicture(pictures[1]); |
| 136 } | 227 } |
| 137 | 228 |
| 138 // Two pictures with a clip path on the second one | 229 // Two pictures with a clip path on the second one |
| 139 static void path_clip(SkCanvas* canvas, const SkPicture* pictures[2]) { | 230 static void path_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPictures])
{ |
| 140 canvas->drawPicture(pictures[0]); | 231 canvas->drawPicture(pictures[0]); |
| 141 | 232 |
| 142 // Create a hexagon centered on the middle of the hex grid | 233 // Create a hexagon centered on the middle of the hex grid |
| 143 SkPath hex = make_hex_path((kNumHexX / 2.0f) * kHexSide, kNumHexY * kHexSide
* kRoot3Over2); | 234 SkPath hex = make_hex_path((kNumHexX / 2.0f) * kHexSide, kNumHexY * kHexSide
* kRoot3Over2); |
| 144 | 235 |
| 145 canvas->clipPath(hex); | 236 canvas->clipPath(hex); |
| 146 | 237 |
| 147 canvas->drawPicture(pictures[1]); | 238 canvas->drawPicture(pictures[1]); |
| 148 } | 239 } |
| 149 | 240 |
| 150 // Two pictures with an inverse clip path on the second one | 241 // Two pictures with an inverse clip path on the second one |
| 151 static void invpath_clip(SkCanvas* canvas, const SkPicture* pictures[2]) { | 242 static void invpath_clip(SkCanvas* canvas, const SkPicture* pictures[kNumPicture
s]) { |
| 152 canvas->drawPicture(pictures[0]); | 243 canvas->drawPicture(pictures[0]); |
| 153 | 244 |
| 154 // Create a hexagon centered on the middle of the hex grid | 245 // Create a hexagon centered on the middle of the hex grid |
| 155 SkPath hex = make_hex_path((kNumHexX / 2.0f) * kHexSide, kNumHexY * kHexSide
* kRoot3Over2); | 246 SkPath hex = make_hex_path((kNumHexX / 2.0f) * kHexSide, kNumHexY * kHexSide
* kRoot3Over2); |
| 156 hex.setFillType(SkPath::kInverseEvenOdd_FillType); | 247 hex.setFillType(SkPath::kInverseEvenOdd_FillType); |
| 157 | 248 |
| 158 canvas->clipPath(hex); | 249 canvas->clipPath(hex); |
| 159 | 250 |
| 160 canvas->drawPicture(pictures[1]); | 251 canvas->drawPicture(pictures[1]); |
| 161 } | 252 } |
| 162 | 253 |
| 254 // Reuse a single base (triangular) picture a _lot_ (rotated, scaled and transla
ted). |
| 255 static void sierpinski(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]
) { |
| 256 canvas->save(); |
| 257 canvas->translate(kPicWidth / 2.0f, 0.0f); |
| 258 canvas->drawPicture(pictures[2]); |
| 259 |
| 260 canvas->rotate(180.0f); |
| 261 canvas->translate(0.0f, -SkIntToScalar(kPicHeight)); |
| 262 canvas->drawPicture(pictures[2]); |
| 263 canvas->restore(); |
| 264 } |
| 265 |
| 163 static const PFContentMtd gContentMthds[] = { | 266 static const PFContentMtd gContentMthds[] = { |
| 164 no_clip, | 267 no_clip, |
| 165 rect_clip, | 268 rect_clip, |
| 166 rrect_clip, | 269 rrect_clip, |
| 167 path_clip, | 270 path_clip, |
| 168 invpath_clip | 271 invpath_clip, |
| 272 sierpinski |
| 169 }; | 273 }; |
| 170 | 274 |
| 171 static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen, | 275 static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen, |
| 172 const SkPicture* pictures[2], | 276 const SkPicture* pictures[kNumPictures], |
| 173 SkCanvas* dest, const SkMatrix& xform) { | 277 SkCanvas* dest, const SkMatrix& xform) { |
| 174 SkAutoTUnref<SkPicture> composite; | 278 SkAutoTUnref<SkPicture> composite; |
| 175 | 279 |
| 176 { | 280 { |
| 177 SkPictureRecorder recorder; | 281 SkPictureRecorder recorder; |
| 178 | 282 |
| 179 SkCanvas* pictureCanvas = recorder.beginRecording(SkIntToScalar(kPicWidt
h), | 283 SkCanvas* pictureCanvas = recorder.beginRecording(SkIntToScalar(kPicWidt
h), |
| 180 SkIntToScalar(kPicHeig
ht)); | 284 SkIntToScalar(kPicHeig
ht)); |
| 181 | 285 |
| 182 (*pfGen)(pictureCanvas, pictures); | 286 (*pfGen)(pictureCanvas, pictures); |
| 183 | 287 |
| 184 composite.reset(recorder.endRecording()); | 288 composite.reset(recorder.endRecording()); |
| 185 } | 289 } |
| 186 | 290 |
| 187 mpd->add(dest, composite, &xform); | 291 mpd->add(dest, composite, &xform); |
| 188 } | 292 } |
| 189 | 293 |
| 190 typedef void(*PFLayoutMtd)(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, | 294 typedef void(*PFLayoutMtd)(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, |
| 191 PFContentMtd pfGen, const SkPicture* pictures[2], | 295 PFContentMtd pfGen, const SkPicture* pictures[kNumPic
tures], |
| 192 SkTArray<ComposeStep>* composeSteps); | 296 SkTArray<ComposeStep>* composeSteps); |
| 193 | 297 |
| 194 // Draw the content into a single canvas | 298 // Draw the content into a single canvas |
| 195 static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, | 299 static void simple(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, |
| 196 PFContentMtd pfGen, | 300 PFContentMtd pfGen, |
| 197 const SkPicture* pictures[2], | 301 const SkPicture* pictures[kNumPictures], |
| 198 SkTArray<ComposeStep> *composeSteps) { | 302 SkTArray<ComposeStep> *composeSteps) { |
| 199 | 303 |
| 200 ComposeStep& step = composeSteps->push_back(); | 304 ComposeStep& step = composeSteps->push_back(); |
| 201 | 305 |
| 202 step.fSurf = create_compat_surface(finalCanvas, kPicWidth, kPicHeight); | 306 step.fSurf = create_compat_surface(finalCanvas, kPicWidth, kPicHeight); |
| 203 | 307 |
| 204 SkCanvas* subCanvas = step.fSurf->getCanvas(); | 308 SkCanvas* subCanvas = step.fSurf->getCanvas(); |
| 205 | 309 |
| 206 create_content(mpd, pfGen, pictures, subCanvas, SkMatrix::I()); | 310 create_content(mpd, pfGen, pictures, subCanvas, SkMatrix::I()); |
| 207 } | 311 } |
| 208 | 312 |
| 209 // Draw the content into multiple canvases/tiles | 313 // Draw the content into multiple canvases/tiles |
| 210 static void tiled(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, | 314 static void tiled(SkCanvas* finalCanvas, SkMultiPictureDraw* mpd, |
| 211 PFContentMtd pfGen, | 315 PFContentMtd pfGen, |
| 212 const SkPicture* pictures[2], | 316 const SkPicture* pictures[kNumPictures], |
| 213 SkTArray<ComposeStep> *composeSteps) { | 317 SkTArray<ComposeStep> *composeSteps) { |
| 214 static const int kNumTilesX = 2; | 318 static const int kNumTilesX = 2; |
| 215 static const int kNumTilesY = 2; | 319 static const int kNumTilesY = 2; |
| 216 static const int kTileWidth = kPicWidth / kNumTilesX; | 320 static const int kTileWidth = kPicWidth / kNumTilesX; |
| 217 static const int kTileHeight = kPicHeight / kNumTilesY; | 321 static const int kTileHeight = kPicHeight / kNumTilesY; |
| 218 | 322 |
| 219 SkASSERT(kPicWidth == kNumTilesX * kTileWidth); | 323 SkASSERT(kPicWidth == kNumTilesX * kTileWidth); |
| 220 SkASSERT(kPicHeight == kNumTilesY * kTileHeight); | 324 SkASSERT(kPicHeight == kNumTilesY * kTileHeight); |
| 221 | 325 |
| 222 static const SkColor colors[kNumTilesX][kNumTilesY] = { | 326 static const SkColor colors[kNumTilesX][kNumTilesY] = { |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 * single vs. multiple pictures (e.g., normal vs. picture-pile-style co
ntent) | 361 * single vs. multiple pictures (e.g., normal vs. picture-pile-style co
ntent) |
| 258 */ | 362 */ |
| 259 class MultiPictureDraw : public GM { | 363 class MultiPictureDraw : public GM { |
| 260 public: | 364 public: |
| 261 enum Content { | 365 enum Content { |
| 262 kNoClipSingle_Content, | 366 kNoClipSingle_Content, |
| 263 kRectClipMulti_Content, | 367 kRectClipMulti_Content, |
| 264 kRRectClipMulti_Content, | 368 kRRectClipMulti_Content, |
| 265 kPathClipMulti_Content, | 369 kPathClipMulti_Content, |
| 266 kInvPathClipMulti_Content, | 370 kInvPathClipMulti_Content, |
| 371 kSierpinski_Content, |
| 267 | 372 |
| 268 kLast_Content = kInvPathClipMulti_Content | 373 kLast_Content = kSierpinski_Content |
| 269 }; | 374 }; |
| 270 | 375 |
| 271 static const int kContentCnt = kLast_Content + 1; | 376 static const int kContentCnt = kLast_Content + 1; |
| 272 | 377 |
| 273 enum Layout { | 378 enum Layout { |
| 274 kSimple_Layout, | 379 kSimple_Layout, |
| 275 kTiled_Layout, | 380 kTiled_Layout, |
| 276 | 381 |
| 277 kLast_Layout = kTiled_Layout | 382 kLast_Layout = kTiled_Layout |
| 278 }; | 383 }; |
| 279 | 384 |
| 280 static const int kLayoutCnt = kLast_Layout + 1; | 385 static const int kLayoutCnt = kLast_Layout + 1; |
| 281 | 386 |
| 282 MultiPictureDraw(Content content, Layout layout) : fContent(content), fL
ayout(layout) { | 387 MultiPictureDraw(Content content, Layout layout) : fContent(content), fL
ayout(layout) { |
| 283 SkASSERT(SK_ARRAY_COUNT(gLayoutMthds) == kLayoutCnt); | 388 SkASSERT(SK_ARRAY_COUNT(gLayoutMthds) == kLayoutCnt); |
| 284 SkASSERT(SK_ARRAY_COUNT(gContentMthds) == kContentCnt); | 389 SkASSERT(SK_ARRAY_COUNT(gContentMthds) == kContentCnt); |
| 285 | 390 |
| 286 fPictures[0] = fPictures[1] = NULL; | 391 for (int i = 0; i < kNumPictures; ++i) { |
| 392 fPictures[i] = NULL; |
| 393 } |
| 287 } | 394 } |
| 288 | 395 |
| 289 virtual ~MultiPictureDraw() { | 396 virtual ~MultiPictureDraw() { |
| 290 SkSafeUnref(fPictures[0]); | 397 for (int i = 0; i < kNumPictures; ++i) { |
| 291 SkSafeUnref(fPictures[1]); | 398 SkSafeUnref(fPictures[i]); |
| 399 } |
| 292 } | 400 } |
| 293 | 401 |
| 294 protected: | 402 protected: |
| 295 Content fContent; | 403 Content fContent; |
| 296 Layout fLayout; | 404 Layout fLayout; |
| 297 const SkPicture* fPictures[2]; | 405 const SkPicture* fPictures[kNumPictures]; |
| 298 | 406 |
| 299 virtual void onOnceBeforeDraw() SK_OVERRIDE { | 407 virtual void onOnceBeforeDraw() SK_OVERRIDE { |
| 300 fPictures[0] = make_picture(SK_ColorWHITE); | 408 fPictures[0] = make_hex_plane_picture(SK_ColorWHITE); |
| 301 fPictures[1] = make_picture(SK_ColorGRAY); | 409 fPictures[1] = make_hex_plane_picture(SK_ColorGRAY); |
| 410 fPictures[2] = SkRef(make_sierpinski_picture()); |
| 302 } | 411 } |
| 303 | 412 |
| 304 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 413 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
| 305 SkMultiPictureDraw mpd; | 414 SkMultiPictureDraw mpd; |
| 306 SkTArray<ComposeStep> composeSteps; | 415 SkTArray<ComposeStep> composeSteps; |
| 307 | 416 |
| 308 // Fill up the MultiPictureDraw | 417 // Fill up the MultiPictureDraw |
| 309 (*gLayoutMthds[fLayout])(canvas, &mpd, | 418 (*gLayoutMthds[fLayout])(canvas, &mpd, |
| 310 gContentMthds[fContent], | 419 gContentMthds[fContent], |
| 311 fPictures, &composeSteps); | 420 fPictures, &composeSteps); |
| 312 | 421 |
| 313 mpd.draw(); | 422 mpd.draw(); |
| 314 | 423 |
| 315 // Compose all the drawn canvases into the final canvas | 424 // Compose all the drawn canvases into the final canvas |
| 316 for (int i = 0; i < composeSteps.count(); ++i) { | 425 for (int i = 0; i < composeSteps.count(); ++i) { |
| 317 const ComposeStep& step = composeSteps[i]; | 426 const ComposeStep& step = composeSteps[i]; |
| 318 | 427 |
| 319 SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot()); | 428 SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot()); |
| 320 | 429 |
| 321 image->draw(canvas, step.fX, step.fY, step.fPaint); | 430 image->draw(canvas, step.fX, step.fY, step.fPaint); |
| 322 } | 431 } |
| 323 } | 432 } |
| 324 | 433 |
| 325 virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth,
kPicHeight); } | 434 virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth,
kPicHeight); } |
| 326 | 435 |
| 327 virtual SkString onShortName() SK_OVERRIDE { | 436 virtual SkString onShortName() SK_OVERRIDE { |
| 328 static const char* gContentNames[] = { | 437 static const char* gContentNames[] = { |
| 329 "noclip", "rectclip", "rrectclip", "pathclip", "invpathclip" | 438 "noclip", "rectclip", "rrectclip", "pathclip", "invpathclip", "s
ierpinski" |
| 330 }; | 439 }; |
| 331 static const char* gLayoutNames[] = { "simple", "tiled" }; | 440 static const char* gLayoutNames[] = { "simple", "tiled" }; |
| 332 | 441 |
| 333 SkASSERT(SK_ARRAY_COUNT(gLayoutNames) == kLayoutCnt); | 442 SkASSERT(SK_ARRAY_COUNT(gLayoutNames) == kLayoutCnt); |
| 334 SkASSERT(SK_ARRAY_COUNT(gContentNames) == kContentCnt); | 443 SkASSERT(SK_ARRAY_COUNT(gContentNames) == kContentCnt); |
| 335 | 444 |
| 336 SkString name("multipicturedraw_"); | 445 SkString name("multipicturedraw_"); |
| 337 | 446 |
| 338 name.append(gContentNames[fContent]); | 447 name.append(gContentNames[fContent]); |
| 339 name.append("_"); | 448 name.append("_"); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 350 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_
Content, | 459 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_
Content, |
| 351 MultiPictureDraw::kSimple_Layout
));) | 460 MultiPictureDraw::kSimple_Layout
));) |
| 352 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, | 461 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, |
| 353 MultiPictureDraw::kSimple_Layout
));) | 462 MultiPictureDraw::kSimple_Layout
));) |
| 354 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, | 463 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, |
| 355 MultiPictureDraw::kSimple_Layout
));) | 464 MultiPictureDraw::kSimple_Layout
));) |
| 356 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, | 465 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, |
| 357 MultiPictureDraw::kSimple_Layout
));) | 466 MultiPictureDraw::kSimple_Layout
));) |
| 358 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, | 467 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, |
| 359 MultiPictureDraw::kSimple_Layout
));) | 468 MultiPictureDraw::kSimple_Layout
));) |
| 469 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co
ntent, |
| 470 MultiPictureDraw::kSimple_Layout
));) |
| 360 | 471 |
| 361 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_
Content, | 472 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_
Content, |
| 362 MultiPictureDraw::kTiled_Layout)
);) | 473 MultiPictureDraw::kTiled_Layout)
);) |
| 363 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, | 474 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, |
| 364 MultiPictureDraw::kTiled_Layout)
);) | 475 MultiPictureDraw::kTiled_Layout)
);) |
| 365 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, | 476 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, |
| 366 MultiPictureDraw::kTiled_Layout)
);) | 477 MultiPictureDraw::kTiled_Layout)
);) |
| 367 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, | 478 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, |
| 368 MultiPictureDraw::kTiled_Layout)
);) | 479 MultiPictureDraw::kTiled_Layout)
);) |
| 369 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, | 480 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, |
| 370 MultiPictureDraw::kTiled_Layout)
);) | 481 MultiPictureDraw::kTiled_Layout)
);) |
| 482 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co
ntent, |
| 483 MultiPictureDraw::kTiled_Layout)
);) |
| 371 } | 484 } |
| OLD | NEW |