1 /* 2 * Copyright 2012 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 /* Description: 9 * This test defines a series of elementatry test steps that perform 10 * a single or a small group of canvas API calls. Each test step is 11 * used in several test cases that verify that different types of SkCanvas 12 * flavors and derivatives pass it and yield consistent behavior. The 13 * test cases analyse results that are queryable through the API. They do 14 * not look at rendering results. 15 * 16 * Adding test stepss: 17 * The general pattern for creating a new test step is to write a test 18 * function of the form: 19 * 20 * static void MyTestStepFunction(SkCanvas* canvas, 21 * skiatest::Reporter* reporter, 22 * CanvasTestStep* testStep) 23 * { 24 * canvas->someCanvasAPImethod(); 25 * (...) 26 * REPORTER_ASSERT_MESSAGE(reporter, (...), \ 27 * testStep->assertMessage()); 28 * } 29 * 30 * The definition of the test step function should be followed by an 31 * invocation of the TEST_STEP macro, which generates a class and 32 * instance for the test step: 33 * 34 * TEST_STEP(MyTestStep, MyTestStepFunction) 35 * 36 * There are also short hand macros for defining simple test steps 37 * in a single line of code. A simple test step is a one that is made 38 * of a single canvas API call. 39 * 40 * SIMPLE_TEST_STEP(MytestStep, someCanvasAPIMethod()); 41 * 42 * There is another macro called SIMPLE_TEST_STEP_WITH_ASSERT that 43 * works the same way as SIMPLE_TEST_STEP, and additionally verifies 44 * that the invoked method returns a non-zero value. 45 */ 46 #include "SkBitmap.h" 47 #include "SkCanvas.h" 48 #include "SkDeferredCanvas.h" 49 #include "SkDevice.h" 50 #include "SkMatrix.h" 51 #include "SkNWayCanvas.h" 52 #include "SkPDFDevice.h" 53 #include "SkPDFDocument.h" 54 #include "SkPaint.h" 55 #include "SkPath.h" 56 #include "SkPicture.h" 57 #include "SkPictureRecord.h" 58 #include "SkPictureRecorder.h" 59 #include "SkProxyCanvas.h" 60 #include "SkRect.h" 61 #include "SkRegion.h" 62 #include "SkShader.h" 63 #include "SkStream.h" 64 #include "SkSurface.h" 65 #include "SkTDArray.h" 66 #include "Test.h" 67 68 static bool equal_clips(const SkCanvas& a, const SkCanvas& b) { 69 if (a.isClipEmpty()) { 70 return b.isClipEmpty(); 71 } 72 if (!a.isClipRect()) { 73 // this is liberally true, since we don't expose a way to know this exactly (for non-rects) 74 return !b.isClipRect(); 75 } 76 SkIRect ar, br; 77 a.getClipDeviceBounds(&ar); 78 b.getClipDeviceBounds(&br); 79 return ar == br; 80 } 81 82 class Canvas2CanvasClipVisitor : public SkCanvas::ClipVisitor { 83 public: 84 Canvas2CanvasClipVisitor(SkCanvas* target) : fTarget(target) {} 85 86 virtual void clipRect(const SkRect& r, SkRegion::Op op, bool aa) SK_OVERRIDE { 87 fTarget->clipRect(r, op, aa); 88 } 89 virtual void clipRRect(const SkRRect& r, SkRegion::Op op, bool aa) SK_OVERRIDE { 90 fTarget->clipRRect(r, op, aa); 91 } 92 virtual void clipPath(const SkPath& p, SkRegion::Op op, bool aa) SK_OVERRIDE { 93 fTarget->clipPath(p, op, aa); 94 } 95 96 private: 97 SkCanvas* fTarget; 98 }; 99 100 static void test_clipVisitor(skiatest::Reporter* reporter, SkCanvas* canvas) { 101 SkISize size = canvas->getDeviceSize(); 102 103 SkBitmap bm; 104 bm.setInfo(SkImageInfo::MakeN32Premul(size.width(), size.height())); 105 SkCanvas c(bm); 106 107 Canvas2CanvasClipVisitor visitor(&c); 108 canvas->replayClips(&visitor); 109 110 REPORTER_ASSERT(reporter, equal_clips(c, *canvas)); 111 } 112 113 static const int kWidth = 2; 114 static const int kHeight = 2; 115 116 // Format strings that describe the test context. The %s token is where 117 // the name of the test step is inserted. The context is required for 118 // disambiguating the error in the case of failures that are reported in 119 // functions that are called multiple times in different contexts (test 120 // cases and test steps). 121 static const char* const kDefaultAssertMessageFormat = "%s"; 122 static const char* const kCanvasDrawAssertMessageFormat = 123 "Drawing test step %s with SkCanvas"; 124 static const char* const kPictureDrawAssertMessageFormat = 125 "Drawing test step %s with SkPicture"; 126 static const char* const kPictureSecondDrawAssertMessageFormat = 127 "Duplicate draw of test step %s with SkPicture"; 128 static const char* const kDeferredDrawAssertMessageFormat = 129 "Drawing test step %s with SkDeferredCanvas"; 130 static const char* const kProxyDrawAssertMessageFormat = 131 "Drawing test step %s with SkProxyCanvas"; 132 static const char* const kNWayDrawAssertMessageFormat = 133 "Drawing test step %s with SkNWayCanvas"; 134 static const char* const kDeferredPreFlushAssertMessageFormat = 135 "test step %s, SkDeferredCanvas state consistency before flush"; 136 static const char* const kDeferredPostFlushPlaybackAssertMessageFormat = 137 "test step %s, SkDeferredCanvas playback canvas state consistency after flush"; 138 static const char* const kDeferredPostSilentFlushPlaybackAssertMessageFormat = 139 "test step %s, SkDeferredCanvas playback canvas state consistency after silent flush"; 140 static const char* const kPictureResourceReuseMessageFormat = 141 "test step %s, SkPicture duplicate flattened object test"; 142 static const char* const kProxyStateAssertMessageFormat = 143 "test step %s, SkProxyCanvas state consistency"; 144 static const char* const kProxyIndirectStateAssertMessageFormat = 145 "test step %s, SkProxyCanvas indirect canvas state consistency"; 146 static const char* const kNWayStateAssertMessageFormat = 147 "test step %s, SkNWayCanvas state consistency"; 148 static const char* const kNWayIndirect1StateAssertMessageFormat = 149 "test step %s, SkNWayCanvas indirect canvas 1 state consistency"; 150 static const char* const kNWayIndirect2StateAssertMessageFormat = 151 "test step %s, SkNWayCanvas indirect canvas 2 state consistency"; 152 static const char* const kPdfAssertMessageFormat = 153 "PDF sanity check failed %s"; 154 155 static void createBitmap(SkBitmap* bm, SkColor color) { 156 bm->allocN32Pixels(kWidth, kHeight); 157 bm->eraseColor(color); 158 } 159 160 static SkSurface* createSurface(SkColor color) { 161 SkSurface* surface = SkSurface::NewRasterPMColor(kWidth, kHeight); 162 surface->getCanvas()->clear(color); 163 return surface; 164 } 165 166 class CanvasTestStep; 167 static SkTDArray<CanvasTestStep*>& testStepArray() { 168 static SkTDArray<CanvasTestStep*> theTests; 169 return theTests; 170 } 171 172 class CanvasTestStep { 173 public: 174 CanvasTestStep(bool fEnablePdfTesting = true) { 175 *testStepArray().append() = this; 176 fAssertMessageFormat = kDefaultAssertMessageFormat; 177 this->fEnablePdfTesting = fEnablePdfTesting; 178 } 179 virtual ~CanvasTestStep() { } 180 181 virtual void draw(SkCanvas*, skiatest::Reporter*) = 0; 182 virtual const char* name() const = 0; 183 184 const char* assertMessage() { 185 fAssertMessage.printf(fAssertMessageFormat, name()); 186 return fAssertMessage.c_str(); 187 } 188 189 void setAssertMessageFormat(const char* format) { 190 fAssertMessageFormat = format; 191 } 192 193 bool enablePdfTesting() { return fEnablePdfTesting; } 194 195 private: 196 SkString fAssertMessage; 197 const char* fAssertMessageFormat; 198 bool fEnablePdfTesting; 199 }; 200 201 /////////////////////////////////////////////////////////////////////////////// 202 // Constants used by test steps 203 204 const SkRect kTestRect = 205 SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 206 SkIntToScalar(2), SkIntToScalar(1)); 207 static SkMatrix testMatrix() { 208 SkMatrix matrix; 209 matrix.reset(); 210 matrix.setScale(SkIntToScalar(2), SkIntToScalar(3)); 211 return matrix; 212 } 213 const SkMatrix kTestMatrix = testMatrix(); 214 static SkPath test_path() { 215 SkPath path; 216 path.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 217 SkIntToScalar(2), SkIntToScalar(1))); 218 return path; 219 } 220 const SkPath kTestPath = test_path(); 221 static SkPath test_nearly_zero_length_path() { 222 SkPath path; 223 SkPoint pt1 = { 0, 0 }; 224 SkPoint pt2 = { 0, SK_ScalarNearlyZero }; 225 SkPoint pt3 = { SkIntToScalar(1), 0 }; 226 SkPoint pt4 = { SkIntToScalar(1), SK_ScalarNearlyZero/2 }; 227 path.moveTo(pt1); 228 path.lineTo(pt2); 229 path.lineTo(pt3); 230 path.lineTo(pt4); 231 return path; 232 } 233 const SkPath kNearlyZeroLengthPath = test_nearly_zero_length_path(); 234 static SkRegion testRegion() { 235 SkRegion region; 236 SkIRect rect = SkIRect::MakeXYWH(0, 0, 2, 1); 237 region.setRect(rect); 238 return region; 239 } 240 const SkIRect kTestIRect = SkIRect::MakeXYWH(0, 0, 2, 1); 241 const SkRegion kTestRegion = testRegion(); 242 const SkColor kTestColor = 0x01020304; 243 const SkPaint kTestPaint; 244 const SkPoint kTestPoints[3] = { 245 {SkIntToScalar(0), SkIntToScalar(0)}, 246 {SkIntToScalar(2), SkIntToScalar(1)}, 247 {SkIntToScalar(0), SkIntToScalar(2)} 248 }; 249 const size_t kTestPointCount = 3; 250 static SkBitmap testBitmap() { 251 SkBitmap bitmap; 252 createBitmap(&bitmap, 0x05060708); 253 return bitmap; 254 } 255 SkBitmap kTestBitmap; // cannot be created during static init 256 SkString kTestText("Hello World"); 257 SkPoint kTestPoints2[] = { 258 { SkIntToScalar(0), SkIntToScalar(1) }, 259 { SkIntToScalar(1), SkIntToScalar(1) }, 260 { SkIntToScalar(2), SkIntToScalar(1) }, 261 { SkIntToScalar(3), SkIntToScalar(1) }, 262 { SkIntToScalar(4), SkIntToScalar(1) }, 263 { SkIntToScalar(5), SkIntToScalar(1) }, 264 { SkIntToScalar(6), SkIntToScalar(1) }, 265 { SkIntToScalar(7), SkIntToScalar(1) }, 266 { SkIntToScalar(8), SkIntToScalar(1) }, 267 { SkIntToScalar(9), SkIntToScalar(1) }, 268 { SkIntToScalar(10), SkIntToScalar(1) }, 269 }; 270 271 272 /////////////////////////////////////////////////////////////////////////////// 273 // Macros for defining test steps 274 275 #define TEST_STEP(NAME, FUNCTION) \ 276 class NAME##_TestStep : public CanvasTestStep{ \ 277 public: \ 278 virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \ 279 FUNCTION (canvas, reporter, this); \ 280 } \ 281 virtual const char* name() const {return #NAME ;} \ 282 }; \ 283 static NAME##_TestStep NAME##_TestStepInstance; 284 285 #define TEST_STEP_NO_PDF(NAME, FUNCTION) \ 286 class NAME##_TestStep : public CanvasTestStep{ \ 287 public: \ 288 NAME##_TestStep() : CanvasTestStep(false) {} \ 289 virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \ 290 FUNCTION (canvas, reporter, this); \ 291 } \ 292 virtual const char* name() const {return #NAME ;} \ 293 }; \ 294 static NAME##_TestStep NAME##_TestStepInstance; 295 296 #define SIMPLE_TEST_STEP(NAME, CALL) \ 297 static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter*, \ 298 CanvasTestStep*) { \ 299 canvas-> CALL ; \ 300 } \ 301 TEST_STEP(NAME, NAME##TestStep ) 302 303 #define SIMPLE_TEST_STEP_WITH_ASSERT(NAME, CALL) \ 304 static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter* reporter, \ 305 CanvasTestStep* testStep) { \ 306 REPORTER_ASSERT_MESSAGE(reporter, canvas-> CALL , \ 307 testStep->assertMessage()); \ 308 } \ 309 TEST_STEP(NAME, NAME##TestStep ) 310 311 312 /////////////////////////////////////////////////////////////////////////////// 313 // Basic test steps for most virtual methods in SkCanvas that draw or affect 314 // the state of the canvas. 315 316 SIMPLE_TEST_STEP(Translate, translate(SkIntToScalar(1), SkIntToScalar(2))); 317 SIMPLE_TEST_STEP(Scale, scale(SkIntToScalar(1), SkIntToScalar(2))); 318 SIMPLE_TEST_STEP(Rotate, rotate(SkIntToScalar(1))); 319 SIMPLE_TEST_STEP(Skew, skew(SkIntToScalar(1), SkIntToScalar(2))); 320 SIMPLE_TEST_STEP(Concat, concat(kTestMatrix)); 321 SIMPLE_TEST_STEP(SetMatrix, setMatrix(kTestMatrix)); 322 SIMPLE_TEST_STEP(ClipRect, clipRect(kTestRect)); 323 SIMPLE_TEST_STEP(ClipPath, clipPath(kTestPath)); 324 SIMPLE_TEST_STEP(ClipRegion, 325 clipRegion(kTestRegion, SkRegion::kReplace_Op)); 326 SIMPLE_TEST_STEP(Clear, clear(kTestColor)); 327 SIMPLE_TEST_STEP(DrawPaint, drawPaint(kTestPaint)); 328 SIMPLE_TEST_STEP(DrawPointsPoints, drawPoints(SkCanvas::kPoints_PointMode, 329 kTestPointCount, kTestPoints, kTestPaint)); 330 SIMPLE_TEST_STEP(DrawPointsLiness, drawPoints(SkCanvas::kLines_PointMode, 331 kTestPointCount, kTestPoints, kTestPaint)); 332 SIMPLE_TEST_STEP(DrawPointsPolygon, drawPoints(SkCanvas::kPolygon_PointMode, 333 kTestPointCount, kTestPoints, kTestPaint)); 334 SIMPLE_TEST_STEP(DrawRect, drawRect(kTestRect, kTestPaint)); 335 SIMPLE_TEST_STEP(DrawPath, drawPath(kTestPath, kTestPaint)); 336 SIMPLE_TEST_STEP(DrawBitmap, drawBitmap(kTestBitmap, 0, 0)); 337 SIMPLE_TEST_STEP(DrawBitmapPaint, drawBitmap(kTestBitmap, 0, 0, &kTestPaint)); 338 SIMPLE_TEST_STEP(DrawBitmapRect, drawBitmapRect(kTestBitmap, NULL, kTestRect, 339 NULL)); 340 SIMPLE_TEST_STEP(DrawBitmapRectSrcRect, drawBitmapRect(kTestBitmap, 341 &kTestIRect, kTestRect, NULL)); 342 SIMPLE_TEST_STEP(DrawBitmapRectPaint, drawBitmapRect(kTestBitmap, NULL, 343 kTestRect, &kTestPaint)); 344 SIMPLE_TEST_STEP(DrawBitmapMatrix, drawBitmapMatrix(kTestBitmap, kTestMatrix, 345 NULL)); 346 SIMPLE_TEST_STEP(DrawBitmapMatrixPaint, drawBitmapMatrix(kTestBitmap, 347 kTestMatrix, &kTestPaint)); 348 SIMPLE_TEST_STEP(DrawBitmapNine, drawBitmapNine(kTestBitmap, kTestIRect, 349 kTestRect, NULL)); 350 SIMPLE_TEST_STEP(DrawBitmapNinePaint, drawBitmapNine(kTestBitmap, kTestIRect, 351 kTestRect, &kTestPaint)); 352 SIMPLE_TEST_STEP(DrawSprite, drawSprite(kTestBitmap, 0, 0, NULL)); 353 SIMPLE_TEST_STEP(DrawSpritePaint, drawSprite(kTestBitmap, 0, 0, &kTestPaint)); 354 SIMPLE_TEST_STEP(DrawText, drawText(kTestText.c_str(), kTestText.size(), 355 0, 1, kTestPaint)); 356 SIMPLE_TEST_STEP(DrawPosText, drawPosText(kTestText.c_str(), 357 kTestText.size(), kTestPoints2, kTestPaint)); 358 SIMPLE_TEST_STEP(DrawTextOnPath, drawTextOnPath(kTestText.c_str(), 359 kTestText.size(), kTestPath, NULL, kTestPaint)); 360 SIMPLE_TEST_STEP(DrawTextOnPathMatrix, drawTextOnPath(kTestText.c_str(), 361 kTestText.size(), kTestPath, &kTestMatrix, kTestPaint)); 362 SIMPLE_TEST_STEP(DrawData, drawData(kTestText.c_str(), kTestText.size())); 363 SIMPLE_TEST_STEP(BeginGroup, beginCommentGroup(kTestText.c_str())); 364 SIMPLE_TEST_STEP(AddComment, addComment(kTestText.c_str(), kTestText.c_str())); 365 SIMPLE_TEST_STEP(EndGroup, endCommentGroup()); 366 367 /////////////////////////////////////////////////////////////////////////////// 368 // Complex test steps 369 370 static void SaveMatrixClipStep(SkCanvas* canvas, 371 skiatest::Reporter* reporter, 372 CanvasTestStep* testStep) { 373 int saveCount = canvas->getSaveCount(); 374 canvas->save(); 375 canvas->translate(SkIntToScalar(1), SkIntToScalar(2)); 376 canvas->clipRegion(kTestRegion); 377 canvas->restore(); 378 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 379 testStep->assertMessage()); 380 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(), 381 testStep->assertMessage()); 382 // REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion, testStep->assertMessage()); 383 } 384 TEST_STEP(SaveMatrixClip, SaveMatrixClipStep); 385 386 static void SaveLayerStep(SkCanvas* canvas, 387 skiatest::Reporter* reporter, 388 CanvasTestStep* testStep) { 389 int saveCount = canvas->getSaveCount(); 390 canvas->saveLayer(NULL, NULL); 391 canvas->restore(); 392 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 393 testStep->assertMessage()); 394 } 395 TEST_STEP(SaveLayer, SaveLayerStep); 396 397 static void BoundedSaveLayerStep(SkCanvas* canvas, 398 skiatest::Reporter* reporter, 399 CanvasTestStep* testStep) { 400 int saveCount = canvas->getSaveCount(); 401 canvas->saveLayer(&kTestRect, NULL); 402 canvas->restore(); 403 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 404 testStep->assertMessage()); 405 } 406 TEST_STEP(BoundedSaveLayer, BoundedSaveLayerStep); 407 408 static void PaintSaveLayerStep(SkCanvas* canvas, 409 skiatest::Reporter* reporter, 410 CanvasTestStep* testStep) { 411 int saveCount = canvas->getSaveCount(); 412 canvas->saveLayer(NULL, &kTestPaint); 413 canvas->restore(); 414 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 415 testStep->assertMessage()); 416 } 417 TEST_STEP(PaintSaveLayer, PaintSaveLayerStep); 418 419 static void TwoClipOpsStep(SkCanvas* canvas, 420 skiatest::Reporter*, 421 CanvasTestStep*) { 422 // This test exercises a functionality in SkPicture that leads to the 423 // recording of restore offset placeholders. This test will trigger an 424 // assertion at playback time if the placeholders are not properly 425 // filled when the recording ends. 426 canvas->clipRect(kTestRect); 427 canvas->clipRegion(kTestRegion); 428 } 429 TEST_STEP(TwoClipOps, TwoClipOpsStep); 430 431 // exercise fix for http://code.google.com/p/skia/issues/detail?id=560 432 // ('SkPathStroker::lineTo() fails for line with length SK_ScalarNearlyZero') 433 static void DrawNearlyZeroLengthPathTestStep(SkCanvas* canvas, 434 skiatest::Reporter*, 435 CanvasTestStep*) { 436 SkPaint paint; 437 paint.setStrokeWidth(SkIntToScalar(1)); 438 paint.setStyle(SkPaint::kStroke_Style); 439 440 canvas->drawPath(kNearlyZeroLengthPath, paint); 441 } 442 TEST_STEP(DrawNearlyZeroLengthPath, DrawNearlyZeroLengthPathTestStep); 443 444 static void DrawVerticesShaderTestStep(SkCanvas* canvas, 445 skiatest::Reporter*, 446 CanvasTestStep*) { 447 SkPoint pts[4]; 448 pts[0].set(0, 0); 449 pts[1].set(SkIntToScalar(kWidth), 0); 450 pts[2].set(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); 451 pts[3].set(0, SkIntToScalar(kHeight)); 452 SkPaint paint; 453 SkShader* shader = SkShader::CreateBitmapShader(kTestBitmap, 454 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); 455 paint.setShader(shader)->unref(); 456 canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, pts, pts, 457 NULL, NULL, NULL, 0, paint); 458 } 459 // NYI: issue 240. 460 TEST_STEP_NO_PDF(DrawVerticesShader, DrawVerticesShaderTestStep); 461 462 static void DrawPictureTestStep(SkCanvas* canvas, 463 skiatest::Reporter*, 464 CanvasTestStep*) { 465 SkPictureRecorder recorder; 466 SkCanvas* testCanvas = recorder.beginRecording(SkIntToScalar(kWidth), SkIntToScalar(kHeight), 467 NULL, 0); 468 testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1)); 469 testCanvas->clipRect(kTestRect); 470 testCanvas->drawRect(kTestRect, kTestPaint); 471 SkAutoTUnref<SkPicture> testPicture(recorder.endRecording()); 472 473 canvas->drawPicture(testPicture); 474 } 475 TEST_STEP(DrawPicture, DrawPictureTestStep); 476 477 static void SaveRestoreTestStep(SkCanvas* canvas, 478 skiatest::Reporter* reporter, 479 CanvasTestStep* testStep) { 480 int baseSaveCount = canvas->getSaveCount(); 481 int n = canvas->save(); 482 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount == n, testStep->assertMessage()); 483 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(), 484 testStep->assertMessage()); 485 canvas->save(); 486 canvas->save(); 487 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 3 == canvas->getSaveCount(), 488 testStep->assertMessage()); 489 canvas->restoreToCount(baseSaveCount + 1); 490 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(), 491 testStep->assertMessage()); 492 493 // should this pin to 1, or be a no-op, or crash? 494 canvas->restoreToCount(0); 495 REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(), 496 testStep->assertMessage()); 497 } 498 TEST_STEP(SaveRestore, SaveRestoreTestStep); 499 500 static void DrawLayerTestStep(SkCanvas* canvas, 501 skiatest::Reporter* reporter, 502 CanvasTestStep* testStep) { 503 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 504 testStep->assertMessage()); 505 canvas->save(); 506 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 507 testStep->assertMessage()); 508 canvas->restore(); 509 510 const SkRect* bounds = NULL; // null means include entire bounds 511 const SkPaint* paint = NULL; 512 513 canvas->saveLayer(bounds, paint); 514 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 515 testStep->assertMessage()); 516 canvas->restore(); 517 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 518 testStep->assertMessage()); 519 520 canvas->saveLayer(bounds, paint); 521 canvas->saveLayer(bounds, paint); 522 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 523 testStep->assertMessage()); 524 canvas->restore(); 525 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 526 testStep->assertMessage()); 527 canvas->restore(); 528 // now layer count should be 0 529 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 530 testStep->assertMessage()); 531 } 532 TEST_STEP(DrawLayer, DrawLayerTestStep); 533 534 static void NestedSaveRestoreWithSolidPaintTestStep(SkCanvas* canvas, 535 skiatest::Reporter*, 536 CanvasTestStep*) { 537 // This test step challenges the TestDeferredCanvasStateConsistency 538 // test cases because the opaque paint can trigger an optimization 539 // that discards previously recorded commands. The challenge is to maintain 540 // correct clip and matrix stack state. 541 canvas->resetMatrix(); 542 canvas->rotate(SkIntToScalar(30)); 543 canvas->save(); 544 canvas->translate(SkIntToScalar(2), SkIntToScalar(1)); 545 canvas->save(); 546 canvas->scale(SkIntToScalar(3), SkIntToScalar(3)); 547 SkPaint paint; 548 paint.setColor(0xFFFFFFFF); 549 canvas->drawPaint(paint); 550 canvas->restore(); 551 canvas->restore(); 552 } 553 TEST_STEP(NestedSaveRestoreWithSolidPaint, \ 554 NestedSaveRestoreWithSolidPaintTestStep); 555 556 static void NestedSaveRestoreWithFlushTestStep(SkCanvas* canvas, 557 skiatest::Reporter*, 558 CanvasTestStep*) { 559 // This test step challenges the TestDeferredCanvasStateConsistency 560 // test case because the canvas flush on a deferred canvas will 561 // reset the recording session. The challenge is to maintain correct 562 // clip and matrix stack state on the playback canvas. 563 canvas->resetMatrix(); 564 canvas->rotate(SkIntToScalar(30)); 565 canvas->save(); 566 canvas->translate(SkIntToScalar(2), SkIntToScalar(1)); 567 canvas->save(); 568 canvas->scale(SkIntToScalar(3), SkIntToScalar(3)); 569 canvas->drawRect(kTestRect,kTestPaint); 570 canvas->flush(); 571 canvas->restore(); 572 canvas->restore(); 573 } 574 TEST_STEP(NestedSaveRestoreWithFlush, \ 575 NestedSaveRestoreWithFlushTestStep); 576 577 static void AssertCanvasStatesEqual(skiatest::Reporter* reporter, 578 const SkCanvas* canvas1, 579 const SkCanvas* canvas2, 580 CanvasTestStep* testStep) { 581 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDeviceSize() == 582 canvas2->getDeviceSize(), testStep->assertMessage()); 583 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getSaveCount() == 584 canvas2->getSaveCount(), testStep->assertMessage()); 585 REPORTER_ASSERT_MESSAGE(reporter, canvas1->isDrawingToLayer() == 586 canvas2->isDrawingToLayer(), testStep->assertMessage()); 587 588 SkRect bounds1, bounds2; 589 REPORTER_ASSERT_MESSAGE(reporter, 590 canvas1->getClipBounds(&bounds1) == canvas2->getClipBounds(&bounds2), 591 testStep->assertMessage()); 592 REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2, 593 testStep->assertMessage()); 594 595 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDrawFilter() == 596 canvas2->getDrawFilter(), testStep->assertMessage()); 597 SkIRect deviceBounds1, deviceBounds2; 598 REPORTER_ASSERT_MESSAGE(reporter, 599 canvas1->getClipDeviceBounds(&deviceBounds1) == 600 canvas2->getClipDeviceBounds(&deviceBounds2), 601 testStep->assertMessage()); 602 REPORTER_ASSERT_MESSAGE(reporter, deviceBounds1 == deviceBounds2, testStep->assertMessage()); 603 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalMatrix() == 604 canvas2->getTotalMatrix(), testStep->assertMessage()); 605 REPORTER_ASSERT_MESSAGE(reporter, equal_clips(*canvas1, *canvas2), testStep->assertMessage()); 606 607 // The following test code is commented out because the test fails when 608 // the canvas is an SkPictureRecord or SkDeferredCanvas 609 // Issue: http://code.google.com/p/skia/issues/detail?id=498 610 // Also, creating a LayerIter on an SkProxyCanvas crashes 611 // Issue: http://code.google.com/p/skia/issues/detail?id=499 612 /* 613 SkCanvas::LayerIter layerIter1(const_cast<SkCanvas*>(canvas1), false); 614 SkCanvas::LayerIter layerIter2(const_cast<SkCanvas*>(canvas2), false); 615 while (!layerIter1.done() && !layerIter2.done()) { 616 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.matrix() == 617 layerIter2.matrix(), testStep->assertMessage()); 618 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.clip() == 619 layerIter2.clip(), testStep->assertMessage()); 620 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.paint() == 621 layerIter2.paint(), testStep->assertMessage()); 622 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.x() == 623 layerIter2.x(), testStep->assertMessage()); 624 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.y() == 625 layerIter2.y(), testStep->assertMessage()); 626 layerIter1.next(); 627 layerIter2.next(); 628 } 629 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.done(), 630 testStep->assertMessage()); 631 REPORTER_ASSERT_MESSAGE(reporter, layerIter2.done(), 632 testStep->assertMessage()); 633 */ 634 } 635 636 // The following class groups static functions that need to access 637 // the privates members of SkPictureRecord 638 class SkPictureTester { 639 private: 640 static int EQ(const SkFlatData* a, const SkFlatData* b) { 641 return *a == *b; 642 } 643 644 static void AssertFlattenedObjectsEqual( 645 SkPictureRecord* referenceRecord, 646 SkPictureRecord* testRecord, 647 skiatest::Reporter* reporter, 648 CanvasTestStep* testStep) { 649 650 REPORTER_ASSERT_MESSAGE(reporter, 651 referenceRecord->fBitmapHeap->count() == 652 testRecord->fBitmapHeap->count(), testStep->assertMessage()); 653 REPORTER_ASSERT_MESSAGE(reporter, 654 referenceRecord->fPaints.count() == 655 testRecord->fPaints.count(), testStep->assertMessage()); 656 for (int i = 0; i < referenceRecord->fPaints.count(); ++i) { 657 REPORTER_ASSERT_MESSAGE(reporter, 658 EQ(referenceRecord->fPaints[i], testRecord->fPaints[i]), 659 testStep->assertMessage()); 660 } 661 REPORTER_ASSERT_MESSAGE(reporter, 662 !referenceRecord->fPathHeap == !testRecord->fPathHeap, 663 testStep->assertMessage()); 664 // The following tests are commented out because they currently 665 // fail. Issue: http://code.google.com/p/skia/issues/detail?id=507 666 /* 667 if (referenceRecord->fPathHeap) { 668 REPORTER_ASSERT_MESSAGE(reporter, 669 referenceRecord->fPathHeap->count() == 670 testRecord->fPathHeap->count(), 671 testStep->assertMessage()); 672 for (int i = 0; i < referenceRecord->fPathHeap->count(); ++i) { 673 REPORTER_ASSERT_MESSAGE(reporter, 674 (*referenceRecord->fPathHeap)[i] == 675 (*testRecord->fPathHeap)[i], testStep->assertMessage()); 676 } 677 } 678 */ 679 680 } 681 682 public: 683 684 static void TestPictureFlattenedObjectReuse(skiatest::Reporter* reporter, 685 CanvasTestStep* testStep, 686 uint32_t recordFlags) { 687 // Verify that when a test step is executed twice, no extra resources 688 // are flattened during the second execution 689 testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat); 690 SkPictureRecorder referenceRecorder; 691 SkCanvas* referenceCanvas = 692 referenceRecorder.DEPRECATED_beginRecording(SkIntToScalar(kWidth), 693 SkIntToScalar(kHeight), 694 NULL, recordFlags); 695 testStep->draw(referenceCanvas, reporter); 696 697 SkPictureRecorder testRecorder; 698 SkCanvas* testCanvas = 699 testRecorder.DEPRECATED_beginRecording(SkIntToScalar(kWidth), 700 SkIntToScalar(kHeight), 701 NULL, recordFlags); 702 testStep->draw(testCanvas, reporter); 703 testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat); 704 testStep->draw(testCanvas, reporter); 705 706 SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>(referenceCanvas); 707 SkPictureRecord* testRecord = static_cast<SkPictureRecord*>(testCanvas); 708 testStep->setAssertMessageFormat(kPictureResourceReuseMessageFormat); 709 AssertFlattenedObjectsEqual(referenceRecord, testRecord, 710 reporter, testStep); 711 } 712 }; 713 714 static void TestPdfDevice(skiatest::Reporter* reporter, 715 CanvasTestStep* testStep) { 716 SkISize pageSize = SkISize::Make(kWidth, kHeight); 717 SkPDFDevice device(pageSize, pageSize, SkMatrix::I()); 718 SkCanvas canvas(&device); 719 testStep->setAssertMessageFormat(kPdfAssertMessageFormat); 720 testStep->draw(&canvas, reporter); 721 SkPDFDocument doc; 722 doc.appendPage(&device); 723 SkDynamicMemoryWStream stream; 724 doc.emitPDF(&stream); 725 } 726 727 // The following class groups static functions that need to access 728 // the privates members of SkDeferredCanvas 729 class SkDeferredCanvasTester { 730 public: 731 static void TestDeferredCanvasStateConsistency( 732 skiatest::Reporter* reporter, 733 CanvasTestStep* testStep, 734 const SkCanvas& referenceCanvas, bool silent) { 735 736 SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF)); 737 SkAutoTUnref<SkDeferredCanvas> deferredCanvas(SkDeferredCanvas::Create(surface.get())); 738 739 testStep->setAssertMessageFormat(kDeferredDrawAssertMessageFormat); 740 testStep->draw(deferredCanvas, reporter); 741 testStep->setAssertMessageFormat(kDeferredPreFlushAssertMessageFormat); 742 AssertCanvasStatesEqual(reporter, deferredCanvas, &referenceCanvas, 743 testStep); 744 745 if (silent) { 746 deferredCanvas->silentFlush(); 747 } else { 748 deferredCanvas->flush(); 749 } 750 751 testStep->setAssertMessageFormat( 752 silent ? kDeferredPostSilentFlushPlaybackAssertMessageFormat : 753 kDeferredPostFlushPlaybackAssertMessageFormat); 754 AssertCanvasStatesEqual(reporter, 755 deferredCanvas->immediateCanvas(), 756 &referenceCanvas, testStep); 757 758 // Verified that deferred canvas state is not affected by flushing 759 // pending draw operations 760 761 // The following test code is commented out because it currently fails. 762 // Issue: http://code.google.com/p/skia/issues/detail?id=496 763 /* 764 testStep->setAssertMessageFormat(kDeferredPostFlushAssertMessageFormat); 765 AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas, 766 testStep); 767 */ 768 } 769 }; 770 771 // unused 772 static void TestProxyCanvasStateConsistency( 773 skiatest::Reporter* reporter, 774 CanvasTestStep* testStep, 775 const SkCanvas& referenceCanvas) { 776 777 SkBitmap indirectStore; 778 createBitmap(&indirectStore, 0xFFFFFFFF); 779 SkCanvas indirectCanvas(indirectStore); 780 SkProxyCanvas proxyCanvas(&indirectCanvas); 781 testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat); 782 testStep->draw(&proxyCanvas, reporter); 783 // Verify that the SkProxyCanvas reports consitent state 784 testStep->setAssertMessageFormat(kProxyStateAssertMessageFormat); 785 AssertCanvasStatesEqual(reporter, &proxyCanvas, &referenceCanvas, 786 testStep); 787 // Verify that the indirect canvas reports consitent state 788 testStep->setAssertMessageFormat(kProxyIndirectStateAssertMessageFormat); 789 AssertCanvasStatesEqual(reporter, &indirectCanvas, &referenceCanvas, 790 testStep); 791 } 792 793 // unused 794 static void TestNWayCanvasStateConsistency( 795 skiatest::Reporter* reporter, 796 CanvasTestStep* testStep, 797 const SkCanvas& referenceCanvas) { 798 799 SkBitmap indirectStore1; 800 createBitmap(&indirectStore1, 0xFFFFFFFF); 801 SkCanvas indirectCanvas1(indirectStore1); 802 803 SkBitmap indirectStore2; 804 createBitmap(&indirectStore2, 0xFFFFFFFF); 805 SkCanvas indirectCanvas2(indirectStore2); 806 807 SkISize canvasSize = referenceCanvas.getDeviceSize(); 808 SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height()); 809 nWayCanvas.addCanvas(&indirectCanvas1); 810 nWayCanvas.addCanvas(&indirectCanvas2); 811 812 testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat); 813 testStep->draw(&nWayCanvas, reporter); 814 // Verify that the SkProxyCanvas reports consitent state 815 testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat); 816 AssertCanvasStatesEqual(reporter, &nWayCanvas, &referenceCanvas, 817 testStep); 818 // Verify that the indirect canvases report consitent state 819 testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat); 820 AssertCanvasStatesEqual(reporter, &indirectCanvas1, &referenceCanvas, 821 testStep); 822 testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat); 823 AssertCanvasStatesEqual(reporter, &indirectCanvas2, &referenceCanvas, 824 testStep); 825 } 826 827 /* 828 * This sub-test verifies that the test step passes when executed 829 * with SkCanvas and with classes derrived from SkCanvas. It also verifies 830 * that the all canvas derivatives report the same state as an SkCanvas 831 * after having executed the test step. 832 */ 833 static void TestOverrideStateConsistency(skiatest::Reporter* reporter, 834 CanvasTestStep* testStep) { 835 SkBitmap referenceStore; 836 createBitmap(&referenceStore, 0xFFFFFFFF); 837 SkCanvas referenceCanvas(referenceStore); 838 testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat); 839 testStep->draw(&referenceCanvas, reporter); 840 841 SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, false); 842 843 SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, true); 844 845 // The following test code is disabled because SkProxyCanvas is 846 // missing a lot of virtual overrides on get* methods, which are used 847 // to verify canvas state. 848 // Issue: http://code.google.com/p/skia/issues/detail?id=500 849 850 if (false) { // avoid bit rot, suppress warning 851 TestProxyCanvasStateConsistency(reporter, testStep, referenceCanvas); 852 } 853 854 // The following test code is disabled because SkNWayCanvas does not 855 // report correct clipping and device bounds information 856 // Issue: http://code.google.com/p/skia/issues/detail?id=501 857 858 if (false) { // avoid bit rot, suppress warning 859 TestNWayCanvasStateConsistency(reporter, testStep, referenceCanvas); 860 } 861 862 if (false) { // avoid bit rot, suppress warning 863 test_clipVisitor(reporter, &referenceCanvas); 864 } 865 } 866 867 static void test_newraster(skiatest::Reporter* reporter) { 868 SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); 869 SkCanvas* canvas = SkCanvas::NewRaster(info); 870 REPORTER_ASSERT(reporter, canvas); 871 872 SkImageInfo info2; 873 size_t rowBytes; 874 const SkPMColor* addr = (const SkPMColor*)canvas->peekPixels(&info2, &rowBytes); 875 REPORTER_ASSERT(reporter, addr); 876 REPORTER_ASSERT(reporter, info == info2); 877 for (int y = 0; y < info.height(); ++y) { 878 for (int x = 0; x < info.width(); ++x) { 879 REPORTER_ASSERT(reporter, 0 == addr[x]); 880 } 881 addr = (const SkPMColor*)((const char*)addr + rowBytes); 882 } 883 SkDELETE(canvas); 884 885 // now try a deliberately bad info 886 info = info.makeWH(-1, info.height()); 887 REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info)); 888 889 // too big 890 info = info.makeWH(1 << 30, 1 << 30); 891 REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info)); 892 893 // not a valid pixel type 894 info = SkImageInfo::Make(10, 10, kUnknown_SkColorType, info.alphaType()); 895 REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info)); 896 897 // We should succeed with a zero-sized valid info 898 info = SkImageInfo::MakeN32Premul(0, 0); 899 canvas = SkCanvas::NewRaster(info); 900 REPORTER_ASSERT(reporter, canvas); 901 SkDELETE(canvas); 902 } 903 904 DEF_TEST(Canvas, reporter) { 905 // Init global here because bitmap pixels cannot be alocated during 906 // static initialization 907 kTestBitmap = testBitmap(); 908 909 for (int testStep = 0; testStep < testStepArray().count(); testStep++) { 910 TestOverrideStateConsistency(reporter, testStepArray()[testStep]); 911 SkPictureTester::TestPictureFlattenedObjectReuse(reporter, 912 testStepArray()[testStep], 0); 913 if (testStepArray()[testStep]->enablePdfTesting()) { 914 TestPdfDevice(reporter, testStepArray()[testStep]); 915 } 916 } 917 918 // Explicitly call reset(), so we don't leak the pixels (since kTestBitmap is a global) 919 kTestBitmap.reset(); 920 921 test_newraster(reporter); 922 } 923