Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(278)

Side by Side Diff: cc/paint/paint_op_buffer_unittest.cc

Issue 2810363004: Revert of Back PaintRecord with PaintOpBuffer instead of SkPicture (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/paint/paint_op_buffer.cc ('k') | cc/paint/paint_record.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "cc/paint/paint_op_buffer.h"
6 #include "cc/test/test_skcanvas.h"
7 #include "testing/gtest/include/gtest/gtest.h"
8
9 namespace cc {
10
11 TEST(PaintOpBufferTest, Empty) {
12 PaintOpBuffer buffer;
13 EXPECT_EQ(buffer.approximateOpCount(), 0);
14 EXPECT_EQ(buffer.approximateBytesUsed(), sizeof(PaintOpBuffer));
15 EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false);
16
17 buffer.Reset();
18 EXPECT_EQ(buffer.approximateOpCount(), 0);
19 EXPECT_EQ(buffer.approximateBytesUsed(), sizeof(PaintOpBuffer));
20 EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false);
21 }
22
23 TEST(PaintOpBufferTest, SimpleAppend) {
24 SkRect rect = SkRect::MakeXYWH(2, 3, 4, 5);
25 PaintFlags flags;
26 flags.setColor(SK_ColorMAGENTA);
27 flags.setAlpha(100);
28 SkColor draw_color = SK_ColorRED;
29 SkBlendMode blend = SkBlendMode::kSrc;
30
31 PaintOpBuffer buffer;
32 buffer.push<SaveLayerOp>(&rect, &flags);
33 buffer.push<SaveOp>();
34 buffer.push<DrawColorOp>(draw_color, blend);
35 buffer.push<RestoreOp>();
36
37 EXPECT_EQ(buffer.approximateOpCount(), 4);
38
39 PaintOpBuffer::Iterator iter(&buffer);
40 ASSERT_EQ(iter->GetType(), PaintOpType::SaveLayer);
41 SaveLayerOp* save_op = static_cast<SaveLayerOp*>(*iter);
42 EXPECT_EQ(save_op->bounds, rect);
43 EXPECT_TRUE(save_op->flags == flags);
44 ++iter;
45
46 ASSERT_EQ(iter->GetType(), PaintOpType::Save);
47 ++iter;
48
49 ASSERT_EQ(iter->GetType(), PaintOpType::DrawColor);
50 DrawColorOp* op = static_cast<DrawColorOp*>(*iter);
51 EXPECT_EQ(op->color, draw_color);
52 EXPECT_EQ(op->mode, blend);
53 ++iter;
54
55 ASSERT_EQ(iter->GetType(), PaintOpType::Restore);
56 ++iter;
57
58 EXPECT_FALSE(iter);
59 }
60
61 // PaintOpBuffer has a special case for first ops stored locally, so
62 // make sure that appending different kind of ops as a first op works
63 // properly, as well as resetting and reusing the first local op.
64 TEST(PaintOpBufferTest, FirstOpWithAndWithoutData) {
65 PaintOpBuffer buffer;
66 char text[] = "asdf";
67
68 // Use a color filter and its ref count to verify that the destructor
69 // is called on ops after reset.
70 PaintFlags flags;
71 sk_sp<SkColorFilter> filter =
72 SkColorFilter::MakeModeFilter(SK_ColorMAGENTA, SkBlendMode::kSrcOver);
73 flags.setColorFilter(filter);
74 EXPECT_EQ(filter->getRefCnt(), 2);
75
76 buffer.push_with_data<DrawTextOp>(text, arraysize(text), 0.f, 0.f, flags);
77 EXPECT_EQ(filter->getRefCnt(), 3);
78
79 // Verify that when the first op has data, which may not fit in the
80 // PaintRecord internal buffer, that it adds a noop as the first op
81 // and then appends the "op with data" into the heap buffer.
82 ASSERT_EQ(buffer.approximateOpCount(), 2);
83 EXPECT_EQ(buffer.GetFirstOp()->GetType(), PaintOpType::Noop);
84
85 // Verify iteration behavior and brief smoke test of op state.
86 {
87 PaintOpBuffer::Iterator iter(&buffer);
88 PaintOp* noop = *iter;
89 EXPECT_EQ(buffer.GetFirstOp(), noop);
90 ++iter;
91
92 PaintOp* op = *iter;
93 ASSERT_EQ(op->GetType(), PaintOpType::DrawText);
94 DrawTextOp* draw_text_op = static_cast<DrawTextOp*>(op);
95 EXPECT_EQ(draw_text_op->bytes, arraysize(text));
96
97 void* data = paint_op_data(draw_text_op);
98 EXPECT_EQ(memcmp(data, text, arraysize(text)), 0);
99
100 ++iter;
101 EXPECT_FALSE(iter);
102 }
103
104 // Reset, verify state, and append an op that will fit in the first slot.
105 buffer.Reset();
106 EXPECT_EQ(filter->getRefCnt(), 2);
107
108 ASSERT_EQ(buffer.approximateOpCount(), 0);
109 EXPECT_EQ(PaintOpBuffer::Iterator(&buffer), false);
110
111 SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
112 buffer.push<DrawRectOp>(rect, flags);
113 EXPECT_EQ(filter->getRefCnt(), 3);
114
115 ASSERT_EQ(buffer.approximateOpCount(), 1);
116 EXPECT_EQ(buffer.GetFirstOp()->GetType(), PaintOpType::DrawRect);
117
118 PaintOpBuffer::Iterator iter(&buffer);
119 ASSERT_EQ(iter->GetType(), PaintOpType::DrawRect);
120 DrawRectOp* draw_rect_op = static_cast<DrawRectOp*>(*iter);
121 EXPECT_EQ(draw_rect_op->rect, rect);
122
123 ++iter;
124 EXPECT_FALSE(iter);
125
126 buffer.Reset();
127 ASSERT_EQ(buffer.approximateOpCount(), 0);
128 EXPECT_EQ(filter->getRefCnt(), 2);
129 }
130
131 TEST(PaintOpBufferTest, Peek) {
132 PaintOpBuffer buffer;
133
134 uint8_t alpha = 100;
135 buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
136 PaintFlags draw_flags;
137 buffer.push<DrawRectOp>(SkRect::MakeXYWH(1, 2, 3, 4), draw_flags);
138 buffer.push<RestoreOp>();
139 buffer.push<SaveOp>();
140 buffer.push<NoopOp>();
141 buffer.push<RestoreOp>();
142
143 PaintOpBuffer::Iterator init_iter(&buffer);
144 PaintOp* peek[2] = {*init_iter, init_iter.peek1()};
145
146 // Expect that while iterating that next = current.peek1() and that
147 // next.peek1() == current.peek2().
148 for (PaintOpBuffer::Iterator iter(&buffer); iter; ++iter) {
149 EXPECT_EQ(*iter, peek[0]) << iter.op_idx();
150 EXPECT_EQ(iter.peek1(), peek[1]) << iter.op_idx();
151
152 peek[0] = iter.peek1();
153 peek[1] = iter.peek2();
154 }
155 }
156
157 TEST(PaintOpBufferTest, PeekEmpty) {
158 PaintOpBuffer empty;
159 PaintOpBuffer::Iterator empty_iter(&empty);
160 EXPECT_EQ(nullptr, empty_iter.peek1());
161 EXPECT_EQ(nullptr, empty_iter.peek2());
162 }
163
164 // Verify that a SaveLayerAlpha / Draw / Restore can be optimized to just
165 // a draw with opacity.
166 TEST(PaintOpBufferTest, SaveDrawRestore) {
167 PaintOpBuffer buffer;
168
169 uint8_t alpha = 100;
170 buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
171
172 PaintFlags draw_flags;
173 draw_flags.setColor(SK_ColorMAGENTA);
174 draw_flags.setAlpha(50);
175 EXPECT_TRUE(draw_flags.SupportsFoldingAlpha());
176 SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
177 buffer.push<DrawRectOp>(rect, draw_flags);
178 buffer.push<RestoreOp>();
179
180 SaveCountingCanvas canvas;
181 buffer.playback(&canvas);
182
183 EXPECT_EQ(0, canvas.save_count_);
184 EXPECT_EQ(0, canvas.restore_count_);
185 EXPECT_EQ(rect, canvas.draw_rect_);
186
187 // Expect the alpha from the draw and the save layer to be folded together.
188 // Since alpha is stored in a uint8_t and gets rounded, so use tolerance.
189 float expected_alpha = alpha * 50 / 255.f;
190 EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f);
191 }
192
193 // The same as SaveDrawRestore, but test that the optimization doesn't apply
194 // when the drawing op's flags are not compatible with being folded into the
195 // save layer with opacity.
196 TEST(PaintOpBufferTest, SaveDrawRestoreFail_BadFlags) {
197 PaintOpBuffer buffer;
198
199 uint8_t alpha = 100;
200 buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
201
202 PaintFlags draw_flags;
203 draw_flags.setColor(SK_ColorMAGENTA);
204 draw_flags.setAlpha(50);
205 draw_flags.setBlendMode(SkBlendMode::kSrc);
206 EXPECT_FALSE(draw_flags.SupportsFoldingAlpha());
207 SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
208 buffer.push<DrawRectOp>(rect, draw_flags);
209 buffer.push<RestoreOp>();
210
211 SaveCountingCanvas canvas;
212 buffer.playback(&canvas);
213
214 EXPECT_EQ(1, canvas.save_count_);
215 EXPECT_EQ(1, canvas.restore_count_);
216 EXPECT_EQ(rect, canvas.draw_rect_);
217 EXPECT_EQ(draw_flags.getAlpha(), canvas.paint_.getAlpha());
218 }
219
220 // The same as SaveDrawRestore, but test that the optimization doesn't apply
221 // when there are more than one ops between the save and restore.
222 TEST(PaintOpBufferTest, SaveDrawRestoreFail_TooManyOps) {
223 PaintOpBuffer buffer;
224
225 uint8_t alpha = 100;
226 buffer.push<SaveLayerAlphaOp>(nullptr, alpha);
227
228 PaintFlags draw_flags;
229 draw_flags.setColor(SK_ColorMAGENTA);
230 draw_flags.setAlpha(50);
231 draw_flags.setBlendMode(SkBlendMode::kSrcOver);
232 EXPECT_TRUE(draw_flags.SupportsFoldingAlpha());
233 SkRect rect = SkRect::MakeXYWH(1, 2, 3, 4);
234 buffer.push<DrawRectOp>(rect, draw_flags);
235 buffer.push<NoopOp>();
236 buffer.push<RestoreOp>();
237
238 SaveCountingCanvas canvas;
239 buffer.playback(&canvas);
240
241 EXPECT_EQ(1, canvas.save_count_);
242 EXPECT_EQ(1, canvas.restore_count_);
243 EXPECT_EQ(rect, canvas.draw_rect_);
244 EXPECT_EQ(draw_flags.getAlpha(), canvas.paint_.getAlpha());
245 }
246
247 } // namespace cc
OLDNEW
« no previous file with comments | « cc/paint/paint_op_buffer.cc ('k') | cc/paint/paint_record.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698