blob: 5c63b53ee9fdea620c75e930b05746683062b9f7 [file] [log] [blame]
commit-bot@chromium.orgc4b21e62014-04-11 18:33:31 +00001/*
2 * Copyright 2014 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +00008#include "Test.h"
commit-bot@chromium.org0a98d872014-05-19 15:15:24 +00009#include "RecordTestUtils.h"
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +000010
11#include "SkDebugCanvas.h"
Mike Kleinc11530e2014-06-24 11:29:06 -040012#include "SkDrawPictureCallback.h"
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +000013#include "SkRecord.h"
commit-bot@chromium.orgad8ce572014-04-21 15:03:36 +000014#include "SkRecordOpts.h"
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +000015#include "SkRecordDraw.h"
16#include "SkRecorder.h"
17#include "SkRecords.h"
18
19static const int W = 1920, H = 1080;
20
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000021static void draw_pos_text_h(SkCanvas* canvas, const char* text, SkScalar y) {
22 const size_t len = strlen(text);
23 SkAutoTMalloc<SkScalar> xpos(len);
24 for (size_t i = 0; i < len; i++) {
25 xpos[i] = (SkScalar)i;
26 }
27 canvas->drawPosTextH(text, len, xpos, y, SkPaint());
28}
29
Mike Kleinc11530e2014-06-24 11:29:06 -040030class JustOneDraw : public SkDrawPictureCallback {
31public:
32 JustOneDraw() : fCalls(0) {}
33
34 virtual bool abortDrawing() SK_OVERRIDE { return fCalls++ > 0; }
35private:
36 int fCalls;
37};
38
39DEF_TEST(RecordDraw_Abort, r) {
40 // Record two commands.
41 SkRecord record;
42 SkRecorder recorder(&record, W, H);
43 recorder.drawRect(SkRect::MakeWH(200, 300), SkPaint());
44 recorder.clipRect(SkRect::MakeWH(100, 200));
45
46 SkRecord rerecord;
47 SkRecorder canvas(&rerecord, W, H);
48
49 JustOneDraw callback;
50 SkRecordDraw(record, &canvas, &callback);
51
52 REPORTER_ASSERT(r, 3 == rerecord.count());
53 assert_type<SkRecords::Save> (r, rerecord, 0);
54 assert_type<SkRecords::DrawRect>(r, rerecord, 1);
55 assert_type<SkRecords::Restore> (r, rerecord, 2);
56}
57
58DEF_TEST(RecordDraw_Unbalanced, r) {
59 SkRecord record;
60 SkRecorder recorder(&record, W, H);
61 recorder.save(); // We won't balance this, but SkRecordDraw will for us.
62
63 SkRecord rerecord;
64 SkRecorder canvas(&rerecord, W, H);
65 SkRecordDraw(record, &canvas);
66
67 REPORTER_ASSERT(r, 4 == rerecord.count());
68 assert_type<SkRecords::Save> (r, rerecord, 0);
69 assert_type<SkRecords::Save> (r, rerecord, 1);
70 assert_type<SkRecords::Restore> (r, rerecord, 2);
71 assert_type<SkRecords::Restore> (r, rerecord, 3);
72}
73
74// Rerecord into another SkRecord with a clip.
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000075static void record_clipped(const SkRecord& record, SkRect clip, SkRecord* clipped) {
commit-bot@chromium.orga0950412014-05-29 16:52:40 +000076 SkRecorder recorder(clipped, W, H);
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000077 recorder.clipRect(clip);
78 SkRecordDraw(record, &recorder);
79}
80
81DEF_TEST(RecordDraw_PosTextHQuickReject, r) {
82 SkRecord record;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +000083 SkRecorder recorder(&record, W, H);
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000084
85 draw_pos_text_h(&recorder, "This will draw.", 20);
86 draw_pos_text_h(&recorder, "This won't.", 5000);
87
88 SkRecordBoundDrawPosTextH(&record);
89
90 SkRecord clipped;
91 record_clipped(record, SkRect::MakeLTRB(20, 20, 200, 200), &clipped);
92
Mike Kleinc11530e2014-06-24 11:29:06 -040093 REPORTER_ASSERT(r, 4 == clipped.count());
94 assert_type<SkRecords::ClipRect> (r, clipped, 0);
95 assert_type<SkRecords::Save> (r, clipped, 1);
96 assert_type<SkRecords::DrawPosTextH>(r, clipped, 2);
97 assert_type<SkRecords::Restore> (r, clipped, 3);
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +000098}
99
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +0000100DEF_TEST(RecordDraw_Culling, r) {
101 // Record these 7 drawing commands verbatim.
102 SkRecord record;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +0000103 SkRecorder recorder(&record, W, H);
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +0000104
105 recorder.pushCull(SkRect::MakeWH(100, 100));
106 recorder.drawRect(SkRect::MakeWH(10, 10), SkPaint());
107 recorder.drawRect(SkRect::MakeWH(30, 30), SkPaint());
108 recorder.pushCull(SkRect::MakeWH(5, 5));
109 recorder.drawRect(SkRect::MakeWH(1, 1), SkPaint());
110 recorder.popCull();
111 recorder.popCull();
112
113 // Take a pass over to match up pushCulls and popCulls.
114 SkRecordAnnotateCullingPairs(&record);
115
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +0000116 // This clip intersects the outer cull, but allows us to quick reject the inner one.
commit-bot@chromium.org8dac8b12014-04-30 13:18:12 +0000117 SkRecord clipped;
118 record_clipped(record, SkRect::MakeLTRB(20, 20, 200, 200), &clipped);
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +0000119
Mike Kleinc11530e2014-06-24 11:29:06 -0400120 // If culling weren't working, we'd see 3 more commands recorded here.
121 REPORTER_ASSERT(r, 7 == clipped.count());
122 assert_type<SkRecords::ClipRect>(r, clipped, 0);
123 assert_type<SkRecords::Save> (r, clipped, 1);
124 assert_type<SkRecords::PushCull>(r, clipped, 2);
125 assert_type<SkRecords::DrawRect>(r, clipped, 3);
126 assert_type<SkRecords::DrawRect>(r, clipped, 4);
127 assert_type<SkRecords::PopCull> (r, clipped, 5);
128 assert_type<SkRecords::Restore> (r, clipped, 6);
commit-bot@chromium.orgd9ce2be2014-04-09 23:30:28 +0000129}
commit-bot@chromium.org0a98d872014-05-19 15:15:24 +0000130
131DEF_TEST(RecordDraw_SetMatrixClobber, r) {
132 // Set up an SkRecord that just scales by 2x,3x.
133 SkRecord scaleRecord;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +0000134 SkRecorder scaleCanvas(&scaleRecord, W, H);
commit-bot@chromium.org0a98d872014-05-19 15:15:24 +0000135 SkMatrix scale;
136 scale.setScale(2, 3);
137 scaleCanvas.setMatrix(scale);
138
139 // Set up an SkRecord with an initial +20, +20 translate.
140 SkRecord translateRecord;
commit-bot@chromium.orga0950412014-05-29 16:52:40 +0000141 SkRecorder translateCanvas(&translateRecord, W, H);
commit-bot@chromium.org0a98d872014-05-19 15:15:24 +0000142 SkMatrix translate;
143 translate.setTranslate(20, 20);
144 translateCanvas.setMatrix(translate);
145
146 SkRecordDraw(scaleRecord, &translateCanvas);
Mike Kleinc11530e2014-06-24 11:29:06 -0400147 REPORTER_ASSERT(r, 4 == translateRecord.count());
148 assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
149 assert_type<SkRecords::Save> (r, translateRecord, 1);
150 assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
151 assert_type<SkRecords::Restore> (r, translateRecord, 3);
commit-bot@chromium.org0a98d872014-05-19 15:15:24 +0000152
153 // When we look at translateRecord now, it should have its first +20,+20 translate,
154 // then a 2x,3x scale that's been concatted with that +20,+20 translate.
155 const SkRecords::SetMatrix* setMatrix;
156 setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 0);
157 REPORTER_ASSERT(r, setMatrix->matrix == translate);
158
Mike Kleinc11530e2014-06-24 11:29:06 -0400159 setMatrix = assert_type<SkRecords::SetMatrix>(r, translateRecord, 2);
commit-bot@chromium.org0a98d872014-05-19 15:15:24 +0000160 SkMatrix expected = scale;
161 expected.postConcat(translate);
162 REPORTER_ASSERT(r, setMatrix->matrix == expected);
163}