Chromium Code Reviews| 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 | |
|
egdaniel
2014/10/02 13:03:34
extra \n
| |
| 132 } | |
| 133 | |
| 83 // Make an equilateral triangle path with its top corner at (originX, originY) | 134 // Make an equilateral triangle path with its top corner at (originX, originY) |
| 84 static SkPath make_tri_path(SkScalar originX, SkScalar originY) { | 135 static SkPath make_tri_path(SkScalar originX, SkScalar originY) { |
| 85 SkPath tri; | 136 SkPath tri; |
| 86 tri.moveTo(originX, originY); | 137 tri.moveTo(originX, originY); |
| 87 tri.rLineTo(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3); | 138 tri.rLineTo(SkScalarHalf(kTriSide), 1.5f * kTriSide / kRoot3); |
| 88 tri.rLineTo(-kTriSide, 0); | 139 tri.rLineTo(-kTriSide, 0); |
| 89 tri.close(); | 140 tri.close(); |
| 90 return tri; | 141 return tri; |
| 91 } | 142 } |
| 92 | 143 |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 258 static void sierpinski(SkCanvas* canvas, const SkPicture* pictures[kNumPictures] ) { | 309 static void sierpinski(SkCanvas* canvas, const SkPicture* pictures[kNumPictures] ) { |
| 259 canvas->save(); | 310 canvas->save(); |
| 260 canvas->drawPicture(pictures[2]); | 311 canvas->drawPicture(pictures[2]); |
| 261 | 312 |
| 262 canvas->rotate(180.0f); | 313 canvas->rotate(180.0f); |
| 263 canvas->translate(-SkIntToScalar(kPicWidth), -SkIntToScalar(kPicHeight)) ; | 314 canvas->translate(-SkIntToScalar(kPicWidth), -SkIntToScalar(kPicHeight)) ; |
| 264 canvas->drawPicture(pictures[2]); | 315 canvas->drawPicture(pictures[2]); |
| 265 canvas->restore(); | 316 canvas->restore(); |
| 266 } | 317 } |
| 267 | 318 |
| 319 static void big_layer(SkCanvas* canvas, const SkPicture* pictures[kNumPictures]) { | |
| 320 canvas->drawPicture(pictures[3]); | |
| 321 } | |
| 322 | |
| 268 static const PFContentMtd gContentMthds[] = { | 323 static const PFContentMtd gContentMthds[] = { |
| 269 no_clip, | 324 no_clip, |
| 270 rect_clip, | 325 rect_clip, |
| 271 rrect_clip, | 326 rrect_clip, |
| 272 path_clip, | 327 path_clip, |
| 273 invpath_clip, | 328 invpath_clip, |
| 274 sierpinski | 329 sierpinski, |
| 330 big_layer, | |
| 275 }; | 331 }; |
| 276 | 332 |
| 277 static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen, | 333 static void create_content(SkMultiPictureDraw* mpd, PFContentMtd pfGen, |
| 278 const SkPicture* pictures[kNumPictures], | 334 const SkPicture* pictures[kNumPictures], |
| 279 SkCanvas* dest, const SkMatrix& xform) { | 335 SkCanvas* dest, const SkMatrix& xform) { |
| 280 SkAutoTUnref<SkPicture> composite; | 336 SkAutoTUnref<SkPicture> composite; |
| 281 | 337 |
| 282 { | 338 { |
| 283 SkPictureRecorder recorder; | 339 SkPictureRecorder recorder; |
| 284 | 340 |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 */ | 420 */ |
| 365 class MultiPictureDraw : public GM { | 421 class MultiPictureDraw : public GM { |
| 366 public: | 422 public: |
| 367 enum Content { | 423 enum Content { |
| 368 kNoClipSingle_Content, | 424 kNoClipSingle_Content, |
| 369 kRectClipMulti_Content, | 425 kRectClipMulti_Content, |
| 370 kRRectClipMulti_Content, | 426 kRRectClipMulti_Content, |
| 371 kPathClipMulti_Content, | 427 kPathClipMulti_Content, |
| 372 kInvPathClipMulti_Content, | 428 kInvPathClipMulti_Content, |
| 373 kSierpinski_Content, | 429 kSierpinski_Content, |
| 430 kBigLayer_Content, | |
| 374 | 431 |
| 375 kLast_Content = kSierpinski_Content | 432 kLast_Content = kBigLayer_Content |
| 376 }; | 433 }; |
| 377 | 434 |
| 378 static const int kContentCnt = kLast_Content + 1; | 435 static const int kContentCnt = kLast_Content + 1; |
| 379 | 436 |
| 380 enum Layout { | 437 enum Layout { |
| 381 kSimple_Layout, | 438 kSimple_Layout, |
| 382 kTiled_Layout, | 439 kTiled_Layout, |
| 383 | 440 |
| 384 kLast_Layout = kTiled_Layout | 441 kLast_Layout = kTiled_Layout |
| 385 }; | 442 }; |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 403 | 460 |
| 404 protected: | 461 protected: |
| 405 Content fContent; | 462 Content fContent; |
| 406 Layout fLayout; | 463 Layout fLayout; |
| 407 const SkPicture* fPictures[kNumPictures]; | 464 const SkPicture* fPictures[kNumPictures]; |
| 408 | 465 |
| 409 virtual void onOnceBeforeDraw() SK_OVERRIDE { | 466 virtual void onOnceBeforeDraw() SK_OVERRIDE { |
| 410 fPictures[0] = make_hex_plane_picture(SK_ColorWHITE); | 467 fPictures[0] = make_hex_plane_picture(SK_ColorWHITE); |
| 411 fPictures[1] = make_hex_plane_picture(SK_ColorGRAY); | 468 fPictures[1] = make_hex_plane_picture(SK_ColorGRAY); |
| 412 fPictures[2] = make_sierpinski_picture(); | 469 fPictures[2] = make_sierpinski_picture(); |
| 470 fPictures[3] = make_single_layer_hex_plane_picture(); | |
| 413 } | 471 } |
| 414 | 472 |
| 415 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { | 473 virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE { |
| 416 SkMultiPictureDraw mpd; | 474 SkMultiPictureDraw mpd; |
| 417 SkTArray<ComposeStep> composeSteps; | 475 SkTArray<ComposeStep> composeSteps; |
| 418 | 476 |
| 419 // Fill up the MultiPictureDraw | 477 // Fill up the MultiPictureDraw |
| 420 (*gLayoutMthds[fLayout])(canvas, &mpd, | 478 (*gLayoutMthds[fLayout])(canvas, &mpd, |
| 421 gContentMthds[fContent], | 479 gContentMthds[fContent], |
| 422 fPictures, &composeSteps); | 480 fPictures, &composeSteps); |
| 423 | 481 |
| 424 mpd.draw(); | 482 mpd.draw(); |
| 425 | 483 |
| 426 // Compose all the drawn canvases into the final canvas | 484 // Compose all the drawn canvases into the final canvas |
| 427 for (int i = 0; i < composeSteps.count(); ++i) { | 485 for (int i = 0; i < composeSteps.count(); ++i) { |
| 428 const ComposeStep& step = composeSteps[i]; | 486 const ComposeStep& step = composeSteps[i]; |
| 429 | 487 |
| 430 SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot()); | 488 SkAutoTUnref<SkImage> image(step.fSurf->newImageSnapshot()); |
| 431 | 489 |
| 432 canvas->drawImage(image, step.fX, step.fY, step.fPaint); | 490 canvas->drawImage(image, step.fX, step.fY, step.fPaint); |
| 433 } | 491 } |
| 434 } | 492 } |
| 435 | 493 |
| 436 virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth, kPicHeight); } | 494 virtual SkISize onISize() SK_OVERRIDE { return SkISize::Make(kPicWidth, kPicHeight); } |
| 437 | 495 |
| 438 virtual SkString onShortName() SK_OVERRIDE { | 496 virtual SkString onShortName() SK_OVERRIDE { |
| 439 static const char* gContentNames[] = { | 497 static const char* gContentNames[] = { |
| 440 "noclip", "rectclip", "rrectclip", "pathclip", "invpathclip", "s ierpinski" | 498 "noclip", "rectclip", "rrectclip", "pathclip", |
| 499 "invpathclip", "sierpinski", "biglayer" | |
| 441 }; | 500 }; |
| 442 static const char* gLayoutNames[] = { "simple", "tiled" }; | 501 static const char* gLayoutNames[] = { "simple", "tiled" }; |
| 443 | 502 |
| 444 SkASSERT(SK_ARRAY_COUNT(gLayoutNames) == kLayoutCnt); | 503 SkASSERT(SK_ARRAY_COUNT(gLayoutNames) == kLayoutCnt); |
| 445 SkASSERT(SK_ARRAY_COUNT(gContentNames) == kContentCnt); | 504 SkASSERT(SK_ARRAY_COUNT(gContentNames) == kContentCnt); |
| 446 | 505 |
| 447 SkString name("multipicturedraw_"); | 506 SkString name("multipicturedraw_"); |
| 448 | 507 |
| 449 name.append(gContentNames[fContent]); | 508 name.append(gContentNames[fContent]); |
| 450 name.append("_"); | 509 name.append("_"); |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 463 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti _Content, | 522 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti _Content, |
| 464 MultiPictureDraw::kSimple_Layout ));) | 523 MultiPictureDraw::kSimple_Layout ));) |
| 465 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult i_Content, | 524 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult i_Content, |
| 466 MultiPictureDraw::kSimple_Layout ));) | 525 MultiPictureDraw::kSimple_Layout ));) |
| 467 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti _Content, | 526 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti _Content, |
| 468 MultiPictureDraw::kSimple_Layout ));) | 527 MultiPictureDraw::kSimple_Layout ));) |
| 469 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu lti_Content, | 528 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu lti_Content, |
| 470 MultiPictureDraw::kSimple_Layout ));) | 529 MultiPictureDraw::kSimple_Layout ));) |
| 471 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co ntent, | 530 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co ntent, |
| 472 MultiPictureDraw::kSimple_Layout ));) | 531 MultiPictureDraw::kSimple_Layout ));) |
| 532 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kBigLayer_Cont ent, | |
| 533 MultiPictureDraw::kSimple_Layout ));) | |
| 473 | 534 |
| 474 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_ Content, | 535 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kNoClipSingle_ Content, |
| 475 MultiPictureDraw::kTiled_Layout) );) | 536 MultiPictureDraw::kTiled_Layout) );) |
| 476 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti _Content, | 537 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRectClipMulti _Content, |
| 477 MultiPictureDraw::kTiled_Layout) );) | 538 MultiPictureDraw::kTiled_Layout) );) |
| 478 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult i_Content, | 539 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kRRectClipMult i_Content, |
| 479 MultiPictureDraw::kTiled_Layout) );) | 540 MultiPictureDraw::kTiled_Layout) );) |
| 480 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti _Content, | 541 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kPathClipMulti _Content, |
| 481 MultiPictureDraw::kTiled_Layout) );) | 542 MultiPictureDraw::kTiled_Layout) );) |
| 482 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu lti_Content, | 543 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kInvPathClipMu lti_Content, |
| 483 MultiPictureDraw::kTiled_Layout) );) | 544 MultiPictureDraw::kTiled_Layout) );) |
| 484 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co ntent, | 545 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kSierpinski_Co ntent, |
| 485 MultiPictureDraw::kTiled_Layout) );) | 546 MultiPictureDraw::kTiled_Layout) );) |
| 547 DEF_GM(return SkNEW_ARGS(MultiPictureDraw, (MultiPictureDraw::kBigLayer_Cont ent, | |
| 548 MultiPictureDraw::kTiled_Layout) );) | |
| 486 } | 549 } |
| OLD | NEW |