1 2 /* 3 * Copyright 2012 Google Inc. 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 /* Description: 10 * This test defines a series of elementatry test steps that perform 11 * a single or a small group of canvas API calls. Each test step is 12 * used in several test cases that verify that different types of SkCanvas 13 * flavors and derivatives pass it and yield consistent behavior. The 14 * test cases analyse results that are queryable through the API. They do 15 * not look at rendering results. 16 * 17 * Adding test stepss: 18 * The general pattern for creating a new test step is to write a test 19 * function of the form: 20 * 21 * static void MyTestStepFunction(SkCanvas* canvas, 22 * skiatest::Reporter* reporter, 23 * CanvasTestStep* testStep) 24 * { 25 * canvas->someCanvasAPImethod(); 26 * (...) 27 * REPORTER_ASSERT_MESSAGE(reporter, (...), \ 28 * testStep->assertMessage()); 29 * } 30 * 31 * The definition of the test step function should be followed by an 32 * invocation of the TEST_STEP macro, which generates a class and 33 * instance for the test step: 34 * 35 * TEST_STEP(MyTestStep, MyTestStepFunction) 36 * 37 * There are also short hand macros for defining simple test steps 38 * in a single line of code. A simple test step is a one that is made 39 * of a single canvas API call. 40 * 41 * SIMPLE_TEST_STEP(MytestStep, someCanvasAPIMethod()); 42 * 43 * There is another macro called SIMPLE_TEST_STEP_WITH_ASSERT that 44 * works the same way as SIMPLE_TEST_STEP, and additionally verifies 45 * that the invoked method returns a non-zero value. 46 */ 47 #include "SkBitmap.h" 48 #include "SkCanvas.h" 49 #include "SkDeferredCanvas.h" 50 #include "SkDevice.h" 51 #include "SkMatrix.h" 52 #include "SkNWayCanvas.h" 53 #include "SkPaint.h" 54 #include "SkPath.h" 55 #include "SkPicture.h" 56 #include "SkPictureRecord.h" 57 #include "SkProxyCanvas.h" 58 #include "SkRect.h" 59 #include "SkRegion.h" 60 #include "SkShader.h" 61 #include "SkStream.h" 62 #include "SkTDArray.h" 63 #include "Test.h" 64 65 static const int kWidth = 2; 66 static const int kHeight = 2; 67 // Maximum stream length for picture serialization 68 static const size_t kMaxPictureBufferSize = 1024; 69 70 // Format strings that describe the test context. The %s token is where 71 // the name of the test step is inserted. The context is required for 72 // disambiguating the error in the case of failures that are reported in 73 // functions that are called multiple times in different contexts (test 74 // cases and test steps). 75 static const char* const kDefaultAssertMessageFormat = "%s"; 76 static const char* const kCanvasDrawAssertMessageFormat = 77 "Drawing test step %s with SkCanvas"; 78 static const char* const kPictureDrawAssertMessageFormat = 79 "Drawing test step %s with SkPicture"; 80 static const char* const kPictureSecondDrawAssertMessageFormat = 81 "Duplicate draw of test step %s with SkPicture"; 82 static const char* const kPictureReDrawAssertMessageFormat = 83 "Playing back test step %s from an SkPicture to another SkPicture"; 84 static const char* const kDeferredDrawAssertMessageFormat = 85 "Drawing test step %s with SkDeferredCanvas"; 86 static const char* const kProxyDrawAssertMessageFormat = 87 "Drawing test step %s with SkProxyCanvas"; 88 static const char* const kNWayDrawAssertMessageFormat = 89 "Drawing test step %s with SkNWayCanvas"; 90 static const char* const kRoundTripAssertMessageFormat = 91 "test step %s, SkPicture consistency after round trip"; 92 static const char* const kPictureRecoringAssertMessageFormat = 93 "test step %s, SkPicture state consistency after recording"; 94 static const char* const kPicturePlaybackAssertMessageFormat = 95 "test step %s, SkPicture state consistency in playback canvas"; 96 static const char* const kDeferredPreFlushAssertMessageFormat = 97 "test step %s, SkDeferredCanvas state consistency before flush"; 98 static const char* const kDeferredPostFlushAssertMessageFormat = 99 "test step %s, SkDeferredCanvas state consistency after flush"; 100 static const char* const kPictureResourceReuseMessageFormat = 101 "test step %s, SkPicture duplicate flattened object test"; 102 static const char* const kProxyStateAssertMessageFormat = 103 "test step %s, SkProxyCanvas state consistency"; 104 static const char* const kProxyIndirectStateAssertMessageFormat = 105 "test step %s, SkProxyCanvas indirect canvas state consistency"; 106 static const char* const kNWayStateAssertMessageFormat = 107 "test step %s, SkNWayCanvas state consistency"; 108 static const char* const kNWayIndirect1StateAssertMessageFormat = 109 "test step %s, SkNWayCanvas indirect canvas 1 state consistency"; 110 static const char* const kNWayIndirect2StateAssertMessageFormat = 111 "test step %s, SkNWayCanvas indirect canvas 2 state consistency"; 112 113 static void createBitmap(SkBitmap* bm, SkBitmap::Config config, SkColor color) { 114 bm->setConfig(config, kWidth, kHeight); 115 bm->allocPixels(); 116 bm->eraseColor(color); 117 } 118 119 class CanvasTestStep; 120 static SkTDArray<CanvasTestStep*>& testStepArray() { 121 static SkTDArray<CanvasTestStep*> theTests; 122 return theTests; 123 } 124 125 class CanvasTestStep { 126 public: 127 CanvasTestStep() { 128 *testStepArray().append() = this; 129 fAssertMessageFormat = kDefaultAssertMessageFormat; 130 } 131 virtual ~CanvasTestStep() { } 132 133 virtual void draw(SkCanvas*, skiatest::Reporter*) = 0; 134 virtual const char* name() const = 0; 135 136 const char* assertMessage() { 137 fAssertMessage.printf(fAssertMessageFormat, name()); 138 return fAssertMessage.c_str(); 139 } 140 141 void setAssertMessageFormat(const char* format) { 142 fAssertMessageFormat = format; 143 } 144 145 private: 146 SkString fAssertMessage; 147 const char* fAssertMessageFormat; 148 }; 149 150 /////////////////////////////////////////////////////////////////////////////// 151 // Constants used by test steps 152 153 const SkRect kTestRect = 154 SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 155 SkIntToScalar(2), SkIntToScalar(1)); 156 static SkMatrix testMatrix() { 157 SkMatrix matrix; 158 matrix.reset(); 159 matrix.setScale(SkIntToScalar(2), SkIntToScalar(3)); 160 return matrix; 161 } 162 const SkMatrix kTestMatrix = testMatrix(); 163 static SkPath testPath() { 164 SkPath path; 165 path.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0), 166 SkIntToScalar(2), SkIntToScalar(1))); 167 return path; 168 } 169 const SkPath kTestPath = testPath(); 170 static SkRegion testRegion() { 171 SkRegion region; 172 SkIRect rect = SkIRect::MakeXYWH(0, 0, 2, 1); 173 region.setRect(rect); 174 return region; 175 } 176 const SkIRect kTestIRect = SkIRect::MakeXYWH(0, 0, 2, 1); 177 const SkRegion kTestRegion = testRegion(); 178 const SkColor kTestColor = 0x01020304; 179 const SkPaint kTestPaint; 180 const SkPoint kTestPoints[3] = { 181 {SkIntToScalar(0), SkIntToScalar(0)}, 182 {SkIntToScalar(2), SkIntToScalar(1)}, 183 {SkIntToScalar(0), SkIntToScalar(2)} 184 }; 185 const size_t kTestPointCount = 3; 186 static SkBitmap testBitmap() { 187 SkBitmap bitmap; 188 createBitmap(&bitmap, SkBitmap::kARGB_8888_Config, 0x05060708); 189 return bitmap; 190 } 191 SkBitmap kTestBitmap; // cannot be created during static init 192 SkString kTestText("Hello World"); 193 SkPoint kTestPoint = SkPoint::Make(SkIntToScalar(0), SkIntToScalar(1)); 194 195 /////////////////////////////////////////////////////////////////////////////// 196 // Macros for defining test steps 197 198 #define TEST_STEP(NAME, FUNCTION) \ 199 class NAME##_TestStep : public CanvasTestStep{ \ 200 public: \ 201 virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \ 202 FUNCTION (canvas, reporter, this); \ 203 } \ 204 virtual const char* name() const {return #NAME ;} \ 205 }; \ 206 static NAME##_TestStep NAME##_TestStepInstance; 207 208 #define SIMPLE_TEST_STEP(NAME, CALL) \ 209 static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter*, \ 210 CanvasTestStep*) { \ 211 canvas-> CALL ; \ 212 } \ 213 TEST_STEP(NAME, NAME##TestStep ) 214 215 #define SIMPLE_TEST_STEP_WITH_ASSERT(NAME, CALL) \ 216 static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter* reporter, \ 217 CanvasTestStep* testStep) { \ 218 REPORTER_ASSERT_MESSAGE(reporter, canvas-> CALL , \ 219 testStep->assertMessage()); \ 220 } \ 221 TEST_STEP(NAME, NAME##TestStep ) 222 223 224 /////////////////////////////////////////////////////////////////////////////// 225 // Basic test steps for most virtual methods in SkCanvas that draw or affect 226 // the state of the canvas. 227 228 SIMPLE_TEST_STEP(SaveMatrix, save(SkCanvas::kMatrix_SaveFlag)); 229 SIMPLE_TEST_STEP(SaveClip, save(SkCanvas::kClip_SaveFlag)); 230 SIMPLE_TEST_STEP(SaveMatrixClip, save(SkCanvas::kMatrixClip_SaveFlag)); 231 SIMPLE_TEST_STEP(SaveLayer, saveLayer(NULL, NULL)); 232 SIMPLE_TEST_STEP(BoundedSaveLayer, saveLayer(&kTestRect, NULL)); 233 SIMPLE_TEST_STEP(PaintSaveLayer, saveLayer(NULL, &kTestPaint)); 234 SIMPLE_TEST_STEP_WITH_ASSERT(Translate, 235 translate(SkIntToScalar(1), SkIntToScalar(2))); 236 SIMPLE_TEST_STEP_WITH_ASSERT(Scale, 237 scale(SkIntToScalar(1), SkIntToScalar(2))); 238 SIMPLE_TEST_STEP_WITH_ASSERT(Rotate, rotate(SkIntToScalar(1))); 239 SIMPLE_TEST_STEP_WITH_ASSERT(Skew, 240 skew(SkIntToScalar(1), SkIntToScalar(2))); 241 SIMPLE_TEST_STEP_WITH_ASSERT(Concat, concat(kTestMatrix)); 242 SIMPLE_TEST_STEP(SetMatrix, setMatrix(kTestMatrix)); 243 SIMPLE_TEST_STEP_WITH_ASSERT(ClipRect, clipRect(kTestRect)); 244 SIMPLE_TEST_STEP_WITH_ASSERT(ClipPath, clipPath(kTestPath)); 245 SIMPLE_TEST_STEP_WITH_ASSERT(ClipRegion, 246 clipRegion(kTestRegion, SkRegion::kReplace_Op)); 247 SIMPLE_TEST_STEP(Clear, clear(kTestColor)); 248 SIMPLE_TEST_STEP(DrawPaint, drawPaint(kTestPaint)); 249 SIMPLE_TEST_STEP(DrawPointsPoints, drawPoints(SkCanvas::kPoints_PointMode, 250 kTestPointCount, kTestPoints, kTestPaint)); 251 SIMPLE_TEST_STEP(DrawPointsLiness, drawPoints(SkCanvas::kLines_PointMode, 252 kTestPointCount, kTestPoints, kTestPaint)); 253 SIMPLE_TEST_STEP(DrawPointsPolygon, drawPoints(SkCanvas::kPolygon_PointMode, 254 kTestPointCount, kTestPoints, kTestPaint)); 255 SIMPLE_TEST_STEP(DrawRect, drawRect(kTestRect, kTestPaint)); 256 SIMPLE_TEST_STEP(DrawPath, drawPath(kTestPath, kTestPaint)); 257 SIMPLE_TEST_STEP(DrawBitmap, drawBitmap(kTestBitmap, 0, 0)); 258 SIMPLE_TEST_STEP(DrawBitmapPaint, drawBitmap(kTestBitmap, 0, 0, &kTestPaint)); 259 SIMPLE_TEST_STEP(DrawBitmapRect, drawBitmapRect(kTestBitmap, NULL, kTestRect, 260 NULL)); 261 SIMPLE_TEST_STEP(DrawBitmapRectSrcRect, drawBitmapRect(kTestBitmap, 262 &kTestIRect, kTestRect, NULL)); 263 SIMPLE_TEST_STEP(DrawBitmapRectPaint, drawBitmapRect(kTestBitmap, NULL, 264 kTestRect, &kTestPaint)); 265 SIMPLE_TEST_STEP(DrawBitmapMatrix, drawBitmapMatrix(kTestBitmap, kTestMatrix, 266 NULL)); 267 SIMPLE_TEST_STEP(DrawBitmapMatrixPaint, drawBitmapMatrix(kTestBitmap, 268 kTestMatrix, &kTestPaint)); 269 SIMPLE_TEST_STEP(DrawBitmapNine, drawBitmapNine(kTestBitmap, kTestIRect, 270 kTestRect, NULL)); 271 SIMPLE_TEST_STEP(DrawBitmapNinePaint, drawBitmapNine(kTestBitmap, kTestIRect, 272 kTestRect, &kTestPaint)); 273 SIMPLE_TEST_STEP(DrawSprite, drawSprite(kTestBitmap, 0, 0, NULL)); 274 SIMPLE_TEST_STEP(DrawSpritePaint, drawSprite(kTestBitmap, 0, 0, &kTestPaint)); 275 SIMPLE_TEST_STEP(DrawText, drawText(kTestText.c_str(), kTestText.size(), 276 0, 1, kTestPaint)); 277 SIMPLE_TEST_STEP(DrawPosText, drawPosText(kTestText.c_str(), 278 kTestText.size(), &kTestPoint, kTestPaint)); 279 SIMPLE_TEST_STEP(DrawTextOnPath, drawTextOnPath(kTestText.c_str(), 280 kTestText.size(), kTestPath, NULL, kTestPaint)); 281 SIMPLE_TEST_STEP(DrawTextOnPathMatrix, drawTextOnPath(kTestText.c_str(), 282 kTestText.size(), kTestPath, &kTestMatrix, kTestPaint)); 283 SIMPLE_TEST_STEP(SetExternalMatrix, setExternalMatrix(&kTestMatrix)); 284 SIMPLE_TEST_STEP(DrawData, drawData(kTestText.c_str(), kTestText.size())); 285 286 /////////////////////////////////////////////////////////////////////////////// 287 // Complex test steps 288 289 static void DrawVerticesShaderTestStep(SkCanvas* canvas, 290 skiatest::Reporter* reporter, 291 CanvasTestStep* testStep) { 292 SkPoint pts[4]; 293 pts[0].set(0, 0); 294 pts[1].set(SkIntToScalar(kWidth), 0); 295 pts[2].set(SkIntToScalar(kWidth), SkIntToScalar(kHeight)); 296 pts[3].set(0, SkIntToScalar(kHeight)); 297 SkPaint paint; 298 SkShader* shader = SkShader::CreateBitmapShader(kTestBitmap, 299 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode); 300 paint.setShader(shader)->unref(); 301 canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, pts, pts, 302 NULL, NULL, NULL, 0, paint); 303 } 304 TEST_STEP(DrawVerticesShader, DrawVerticesShaderTestStep); 305 306 static void DrawPictureTestStep(SkCanvas* canvas, 307 skiatest::Reporter* reporter, 308 CanvasTestStep* testStep) { 309 SkPicture* testPicture = SkNEW_ARGS(SkPicture, ()); 310 SkAutoUnref aup(testPicture); 311 SkCanvas* testCanvas = testPicture->beginRecording(kWidth, kHeight); 312 testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1)); 313 testCanvas->clipRect(kTestRect); 314 testCanvas->drawRect(kTestRect, kTestPaint); 315 canvas->drawPicture(*testPicture); 316 } 317 TEST_STEP(DrawPicture, DrawPictureTestStep); 318 319 static void SaveRestoreTestStep(SkCanvas* canvas, 320 skiatest::Reporter* reporter, 321 CanvasTestStep* testStep) { 322 REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(), 323 testStep->assertMessage()); 324 size_t n = canvas->save(); 325 REPORTER_ASSERT_MESSAGE(reporter, 1 == n, testStep->assertMessage()); 326 REPORTER_ASSERT_MESSAGE(reporter, 2 == canvas->getSaveCount(), 327 testStep->assertMessage()); 328 canvas->save(); 329 canvas->save(); 330 REPORTER_ASSERT_MESSAGE(reporter, 4 == canvas->getSaveCount(), 331 testStep->assertMessage()); 332 canvas->restoreToCount(2); 333 REPORTER_ASSERT_MESSAGE(reporter, 2 == canvas->getSaveCount(), 334 testStep->assertMessage()); 335 336 // should this pin to 1, or be a no-op, or crash? 337 canvas->restoreToCount(0); 338 REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(), 339 testStep->assertMessage()); 340 } 341 TEST_STEP(SaveRestore, SaveRestoreTestStep); 342 343 static void DrawLayerTestStep(SkCanvas* canvas, 344 skiatest::Reporter* reporter, 345 CanvasTestStep* testStep) { 346 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 347 testStep->assertMessage()); 348 canvas->save(); 349 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 350 testStep->assertMessage()); 351 352 const SkRect* bounds = NULL; // null means include entire bounds 353 const SkPaint* paint = NULL; 354 355 canvas->saveLayer(bounds, paint); 356 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 357 testStep->assertMessage()); 358 canvas->restore(); 359 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 360 testStep->assertMessage()); 361 362 canvas->saveLayer(bounds, paint); 363 canvas->saveLayer(bounds, paint); 364 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 365 testStep->assertMessage()); 366 canvas->restore(); 367 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(), 368 testStep->assertMessage()); 369 canvas->restore(); 370 // now layer count should be 0 371 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(), 372 testStep->assertMessage()); 373 } 374 TEST_STEP(DrawLayer, DrawLayerTestStep); 375 376 static void AssertCanvasStatesEqual(skiatest::Reporter* reporter, 377 const SkCanvas* canvas1, 378 const SkCanvas* canvas2, 379 CanvasTestStep* testStep) { 380 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDeviceSize() == 381 canvas2->getDeviceSize(), testStep->assertMessage()); 382 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getSaveCount() == 383 canvas2->getSaveCount(), testStep->assertMessage()); 384 REPORTER_ASSERT_MESSAGE(reporter, canvas1->isDrawingToLayer() == 385 canvas2->isDrawingToLayer(), testStep->assertMessage()); 386 SkRect bounds1, bounds2; 387 REPORTER_ASSERT_MESSAGE(reporter, 388 canvas1->getClipBounds(&bounds1, SkCanvas::kAA_EdgeType) == 389 canvas2->getClipBounds(&bounds2, SkCanvas::kAA_EdgeType), 390 testStep->assertMessage()); 391 REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2, 392 testStep->assertMessage()); 393 REPORTER_ASSERT_MESSAGE(reporter, 394 canvas1->getClipBounds(&bounds1, SkCanvas::kBW_EdgeType) == 395 canvas2->getClipBounds(&bounds2, SkCanvas::kBW_EdgeType), 396 testStep->assertMessage()); 397 REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2, 398 testStep->assertMessage()); 399 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDrawFilter() == 400 canvas2->getDrawFilter(), testStep->assertMessage()); 401 SkIRect deviceBounds1, deviceBounds2; 402 REPORTER_ASSERT_MESSAGE(reporter, 403 canvas1->getClipDeviceBounds(&deviceBounds1) == 404 canvas2->getClipDeviceBounds(&deviceBounds2), 405 testStep->assertMessage()); 406 REPORTER_ASSERT_MESSAGE(reporter, deviceBounds1 == deviceBounds2, 407 testStep->assertMessage()); 408 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getBounder() == 409 canvas2->getBounder(), testStep->assertMessage()); 410 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalMatrix() == 411 canvas2->getTotalMatrix(), testStep->assertMessage()); 412 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getClipType() == 413 canvas2->getClipType(), testStep->assertMessage()); 414 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClip() == 415 canvas2->getTotalClip(), testStep->assertMessage()); 416 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClipStack() == 417 canvas2->getTotalClipStack(), testStep->assertMessage()); 418 419 // The following test code is commented out because the test fails when 420 // the canvas is an SkPictureRecord or SkDeferredCanvas 421 // Issue: http://code.google.com/p/skia/issues/detail?id=498 422 // Also, creating a LayerIter on an SkProxyCanvas crashes 423 // Issue: http://code.google.com/p/skia/issues/detail?id=499 424 /* 425 SkCanvas::LayerIter layerIter1(const_cast<SkCanvas*>(canvas1), false); 426 SkCanvas::LayerIter layerIter2(const_cast<SkCanvas*>(canvas2), false); 427 while (!layerIter1.done() && !layerIter2.done()) { 428 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.matrix() == 429 layerIter2.matrix(), testStep->assertMessage()); 430 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.clip() == 431 layerIter2.clip(), testStep->assertMessage()); 432 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.paint() == 433 layerIter2.paint(), testStep->assertMessage()); 434 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.x() == 435 layerIter2.x(), testStep->assertMessage()); 436 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.y() == 437 layerIter2.y(), testStep->assertMessage()); 438 layerIter1.next(); 439 layerIter2.next(); 440 } 441 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.done(), 442 testStep->assertMessage()); 443 REPORTER_ASSERT_MESSAGE(reporter, layerIter2.done(), 444 testStep->assertMessage()); 445 */ 446 } 447 448 // The following class groups static functions that need to access 449 // the privates members of SkPictureRecord 450 class SkPictureTester { 451 private: 452 static void AssertFlattenedObjectsEqual( 453 SkPictureRecord* referenceRecord, 454 SkPictureRecord* testRecord, 455 skiatest::Reporter* reporter, 456 CanvasTestStep* testStep) { 457 458 REPORTER_ASSERT_MESSAGE(reporter, 459 referenceRecord->fBitmaps.count() == 460 testRecord->fBitmaps.count(), testStep->assertMessage()); 461 for (int i = 0; i < referenceRecord->fBitmaps.count(); ++i) { 462 REPORTER_ASSERT_MESSAGE(reporter, 463 SkFlatData::Compare(referenceRecord->fBitmaps[i], 464 testRecord->fBitmaps[i]) == 0, testStep->assertMessage()); 465 } 466 REPORTER_ASSERT_MESSAGE(reporter, 467 referenceRecord->fMatrices.count() == 468 testRecord->fMatrices.count(), testStep->assertMessage()); 469 for (int i = 0; i < referenceRecord->fMatrices.count(); ++i) { 470 REPORTER_ASSERT_MESSAGE(reporter, 471 SkFlatData::Compare(referenceRecord->fMatrices[i], 472 testRecord->fMatrices[i]) == 0, 473 testStep->assertMessage()); 474 } 475 REPORTER_ASSERT_MESSAGE(reporter, 476 referenceRecord->fPaints.count() == 477 testRecord->fPaints.count(), testStep->assertMessage()); 478 for (int i = 0; i < referenceRecord->fPaints.count(); ++i) { 479 REPORTER_ASSERT_MESSAGE(reporter, 480 SkFlatData::Compare(referenceRecord->fPaints[i], 481 testRecord->fPaints[i]) == 0, testStep->assertMessage()); 482 } 483 REPORTER_ASSERT_MESSAGE(reporter, 484 referenceRecord->fRegions.count() == 485 testRecord->fRegions.count(), testStep->assertMessage()); 486 for (int i = 0; i < referenceRecord->fRegions.count(); ++i) { 487 REPORTER_ASSERT_MESSAGE(reporter, 488 SkFlatData::Compare(referenceRecord->fRegions[i], 489 testRecord->fRegions[i]) == 0, testStep->assertMessage()); 490 } 491 REPORTER_ASSERT_MESSAGE(reporter, 492 !referenceRecord->fPathHeap == 493 !testRecord->fPathHeap, 494 testStep->assertMessage()); 495 // The following tests are commented out because they currently 496 // fail. Issue: http://code.google.com/p/skia/issues/detail?id=507 497 /* 498 if (referenceRecord->fPathHeap) { 499 REPORTER_ASSERT_MESSAGE(reporter, 500 referenceRecord->fPathHeap->count() == 501 testRecord->fPathHeap->count(), 502 testStep->assertMessage()); 503 for (int i = 0; i < referenceRecord->fPathHeap->count(); ++i) { 504 REPORTER_ASSERT_MESSAGE(reporter, 505 (*referenceRecord->fPathHeap)[i] == 506 (*testRecord->fPathHeap)[i], testStep->assertMessage()); 507 } 508 } 509 */ 510 511 } 512 513 public: 514 515 static void TestPictureSerializationRoundTrip(skiatest::Reporter* reporter, 516 CanvasTestStep* testStep) { 517 testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat); 518 SkPicture referencePicture; 519 testStep->draw(referencePicture.beginRecording(kWidth, kHeight), 520 reporter); 521 SkPicture initialPicture; 522 testStep->draw(initialPicture.beginRecording(kWidth, kHeight), 523 reporter); 524 testStep->setAssertMessageFormat(kPictureReDrawAssertMessageFormat); 525 SkPicture roundTripPicture; 526 initialPicture.draw(roundTripPicture.beginRecording(kWidth, kHeight)); 527 528 SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>( 529 referencePicture.getRecordingCanvas()); 530 SkPictureRecord* roundTripRecord = static_cast<SkPictureRecord*>( 531 roundTripPicture.getRecordingCanvas()); 532 533 testStep->setAssertMessageFormat(kPictureReDrawAssertMessageFormat); 534 535 // Verify that deserialization-serialization round trip conserves all 536 // data by comparing referenceRecord to roundTripRecord 537 REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fBitmapIndex == 538 roundTripRecord->fBitmapIndex, testStep->assertMessage()); 539 REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fMatrixIndex == 540 roundTripRecord->fMatrixIndex, testStep->assertMessage()); 541 REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fPaintIndex == 542 roundTripRecord->fPaintIndex, testStep->assertMessage()); 543 REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fRegionIndex == 544 roundTripRecord->fRegionIndex, testStep->assertMessage()); 545 char referenceBuffer[kMaxPictureBufferSize]; 546 SkMemoryWStream referenceStream(referenceBuffer, 547 kMaxPictureBufferSize); 548 referenceRecord->fWriter.writeToStream(&referenceStream); 549 char roundTripBuffer[kMaxPictureBufferSize]; 550 SkMemoryWStream roundTripStream(roundTripBuffer, 551 kMaxPictureBufferSize); 552 roundTripRecord->fWriter.writeToStream(&roundTripStream); 553 REPORTER_ASSERT_MESSAGE(reporter, 554 roundTripStream.bytesWritten() == referenceStream.bytesWritten(), 555 testStep->assertMessage()); 556 REPORTER_ASSERT_MESSAGE(reporter, 0 == memcmp(referenceBuffer, 557 roundTripBuffer, roundTripStream.bytesWritten()), 558 testStep->assertMessage()); 559 REPORTER_ASSERT_MESSAGE(reporter, referenceRecord->fRecordFlags == 560 roundTripRecord->fRecordFlags, testStep->assertMessage()); 561 REPORTER_ASSERT_MESSAGE(reporter, 562 referenceRecord->fRestoreOffsetStack == 563 roundTripRecord->fRestoreOffsetStack, 564 testStep->assertMessage()); 565 AssertFlattenedObjectsEqual(referenceRecord, roundTripRecord, 566 reporter, testStep); 567 AssertCanvasStatesEqual(reporter, referenceRecord, roundTripRecord, 568 testStep); 569 } 570 571 static void TestPictureFlattenedObjectReuse(skiatest::Reporter* reporter, 572 CanvasTestStep* testStep) { 573 // Verify that when a test step is executed twice, no extra resources 574 // are flattened during the second execution 575 testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat); 576 SkPicture referencePicture; 577 SkCanvas* referenceCanvas = referencePicture.beginRecording(kWidth, 578 kHeight); 579 testStep->draw(referenceCanvas, reporter); 580 SkPicture testPicture; 581 SkCanvas* testCanvas = testPicture.beginRecording(kWidth, 582 kHeight); 583 testStep->draw(testCanvas, reporter); 584 testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat); 585 testStep->draw(testCanvas, reporter); 586 587 SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>( 588 referenceCanvas); 589 SkPictureRecord* testRecord = static_cast<SkPictureRecord*>( 590 testCanvas); 591 testStep->setAssertMessageFormat(kPictureResourceReuseMessageFormat); 592 AssertFlattenedObjectsEqual(referenceRecord, testRecord, 593 reporter, testStep); 594 } 595 }; 596 597 static void TestPictureStateConsistency(skiatest::Reporter* reporter, 598 CanvasTestStep* testStep, 599 const SkCanvas& referenceCanvas) { 600 // Verify that the recording canvas's state is consistent 601 // with that of a regular canvas 602 SkPicture testPicture; 603 SkCanvas* pictureCanvas = testPicture.beginRecording(kWidth, kHeight); 604 testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat); 605 testStep->draw(pictureCanvas, reporter); 606 testStep->setAssertMessageFormat(kPictureRecoringAssertMessageFormat); 607 AssertCanvasStatesEqual(reporter, pictureCanvas, &referenceCanvas, 608 testStep); 609 610 SkBitmap playbackStore; 611 createBitmap(&playbackStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 612 SkDevice playbackDevice(playbackStore); 613 SkCanvas playbackCanvas(&playbackDevice); 614 testPicture.draw(&playbackCanvas); 615 testStep->setAssertMessageFormat(kPicturePlaybackAssertMessageFormat); 616 AssertCanvasStatesEqual(reporter, &playbackCanvas, &referenceCanvas, 617 testStep); 618 619 // The following test code is commented out because SkPicture is not 620 // currently expected to preserve state when restarting recording. 621 /* 622 SkCanvas* pictureCanvas = testPicture.beginRecording(kWidth, kHeight); 623 testStep->setAssertMessageFormat(kPictureResumeAssertMessageFormat); 624 AssertCanvasStatesEqual(reporter, pictureCanvas, &referenceCanvas, 625 testStep); 626 */ 627 } 628 629 static void TestDeferredCanvasStateConsistency( 630 skiatest::Reporter* reporter, 631 CanvasTestStep* testStep, 632 const SkCanvas& referenceCanvas) { 633 634 SkBitmap deferredStore; 635 createBitmap(&deferredStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 636 SkDevice deferredDevice(deferredStore); 637 SkDeferredCanvas deferredCanvas(&deferredDevice); 638 testStep->setAssertMessageFormat(kDeferredDrawAssertMessageFormat); 639 testStep->draw(&deferredCanvas, reporter); 640 testStep->setAssertMessageFormat(kDeferredPreFlushAssertMessageFormat); 641 AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas, 642 testStep); 643 644 // Verified that deferred canvas state is not affected by flushing 645 // pending draw operations 646 647 // The following test code is commented out because it currently fails. 648 // Issue: http://code.google.com/p/skia/issues/detail?id=496 649 /* 650 deferredCanvas.flush(); 651 testStep->setAssertMessageFormat(kDeferredPostFlushAssertMessageFormat); 652 AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas, 653 testStep); 654 */ 655 } 656 657 static void TestProxyCanvasStateConsistency( 658 skiatest::Reporter* reporter, 659 CanvasTestStep* testStep, 660 const SkCanvas& referenceCanvas) { 661 662 SkBitmap indirectStore; 663 createBitmap(&indirectStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 664 SkDevice indirectDevice(indirectStore); 665 SkCanvas indirectCanvas(&indirectDevice); 666 SkProxyCanvas proxyCanvas(&indirectCanvas); 667 testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat); 668 testStep->draw(&proxyCanvas, reporter); 669 // Verify that the SkProxyCanvas reports consitent state 670 testStep->setAssertMessageFormat(kProxyStateAssertMessageFormat); 671 AssertCanvasStatesEqual(reporter, &proxyCanvas, &referenceCanvas, 672 testStep); 673 // Verify that the indirect canvas reports consitent state 674 testStep->setAssertMessageFormat(kProxyIndirectStateAssertMessageFormat); 675 AssertCanvasStatesEqual(reporter, &indirectCanvas, &referenceCanvas, 676 testStep); 677 } 678 679 static void TestNWayCanvasStateConsistency( 680 skiatest::Reporter* reporter, 681 CanvasTestStep* testStep, 682 const SkCanvas& referenceCanvas) { 683 684 SkBitmap indirectStore1; 685 createBitmap(&indirectStore1, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 686 SkDevice indirectDevice1(indirectStore1); 687 SkCanvas indirectCanvas1(&indirectDevice1); 688 689 SkBitmap indirectStore2; 690 createBitmap(&indirectStore2, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 691 SkDevice indirectDevice2(indirectStore2); 692 SkCanvas indirectCanvas2(&indirectDevice2); 693 694 SkISize canvasSize = referenceCanvas.getDeviceSize(); 695 SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height()); 696 nWayCanvas.addCanvas(&indirectCanvas1); 697 nWayCanvas.addCanvas(&indirectCanvas2); 698 699 testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat); 700 testStep->draw(&nWayCanvas, reporter); 701 // Verify that the SkProxyCanvas reports consitent state 702 testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat); 703 AssertCanvasStatesEqual(reporter, &nWayCanvas, &referenceCanvas, 704 testStep); 705 // Verify that the indirect canvases report consitent state 706 testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat); 707 AssertCanvasStatesEqual(reporter, &indirectCanvas1, &referenceCanvas, 708 testStep); 709 testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat); 710 AssertCanvasStatesEqual(reporter, &indirectCanvas2, &referenceCanvas, 711 testStep); 712 } 713 714 /* 715 * This sub-test verifies that the test step passes when executed 716 * with SkCanvas and with classes derrived from SkCanvas. It also verifies 717 * that the all canvas derivatives report the same state as an SkCanvas 718 * after having executed the test step. 719 */ 720 static void TestOverrideStateConsistency(skiatest::Reporter* reporter, 721 CanvasTestStep* testStep) { 722 SkBitmap referenceStore; 723 createBitmap(&referenceStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF); 724 SkDevice referenceDevice(referenceStore); 725 SkCanvas referenceCanvas(&referenceDevice); 726 testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat); 727 testStep->draw(&referenceCanvas, reporter); 728 729 TestPictureStateConsistency(reporter, testStep, referenceCanvas); 730 TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas); 731 732 // The following test code is commented out because SkProxyCanvas is 733 // missing a lot of virtual overrides on get* methods, which are used 734 // to verify canvas state. 735 // Issue: http://code.google.com/p/skia/issues/detail?id=500 736 737 //TestProxyCanvasStateConsistency(reporter, testStep, referenceCanvas); 738 739 // The following test code is commented out because SkNWayCanvas does not 740 // report correct clipping and device bounds information 741 // Issue: http://code.google.com/p/skia/issues/detail?id=501 742 743 //TestNWayCanvasStateConsistency(reporter, testStep, referenceCanvas); 744 } 745 746 static void TestCanvas(skiatest::Reporter* reporter) { 747 // Init global here because bitmap pixels cannot be alocated during 748 // static initialization 749 kTestBitmap = testBitmap(); 750 751 for (int testStep = 0; testStep < testStepArray().count(); testStep++) { 752 TestOverrideStateConsistency(reporter, testStepArray()[testStep]); 753 SkPictureTester::TestPictureSerializationRoundTrip(reporter, 754 testStepArray()[testStep]); 755 SkPictureTester::TestPictureFlattenedObjectReuse(reporter, 756 testStepArray()[testStep]); 757 } 758 } 759 760 #include "TestClassDef.h" 761 DEFINE_TESTCLASS("Canvas", TestCanvasClass, TestCanvas) 762