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 // Save/restore calls cannot be in isolated simple test steps because the test 371 // cases that use SkPicture require that save and restore calls be balanced. 372 static void SaveMatrixStep(SkCanvas* canvas, 373 skiatest::Reporter* reporter, 374 CanvasTestStep* testStep) { 375 int saveCount = canvas->getSaveCount(); 376 canvas->save(SkCanvas::kMatrix_SaveFlag); 377 canvas->clipRegion(kTestRegion); 378 canvas->translate(SkIntToScalar(1), SkIntToScalar(2)); 379 canvas->restore(); 380 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 381 testStep->assertMessage()); 382 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(), 383 testStep->assertMessage()); 384 // REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() == kTestRegion, testStep->assertMessage()); 385 } 386 TEST_STEP(SaveMatrix, SaveMatrixStep); 387 388 static void SaveClipStep(SkCanvas* canvas, 389 skiatest::Reporter* reporter, 390 CanvasTestStep* testStep) { 391 int saveCount = canvas->getSaveCount(); 392 canvas->save(SkCanvas::kClip_SaveFlag); 393 canvas->translate(SkIntToScalar(1), SkIntToScalar(2)); 394 canvas->clipRegion(kTestRegion); 395 canvas->restore(); 396 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 397 testStep->assertMessage()); 398 REPORTER_ASSERT_MESSAGE(reporter, !canvas->getTotalMatrix().isIdentity(), 399 testStep->assertMessage()); 400 // REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion, testStep->assertMessage()); 401 } 402 TEST_STEP(SaveClip, SaveClipStep); 403 404 static void SaveMatrixClipStep(SkCanvas* canvas, 405 skiatest::Reporter* reporter, 406 CanvasTestStep* testStep) { 407 int saveCount = canvas->getSaveCount(); 408 canvas->save(SkCanvas::kMatrixClip_SaveFlag); 409 canvas->translate(SkIntToScalar(1), SkIntToScalar(2)); 410 canvas->clipRegion(kTestRegion); 411 canvas->restore(); 412 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 413 testStep->assertMessage()); 414 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(), 415 testStep->assertMessage()); 416 // REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion, testStep->assertMessage()); 417 } 418 TEST_STEP(SaveMatrixClip, SaveMatrixClipStep); 419 420 static void SaveLayerStep(SkCanvas* canvas, 421 skiatest::Reporter* reporter, 422 CanvasTestStep* testStep) { 423 int saveCount = canvas->getSaveCount(); 424 canvas->saveLayer(NULL, NULL); 425 canvas->restore(); 426 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 427 testStep->assertMessage()); 428 } 429 TEST_STEP(SaveLayer, SaveLayerStep); 430 431 static void BoundedSaveLayerStep(SkCanvas* canvas, 432 skiatest::Reporter* reporter, 433 CanvasTestStep* testStep) { 434 int saveCount = canvas->getSaveCount(); 435 canvas->saveLayer(&kTestRect, NULL); 436 canvas->restore(); 437 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 438 testStep->assertMessage()); 439 } 440 TEST_STEP(BoundedSaveLayer, BoundedSaveLayerStep); 441 442 static void PaintSaveLayerStep(SkCanvas* canvas, 443 skiatest::Reporter* reporter, 444 CanvasTestStep* testStep) { 445 int saveCount = canvas->getSaveCount(); 446 canvas->saveLayer(NULL, &kTestPaint); 447 canvas->restore(); 448 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount, 449 testStep->assertMessage()); 450 } 451 TEST_STEP(PaintSaveLayer, PaintSaveLayerStep); 452 453 static void TwoClipOpsStep(SkCanvas* canvas, 454 skiatest::Reporter*, 455 CanvasTestStep*) { 456 // This test exercises a functionality in SkPicture that leads to the 457 // recording of restore offset placeholders. This test will trigger an 458 // assertion at playback time if the placeholders are not properly 459 // filled when the recording ends. 460 canvas->clipRect(kTestRect); 461 canvas->clipRegion(kTestRegion); 462 } 463 TEST_STEP(TwoClipOps, TwoClipOpsStep); 464 465 // exercise fix for http://code.google.com/p/skia/issues/detail?id=560 466 // ('SkPathStroker::lineTo() fails for line with length SK_ScalarNearlyZero') 467 static void DrawNearlyZeroLengthPathTestStep(SkCanvas* canvas, 468 skiatest::Reporter*, 469 CanvasTestStep*) { 470 SkPaint paint; 471 paint.setStrokeWidth(SkIntToScalar(1)); 472 paint.setStyle(SkPaint::kStroke_Style); 473 474 canvas->drawPath(kNearlyZeroLengthPath, paint); 475 } 476 TEST_STEP(DrawNearlyZeroLengthPath, DrawNearlyZeroLengthPathTestStep); 477 478 static void DrawVerticesShaderTestStep(SkCanvas* canvas, 479 skiatest::Reporter*, 480 CanvasTestStep*) { 481 SkPoint pts[4]; 482 pts[0].set(0, 0); 483 pts[1].set(SkIntToScalar(kWidth), 0); 484 pts[2].set(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); 485 pts[3].set(0, SkIntToScalar(kHeight)); 486 SkPaint paint; 487 SkShader* shader = SkShader::CreateBitmapShader(kTestBitmap, 488 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); 489 paint.setShader(shader)->unref(); 490 canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, pts, pts, 491 NULL, NULL, NULL, 0, paint); 492 } 493 // NYI: issue 240. 494 TEST_STEP_NO_PDF(DrawVerticesShader, DrawVerticesShaderTestStep); 495 496 static void DrawPictureTestStep(SkCanvas* canvas, 497 skiatest::Reporter*, 498 CanvasTestStep*) { 499 SkPictureRecorder recorder; 500 SkCanvas* testCanvas = recorder.beginRecording(kWidth, kHeight, NULL, 0); 501 testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1)); 502 testCanvas->clipRect(kTestRect); 503 testCanvas->drawRect(kTestRect, kTestPaint); 504 SkAutoTUnref<SkPicture> testPicture(recorder.endRecording()); 505 506 canvas->drawPicture(testPicture); 507 } 508 TEST_STEP(DrawPicture, DrawPictureTestStep); 509 510 static void SaveRestoreTestStep(SkCanvas* canvas, 511 skiatest::Reporter* reporter, 512 CanvasTestStep* testStep) { 513 int baseSaveCount = canvas->getSaveCount(); 514 int n = canvas->save(); 515 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount == n, testStep->assertMessage()); 516 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(), 517 testStep->assertMessage()); 518 canvas->save(); 519 canvas->save(); 520 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 3 == canvas->getSaveCount(), 521 testStep->assertMessage()); 522 canvas->restoreToCount(baseSaveCount + 1); 523 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(), 524 testStep->assertMessage()); 525 526 // should this pin to 1, or be a no-op, or crash? 527 canvas->restoreToCount(0); 528 REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(), 529 testStep->assertMessage()); 530 } 531 TEST_STEP(SaveRestore, SaveRestoreTestStep); 532 533 static void DrawLayerTestStep(SkCanvas* canvas, 534 skiatest::Reporter* reporter, 535 CanvasTestStep* testStep) { 536 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 537 testStep->assertMessage()); 538 canvas->save(); 539 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 540 testStep->assertMessage()); 541 canvas->restore(); 542 543 const SkRect* bounds = NULL; // null means include entire bounds 544 const SkPaint* paint = NULL; 545 546 canvas->saveLayer(bounds, paint); 547 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 548 testStep->assertMessage()); 549 canvas->restore(); 550 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 551 testStep->assertMessage()); 552 553 canvas->saveLayer(bounds, paint); 554 canvas->saveLayer(bounds, paint); 555 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 556 testStep->assertMessage()); 557 canvas->restore(); 558 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 559 testStep->assertMessage()); 560 canvas->restore(); 561 // now layer count should be 0 562 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 563 testStep->assertMessage()); 564 } 565 TEST_STEP(DrawLayer, DrawLayerTestStep); 566 567 static void NestedSaveRestoreWithSolidPaintTestStep(SkCanvas* canvas, 568 skiatest::Reporter*, 569 CanvasTestStep*) { 570 // This test step challenges the TestDeferredCanvasStateConsistency 571 // test cases because the opaque paint can trigger an optimization 572 // that discards previously recorded commands. The challenge is to maintain 573 // correct clip and matrix stack state. 574 canvas->resetMatrix(); 575 canvas->rotate(SkIntToScalar(30)); 576 canvas->save(); 577 canvas->translate(SkIntToScalar(2), SkIntToScalar(1)); 578 canvas->save(); 579 canvas->scale(SkIntToScalar(3), SkIntToScalar(3)); 580 SkPaint paint; 581 paint.setColor(0xFFFFFFFF); 582 canvas->drawPaint(paint); 583 canvas->restore(); 584 canvas->restore(); 585 } 586 TEST_STEP(NestedSaveRestoreWithSolidPaint, \ 587 NestedSaveRestoreWithSolidPaintTestStep); 588 589 static void NestedSaveRestoreWithFlushTestStep(SkCanvas* canvas, 590 skiatest::Reporter*, 591 CanvasTestStep*) { 592 // This test step challenges the TestDeferredCanvasStateConsistency 593 // test case because the canvas flush on a deferred canvas will 594 // reset the recording session. The challenge is to maintain correct 595 // clip and matrix stack state on the playback canvas. 596 canvas->resetMatrix(); 597 canvas->rotate(SkIntToScalar(30)); 598 canvas->save(); 599 canvas->translate(SkIntToScalar(2), SkIntToScalar(1)); 600 canvas->save(); 601 canvas->scale(SkIntToScalar(3), SkIntToScalar(3)); 602 canvas->drawRect(kTestRect,kTestPaint); 603 canvas->flush(); 604 canvas->restore(); 605 canvas->restore(); 606 } 607 TEST_STEP(NestedSaveRestoreWithFlush, \ 608 NestedSaveRestoreWithFlushTestStep); 609 610 static void AssertCanvasStatesEqual(skiatest::Reporter* reporter, 611 const SkCanvas* canvas1, 612 const SkCanvas* canvas2, 613 CanvasTestStep* testStep) { 614 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDeviceSize() == 615 canvas2->getDeviceSize(), testStep->assertMessage()); 616 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getSaveCount() == 617 canvas2->getSaveCount(), testStep->assertMessage()); 618 REPORTER_ASSERT_MESSAGE(reporter, canvas1->isDrawingToLayer() == 619 canvas2->isDrawingToLayer(), testStep->assertMessage()); 620 621 SkRect bounds1, bounds2; 622 REPORTER_ASSERT_MESSAGE(reporter, 623 canvas1->getClipBounds(&bounds1) == canvas2->getClipBounds(&bounds2), 624 testStep->assertMessage()); 625 REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2, 626 testStep->assertMessage()); 627 628 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDrawFilter() == 629 canvas2->getDrawFilter(), testStep->assertMessage()); 630 SkIRect deviceBounds1, deviceBounds2; 631 REPORTER_ASSERT_MESSAGE(reporter, 632 canvas1->getClipDeviceBounds(&deviceBounds1) == 633 canvas2->getClipDeviceBounds(&deviceBounds2), 634 testStep->assertMessage()); 635 REPORTER_ASSERT_MESSAGE(reporter, deviceBounds1 == deviceBounds2, testStep->assertMessage()); 636 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalMatrix() == 637 canvas2->getTotalMatrix(), testStep->assertMessage()); 638 REPORTER_ASSERT_MESSAGE(reporter, equal_clips(*canvas1, *canvas2), testStep->assertMessage()); 639 640 // The following test code is commented out because the test fails when 641 // the canvas is an SkPictureRecord or SkDeferredCanvas 642 // Issue: http://code.google.com/p/skia/issues/detail?id=498 643 // Also, creating a LayerIter on an SkProxyCanvas crashes 644 // Issue: http://code.google.com/p/skia/issues/detail?id=499 645 /* 646 SkCanvas::LayerIter layerIter1(const_cast<SkCanvas*>(canvas1), false); 647 SkCanvas::LayerIter layerIter2(const_cast<SkCanvas*>(canvas2), false); 648 while (!layerIter1.done() && !layerIter2.done()) { 649 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.matrix() == 650 layerIter2.matrix(), testStep->assertMessage()); 651 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.clip() == 652 layerIter2.clip(), testStep->assertMessage()); 653 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.paint() == 654 layerIter2.paint(), testStep->assertMessage()); 655 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.x() == 656 layerIter2.x(), testStep->assertMessage()); 657 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.y() == 658 layerIter2.y(), testStep->assertMessage()); 659 layerIter1.next(); 660 layerIter2.next(); 661 } 662 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.done(), 663 testStep->assertMessage()); 664 REPORTER_ASSERT_MESSAGE(reporter, layerIter2.done(), 665 testStep->assertMessage()); 666 */ 667 } 668 669 // The following class groups static functions that need to access 670 // the privates members of SkPictureRecord 671 class SkPictureTester { 672 private: 673 static int EQ(const SkFlatData* a, const SkFlatData* b) { 674 return *a == *b; 675 } 676 677 static void AssertFlattenedObjectsEqual( 678 SkPictureRecord* referenceRecord, 679 SkPictureRecord* testRecord, 680 skiatest::Reporter* reporter, 681 CanvasTestStep* testStep) { 682 683 REPORTER_ASSERT_MESSAGE(reporter, 684 referenceRecord->fBitmapHeap->count() == 685 testRecord->fBitmapHeap->count(), testStep->assertMessage()); 686 REPORTER_ASSERT_MESSAGE(reporter, 687 referenceRecord->fPaints.count() == 688 testRecord->fPaints.count(), testStep->assertMessage()); 689 for (int i = 0; i < referenceRecord->fPaints.count(); ++i) { 690 REPORTER_ASSERT_MESSAGE(reporter, 691 EQ(referenceRecord->fPaints[i], testRecord->fPaints[i]), 692 testStep->assertMessage()); 693 } 694 REPORTER_ASSERT_MESSAGE(reporter, 695 !referenceRecord->fPathHeap == !testRecord->fPathHeap, 696 testStep->assertMessage()); 697 // The following tests are commented out because they currently 698 // fail. Issue: http://code.google.com/p/skia/issues/detail?id=507 699 /* 700 if (referenceRecord->fPathHeap) { 701 REPORTER_ASSERT_MESSAGE(reporter, 702 referenceRecord->fPathHeap->count() == 703 testRecord->fPathHeap->count(), 704 testStep->assertMessage()); 705 for (int i = 0; i < referenceRecord->fPathHeap->count(); ++i) { 706 REPORTER_ASSERT_MESSAGE(reporter, 707 (*referenceRecord->fPathHeap)[i] == 708 (*testRecord->fPathHeap)[i], testStep->assertMessage()); 709 } 710 } 711 */ 712 713 } 714 715 public: 716 717 static void TestPictureFlattenedObjectReuse(skiatest::Reporter* reporter, 718 CanvasTestStep* testStep, 719 uint32_t recordFlags) { 720 // Verify that when a test step is executed twice, no extra resources 721 // are flattened during the second execution 722 testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat); 723 SkPictureRecorder referenceRecorder; 724 SkCanvas* referenceCanvas = referenceRecorder.beginRecording(kWidth, kHeight, 725 NULL, recordFlags); 726 testStep->draw(referenceCanvas, reporter); 727 728 SkPictureRecorder testRecorder; 729 SkCanvas* testCanvas = testRecorder.beginRecording(kWidth, kHeight, 730 NULL, recordFlags); 731 testStep->draw(testCanvas, reporter); 732 testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat); 733 testStep->draw(testCanvas, reporter); 734 735 SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>(referenceCanvas); 736 SkPictureRecord* testRecord = static_cast<SkPictureRecord*>(testCanvas); 737 testStep->setAssertMessageFormat(kPictureResourceReuseMessageFormat); 738 AssertFlattenedObjectsEqual(referenceRecord, testRecord, 739 reporter, testStep); 740 } 741 }; 742 743 static void TestPdfDevice(skiatest::Reporter* reporter, 744 CanvasTestStep* testStep) { 745 SkISize pageSize = SkISize::Make(kWidth, kHeight); 746 SkPDFDevice device(pageSize, pageSize, SkMatrix::I()); 747 SkCanvas canvas(&device); 748 testStep->setAssertMessageFormat(kPdfAssertMessageFormat); 749 testStep->draw(&canvas, reporter); 750 SkPDFDocument doc; 751 doc.appendPage(&device); 752 SkDynamicMemoryWStream stream; 753 doc.emitPDF(&stream); 754 } 755 756 // The following class groups static functions that need to access 757 // the privates members of SkDeferredCanvas 758 class SkDeferredCanvasTester { 759 public: 760 static void TestDeferredCanvasStateConsistency( 761 skiatest::Reporter* reporter, 762 CanvasTestStep* testStep, 763 const SkCanvas& referenceCanvas, bool silent) { 764 765 SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF)); 766 SkAutoTUnref<SkDeferredCanvas> deferredCanvas(SkDeferredCanvas::Create(surface.get())); 767 768 testStep->setAssertMessageFormat(kDeferredDrawAssertMessageFormat); 769 testStep->draw(deferredCanvas, reporter); 770 testStep->setAssertMessageFormat(kDeferredPreFlushAssertMessageFormat); 771 AssertCanvasStatesEqual(reporter, deferredCanvas, &referenceCanvas, 772 testStep); 773 774 if (silent) { 775 deferredCanvas->silentFlush(); 776 } else { 777 deferredCanvas->flush(); 778 } 779 780 testStep->setAssertMessageFormat( 781 silent ? kDeferredPostSilentFlushPlaybackAssertMessageFormat : 782 kDeferredPostFlushPlaybackAssertMessageFormat); 783 AssertCanvasStatesEqual(reporter, 784 deferredCanvas->immediateCanvas(), 785 &referenceCanvas, testStep); 786 787 // Verified that deferred canvas state is not affected by flushing 788 // pending draw operations 789 790 // The following test code is commented out because it currently fails. 791 // Issue: http://code.google.com/p/skia/issues/detail?id=496 792 /* 793 testStep->setAssertMessageFormat(kDeferredPostFlushAssertMessageFormat); 794 AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas, 795 testStep); 796 */ 797 } 798 }; 799 800 // unused 801 static void TestProxyCanvasStateConsistency( 802 skiatest::Reporter* reporter, 803 CanvasTestStep* testStep, 804 const SkCanvas& referenceCanvas) { 805 806 SkBitmap indirectStore; 807 createBitmap(&indirectStore, 0xFFFFFFFF); 808 SkBitmapDevice indirectDevice(indirectStore); 809 SkCanvas indirectCanvas(&indirectDevice); 810 SkProxyCanvas proxyCanvas(&indirectCanvas); 811 testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat); 812 testStep->draw(&proxyCanvas, reporter); 813 // Verify that the SkProxyCanvas reports consitent state 814 testStep->setAssertMessageFormat(kProxyStateAssertMessageFormat); 815 AssertCanvasStatesEqual(reporter, &proxyCanvas, &referenceCanvas, 816 testStep); 817 // Verify that the indirect canvas reports consitent state 818 testStep->setAssertMessageFormat(kProxyIndirectStateAssertMessageFormat); 819 AssertCanvasStatesEqual(reporter, &indirectCanvas, &referenceCanvas, 820 testStep); 821 } 822 823 // unused 824 static void TestNWayCanvasStateConsistency( 825 skiatest::Reporter* reporter, 826 CanvasTestStep* testStep, 827 const SkCanvas& referenceCanvas) { 828 829 SkBitmap indirectStore1; 830 createBitmap(&indirectStore1, 0xFFFFFFFF); 831 SkBitmapDevice indirectDevice1(indirectStore1); 832 SkCanvas indirectCanvas1(&indirectDevice1); 833 834 SkBitmap indirectStore2; 835 createBitmap(&indirectStore2, 0xFFFFFFFF); 836 SkBitmapDevice indirectDevice2(indirectStore2); 837 SkCanvas indirectCanvas2(&indirectDevice2); 838 839 SkISize canvasSize = referenceCanvas.getDeviceSize(); 840 SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height()); 841 nWayCanvas.addCanvas(&indirectCanvas1); 842 nWayCanvas.addCanvas(&indirectCanvas2); 843 844 testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat); 845 testStep->draw(&nWayCanvas, reporter); 846 // Verify that the SkProxyCanvas reports consitent state 847 testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat); 848 AssertCanvasStatesEqual(reporter, &nWayCanvas, &referenceCanvas, 849 testStep); 850 // Verify that the indirect canvases report consitent state 851 testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat); 852 AssertCanvasStatesEqual(reporter, &indirectCanvas1, &referenceCanvas, 853 testStep); 854 testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat); 855 AssertCanvasStatesEqual(reporter, &indirectCanvas2, &referenceCanvas, 856 testStep); 857 } 858 859 /* 860 * This sub-test verifies that the test step passes when executed 861 * with SkCanvas and with classes derrived from SkCanvas. It also verifies 862 * that the all canvas derivatives report the same state as an SkCanvas 863 * after having executed the test step. 864 */ 865 static void TestOverrideStateConsistency(skiatest::Reporter* reporter, 866 CanvasTestStep* testStep) { 867 SkBitmap referenceStore; 868 createBitmap(&referenceStore, 0xFFFFFFFF); 869 SkBitmapDevice referenceDevice(referenceStore); 870 SkCanvas referenceCanvas(&referenceDevice); 871 testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat); 872 testStep->draw(&referenceCanvas, reporter); 873 874 SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, false); 875 876 SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, true); 877 878 // The following test code is disabled because SkProxyCanvas is 879 // missing a lot of virtual overrides on get* methods, which are used 880 // to verify canvas state. 881 // Issue: http://code.google.com/p/skia/issues/detail?id=500 882 883 if (false) { // avoid bit rot, suppress warning 884 TestProxyCanvasStateConsistency(reporter, testStep, referenceCanvas); 885 } 886 887 // The following test code is disabled because SkNWayCanvas does not 888 // report correct clipping and device bounds information 889 // Issue: http://code.google.com/p/skia/issues/detail?id=501 890 891 if (false) { // avoid bit rot, suppress warning 892 TestNWayCanvasStateConsistency(reporter, testStep, referenceCanvas); 893 } 894 895 if (false) { // avoid bit rot, suppress warning 896 test_clipVisitor(reporter, &referenceCanvas); 897 } 898 } 899 900 static void test_newraster(skiatest::Reporter* reporter) { 901 SkImageInfo info = SkImageInfo::MakeN32Premul(10, 10); 902 SkCanvas* canvas = SkCanvas::NewRaster(info); 903 REPORTER_ASSERT(reporter, canvas); 904 905 SkImageInfo info2; 906 size_t rowBytes; 907 const SkPMColor* addr = (const SkPMColor*)canvas->peekPixels(&info2, &rowBytes); 908 REPORTER_ASSERT(reporter, addr); 909 REPORTER_ASSERT(reporter, info == info2); 910 for (int y = 0; y < info.height(); ++y) { 911 for (int x = 0; x < info.width(); ++x) { 912 REPORTER_ASSERT(reporter, 0 == addr[x]); 913 } 914 addr = (const SkPMColor*)((const char*)addr + rowBytes); 915 } 916 SkDELETE(canvas); 917 918 // now try a deliberately bad info 919 info.fWidth = -1; 920 REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info)); 921 922 // too big 923 info.fWidth = 1 << 30; 924 info.fHeight = 1 << 30; 925 REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info)); 926 927 // not a valid pixel type 928 info.fWidth = info.fHeight = 10; 929 info.fColorType = kUnknown_SkColorType; 930 REPORTER_ASSERT(reporter, NULL == SkCanvas::NewRaster(info)); 931 932 // We should succeed with a zero-sized valid info 933 info = SkImageInfo::MakeN32Premul(0, 0); 934 canvas = SkCanvas::NewRaster(info); 935 REPORTER_ASSERT(reporter, canvas); 936 SkDELETE(canvas); 937 } 938 939 DEF_TEST(Canvas, reporter) { 940 // Init global here because bitmap pixels cannot be alocated during 941 // static initialization 942 kTestBitmap = testBitmap(); 943 944 for (int testStep = 0; testStep < testStepArray().count(); testStep++) { 945 TestOverrideStateConsistency(reporter, testStepArray()[testStep]); 946 SkPictureTester::TestPictureFlattenedObjectReuse(reporter, 947 testStepArray()[testStep], 0); 948 if (testStepArray()[testStep]->enablePdfTesting()) { 949 TestPdfDevice(reporter, testStepArray()[testStep]); 950 } 951 } 952 953 // Explicitly call reset(), so we don't leak the pixels (since kTestBitmap is a global) 954 kTestBitmap.reset(); 955 956 test_newraster(reporter); 957 } 958