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