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 static const SkScalar kRoot3 = 1.73205081f; |
17 | 17 |
18 static const int kHexSide = 30; | 18 static const int kHexSide = 30; |
19 static const int kNumHexX = 6; | 19 static const int kNumHexX = 6; |
20 static const int kNumHexY = 6; | 20 static const int kNumHexY = 6; |
21 static const int kPicWidth = kNumHexX * kHexSide; | 21 static const int kPicWidth = kNumHexX * kHexSide; |
22 static const int kPicHeight = SkScalarCeilToInt((kNumHexY - 0.5f) * 2 * kHexSide
* kRoot3Over2); | 22 static const int kPicHeight = SkScalarCeilToInt((kNumHexY - 0.5f) * 2 * kHexSide
* kRoot3Over2); |
23 static const SkScalar kInset = 20.0f; | 23 static const SkScalar kInset = 20.0f; |
24 static const int kNumPictures = 3; | 24 static const int kNumPictures = 4; |
25 | 25 |
26 static const int kTriSide = 40; | 26 static const int kTriSide = 40; |
27 | 27 |
28 // Create a hexagon centered at (originX, originY) | 28 // Create a hexagon centered at (originX, originY) |
29 static SkPath make_hex_path(SkScalar originX, SkScalar originY) { | 29 static SkPath make_hex_path(SkScalar originX, SkScalar originY) { |
30 SkPath hex; | 30 SkPath hex; |
31 hex.moveTo(originX-kHexSide, originY); | 31 hex.moveTo(originX-kHexSide, originY); |
32 hex.rLineTo(SkScalarHalf(kHexSide), kRoot3Over2 * kHexSide); | 32 hex.rLineTo(SkScalarHalf(kHexSide), kRoot3Over2 * kHexSide); |
33 hex.rLineTo(SkIntToScalar(kHexSide), 0); | 33 hex.rLineTo(SkIntToScalar(kHexSide), 0); |
34 hex.rLineTo(SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2); | 34 hex.rLineTo(SkScalarHalf(kHexSide), -kHexSide * kRoot3Over2); |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
73 | 73 |
74 xPos += 1.5f * kHexSide; | 74 xPos += 1.5f * kHexSide; |
75 } | 75 } |
76 | 76 |
77 yPos += 2 * kHexSide * kRoot3Over2; | 77 yPos += 2 * kHexSide * kRoot3Over2; |
78 } | 78 } |
79 | 79 |
80 return recorder.endRecording(); | 80 return recorder.endRecording(); |
81 } | 81 } |
82 | 82 |
| 83 // Create a picture that consists of a single large layer that is tiled |
| 84 // with hexagons. |
| 85 // This is intended to exercise the layer hoisting code's clip handling (in |
| 86 // tile mode). |
| 87 static const SkPicture* make_single_layer_hex_plane_picture() { |
| 88 |
| 89 // Create a hexagon with its center at the origin |
| 90 SkPath hex = make_hex_path(0, 0); |
| 91 |
| 92 SkPaint whiteFill; |
| 93 whiteFill.setStyle(SkPaint::kFill_Style); |
| 94 whiteFill.setColor(SK_ColorWHITE); |
| 95 |
| 96 SkPaint greyFill; |
| 97 greyFill.setStyle(SkPaint::kFill_Style); |
| 98 greyFill.setColor(SK_ColorLTGRAY); |
| 99 |
| 100 SkPaint stroke; |
| 101 stroke.setStyle(SkPaint::kStroke_Style); |
| 102 stroke.setStrokeWidth(3); |
| 103 |
| 104 SkPictureRecorder recorder; |
| 105 |
| 106 static const SkScalar kBig = 10000.0f; |
| 107 SkCanvas* canvas = recorder.beginRecording(kBig, kBig); |
| 108 |
| 109 SkScalar xPos = 0.0f, yPos = 0.0f; |
| 110 |
| 111 for (int y = 0; yPos < kBig; ++y) { |
| 112 xPos = 0; |
| 113 |
| 114 for (int x = 0; xPos < kBig; ++x) { |
| 115 canvas->save(); |
| 116 canvas->translate(xPos, yPos + ((x % 2) ? kRoot3Over2 * kHexSide : 0
)); |
| 117 // The color of the filled hex is swapped to yield a different |
| 118 // pattern in each tile. This allows an error in layer hoisting (e.g
., |
| 119 // the clip isn't blocking cache reuse) to cause a visual discrepanc
y. |
| 120 canvas->drawPath(hex, ((x+y) % 3) ? whiteFill : greyFill); |
| 121 canvas->drawPath(hex, stroke); |
| 122 canvas->restore(); |
| 123 |
| 124 xPos += 1.5f * kHexSide; |
| 125 } |
| 126 |
| 127 yPos += 2 * kHexSide * kRoot3Over2; |
| 128 } |
| 129 |
| 130 return recorder.endRecording(); |
| 131 } |
| 132 |
83 // Make an equilateral triangle path with its top corner at (originX, originY) | 133 // Make an equilateral triangle path with its top corner at (originX, originY) |
84 static SkPath make_tri_path(SkScalar originX, SkScalar originY) { | 134 static SkPath make_tri_path(SkScalar originX, SkScalar originY) { |
85 SkPath tri; | 135 SkPath tri; |
86 tri.moveTo(originX, originY); | 136 tri.moveTo(originX, originY); |
87 tri.rLineTo(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3); | 137 tri.rLineTo(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3); |
88 tri.rLineTo(-kTriSide, 0); | 138 tri.rLineTo(-kTriSide, 0); |
89 tri.close(); | 139 tri.close(); |
90 return tri; | 140 return tri; |
91 } | 141 } |
92 | 142 |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
258 static void sierpinski(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]
) { | 308 static void sierpinski(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]
) { |
259 canvas->save(); | 309 canvas->save(); |
260 canvas->drawPicture(pictures[2]); | 310 canvas->drawPicture(pictures[2]); |
261 | 311 |
262 canvas->rotate(180.0f); | 312 canvas->rotate(180.0f); |
263 canvas->translate(-SkIntToScalar(kPicWidth), -SkIntToScalar(kPicHeight))
; | 313 canvas->translate(-SkIntToScalar(kPicWidth), -SkIntToScalar(kPicHeight))
; |
264 canvas->drawPicture(pictures[2]); | 314 canvas->drawPicture(pictures[2]); |
265 canvas->restore(); | 315 canvas->restore(); |
266 } | 316 } |
267 | 317 |
| 318 static void big_layer(SkCanvas* canvas, const SkPicture* pictures[kNumPictures])
{ |
| 319 canvas->drawPicture(pictures[3]); |
| 320 } |
| 321 |
268 static const PFContentMtd gContentMthds[] = { | 322 static const PFContentMtd gContentMthds[] = { |
269 no_clip, | 323 no_clip, |
270 rect_clip, | 324 rect_clip, |
271 rrect_clip, | 325 rrect_clip, |
272 path_clip, | 326 path_clip, |
273 invpath_clip, | 327 invpath_clip, |
274 sierpinski | 328 sierpinski, |
| 329 big_layer, |
275 }; | 330 }; |
276 | 331 |
277 static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen, | 332 static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen, |
278 const SkPicture* pictures[kNumPictures], | 333 const SkPicture* pictures[kNumPictures], |
279 SkCanvas* dest, const SkMatrix& xform) { | 334 SkCanvas* dest, const SkMatrix& xform) { |
280 SkAutoTUnref<SkPicture> composite; | 335 SkAutoTUnref<SkPicture> composite; |
281 | 336 |
282 { | 337 { |
283 SkPictureRecorder recorder; | 338 SkPictureRecorder recorder; |
284 | 339 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 */ | 419 */ |
365 class MultiPictureDraw : public GM { | 420 class MultiPictureDraw : public GM { |
366 public: | 421 public: |
367 enum Content { | 422 enum Content { |
368 kNoClipSingle_Content, | 423 kNoClipSingle_Content, |
369 kRectClipMulti_Content, | 424 kRectClipMulti_Content, |
370 kRRectClipMulti_Content, | 425 kRRectClipMulti_Content, |
371 kPathClipMulti_Content, | 426 kPathClipMulti_Content, |
372 kInvPathClipMulti_Content, | 427 kInvPathClipMulti_Content, |
373 kSierpinski_Content, | 428 kSierpinski_Content, |
| 429 kBigLayer_Content, |
374 | 430 |
375 kLast_Content = kSierpinski_Content | 431 kLast_Content = kBigLayer_Content |
376 }; | 432 }; |
377 | 433 |
378 static const int kContentCnt = kLast_Content + 1; | 434 static const int kContentCnt = kLast_Content + 1; |
379 | 435 |
380 enum Layout { | 436 enum Layout { |
381 kSimple_Layout, | 437 kSimple_Layout, |
382 kTiled_Layout, | 438 kTiled_Layout, |
383 | 439 |
384 kLast_Layout = kTiled_Layout | 440 kLast_Layout = kTiled_Layout |
385 }; | 441 }; |
(...skipping 17 matching lines...) Expand all Loading... |
403 | 459 |
404 protected: | 460 protected: |
405 Content fContent; | 461 Content fContent; |
406 Layout fLayout; | 462 Layout fLayout; |
407 const SkPicture* fPictures[kNumPictures]; | 463 const SkPicture* fPictures[kNumPictures]; |
408 | 464 |
409 virtual void onOnceBeforeDraw() SK_OVERRIDE { | 465 virtual void onOnceBeforeDraw() SK_OVERRIDE { |
410 fPictures[0] = make_hex_plane_picture(SK_ColorWHITE); | 466 fPictures[0] = make_hex_plane_picture(SK_ColorWHITE); |
411 fPictures[1] = make_hex_plane_picture(SK_ColorGRAY); | 467 fPictures[1] = make_hex_plane_picture(SK_ColorGRAY); |
412 fPictures[2] = make_sierpinski_picture(); | 468 fPictures[2] = make_sierpinski_picture(); |
| 469 fPictures[3] = make_single_layer_hex_plane_picture(); |
413 } | 470 } |
414 | 471 |
415 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 472 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
416 SkMultiPictureDraw mpd; | 473 SkMultiPictureDraw mpd; |
417 SkTArray<ComposeStep> composeSteps; | 474 SkTArray<ComposeStep> composeSteps; |
418 | 475 |
419 // Fill up the MultiPictureDraw | 476 // Fill up the MultiPictureDraw |
420 (*gLayoutMthds[fLayout])(canvas, &mpd, | 477 (*gLayoutMthds[fLayout])(canvas, &mpd, |
421 gContentMthds[fContent], | 478 gContentMthds[fContent], |
422 fPictures, &composeSteps); | 479 fPictures, &composeSteps); |
423 | 480 |
424 mpd.draw(); | 481 mpd.draw(); |
425 | 482 |
426 // Compose all the drawn canvases into the final canvas | 483 // Compose all the drawn canvases into the final canvas |
427 for (int i = 0; i < composeSteps.count(); ++i) { | 484 for (int i = 0; i < composeSteps.count(); ++i) { |
428 const ComposeStep& step = composeSteps[i]; | 485 const ComposeStep& step = composeSteps[i]; |
429 | 486 |
430 SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot()); | 487 SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot()); |
431 | 488 |
432 canvas->drawImage(image, step.fX, step.fY, step.fPaint); | 489 canvas->drawImage(image, step.fX, step.fY, step.fPaint); |
433 } | 490 } |
434 } | 491 } |
435 | 492 |
436 virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth,
kPicHeight); } | 493 virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth,
kPicHeight); } |
437 | 494 |
438 virtual SkString onShortName() SK_OVERRIDE { | 495 virtual SkString onShortName() SK_OVERRIDE { |
439 static const char* gContentNames[] = { | 496 static const char* gContentNames[] = { |
440 "noclip", "rectclip", "rrectclip", "pathclip", "invpathclip", "s
ierpinski" | 497 "noclip", "rectclip", "rrectclip", "pathclip", |
| 498 "invpathclip", "sierpinski", "biglayer" |
441 }; | 499 }; |
442 static const char* gLayoutNames[] = { "simple", "tiled" }; | 500 static const char* gLayoutNames[] = { "simple", "tiled" }; |
443 | 501 |
444 SkASSERT(SK_ARRAY_COUNT(gLayoutNames) == kLayoutCnt); | 502 SkASSERT(SK_ARRAY_COUNT(gLayoutNames) == kLayoutCnt); |
445 SkASSERT(SK_ARRAY_COUNT(gContentNames) == kContentCnt); | 503 SkASSERT(SK_ARRAY_COUNT(gContentNames) == kContentCnt); |
446 | 504 |
447 SkString name("multipicturedraw_"); | 505 SkString name("multipicturedraw_"); |
448 | 506 |
449 name.append(gContentNames[fContent]); | 507 name.append(gContentNames[fContent]); |
450 name.append("_"); | 508 name.append("_"); |
(...skipping 12 matching lines...) Expand all Loading... |
463 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, | 521 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, |
464 MultiPictureDraw::kSimple_Layout
));) | 522 MultiPictureDraw::kSimple_Layout
));) |
465 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, | 523 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, |
466 MultiPictureDraw::kSimple_Layout
));) | 524 MultiPictureDraw::kSimple_Layout
));) |
467 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, | 525 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, |
468 MultiPictureDraw::kSimple_Layout
));) | 526 MultiPictureDraw::kSimple_Layout
));) |
469 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, | 527 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, |
470 MultiPictureDraw::kSimple_Layout
));) | 528 MultiPictureDraw::kSimple_Layout
));) |
471 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co
ntent, | 529 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co
ntent, |
472 MultiPictureDraw::kSimple_Layout
));) | 530 MultiPictureDraw::kSimple_Layout
));) |
| 531 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kBigLayer_Cont
ent, |
| 532 MultiPictureDraw::kSimple_Layout
));) |
473 | 533 |
474 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_
Content, | 534 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_
Content, |
475 MultiPictureDraw::kTiled_Layout)
);) | 535 MultiPictureDraw::kTiled_Layout)
);) |
476 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, | 536 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti
_Content, |
477 MultiPictureDraw::kTiled_Layout)
);) | 537 MultiPictureDraw::kTiled_Layout)
);) |
478 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, | 538 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult
i_Content, |
479 MultiPictureDraw::kTiled_Layout)
);) | 539 MultiPictureDraw::kTiled_Layout)
);) |
480 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, | 540 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti
_Content, |
481 MultiPictureDraw::kTiled_Layout)
);) | 541 MultiPictureDraw::kTiled_Layout)
);) |
482 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, | 542 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu
lti_Content, |
483 MultiPictureDraw::kTiled_Layout)
);) | 543 MultiPictureDraw::kTiled_Layout)
);) |
484 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co
ntent, | 544 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co
ntent, |
485 MultiPictureDraw::kTiled_Layout)
);) | 545 MultiPictureDraw::kTiled_Layout)
);) |
| 546 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kBigLayer_Cont
ent, |
| 547 MultiPictureDraw::kTiled_Layout)
);) |
486 } | 548 } |
OLD | NEW |