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