blob: 55169cc344609b98c1f0964bf8e6e2d441c4f1ab [file] [log] [blame]
reed@google.com37f3ae02011-11-28 16:06:04 +00001
2/*
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +00003 * Copyright 2012 Google Inc.
reed@google.com37f3ae02011-11-28 16:06:04 +00004 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +00008
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 *
rmistry@google.comd6176b02012-08-23 18:14:13 +000021 * static void MyTestStepFunction(SkCanvas* canvas,
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +000022 * 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 */
reed@google.com37f3ae02011-11-28 16:06:04 +000047#include "SkBitmap.h"
48#include "SkCanvas.h"
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +000049#include "SkDeferredCanvas.h"
50#include "SkDevice.h"
51#include "SkMatrix.h"
52#include "SkNWayCanvas.h"
edisonn@google.com77909122012-10-18 15:58:23 +000053#include "SkPDFDevice.h"
54#include "SkPDFDocument.h"
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +000055#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"
reed@google.com28183b42014-02-04 15:34:10 +000064#include "SkSurface.h"
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +000065#include "SkTDArray.h"
66#include "Test.h"
reed@google.com37f3ae02011-11-28 16:06:04 +000067
reed@google.com90c07ea2012-04-13 13:50:27 +000068class Canvas2CanvasClipVisitor : public SkCanvas::ClipVisitor {
69public:
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
79private:
80 SkCanvas* fTarget;
81};
82
83static void test_clipVisitor(skiatest::Reporter* reporter, SkCanvas* canvas) {
84 SkISize size = canvas->getDeviceSize();
rmistry@google.comd6176b02012-08-23 18:14:13 +000085
reed@google.com90c07ea2012-04-13 13:50:27 +000086 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
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +000096static const int kWidth = 2;
97static const int kHeight = 2;
reed@google.com7c202932011-12-14 18:48:05 +000098
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +000099// 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).
104static const char* const kDefaultAssertMessageFormat = "%s";
rmistry@google.comd6176b02012-08-23 18:14:13 +0000105static const char* const kCanvasDrawAssertMessageFormat =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000106 "Drawing test step %s with SkCanvas";
rmistry@google.comd6176b02012-08-23 18:14:13 +0000107static const char* const kPictureDrawAssertMessageFormat =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000108 "Drawing test step %s with SkPicture";
rmistry@google.comd6176b02012-08-23 18:14:13 +0000109static const char* const kPictureSecondDrawAssertMessageFormat =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000110 "Duplicate draw of test step %s with SkPicture";
rmistry@google.comd6176b02012-08-23 18:14:13 +0000111static const char* const kDeferredDrawAssertMessageFormat =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000112 "Drawing test step %s with SkDeferredCanvas";
rmistry@google.comd6176b02012-08-23 18:14:13 +0000113static const char* const kProxyDrawAssertMessageFormat =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000114 "Drawing test step %s with SkProxyCanvas";
rmistry@google.comd6176b02012-08-23 18:14:13 +0000115static const char* const kNWayDrawAssertMessageFormat =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000116 "Drawing test step %s with SkNWayCanvas";
rmistry@google.comd6176b02012-08-23 18:14:13 +0000117static const char* const kDeferredPreFlushAssertMessageFormat =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000118 "test step %s, SkDeferredCanvas state consistency before flush";
junov@chromium.orgcff01c52012-07-18 21:50:26 +0000119static const char* const kDeferredPostFlushPlaybackAssertMessageFormat =
120 "test step %s, SkDeferredCanvas playback canvas state consistency after flush";
junov@chromium.orgfb103892012-09-20 19:35:43 +0000121static const char* const kDeferredPostSilentFlushPlaybackAssertMessageFormat =
122 "test step %s, SkDeferredCanvas playback canvas state consistency after silent flush";
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000123static const char* const kPictureResourceReuseMessageFormat =
124 "test step %s, SkPicture duplicate flattened object test";
125static const char* const kProxyStateAssertMessageFormat =
126 "test step %s, SkProxyCanvas state consistency";
127static const char* const kProxyIndirectStateAssertMessageFormat =
128 "test step %s, SkProxyCanvas indirect canvas state consistency";
129static const char* const kNWayStateAssertMessageFormat =
130 "test step %s, SkNWayCanvas state consistency";
131static const char* const kNWayIndirect1StateAssertMessageFormat =
132 "test step %s, SkNWayCanvas indirect canvas 1 state consistency";
133static const char* const kNWayIndirect2StateAssertMessageFormat =
134 "test step %s, SkNWayCanvas indirect canvas 2 state consistency";
edisonn@google.com77909122012-10-18 15:58:23 +0000135static const char* const kPdfAssertMessageFormat =
136 "PDF sanity check failed %s";
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000137
138static void createBitmap(SkBitmap* bm, SkBitmap::Config config, SkColor color) {
139 bm->setConfig(config, kWidth, kHeight);
140 bm->allocPixels();
141 bm->eraseColor(color);
142}
143
reed@google.com28183b42014-02-04 15:34:10 +0000144static SkSurface* createSurface(SkColor color) {
145 SkSurface* surface = SkSurface::NewRasterPMColor(kWidth, kHeight);
146 surface->getCanvas()->clear(color);
147 return surface;
148}
149
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000150class CanvasTestStep;
151static SkTDArray<CanvasTestStep*>& testStepArray() {
152 static SkTDArray<CanvasTestStep*> theTests;
153 return theTests;
154}
155
156class CanvasTestStep {
157public:
edisonn@google.com77909122012-10-18 15:58:23 +0000158 CanvasTestStep(bool fEnablePdfTesting = true) {
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000159 *testStepArray().append() = this;
160 fAssertMessageFormat = kDefaultAssertMessageFormat;
edisonn@google.com77909122012-10-18 15:58:23 +0000161 this->fEnablePdfTesting = fEnablePdfTesting;
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000162 }
djsollen@google.come63793a2012-03-21 15:39:03 +0000163 virtual ~CanvasTestStep() { }
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000164
165 virtual void draw(SkCanvas*, skiatest::Reporter*) = 0;
166 virtual const char* name() const = 0;
167
168 const char* assertMessage() {
169 fAssertMessage.printf(fAssertMessageFormat, name());
170 return fAssertMessage.c_str();
171 }
172
173 void setAssertMessageFormat(const char* format) {
174 fAssertMessageFormat = format;
175 }
176
edisonn@google.com77909122012-10-18 15:58:23 +0000177 bool enablePdfTesting() { return fEnablePdfTesting; }
178
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000179private:
180 SkString fAssertMessage;
181 const char* fAssertMessageFormat;
edisonn@google.com77909122012-10-18 15:58:23 +0000182 bool fEnablePdfTesting;
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000183};
184
185///////////////////////////////////////////////////////////////////////////////
186// Constants used by test steps
187
rmistry@google.comd6176b02012-08-23 18:14:13 +0000188const SkRect kTestRect =
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000189 SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
190 SkIntToScalar(2), SkIntToScalar(1));
191static SkMatrix testMatrix() {
192 SkMatrix matrix;
193 matrix.reset();
194 matrix.setScale(SkIntToScalar(2), SkIntToScalar(3));
195 return matrix;
196}
197const SkMatrix kTestMatrix = testMatrix();
198static SkPath testPath() {
199 SkPath path;
200 path.addRect(SkRect::MakeXYWH(SkIntToScalar(0), SkIntToScalar(0),
201 SkIntToScalar(2), SkIntToScalar(1)));
202 return path;
203}
204const SkPath kTestPath = testPath();
205static SkRegion testRegion() {
206 SkRegion region;
207 SkIRect rect = SkIRect::MakeXYWH(0, 0, 2, 1);
208 region.setRect(rect);
209 return region;
210}
211const SkIRect kTestIRect = SkIRect::MakeXYWH(0, 0, 2, 1);
212const SkRegion kTestRegion = testRegion();
213const SkColor kTestColor = 0x01020304;
214const SkPaint kTestPaint;
215const SkPoint kTestPoints[3] = {
216 {SkIntToScalar(0), SkIntToScalar(0)},
217 {SkIntToScalar(2), SkIntToScalar(1)},
218 {SkIntToScalar(0), SkIntToScalar(2)}
219};
220const size_t kTestPointCount = 3;
221static SkBitmap testBitmap() {
222 SkBitmap bitmap;
223 createBitmap(&bitmap, SkBitmap::kARGB_8888_Config, 0x05060708);
224 return bitmap;
225}
226SkBitmap kTestBitmap; // cannot be created during static init
227SkString kTestText("Hello World");
robertphillips@google.com977b9c82012-06-05 19:35:09 +0000228SkPoint kTestPoints2[] = {
229 { SkIntToScalar(0), SkIntToScalar(1) },
230 { SkIntToScalar(1), SkIntToScalar(1) },
231 { SkIntToScalar(2), SkIntToScalar(1) },
232 { SkIntToScalar(3), SkIntToScalar(1) },
233 { SkIntToScalar(4), SkIntToScalar(1) },
234 { SkIntToScalar(5), SkIntToScalar(1) },
235 { SkIntToScalar(6), SkIntToScalar(1) },
236 { SkIntToScalar(7), SkIntToScalar(1) },
237 { SkIntToScalar(8), SkIntToScalar(1) },
238 { SkIntToScalar(9), SkIntToScalar(1) },
239 { SkIntToScalar(10), SkIntToScalar(1) },
240};
rmistry@google.comd6176b02012-08-23 18:14:13 +0000241
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000242
243///////////////////////////////////////////////////////////////////////////////
244// Macros for defining test steps
245
246#define TEST_STEP(NAME, FUNCTION) \
247class NAME##_TestStep : public CanvasTestStep{ \
248public: \
249 virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \
250 FUNCTION (canvas, reporter, this); \
251 } \
252 virtual const char* name() const {return #NAME ;} \
253}; \
254static NAME##_TestStep NAME##_TestStepInstance;
255
edisonn@google.com77909122012-10-18 15:58:23 +0000256#define TEST_STEP_NO_PDF(NAME, FUNCTION) \
257class NAME##_TestStep : public CanvasTestStep{ \
258public: \
259 NAME##_TestStep() : CanvasTestStep(false) {} \
260 virtual void draw(SkCanvas* canvas, skiatest::Reporter* reporter) { \
261 FUNCTION (canvas, reporter, this); \
262 } \
263 virtual const char* name() const {return #NAME ;} \
264}; \
265static NAME##_TestStep NAME##_TestStepInstance;
266
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000267#define SIMPLE_TEST_STEP(NAME, CALL) \
268static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter*, \
269 CanvasTestStep*) { \
270 canvas-> CALL ; \
271} \
272TEST_STEP(NAME, NAME##TestStep )
273
274#define SIMPLE_TEST_STEP_WITH_ASSERT(NAME, CALL) \
275static void NAME##TestStep(SkCanvas* canvas, skiatest::Reporter* reporter, \
276 CanvasTestStep* testStep) { \
277 REPORTER_ASSERT_MESSAGE(reporter, canvas-> CALL , \
278 testStep->assertMessage()); \
279} \
280TEST_STEP(NAME, NAME##TestStep )
281
282
283///////////////////////////////////////////////////////////////////////////////
rmistry@google.comd6176b02012-08-23 18:14:13 +0000284// Basic test steps for most virtual methods in SkCanvas that draw or affect
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000285// the state of the canvas.
286
junov@chromium.orga907ac32012-02-24 21:54:07 +0000287SIMPLE_TEST_STEP_WITH_ASSERT(Translate,
288 translate(SkIntToScalar(1), SkIntToScalar(2)));
289SIMPLE_TEST_STEP_WITH_ASSERT(Scale,
290 scale(SkIntToScalar(1), SkIntToScalar(2)));
291SIMPLE_TEST_STEP_WITH_ASSERT(Rotate, rotate(SkIntToScalar(1)));
292SIMPLE_TEST_STEP_WITH_ASSERT(Skew,
293 skew(SkIntToScalar(1), SkIntToScalar(2)));
294SIMPLE_TEST_STEP_WITH_ASSERT(Concat, concat(kTestMatrix));
295SIMPLE_TEST_STEP(SetMatrix, setMatrix(kTestMatrix));
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000296SIMPLE_TEST_STEP(ClipRect, clipRect(kTestRect));
297SIMPLE_TEST_STEP(ClipPath, clipPath(kTestPath));
298SIMPLE_TEST_STEP(ClipRegion,
junov@chromium.orga907ac32012-02-24 21:54:07 +0000299 clipRegion(kTestRegion, SkRegion::kReplace_Op));
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000300SIMPLE_TEST_STEP(Clear, clear(kTestColor));
301SIMPLE_TEST_STEP(DrawPaint, drawPaint(kTestPaint));
302SIMPLE_TEST_STEP(DrawPointsPoints, drawPoints(SkCanvas::kPoints_PointMode,
303 kTestPointCount, kTestPoints, kTestPaint));
304SIMPLE_TEST_STEP(DrawPointsLiness, drawPoints(SkCanvas::kLines_PointMode,
305 kTestPointCount, kTestPoints, kTestPaint));
306SIMPLE_TEST_STEP(DrawPointsPolygon, drawPoints(SkCanvas::kPolygon_PointMode,
307 kTestPointCount, kTestPoints, kTestPaint));
308SIMPLE_TEST_STEP(DrawRect, drawRect(kTestRect, kTestPaint));
309SIMPLE_TEST_STEP(DrawPath, drawPath(kTestPath, kTestPaint));
junov@chromium.org87f982c2012-02-23 21:34:34 +0000310SIMPLE_TEST_STEP(DrawBitmap, drawBitmap(kTestBitmap, 0, 0));
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000311SIMPLE_TEST_STEP(DrawBitmapPaint, drawBitmap(kTestBitmap, 0, 0, &kTestPaint));
312SIMPLE_TEST_STEP(DrawBitmapRect, drawBitmapRect(kTestBitmap, NULL, kTestRect,
313 NULL));
314SIMPLE_TEST_STEP(DrawBitmapRectSrcRect, drawBitmapRect(kTestBitmap,
315 &kTestIRect, kTestRect, NULL));
316SIMPLE_TEST_STEP(DrawBitmapRectPaint, drawBitmapRect(kTestBitmap, NULL,
317 kTestRect, &kTestPaint));
318SIMPLE_TEST_STEP(DrawBitmapMatrix, drawBitmapMatrix(kTestBitmap, kTestMatrix,
319 NULL));
320SIMPLE_TEST_STEP(DrawBitmapMatrixPaint, drawBitmapMatrix(kTestBitmap,
321 kTestMatrix, &kTestPaint));
322SIMPLE_TEST_STEP(DrawBitmapNine, drawBitmapNine(kTestBitmap, kTestIRect,
323 kTestRect, NULL));
324SIMPLE_TEST_STEP(DrawBitmapNinePaint, drawBitmapNine(kTestBitmap, kTestIRect,
325 kTestRect, &kTestPaint));
junov@chromium.org87f982c2012-02-23 21:34:34 +0000326SIMPLE_TEST_STEP(DrawSprite, drawSprite(kTestBitmap, 0, 0, NULL));
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000327SIMPLE_TEST_STEP(DrawSpritePaint, drawSprite(kTestBitmap, 0, 0, &kTestPaint));
328SIMPLE_TEST_STEP(DrawText, drawText(kTestText.c_str(), kTestText.size(),
329 0, 1, kTestPaint));
330SIMPLE_TEST_STEP(DrawPosText, drawPosText(kTestText.c_str(),
robertphillips@google.com977b9c82012-06-05 19:35:09 +0000331 kTestText.size(), kTestPoints2, kTestPaint));
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000332SIMPLE_TEST_STEP(DrawTextOnPath, drawTextOnPath(kTestText.c_str(),
333 kTestText.size(), kTestPath, NULL, kTestPaint));
334SIMPLE_TEST_STEP(DrawTextOnPathMatrix, drawTextOnPath(kTestText.c_str(),
335 kTestText.size(), kTestPath, &kTestMatrix, kTestPaint));
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000336SIMPLE_TEST_STEP(DrawData, drawData(kTestText.c_str(), kTestText.size()));
robertphillips@google.com0a4805e2013-05-29 13:24:23 +0000337SIMPLE_TEST_STEP(BeginGroup, beginCommentGroup(kTestText.c_str()));
338SIMPLE_TEST_STEP(AddComment, addComment(kTestText.c_str(), kTestText.c_str()));
339SIMPLE_TEST_STEP(EndGroup, endCommentGroup());
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000340
341///////////////////////////////////////////////////////////////////////////////
342// Complex test steps
343
rmistry@google.comd6176b02012-08-23 18:14:13 +0000344// Save/restore calls cannot be in isolated simple test steps because the test
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000345// cases that use SkPicture require that save and restore calls be balanced.
rmistry@google.comd6176b02012-08-23 18:14:13 +0000346static void SaveMatrixStep(SkCanvas* canvas,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000347 skiatest::Reporter* reporter,
348 CanvasTestStep* testStep) {
349 int saveCount = canvas->getSaveCount();
350 canvas->save(SkCanvas::kMatrix_SaveFlag);
351 canvas->clipRegion(kTestRegion);
352 canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
353 canvas->restore();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000354 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000355 testStep->assertMessage());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000356 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(),
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000357 testStep->assertMessage());
358 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() == kTestRegion,
359 testStep->assertMessage());
360}
361TEST_STEP(SaveMatrix, SaveMatrixStep);
362
rmistry@google.comd6176b02012-08-23 18:14:13 +0000363static void SaveClipStep(SkCanvas* canvas,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000364 skiatest::Reporter* reporter,
365 CanvasTestStep* testStep) {
366 int saveCount = canvas->getSaveCount();
367 canvas->save(SkCanvas::kClip_SaveFlag);
368 canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
369 canvas->clipRegion(kTestRegion);
370 canvas->restore();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000371 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000372 testStep->assertMessage());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000373 REPORTER_ASSERT_MESSAGE(reporter, !canvas->getTotalMatrix().isIdentity(),
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000374 testStep->assertMessage());
375 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion,
376 testStep->assertMessage());
377}
378TEST_STEP(SaveClip, SaveClipStep);
379
rmistry@google.comd6176b02012-08-23 18:14:13 +0000380static void SaveMatrixClipStep(SkCanvas* canvas,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000381 skiatest::Reporter* reporter,
382 CanvasTestStep* testStep) {
383 int saveCount = canvas->getSaveCount();
384 canvas->save(SkCanvas::kMatrixClip_SaveFlag);
385 canvas->translate(SkIntToScalar(1), SkIntToScalar(2));
386 canvas->clipRegion(kTestRegion);
387 canvas->restore();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000388 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000389 testStep->assertMessage());
rmistry@google.comd6176b02012-08-23 18:14:13 +0000390 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalMatrix().isIdentity(),
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000391 testStep->assertMessage());
392 REPORTER_ASSERT_MESSAGE(reporter, canvas->getTotalClip() != kTestRegion,
393 testStep->assertMessage());
394}
395TEST_STEP(SaveMatrixClip, SaveMatrixClipStep);
396
rmistry@google.comd6176b02012-08-23 18:14:13 +0000397static void SaveLayerStep(SkCanvas* canvas,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000398 skiatest::Reporter* reporter,
399 CanvasTestStep* testStep) {
400 int saveCount = canvas->getSaveCount();
401 canvas->saveLayer(NULL, NULL);
402 canvas->restore();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000403 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000404 testStep->assertMessage());
405}
406TEST_STEP(SaveLayer, SaveLayerStep);
407
rmistry@google.comd6176b02012-08-23 18:14:13 +0000408static void BoundedSaveLayerStep(SkCanvas* canvas,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000409 skiatest::Reporter* reporter,
410 CanvasTestStep* testStep) {
411 int saveCount = canvas->getSaveCount();
412 canvas->saveLayer(&kTestRect, NULL);
413 canvas->restore();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000414 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000415 testStep->assertMessage());
416}
417TEST_STEP(BoundedSaveLayer, BoundedSaveLayerStep);
418
rmistry@google.comd6176b02012-08-23 18:14:13 +0000419static void PaintSaveLayerStep(SkCanvas* canvas,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000420 skiatest::Reporter* reporter,
421 CanvasTestStep* testStep) {
422 int saveCount = canvas->getSaveCount();
423 canvas->saveLayer(NULL, &kTestPaint);
424 canvas->restore();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000425 REPORTER_ASSERT_MESSAGE(reporter, canvas->getSaveCount() == saveCount,
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000426 testStep->assertMessage());
427}
428TEST_STEP(PaintSaveLayer, PaintSaveLayerStep);
429
rmistry@google.comd6176b02012-08-23 18:14:13 +0000430static void TwoClipOpsStep(SkCanvas* canvas,
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000431 skiatest::Reporter*,
432 CanvasTestStep*) {
junov@chromium.orga6c9e0e2012-07-12 17:47:34 +0000433 // This test exercises a functionality in SkPicture that leads to the
rmistry@google.comd6176b02012-08-23 18:14:13 +0000434 // recording of restore offset placeholders. This test will trigger an
junov@chromium.orga6c9e0e2012-07-12 17:47:34 +0000435 // assertion at playback time if the placeholders are not properly
436 // filled when the recording ends.
437 canvas->clipRect(kTestRect);
438 canvas->clipRegion(kTestRegion);
439}
440TEST_STEP(TwoClipOps, TwoClipOpsStep);
441
epoger@google.com94fa43c2012-04-11 17:51:01 +0000442// exercise fix for http://code.google.com/p/skia/issues/detail?id=560
443// ('SkPathStroker::lineTo() fails for line with length SK_ScalarNearlyZero')
rmistry@google.comd6176b02012-08-23 18:14:13 +0000444static void DrawNearlyZeroLengthPathTestStep(SkCanvas* canvas,
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000445 skiatest::Reporter*,
446 CanvasTestStep*) {
epoger@google.com94fa43c2012-04-11 17:51:01 +0000447 SkPaint paint;
448 paint.setStrokeWidth(SkIntToScalar(1));
449 paint.setStyle(SkPaint::kStroke_Style);
450
451 SkPath path;
452 SkPoint pt1 = { 0, 0 };
453 SkPoint pt2 = { 0, SK_ScalarNearlyZero };
454 SkPoint pt3 = { SkIntToScalar(1), 0 };
455 SkPoint pt4 = { SkIntToScalar(1), SK_ScalarNearlyZero/2 };
456 path.moveTo(pt1);
457 path.lineTo(pt2);
458 path.lineTo(pt3);
459 path.lineTo(pt4);
460
461 canvas->drawPath(path, paint);
462}
463TEST_STEP(DrawNearlyZeroLengthPath, DrawNearlyZeroLengthPathTestStep);
464
rmistry@google.comd6176b02012-08-23 18:14:13 +0000465static void DrawVerticesShaderTestStep(SkCanvas* canvas,
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000466 skiatest::Reporter*,
467 CanvasTestStep*) {
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000468 SkPoint pts[4];
469 pts[0].set(0, 0);
470 pts[1].set(SkIntToScalar(kWidth), 0);
471 pts[2].set(SkIntToScalar(kWidth), SkIntToScalar(kHeight));
472 pts[3].set(0, SkIntToScalar(kHeight));
473 SkPaint paint;
474 SkShader* shader = SkShader::CreateBitmapShader(kTestBitmap,
475 SkShader::kClamp_TileMode, SkShader::kClamp_TileMode);
476 paint.setShader(shader)->unref();
477 canvas->drawVertices(SkCanvas::kTriangleFan_VertexMode, 4, pts, pts,
478 NULL, NULL, NULL, 0, paint);
479}
edisonn@google.com77909122012-10-18 15:58:23 +0000480// NYI: issue 240.
481TEST_STEP_NO_PDF(DrawVerticesShader, DrawVerticesShaderTestStep);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000482
rmistry@google.comd6176b02012-08-23 18:14:13 +0000483static void DrawPictureTestStep(SkCanvas* canvas,
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000484 skiatest::Reporter*,
485 CanvasTestStep*) {
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000486 SkPicture* testPicture = SkNEW_ARGS(SkPicture, ());
487 SkAutoUnref aup(testPicture);
488 SkCanvas* testCanvas = testPicture->beginRecording(kWidth, kHeight);
489 testCanvas->scale(SkIntToScalar(2), SkIntToScalar(1));
490 testCanvas->clipRect(kTestRect);
491 testCanvas->drawRect(kTestRect, kTestPaint);
492 canvas->drawPicture(*testPicture);
493}
494TEST_STEP(DrawPicture, DrawPictureTestStep);
495
rmistry@google.comd6176b02012-08-23 18:14:13 +0000496static void SaveRestoreTestStep(SkCanvas* canvas,
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000497 skiatest::Reporter* reporter,
498 CanvasTestStep* testStep) {
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000499 int baseSaveCount = canvas->getSaveCount();
tomhudson@google.com8afae612012-08-14 15:03:35 +0000500 int n = canvas->save();
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000501 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount == n, testStep->assertMessage());
502 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(),
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000503 testStep->assertMessage());
504 canvas->save();
505 canvas->save();
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000506 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 3 == canvas->getSaveCount(),
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000507 testStep->assertMessage());
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000508 canvas->restoreToCount(baseSaveCount + 1);
509 REPORTER_ASSERT_MESSAGE(reporter, baseSaveCount + 1 == canvas->getSaveCount(),
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000510 testStep->assertMessage());
511
512 // should this pin to 1, or be a no-op, or crash?
513 canvas->restoreToCount(0);
514 REPORTER_ASSERT_MESSAGE(reporter, 1 == canvas->getSaveCount(),
515 testStep->assertMessage());
516}
517TEST_STEP(SaveRestore, SaveRestoreTestStep);
518
rmistry@google.comd6176b02012-08-23 18:14:13 +0000519static void DrawLayerTestStep(SkCanvas* canvas,
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000520 skiatest::Reporter* reporter,
521 CanvasTestStep* testStep) {
522 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
523 testStep->assertMessage());
524 canvas->save();
525 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
526 testStep->assertMessage());
junov@chromium.org4e6dfa52012-07-16 14:04:59 +0000527 canvas->restore();
rmistry@google.comd6176b02012-08-23 18:14:13 +0000528
reed@google.com7c202932011-12-14 18:48:05 +0000529 const SkRect* bounds = NULL; // null means include entire bounds
530 const SkPaint* paint = NULL;
531
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000532 canvas->saveLayer(bounds, paint);
533 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
534 testStep->assertMessage());
535 canvas->restore();
536 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
537 testStep->assertMessage());
reed@google.com7c202932011-12-14 18:48:05 +0000538
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000539 canvas->saveLayer(bounds, paint);
540 canvas->saveLayer(bounds, paint);
541 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
542 testStep->assertMessage());
543 canvas->restore();
544 REPORTER_ASSERT_MESSAGE(reporter, canvas->isDrawingToLayer(),
545 testStep->assertMessage());
546 canvas->restore();
reed@google.com7c202932011-12-14 18:48:05 +0000547 // now layer count should be 0
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000548 REPORTER_ASSERT_MESSAGE(reporter, !canvas->isDrawingToLayer(),
549 testStep->assertMessage());
550}
551TEST_STEP(DrawLayer, DrawLayerTestStep);
reed@google.com3b3e8952012-08-16 20:53:31 +0000552
553static void NestedSaveRestoreWithSolidPaintTestStep(SkCanvas* canvas,
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000554 skiatest::Reporter*,
555 CanvasTestStep*) {
reed@google.com3b3e8952012-08-16 20:53:31 +0000556 // This test step challenges the TestDeferredCanvasStateConsistency
557 // test cases because the opaque paint can trigger an optimization
558 // that discards previously recorded commands. The challenge is to maintain
559 // correct clip and matrix stack state.
560 canvas->resetMatrix();
561 canvas->rotate(SkIntToScalar(30));
562 canvas->save();
563 canvas->translate(SkIntToScalar(2), SkIntToScalar(1));
564 canvas->save();
565 canvas->scale(SkIntToScalar(3), SkIntToScalar(3));
566 SkPaint paint;
567 paint.setColor(0xFFFFFFFF);
568 canvas->drawPaint(paint);
569 canvas->restore();
570 canvas->restore();
571}
572TEST_STEP(NestedSaveRestoreWithSolidPaint, \
573 NestedSaveRestoreWithSolidPaintTestStep);
574
575static void NestedSaveRestoreWithFlushTestStep(SkCanvas* canvas,
sugoi@google.com54f0d1b2013-02-27 19:17:41 +0000576 skiatest::Reporter*,
577 CanvasTestStep*) {
reed@google.com3b3e8952012-08-16 20:53:31 +0000578 // This test step challenges the TestDeferredCanvasStateConsistency
579 // test case because the canvas flush on a deferred canvas will
580 // reset the recording session. The challenge is to maintain correct
581 // clip and matrix stack state on the playback canvas.
582 canvas->resetMatrix();
583 canvas->rotate(SkIntToScalar(30));
584 canvas->save();
585 canvas->translate(SkIntToScalar(2), SkIntToScalar(1));
586 canvas->save();
587 canvas->scale(SkIntToScalar(3), SkIntToScalar(3));
588 canvas->drawRect(kTestRect,kTestPaint);
589 canvas->flush();
590 canvas->restore();
591 canvas->restore();
592}
593TEST_STEP(NestedSaveRestoreWithFlush, \
594 NestedSaveRestoreWithFlushTestStep);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000595
596static void AssertCanvasStatesEqual(skiatest::Reporter* reporter,
rmistry@google.comd6176b02012-08-23 18:14:13 +0000597 const SkCanvas* canvas1,
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000598 const SkCanvas* canvas2,
599 CanvasTestStep* testStep) {
600 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDeviceSize() ==
601 canvas2->getDeviceSize(), testStep->assertMessage());
602 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getSaveCount() ==
603 canvas2->getSaveCount(), testStep->assertMessage());
604 REPORTER_ASSERT_MESSAGE(reporter, canvas1->isDrawingToLayer() ==
605 canvas2->isDrawingToLayer(), testStep->assertMessage());
reed@google.com3b3e8952012-08-16 20:53:31 +0000606
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000607 SkRect bounds1, bounds2;
608 REPORTER_ASSERT_MESSAGE(reporter,
reed@google.com3b3e8952012-08-16 20:53:31 +0000609 canvas1->getClipBounds(&bounds1) == canvas2->getClipBounds(&bounds2),
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000610 testStep->assertMessage());
611 REPORTER_ASSERT_MESSAGE(reporter, bounds1 == bounds2,
reed@google.com3b3e8952012-08-16 20:53:31 +0000612 testStep->assertMessage());
613
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000614 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getDrawFilter() ==
615 canvas2->getDrawFilter(), testStep->assertMessage());
616 SkIRect deviceBounds1, deviceBounds2;
617 REPORTER_ASSERT_MESSAGE(reporter,
618 canvas1->getClipDeviceBounds(&deviceBounds1) ==
619 canvas2->getClipDeviceBounds(&deviceBounds2),
620 testStep->assertMessage());
621 REPORTER_ASSERT_MESSAGE(reporter, deviceBounds1 == deviceBounds2,
622 testStep->assertMessage());
623 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getBounder() ==
624 canvas2->getBounder(), testStep->assertMessage());
625 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalMatrix() ==
626 canvas2->getTotalMatrix(), testStep->assertMessage());
627 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getClipType() ==
628 canvas2->getClipType(), testStep->assertMessage());
629 REPORTER_ASSERT_MESSAGE(reporter, canvas1->getTotalClip() ==
630 canvas2->getTotalClip(), testStep->assertMessage());
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000631
632 // The following test code is commented out because the test fails when
rmistry@google.comd6176b02012-08-23 18:14:13 +0000633 // the canvas is an SkPictureRecord or SkDeferredCanvas
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000634 // Issue: http://code.google.com/p/skia/issues/detail?id=498
635 // Also, creating a LayerIter on an SkProxyCanvas crashes
636 // Issue: http://code.google.com/p/skia/issues/detail?id=499
637 /*
638 SkCanvas::LayerIter layerIter1(const_cast<SkCanvas*>(canvas1), false);
639 SkCanvas::LayerIter layerIter2(const_cast<SkCanvas*>(canvas2), false);
640 while (!layerIter1.done() && !layerIter2.done()) {
641 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.matrix() ==
642 layerIter2.matrix(), testStep->assertMessage());
643 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.clip() ==
644 layerIter2.clip(), testStep->assertMessage());
645 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.paint() ==
646 layerIter2.paint(), testStep->assertMessage());
647 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.x() ==
648 layerIter2.x(), testStep->assertMessage());
649 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.y() ==
650 layerIter2.y(), testStep->assertMessage());
651 layerIter1.next();
652 layerIter2.next();
653 }
654 REPORTER_ASSERT_MESSAGE(reporter, layerIter1.done(),
655 testStep->assertMessage());
656 REPORTER_ASSERT_MESSAGE(reporter, layerIter2.done(),
657 testStep->assertMessage());
658 */
659}
660
661// The following class groups static functions that need to access
662// the privates members of SkPictureRecord
663class SkPictureTester {
664private:
reed@google.come2589ae2012-07-10 19:38:01 +0000665 static int EQ(const SkFlatData* a, const SkFlatData* b) {
666 return *a == *b;
667 }
668
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000669 static void AssertFlattenedObjectsEqual(
670 SkPictureRecord* referenceRecord,
671 SkPictureRecord* testRecord,
672 skiatest::Reporter* reporter,
673 CanvasTestStep* testStep) {
674
675 REPORTER_ASSERT_MESSAGE(reporter,
djsollen@google.comc9ab9872012-08-29 18:52:07 +0000676 referenceRecord->fBitmapHeap->count() ==
677 testRecord->fBitmapHeap->count(), testStep->assertMessage());
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000678 REPORTER_ASSERT_MESSAGE(reporter,
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000679 referenceRecord->fPaints.count() ==
680 testRecord->fPaints.count(), testStep->assertMessage());
681 for (int i = 0; i < referenceRecord->fPaints.count(); ++i) {
682 REPORTER_ASSERT_MESSAGE(reporter,
reed@google.come2589ae2012-07-10 19:38:01 +0000683 EQ(referenceRecord->fPaints[i], testRecord->fPaints[i]),
684 testStep->assertMessage());
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000685 }
686 REPORTER_ASSERT_MESSAGE(reporter,
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000687 !referenceRecord->fPathHeap ==
688 !testRecord->fPathHeap,
689 testStep->assertMessage());
junov@chromium.orgdadcfdc2012-02-23 14:59:22 +0000690 // The following tests are commented out because they currently
691 // fail. Issue: http://code.google.com/p/skia/issues/detail?id=507
692 /*
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000693 if (referenceRecord->fPathHeap) {
694 REPORTER_ASSERT_MESSAGE(reporter,
695 referenceRecord->fPathHeap->count() ==
696 testRecord->fPathHeap->count(),
697 testStep->assertMessage());
698 for (int i = 0; i < referenceRecord->fPathHeap->count(); ++i) {
699 REPORTER_ASSERT_MESSAGE(reporter,
700 (*referenceRecord->fPathHeap)[i] ==
701 (*testRecord->fPathHeap)[i], testStep->assertMessage());
702 }
703 }
junov@chromium.orgdadcfdc2012-02-23 14:59:22 +0000704 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000705
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000706 }
707
708public:
709
rmistry@google.comd6176b02012-08-23 18:14:13 +0000710 static void TestPictureFlattenedObjectReuse(skiatest::Reporter* reporter,
junov@chromium.org4866cc02012-06-01 21:23:07 +0000711 CanvasTestStep* testStep,
712 uint32_t recordFlags) {
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000713 // Verify that when a test step is executed twice, no extra resources
714 // are flattened during the second execution
715 testStep->setAssertMessageFormat(kPictureDrawAssertMessageFormat);
716 SkPicture referencePicture;
717 SkCanvas* referenceCanvas = referencePicture.beginRecording(kWidth,
junov@chromium.org4866cc02012-06-01 21:23:07 +0000718 kHeight, recordFlags);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000719 testStep->draw(referenceCanvas, reporter);
720 SkPicture testPicture;
junov@chromium.orgdadcfdc2012-02-23 14:59:22 +0000721 SkCanvas* testCanvas = testPicture.beginRecording(kWidth,
junov@chromium.org4866cc02012-06-01 21:23:07 +0000722 kHeight, recordFlags);
junov@chromium.orgdadcfdc2012-02-23 14:59:22 +0000723 testStep->draw(testCanvas, reporter);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000724 testStep->setAssertMessageFormat(kPictureSecondDrawAssertMessageFormat);
junov@chromium.orgdadcfdc2012-02-23 14:59:22 +0000725 testStep->draw(testCanvas, reporter);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000726
727 SkPictureRecord* referenceRecord = static_cast<SkPictureRecord*>(
728 referenceCanvas);
729 SkPictureRecord* testRecord = static_cast<SkPictureRecord*>(
730 testCanvas);
731 testStep->setAssertMessageFormat(kPictureResourceReuseMessageFormat);
732 AssertFlattenedObjectsEqual(referenceRecord, testRecord,
junov@chromium.org76b9c4b2012-02-22 21:24:41 +0000733 reporter, testStep);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000734 }
735};
736
edisonn@google.com77909122012-10-18 15:58:23 +0000737static void TestPdfDevice(skiatest::Reporter* reporter,
738 CanvasTestStep* testStep) {
739 SkISize pageSize = SkISize::Make(kWidth, kHeight);
740 SkPDFDevice device(pageSize, pageSize, SkMatrix::I());
741 SkCanvas canvas(&device);
742 testStep->setAssertMessageFormat(kPdfAssertMessageFormat);
743 testStep->draw(&canvas, reporter);
744 SkPDFDocument doc;
745 doc.appendPage(&device);
746 SkDynamicMemoryWStream stream;
747 doc.emitPDF(&stream);
748}
749
junov@chromium.org88e29142012-08-07 16:48:22 +0000750// The following class groups static functions that need to access
751// the privates members of SkDeferredCanvas
752class SkDeferredCanvasTester {
753public:
754 static void TestDeferredCanvasStateConsistency(
755 skiatest::Reporter* reporter,
756 CanvasTestStep* testStep,
junov@chromium.orgfb103892012-09-20 19:35:43 +0000757 const SkCanvas& referenceCanvas, bool silent) {
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000758
reed@google.com28183b42014-02-04 15:34:10 +0000759 SkAutoTUnref<SkSurface> surface(createSurface(0xFFFFFFFF));
760 SkAutoTUnref<SkDeferredCanvas> deferredCanvas(SkDeferredCanvas::Create(surface.get()));
761
junov@chromium.org88e29142012-08-07 16:48:22 +0000762 testStep->setAssertMessageFormat(kDeferredDrawAssertMessageFormat);
junov@chromium.org66070a52013-05-28 17:39:08 +0000763 testStep->draw(deferredCanvas, reporter);
junov@chromium.org88e29142012-08-07 16:48:22 +0000764 testStep->setAssertMessageFormat(kDeferredPreFlushAssertMessageFormat);
junov@chromium.org66070a52013-05-28 17:39:08 +0000765 AssertCanvasStatesEqual(reporter, deferredCanvas, &referenceCanvas,
junov@chromium.org88e29142012-08-07 16:48:22 +0000766 testStep);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000767
junov@chromium.orgfb103892012-09-20 19:35:43 +0000768 if (silent) {
junov@chromium.org66070a52013-05-28 17:39:08 +0000769 deferredCanvas->silentFlush();
junov@chromium.orgfb103892012-09-20 19:35:43 +0000770 } else {
junov@chromium.org66070a52013-05-28 17:39:08 +0000771 deferredCanvas->flush();
junov@chromium.orgfb103892012-09-20 19:35:43 +0000772 }
773
skia.committer@gmail.com4c5ea442012-09-21 02:01:01 +0000774 testStep->setAssertMessageFormat(
junov@chromium.orgfb103892012-09-20 19:35:43 +0000775 silent ? kDeferredPostSilentFlushPlaybackAssertMessageFormat :
junov@chromium.org88e29142012-08-07 16:48:22 +0000776 kDeferredPostFlushPlaybackAssertMessageFormat);
rmistry@google.comd6176b02012-08-23 18:14:13 +0000777 AssertCanvasStatesEqual(reporter,
junov@chromium.org66070a52013-05-28 17:39:08 +0000778 deferredCanvas->immediateCanvas(),
junov@chromium.org88e29142012-08-07 16:48:22 +0000779 &referenceCanvas, testStep);
junov@chromium.orgcff01c52012-07-18 21:50:26 +0000780
junov@chromium.org88e29142012-08-07 16:48:22 +0000781 // Verified that deferred canvas state is not affected by flushing
782 // pending draw operations
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000783
junov@chromium.org88e29142012-08-07 16:48:22 +0000784 // The following test code is commented out because it currently fails.
785 // Issue: http://code.google.com/p/skia/issues/detail?id=496
786 /*
787 testStep->setAssertMessageFormat(kDeferredPostFlushAssertMessageFormat);
788 AssertCanvasStatesEqual(reporter, &deferredCanvas, &referenceCanvas,
789 testStep);
790 */
791 }
792};
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000793
caryclark@google.com42639cd2012-06-06 12:03:39 +0000794// unused
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000795static void TestProxyCanvasStateConsistency(
796 skiatest::Reporter* reporter,
797 CanvasTestStep* testStep,
798 const SkCanvas& referenceCanvas) {
799
800 SkBitmap indirectStore;
801 createBitmap(&indirectStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000802 SkBitmapDevice indirectDevice(indirectStore);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000803 SkCanvas indirectCanvas(&indirectDevice);
804 SkProxyCanvas proxyCanvas(&indirectCanvas);
805 testStep->setAssertMessageFormat(kProxyDrawAssertMessageFormat);
806 testStep->draw(&proxyCanvas, reporter);
807 // Verify that the SkProxyCanvas reports consitent state
808 testStep->setAssertMessageFormat(kProxyStateAssertMessageFormat);
809 AssertCanvasStatesEqual(reporter, &proxyCanvas, &referenceCanvas,
810 testStep);
811 // Verify that the indirect canvas reports consitent state
812 testStep->setAssertMessageFormat(kProxyIndirectStateAssertMessageFormat);
813 AssertCanvasStatesEqual(reporter, &indirectCanvas, &referenceCanvas,
814 testStep);
815}
816
caryclark@google.com42639cd2012-06-06 12:03:39 +0000817// unused
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000818static void TestNWayCanvasStateConsistency(
819 skiatest::Reporter* reporter,
820 CanvasTestStep* testStep,
821 const SkCanvas& referenceCanvas) {
822
823 SkBitmap indirectStore1;
824 createBitmap(&indirectStore1, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000825 SkBitmapDevice indirectDevice1(indirectStore1);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000826 SkCanvas indirectCanvas1(&indirectDevice1);
827
828 SkBitmap indirectStore2;
829 createBitmap(&indirectStore2, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000830 SkBitmapDevice indirectDevice2(indirectStore2);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000831 SkCanvas indirectCanvas2(&indirectDevice2);
832
djsollen@google.comf0a062b2012-05-01 16:50:25 +0000833 SkISize canvasSize = referenceCanvas.getDeviceSize();
834 SkNWayCanvas nWayCanvas(canvasSize.width(), canvasSize.height());
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000835 nWayCanvas.addCanvas(&indirectCanvas1);
836 nWayCanvas.addCanvas(&indirectCanvas2);
837
838 testStep->setAssertMessageFormat(kNWayDrawAssertMessageFormat);
839 testStep->draw(&nWayCanvas, reporter);
840 // Verify that the SkProxyCanvas reports consitent state
841 testStep->setAssertMessageFormat(kNWayStateAssertMessageFormat);
842 AssertCanvasStatesEqual(reporter, &nWayCanvas, &referenceCanvas,
843 testStep);
844 // Verify that the indirect canvases report consitent state
845 testStep->setAssertMessageFormat(kNWayIndirect1StateAssertMessageFormat);
846 AssertCanvasStatesEqual(reporter, &indirectCanvas1, &referenceCanvas,
847 testStep);
848 testStep->setAssertMessageFormat(kNWayIndirect2StateAssertMessageFormat);
849 AssertCanvasStatesEqual(reporter, &indirectCanvas2, &referenceCanvas,
850 testStep);
851}
852
853/*
854 * This sub-test verifies that the test step passes when executed
855 * with SkCanvas and with classes derrived from SkCanvas. It also verifies
856 * that the all canvas derivatives report the same state as an SkCanvas
857 * after having executed the test step.
858 */
rmistry@google.comd6176b02012-08-23 18:14:13 +0000859static void TestOverrideStateConsistency(skiatest::Reporter* reporter,
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000860 CanvasTestStep* testStep) {
861 SkBitmap referenceStore;
862 createBitmap(&referenceStore, SkBitmap::kARGB_8888_Config, 0xFFFFFFFF);
robertphillips@google.com1f2f3382013-08-29 11:54:56 +0000863 SkBitmapDevice referenceDevice(referenceStore);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000864 SkCanvas referenceCanvas(&referenceDevice);
865 testStep->setAssertMessageFormat(kCanvasDrawAssertMessageFormat);
866 testStep->draw(&referenceCanvas, reporter);
867
junov@chromium.orgfb103892012-09-20 19:35:43 +0000868 SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, false);
869
870 SkDeferredCanvasTester::TestDeferredCanvasStateConsistency(reporter, testStep, referenceCanvas, true);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000871
caryclark@google.com42639cd2012-06-06 12:03:39 +0000872 // The following test code is disabled because SkProxyCanvas is
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000873 // missing a lot of virtual overrides on get* methods, which are used
874 // to verify canvas state.
875 // Issue: http://code.google.com/p/skia/issues/detail?id=500
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000876
caryclark@google.com42639cd2012-06-06 12:03:39 +0000877 if (false) { // avoid bit rot, suppress warning
878 TestProxyCanvasStateConsistency(reporter, testStep, referenceCanvas);
879 }
880
881 // The following test code is disabled because SkNWayCanvas does not
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000882 // report correct clipping and device bounds information
883 // Issue: http://code.google.com/p/skia/issues/detail?id=501
caryclark@google.com42639cd2012-06-06 12:03:39 +0000884
885 if (false) { // avoid bit rot, suppress warning
886 TestNWayCanvasStateConsistency(reporter, testStep, referenceCanvas);
887 }
rmistry@google.comd6176b02012-08-23 18:14:13 +0000888
caryclark@google.com42639cd2012-06-06 12:03:39 +0000889 if (false) { // avoid bit rot, suppress warning
890 test_clipVisitor(reporter, &referenceCanvas);
891 }
reed@google.com7c202932011-12-14 18:48:05 +0000892}
reed@google.com37f3ae02011-11-28 16:06:04 +0000893
tfarina@chromium.orge4fafb12013-12-12 21:11:12 +0000894DEF_TEST(Canvas, reporter) {
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000895 // Init global here because bitmap pixels cannot be alocated during
896 // static initialization
897 kTestBitmap = testBitmap();
reed@google.com37f3ae02011-11-28 16:06:04 +0000898
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000899 for (int testStep = 0; testStep < testStepArray().count(); testStep++) {
900 TestOverrideStateConsistency(reporter, testStepArray()[testStep]);
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000901 SkPictureTester::TestPictureFlattenedObjectReuse(reporter,
junov@chromium.org4866cc02012-06-01 21:23:07 +0000902 testStepArray()[testStep], 0);
edisonn@google.com77909122012-10-18 15:58:23 +0000903 if (testStepArray()[testStep]->enablePdfTesting()) {
904 TestPdfDevice(reporter, testStepArray()[testStep]);
905 }
junov@chromium.org1cc8f6f2012-02-22 21:00:42 +0000906 }
junov@chromium.orgcd62ecf2012-08-02 17:43:25 +0000907
908 // Explicitly call reset(), so we don't leak the pixels (since kTestBitmap is a global)
909 kTestBitmap.reset();
reed@google.com37f3ae02011-11-28 16:06:04 +0000910}