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