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

Side by Side Diff: Source/platform/graphics/paint/DisplayItemTransformTreeBuilderTest.cpp

Issue 1296963002: Put transform tree building in DisplayItemPropertyTreeBuilder. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: comment for inline capacity Created 5 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « Source/platform/graphics/paint/DisplayItemTransformTreeBuilder.cpp ('k') | public/BUILD.gn » ('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 2015 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 "config.h"
6 #include "platform/graphics/paint/DisplayItemTransformTreeBuilder.h"
7
8 #include "platform/graphics/paint/DisplayItem.h"
9 #include "platform/graphics/paint/DisplayItemClient.h"
10 #include "platform/graphics/paint/DisplayItemTransformTree.h"
11 #include "platform/graphics/paint/Transform3DDisplayItem.h"
12 #include "platform/transforms/TransformTestHelper.h"
13 #include "platform/transforms/TransformationMatrix.h"
14 #include "public/platform/WebDisplayItemTransformTree.h"
15 #include <gtest/gtest.h>
16
17 namespace blink {
18 namespace {
19
20 using RangeRecord = WebDisplayItemTransformTree::RangeRecord;
21
22 struct DummyClient {
23 DisplayItemClient displayItemClient() const { return toDisplayItemClient(thi s); }
24 String debugName() const { return "DummyClient"; }
25 };
26
27 class DummyDisplayItem final : public DisplayItem {
28 public:
29 DummyDisplayItem(const DummyClient& client) : DisplayItem(client, DisplayIte m::DrawingFirst, sizeof(*this)) { }
30 };
31
32 class DisplayItemTransformTreeBuilderTest : public ::testing::Test {
33 protected:
34 DisplayItemTransformTreeBuilder& builder() { return m_builder; }
35
36 void processDisplayItem(const DisplayItem& displayItem) { m_builder.processD isplayItem(displayItem); }
37 void processDisplayItem(PassOwnPtr<DisplayItem> displayItem) { processDispla yItem(*displayItem); }
38 void processDummyDisplayItem() { processDisplayItem(DummyDisplayItem(newDumm yClient())); }
39 const DummyClient& processBeginTransform3D(const TransformationMatrix& trans form)
40 {
41 const DummyClient& client = newDummyClient();
42 processDisplayItem(BeginTransform3DDisplayItem(client, DisplayItem::Tran sform3DElementTransform, transform));
43 return client;
44 }
45 void processEndTransform3D(const DummyClient& client)
46 {
47 processDisplayItem(EndTransform3DDisplayItem(client, DisplayItem::transf orm3DTypeToEndTransform3DType(DisplayItem::Transform3DElementTransform)));
48 }
49
50 private:
51 // This makes empty objects which can be used as display item clients.
52 const DummyClient& newDummyClient()
53 {
54 m_dummyClients.append(adoptPtr(new DummyClient));
55 return *m_dummyClients.last();
56 }
57
58 DisplayItemTransformTreeBuilder m_builder;
59 Vector<OwnPtr<DummyClient>> m_dummyClients;
60 };
61
62 TEST_F(DisplayItemTransformTreeBuilderTest, NoDisplayItems)
63 {
64 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
65
66 // There should be a root transform node.
67 ASSERT_EQ(1u, tree.nodeCount());
68 EXPECT_TRUE(tree.nodeAt(0).isRoot());
69 EXPECT_EQ(WebDisplayItemTransformTree::kInvalidIndex, tree.nodeAt(0).parentN odeIndex);
70
71 // There should be no range records, because there are no non-empty
72 // transformed ranges.
73 ASSERT_EQ(0u, tree.rangeRecordCount());
74 }
75
76 TEST_F(DisplayItemTransformTreeBuilderTest, NoTransforms)
77 {
78 // Three dummy display items.
79 processDummyDisplayItem();
80 processDummyDisplayItem();
81 processDummyDisplayItem();
82 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
83
84 // There should only be a root transform node.
85 ASSERT_EQ(1u, tree.nodeCount());
86 EXPECT_TRUE(tree.nodeAt(0).isRoot());
87 EXPECT_EQ(WebDisplayItemTransformTree::kInvalidIndex, tree.nodeAt(0).parentN odeIndex);
88
89 // There should be one range record, for the entire list.
90 ASSERT_EQ(1u, tree.rangeRecordCount());
91 EXPECT_EQ(RangeRecord(0, 3, 0), tree.rangeRecordAt(0));
92 }
93
94 TEST_F(DisplayItemTransformTreeBuilderTest, IdentityTransform)
95 {
96 TransformationMatrix identity;
97
98 // There's an identity transform here, but we should not make a node for it.
99 processDummyDisplayItem();
100 auto transformClient = processBeginTransform3D(identity);
101 processDummyDisplayItem();
102 processEndTransform3D(transformClient);
103 processDummyDisplayItem();
104 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
105
106 // There should only be a root transform node.
107 ASSERT_EQ(1u, tree.nodeCount());
108 EXPECT_TRUE(tree.nodeAt(0).isRoot());
109 EXPECT_EQ(WebDisplayItemTransformTree::kInvalidIndex, tree.nodeAt(0).parentN odeIndex);
110
111 // There should be three range records.
112 // Since the transform is the identity, these could be combined, but there
113 // is not currently a special path for this case.
114 ASSERT_EQ(3u, tree.rangeRecordCount());
115 EXPECT_EQ(RangeRecord(0, 1, 0), tree.rangeRecordAt(0));
116 EXPECT_EQ(RangeRecord(2, 3, 0), tree.rangeRecordAt(1));
117 EXPECT_EQ(RangeRecord(4, 5, 0), tree.rangeRecordAt(2));
118 }
119
120 TEST_F(DisplayItemTransformTreeBuilderTest, Only2DTranslation)
121 {
122 FloatSize offset(200.5, -100);
123 TransformationMatrix translation;
124 translation.translate(offset.width(), offset.height());
125
126 // There's a translation here, but we should not make a node for it.
127 processDummyDisplayItem();
128 auto transformClient = processBeginTransform3D(translation);
129 processDummyDisplayItem();
130 processEndTransform3D(transformClient);
131 processDummyDisplayItem();
132 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
133
134 // There should only be a root transform node.
135 ASSERT_EQ(1u, tree.nodeCount());
136 EXPECT_TRUE(tree.nodeAt(0).isRoot());
137 EXPECT_EQ(WebDisplayItemTransformTree::kInvalidIndex, tree.nodeAt(0).parentN odeIndex);
138
139 // There should be three ranges, even though there's only one node.
140 // The middle one requires an offset.
141 ASSERT_EQ(3u, tree.rangeRecordCount());
142 EXPECT_EQ(RangeRecord(0, 1, 0, FloatSize()), tree.rangeRecordAt(0));
143 EXPECT_EQ(RangeRecord(2, 3, 0, offset), tree.rangeRecordAt(1));
144 EXPECT_EQ(RangeRecord(4, 5, 0, FloatSize()), tree.rangeRecordAt(2));
145 }
146
147 TEST_F(DisplayItemTransformTreeBuilderTest, Nested2DTranslation)
148 {
149 FloatSize offset1(10, -40);
150 TransformationMatrix translation1;
151 translation1.translate(offset1.width(), offset1.height());
152 FloatSize offset2(80, 80);
153 TransformationMatrix translation2;
154 translation2.translate(offset2.width(), offset2.height());
155
156 // These drawings should share a transform node but have different range
157 // record offsets.
158 processDummyDisplayItem();
159 auto transform1 = processBeginTransform3D(translation1);
160 processDummyDisplayItem();
161 auto transform2 = processBeginTransform3D(translation2);
162 processDummyDisplayItem();
163 processEndTransform3D(transform2);
164 processEndTransform3D(transform1);
165 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
166
167 // There should only be a root transform node.
168 ASSERT_EQ(1u, tree.nodeCount());
169 EXPECT_TRUE(tree.nodeAt(0).isRoot());
170 EXPECT_EQ(WebDisplayItemTransformTree::kInvalidIndex, tree.nodeAt(0).parentN odeIndex);
171
172 // Check that the range records have the right offsets.
173 ASSERT_EQ(3u, tree.rangeRecordCount());
174 EXPECT_EQ(RangeRecord(0, 1, 0, FloatSize()), tree.rangeRecordAt(0));
175 EXPECT_EQ(RangeRecord(2, 3, 0, offset1), tree.rangeRecordAt(1));
176 EXPECT_EQ(RangeRecord(4, 5, 0, offset1 + offset2), tree.rangeRecordAt(2));
177 }
178
179 TEST_F(DisplayItemTransformTreeBuilderTest, ZTranslation)
180 {
181 TransformationMatrix zTranslation;
182 zTranslation.translate3d(0, 0, 1);
183
184 // Z translation: we expect another node.
185 processDummyDisplayItem();
186 auto transformClient = processBeginTransform3D(zTranslation);
187 processDummyDisplayItem();
188 processEndTransform3D(transformClient);
189 processDummyDisplayItem();
190 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
191
192 // There should be two nodes here.
193 ASSERT_EQ(2u, tree.nodeCount());
194 EXPECT_TRUE(tree.nodeAt(0).isRoot());
195 EXPECT_EQ(0u, tree.nodeAt(1).parentNodeIndex);
196
197 // There should be three range records.
198 // The middle of these should be transformed, and the others should be
199 // attached to the root node.
200 ASSERT_EQ(3u, tree.rangeRecordCount());
201 EXPECT_EQ(RangeRecord(0, 1, 0), tree.rangeRecordAt(0));
202 EXPECT_EQ(RangeRecord(2, 3, 1), tree.rangeRecordAt(1));
203 EXPECT_EQ(RangeRecord(4, 5, 0), tree.rangeRecordAt(2));
204 }
205
206 size_t nodeDepth(
207 const WebDisplayItemTransformTree& tree,
208 const WebDisplayItemTransformTree::TransformNode& node)
209 {
210 const auto* currentNode = &node;
211 size_t depth = 0;
212 while (!currentNode->isRoot()) {
213 currentNode = &tree.parentNode(*currentNode);
214 depth++;
215 }
216 return depth;
217 }
218
219 TEST_F(DisplayItemTransformTreeBuilderTest, SkipUnnecessaryRangeRecords)
220 {
221 TransformationMatrix rotation;
222 rotation.rotate(1 /* degrees */);
223
224 // The only drawing is in the second transform.
225 auto transform1 = processBeginTransform3D(rotation);
226 auto transform2 = processBeginTransform3D(rotation);
227 processDummyDisplayItem();
228 auto transform3 = processBeginTransform3D(rotation);
229 processEndTransform3D(transform3);
230 processDummyDisplayItem();
231 processEndTransform3D(transform2);
232 processEndTransform3D(transform1);
233 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
234
235 // There should be only two ranges.
236 // They must both belong to the same grandchild of the root node.
237 ASSERT_EQ(2u, tree.rangeRecordCount());
238 size_t transformNodeIndex = tree.rangeRecordAt(0).transformNodeIndex;
239 EXPECT_EQ(2u, nodeDepth(tree, tree.nodeAt(transformNodeIndex)));
240 EXPECT_EQ(RangeRecord(2, 3, transformNodeIndex), tree.rangeRecordAt(0));
241 EXPECT_EQ(RangeRecord(5, 6, transformNodeIndex), tree.rangeRecordAt(1));
242 }
243
244 TEST_F(DisplayItemTransformTreeBuilderTest, RootTransformNodeHasIdentityTransfor m)
245 {
246 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
247 ASSERT_EQ(1u, tree.nodeCount());
248 EXPECT_TRUE(tree.nodeAt(0).matrix.isIdentity());
249 EXPECT_TRANSFORMS_ALMOST_EQ(TransformationMatrix(), tree.nodeAt(0).matrix);
250 }
251
252 TEST_F(DisplayItemTransformTreeBuilderTest, Transform3DMatrix)
253 {
254 TransformationMatrix matrix;
255 matrix.rotate3d(45, 45, 45);
256
257 auto transform1 = processBeginTransform3D(matrix);
258 processDummyDisplayItem();
259 processEndTransform3D(transform1);
260 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
261
262 const auto& rangeRecord = tree.rangeRecordAt(0);
263 const auto& transformNode = tree.nodeAt(rangeRecord.transformNodeIndex);
264 EXPECT_TRANSFORMS_ALMOST_EQ(matrix, transformNode.matrix);
265 }
266
267 TEST_F(DisplayItemTransformTreeBuilderTest, NestedTransformsAreNotCombined)
268 {
269 // It's up the consumer of the tree to multiply transformation matrices.
270
271 TransformationMatrix matrix1;
272 matrix1.rotate3d(45, 45, 45);
273 TransformationMatrix matrix2;
274 matrix2.translate3d(0, 10, 20);
275 EXPECT_NE(matrix2, matrix1 * matrix2);
276
277 auto transform1 = processBeginTransform3D(matrix1);
278 auto transform2 = processBeginTransform3D(matrix2);
279 processDummyDisplayItem();
280 processEndTransform3D(transform2);
281 processDummyDisplayItem();
282 processEndTransform3D(transform1);
283 WebDisplayItemTransformTree tree(builder().releaseTransformTree());
284
285 const auto& transformNode = tree.nodeAt(tree.rangeRecordAt(0).transformNodeI ndex);
286 ASSERT_FALSE(transformNode.isRoot());
287 EXPECT_TRANSFORMS_ALMOST_EQ(matrix2, transformNode.matrix);
288 EXPECT_TRANSFORMS_ALMOST_EQ(matrix1, tree.parentNode(transformNode).matrix);
289 }
290
291 } // namespace
292 } // namespace blink
OLDNEW
« no previous file with comments | « Source/platform/graphics/paint/DisplayItemTransformTreeBuilder.cpp ('k') | public/BUILD.gn » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698