blob: 9b4a5f348b02599331f6edd3ac2c01950ffaa19c [file] [log] [blame]
Xianzhu Wang66e13e02019-09-18 20:39:121// Copyright 2011 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/trees/property_tree_builder.h"
6
7#include "cc/animation/keyframed_animation_curve.h"
8#include "cc/layers/layer.h"
9#include "cc/layers/layer_impl.h"
10#include "cc/layers/picture_layer.h"
11#include "cc/layers/render_surface_impl.h"
12#include "cc/layers/texture_layer.h"
13#include "cc/test/animation_test_common.h"
14#include "cc/test/fake_content_layer_client.h"
15#include "cc/test/layer_tree_impl_test_base.h"
16#include "testing/gtest/include/gtest/gtest.h"
17#include "ui/gfx/geometry/size_conversions.h"
18#include "ui/gfx/geometry/vector2d_conversions.h"
19#include "ui/gfx/transform.h"
20
21namespace cc {
22namespace {
23
24class PropertyTreeBuilderTest : public LayerTreeImplTestBase,
25 public testing::Test {
26 public:
27 PropertyTreeBuilderTest() : LayerTreeImplTestBase(LayerTreeSettings()) {}
28
29 void UpdateMainDrawProperties(float device_scale_factor = 1.0f) {
30 SetDeviceScaleAndUpdateViewportRect(host(), device_scale_factor);
31 UpdateDrawProperties(host());
32 }
33
34 LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) {
35 return layer ? host_impl()->active_tree()->LayerById(layer->id()) : nullptr;
36 }
37 RenderSurfaceImpl* GetRenderSurfaceImpl(const scoped_refptr<Layer>& layer) {
38 return GetRenderSurface(ImplOf(layer));
39 }
40
41 // Updates main thread draw properties, commits main thread tree to
42 // impl-side pending tree, and updates pending tree draw properties.
43 void Commit(float device_scale_factor = 1.0f) {
44 UpdateMainDrawProperties(device_scale_factor);
45 if (!host_impl()->pending_tree())
46 host_impl()->CreatePendingTree();
47 host()->CommitAndCreatePendingTree();
48 // TODO(https://crbug.com/939968) This call should be handled by
49 // FakeLayerTreeHost instead of manually pushing the properties from the
50 // layer tree host to the pending tree.
51 host()->PushLayerTreePropertiesTo(host_impl()->pending_tree());
52
53 UpdateDrawProperties(host_impl()->pending_tree());
54 }
55
56 // Calls Commit(), then activates the pending tree, and updates active tree
57 // draw properties.
58 void CommitAndActivate(float device_scale_factor = 1.0f) {
59 Commit(device_scale_factor);
60 host_impl()->ActivateSyncTree();
61 DCHECK_EQ(device_scale_factor,
62 host_impl()->active_tree()->device_scale_factor());
63 UpdateActiveTreeDrawProperties(device_scale_factor);
64 }
65
66 const RenderSurfaceList& GetRenderSurfaceList() {
67 return host_impl()->active_tree()->GetRenderSurfaceList();
68 }
69};
70
71TEST_F(PropertyTreeBuilderTest, EffectTreeTransformIdTest) {
72 // Tests that effect tree node gets a valid transform id when a layer
73 // has opacity but doesn't create a render surface.
74 auto parent = Layer::Create();
75 host()->SetRootLayer(parent);
76 auto child = Layer::Create();
77 parent->AddChild(child);
78 child->SetIsDrawable(true);
79
80 parent->SetBounds(gfx::Size(100, 100));
81 child->SetPosition(gfx::PointF(10, 10));
82 child->SetBounds(gfx::Size(100, 100));
83 child->SetOpacity(0.f);
84 UpdateMainDrawProperties();
85 EffectNode* node = GetEffectNode(child.get());
86 const int transform_tree_size =
87 GetPropertyTrees(parent.get())->transform_tree.next_available_id();
88 EXPECT_LT(node->transform_id, transform_tree_size);
89}
90
Xianzhu Wang66e13e02019-09-18 20:39:1291TEST_F(PropertyTreeBuilderTest, RenderSurfaceForNonAxisAlignedClipping) {
92 auto root = Layer::Create();
93 host()->SetRootLayer(root);
94 auto rotated_and_transparent = Layer::Create();
95 root->AddChild(rotated_and_transparent);
96 auto clips_subtree = Layer::Create();
97 rotated_and_transparent->AddChild(clips_subtree);
98 auto draws_content = Layer::Create();
99 clips_subtree->AddChild(draws_content);
100
101 root->SetBounds(gfx::Size(10, 10));
102 rotated_and_transparent->SetBounds(gfx::Size(10, 10));
103 rotated_and_transparent->SetOpacity(0.5f);
104 gfx::Transform rotate;
105 rotate.Rotate(2);
106 rotated_and_transparent->SetTransform(rotate);
107 clips_subtree->SetBounds(gfx::Size(10, 10));
108 clips_subtree->SetMasksToBounds(true);
109 draws_content->SetBounds(gfx::Size(10, 10));
110 draws_content->SetIsDrawable(true);
111
112 UpdateMainDrawProperties();
113 EXPECT_TRUE(GetEffectNode(clips_subtree.get())->HasRenderSurface());
114}
115
116TEST_F(PropertyTreeBuilderTest, EffectNodesForNonAxisAlignedClips) {
117 auto root = Layer::Create();
118 host()->SetRootLayer(root);
119 auto rotate_and_clip = Layer::Create();
120 root->AddChild(rotate_and_clip);
121 auto only_clip = Layer::Create();
122 rotate_and_clip->AddChild(only_clip);
123 auto rotate_and_clip2 = Layer::Create();
124 only_clip->AddChild(rotate_and_clip2);
125
126 gfx::Transform rotate;
127 rotate.Rotate(2);
128 root->SetBounds(gfx::Size(10, 10));
129 rotate_and_clip->SetBounds(gfx::Size(10, 10));
130 rotate_and_clip->SetTransform(rotate);
131 rotate_and_clip->SetMasksToBounds(true);
132 only_clip->SetBounds(gfx::Size(10, 10));
133 only_clip->SetMasksToBounds(true);
134 rotate_and_clip2->SetBounds(gfx::Size(10, 10));
135 rotate_and_clip2->SetTransform(rotate);
136 rotate_and_clip2->SetMasksToBounds(true);
137
138 UpdateMainDrawProperties();
139 // non-axis aligned clip should create an effect node
140 EXPECT_NE(root->effect_tree_index(), rotate_and_clip->effect_tree_index());
141 // Since only_clip's clip is in the same non-axis aligned space as
142 // rotate_and_clip's clip, no new effect node should be created.
143 EXPECT_EQ(rotate_and_clip->effect_tree_index(),
144 only_clip->effect_tree_index());
145 // rotate_and_clip2's clip and only_clip's clip are in different non-axis
146 // aligned spaces. So, new effect node should be created.
147 EXPECT_NE(rotate_and_clip2->effect_tree_index(),
148 only_clip->effect_tree_index());
149}
150
151TEST_F(PropertyTreeBuilderTest,
152 RenderSurfaceListForRenderSurfaceWithClippedLayer) {
153 auto root = Layer::Create();
154 host()->SetRootLayer(root);
155 auto render_surface1 = Layer::Create();
156 root->AddChild(render_surface1);
157 auto child = Layer::Create();
158 render_surface1->AddChild(child);
159
160 root->SetBounds(gfx::Size(10, 10));
161 root->SetMasksToBounds(true);
162 render_surface1->SetBounds(gfx::Size(10, 10));
163 render_surface1->SetForceRenderSurfaceForTesting(true);
164 child->SetIsDrawable(true);
165 child->SetPosition(gfx::PointF(30.f, 30.f));
166 child->SetBounds(gfx::Size(10, 10));
167
168 CommitAndActivate();
169
170 // The child layer's content is entirely outside the root's clip rect, so
171 // the intermediate render surface should not be listed here, even if it was
172 // forced to be created. Render surfaces without children or visible content
173 // are unexpected at draw time (e.g. we might try to create a content texture
174 // of size 0).
175 ASSERT_TRUE(GetRenderSurfaceImpl(root));
176 EXPECT_EQ(1U, GetRenderSurfaceList().size());
177}
178
179TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForTransparentChild) {
180 auto root = Layer::Create();
181 host()->SetRootLayer(root);
182 auto render_surface1 = Layer::Create();
183 root->AddChild(render_surface1);
184 auto child = Layer::Create();
185 render_surface1->AddChild(child);
186
187 root->SetBounds(gfx::Size(10, 10));
188 render_surface1->SetBounds(gfx::Size(10, 10));
189 render_surface1->SetForceRenderSurfaceForTesting(true);
190 render_surface1->SetOpacity(0.f);
191 child->SetBounds(gfx::Size(10, 10));
192 child->SetIsDrawable(true);
193
194 CommitAndActivate();
195
196 // Since the layer is transparent, render_surface1_impl->GetRenderSurface()
197 // should not have gotten added anywhere. Also, the drawable content rect
198 // should not have been extended by the children.
199 ASSERT_TRUE(GetRenderSurfaceImpl(root));
200 EXPECT_EQ(0, GetRenderSurfaceImpl(root)->num_contributors());
201 EXPECT_EQ(1U, GetRenderSurfaceList().size());
202 EXPECT_EQ(static_cast<viz::RenderPassId>(root->id()),
203 GetRenderSurfaceList().at(0)->id());
204 EXPECT_EQ(gfx::Rect(), ImplOf(root)->drawable_content_rect());
205}
206
207TEST_F(PropertyTreeBuilderTest,
208 RenderSurfaceListForTransparentChildWithBackdropFilter) {
209 auto root = Layer::Create();
210 host()->SetRootLayer(root);
211 auto render_surface1 = Layer::Create();
212 root->AddChild(render_surface1);
213 auto child = Layer::Create();
214 render_surface1->AddChild(child);
215
216 root->SetBounds(gfx::Size(10, 10));
217 render_surface1->SetBounds(gfx::Size(10, 10));
218 render_surface1->SetForceRenderSurfaceForTesting(true);
219 render_surface1->SetOpacity(0.f);
220 render_surface1->SetIsDrawable(true);
221 FilterOperations filters;
222 filters.Append(FilterOperation::CreateBlurFilter(1.5f));
223 render_surface1->SetBackdropFilters(filters);
224 child->SetBounds(gfx::Size(10, 10));
225 child->SetIsDrawable(true);
226 host()->SetElementIdsForTesting();
227
228 CommitAndActivate();
229 EXPECT_EQ(2U, GetRenderSurfaceList().size());
230
231 // The layer is fully transparent, but has a backdrop filter, so it
232 // shouldn't be skipped and should be drawn.
233 ASSERT_TRUE(GetRenderSurfaceImpl(root));
234 EXPECT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors());
235 EXPECT_EQ(gfx::RectF(0, 0, 10, 10),
236 GetRenderSurfaceImpl(root)->DrawableContentRect());
237 EXPECT_TRUE(GetEffectNode(ImplOf(render_surface1))->is_drawn);
238
239 // When root is transparent, the layer should not be drawn.
240 host_impl()->active_tree()->SetOpacityMutated(root->element_id(), 0.f);
241 host_impl()->active_tree()->SetOpacityMutated(render_surface1->element_id(),
242 1.f);
243 ImplOf(render_surface1)->set_visible_layer_rect(gfx::Rect());
244 UpdateActiveTreeDrawProperties();
245
246 EXPECT_FALSE(GetEffectNode(ImplOf(render_surface1))->is_drawn);
247 EXPECT_EQ(gfx::Rect(), ImplOf(render_surface1)->visible_layer_rect());
248}
249
250TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForFilter) {
251 auto root = Layer::Create();
252 host()->SetRootLayer(root);
253 auto parent = Layer::Create();
254 root->AddChild(parent);
255 auto child1 = Layer::Create();
256 parent->AddChild(child1);
257 auto child2 = Layer::Create();
258 parent->AddChild(child2);
259
260 gfx::Transform scale_matrix;
261 scale_matrix.Scale(2.0f, 2.0f);
262
263 root->SetBounds(gfx::Size(100, 100));
264 parent->SetTransform(scale_matrix);
265 FilterOperations filters;
266 filters.Append(FilterOperation::CreateBlurFilter(10.0f));
267 parent->SetFilters(filters);
268 parent->SetForceRenderSurfaceForTesting(true);
269 child1->SetBounds(gfx::Size(25, 25));
270 child1->SetIsDrawable(true);
271 child1->SetForceRenderSurfaceForTesting(true);
272 child2->SetPosition(gfx::PointF(25, 25));
273 child2->SetBounds(gfx::Size(25, 25));
274 child2->SetIsDrawable(true);
275 child2->SetForceRenderSurfaceForTesting(true);
276
277 CommitAndActivate();
278
279 ASSERT_TRUE(GetRenderSurfaceImpl(parent));
280 EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors());
281 EXPECT_EQ(4U, GetRenderSurfaceList().size());
282
283 // The rectangle enclosing child1 and child2 (0,0 50x50), expanded for the
284 // blur (-30,-30 110x110), and then scaled by the scale matrix
285 // (-60,-60 220x220).
286 EXPECT_EQ(gfx::RectF(-60, -60, 220, 220),
287 GetRenderSurfaceImpl(parent)->DrawableContentRect());
288}
289
290TEST_F(PropertyTreeBuilderTest, ForceRenderSurface) {
291 auto root = Layer::Create();
292 host()->SetRootLayer(root);
293 auto render_surface1 = Layer::Create();
294 root->AddChild(render_surface1);
295 auto child = Layer::Create();
296 render_surface1->AddChild(child);
297
298 root->SetBounds(gfx::Size(10, 10));
299 render_surface1->SetBounds(gfx::Size(10, 10));
300 render_surface1->SetForceRenderSurfaceForTesting(true);
301 child->SetBounds(gfx::Size(10, 10));
302 child->SetIsDrawable(true);
303
304 CommitAndActivate();
305
306 // The root layer always creates a render surface
307 EXPECT_TRUE(GetRenderSurfaceImpl(root));
308 EXPECT_NE(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root));
309
310 render_surface1->SetForceRenderSurfaceForTesting(false);
311 CommitAndActivate();
312
313 EXPECT_TRUE(GetRenderSurfaceImpl(root));
314 EXPECT_EQ(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root));
315}
316
Xianzhu Wang66e13e02019-09-18 20:39:12317TEST_F(PropertyTreeBuilderTest, VisibleRectWithClippingAndFilters) {
318 auto root = Layer::Create();
319 host()->SetRootLayer(root);
320 auto clip = Layer::Create();
321 root->AddChild(clip);
322 auto filter = Layer::Create();
323 clip->AddChild(filter);
324 auto filter_child = Layer::Create();
325 filter->AddChild(filter_child);
326
327 root->SetBounds(gfx::Size(100, 100));
328 clip->SetBounds(gfx::Size(10, 10));
329 filter->SetForceRenderSurfaceForTesting(true);
330 filter_child->SetBounds(gfx::Size(2000, 2000));
331 filter_child->SetPosition(gfx::PointF(-50, -50));
332 filter_child->SetIsDrawable(true);
333
334 clip->SetMasksToBounds(true);
335
336 CommitAndActivate();
337
338 EXPECT_EQ(gfx::Rect(50, 50, 10, 10),
339 ImplOf(filter_child)->visible_layer_rect());
340 EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurfaceImpl(filter)->content_rect());
341
342 FilterOperations blur_filter;
343 blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f));
344 filter->SetFilters(blur_filter);
345
346 CommitAndActivate();
347
348 EXPECT_EQ(gfx::Rect(38, 38, 34, 34),
349 ImplOf(filter_child)->visible_layer_rect());
350 EXPECT_EQ(gfx::Rect(-12, -12, 34, 34),
351 GetRenderSurfaceImpl(filter)->content_rect());
352
353 gfx::Transform vertical_flip;
354 vertical_flip.Scale(1, -1);
355 sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>(
356 vertical_flip.matrix(), kLow_SkFilterQuality, nullptr);
357 FilterOperations reflection_filter;
358 reflection_filter.Append(
359 FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>(
360 SkBlendMode::kSrcOver, std::move(flip_filter), nullptr)));
361 filter->SetFilters(reflection_filter);
362
363 CommitAndActivate();
364
365 EXPECT_EQ(gfx::Rect(49, 39, 12, 21),
366 ImplOf(filter_child)->visible_layer_rect());
367 EXPECT_EQ(gfx::Rect(-1, -11, 12, 21),
368 GetRenderSurfaceImpl(filter)->content_rect());
369}
370
371TEST_F(PropertyTreeBuilderTest, VisibleRectWithScalingClippingAndFilters) {
372 auto root = Layer::Create();
373 host()->SetRootLayer(root);
374 auto scale = Layer::Create();
375 root->AddChild(scale);
376 auto clip = Layer::Create();
377 scale->AddChild(clip);
378 auto filter = Layer::Create();
379 clip->AddChild(filter);
380 auto filter_child = Layer::Create();
381 filter->AddChild(filter_child);
382
383 root->SetBounds(gfx::Size(100, 100));
384 clip->SetBounds(gfx::Size(10, 10));
385 filter->SetForceRenderSurfaceForTesting(true);
386 filter_child->SetBounds(gfx::Size(2000, 2000));
387 filter_child->SetPosition(gfx::PointF(-50, -50));
388 filter_child->SetIsDrawable(true);
389
390 clip->SetMasksToBounds(true);
391
392 gfx::Transform scale_transform;
393 scale_transform.Scale(3, 3);
394 scale->SetTransform(scale_transform);
395
396 CommitAndActivate();
397
398 EXPECT_EQ(gfx::Rect(50, 50, 10, 10),
399 ImplOf(filter_child)->visible_layer_rect());
400 EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurfaceImpl(filter)->content_rect());
401
402 FilterOperations blur_filter;
403 blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f));
404 filter->SetFilters(blur_filter);
405
406 CommitAndActivate();
407
408 EXPECT_EQ(gfx::Rect(38, 38, 34, 34),
409 ImplOf(filter_child)->visible_layer_rect());
410 EXPECT_EQ(gfx::Rect(-36, -36, 102, 102),
411 GetRenderSurfaceImpl(filter)->content_rect());
412
413 gfx::Transform vertical_flip;
414 vertical_flip.Scale(1, -1);
415 sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>(
416 vertical_flip.matrix(), kLow_SkFilterQuality, nullptr);
417 FilterOperations reflection_filter;
418 reflection_filter.Append(
419 FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>(
420 SkBlendMode::kSrcOver, std::move(flip_filter), nullptr)));
421 filter->SetFilters(reflection_filter);
422
423 CommitAndActivate();
424
425 EXPECT_EQ(gfx::Rect(49, 39, 12, 21),
426 ImplOf(filter_child)->visible_layer_rect());
427 EXPECT_EQ(gfx::Rect(-1, -31, 32, 61),
428 GetRenderSurfaceImpl(filter)->content_rect());
429}
430
431TEST_F(PropertyTreeBuilderTest, TextureLayerSnapping) {
432 auto root = Layer::Create();
433 host()->SetRootLayer(root);
434 auto child = TextureLayer::CreateForMailbox(nullptr);
435 root->AddChild(child);
436
437 root->SetBounds(gfx::Size(100, 100));
438 child->SetBounds(gfx::Size(100, 100));
439 child->SetIsDrawable(true);
440 gfx::Transform fractional_translate;
441 fractional_translate.Translate(10.5f, 20.3f);
442 child->SetTransform(fractional_translate);
443
444 CommitAndActivate();
445
446 auto child_screen_space_transform = ImplOf(child)->ScreenSpaceTransform();
447 EXPECT_NE(child_screen_space_transform, fractional_translate);
448 fractional_translate.RoundTranslationComponents();
449 EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform,
450 fractional_translate);
451 gfx::RectF layer_bounds_in_screen_space = MathUtil::MapClippedRect(
452 child_screen_space_transform, gfx::RectF(gfx::SizeF(child->bounds())));
453 EXPECT_EQ(layer_bounds_in_screen_space, gfx::RectF(11.f, 20.f, 100.f, 100.f));
454}
455
456// Verify the behavior of back-face culling when there are no preserve-3d
457// layers. Note that 3d transforms still apply in this case, but they are
458// "flattened" to each parent layer according to current W3C spec.
459TEST_F(PropertyTreeBuilderTest, BackFaceCullingWithoutPreserves3d) {
460 auto root = Layer::Create();
461 host()->SetRootLayer(root);
462 auto front_facing_child = Layer::Create();
463 root->AddChild(front_facing_child);
464 auto back_facing_child = Layer::Create();
465 root->AddChild(back_facing_child);
466 auto front_facing_surface = Layer::Create();
467 root->AddChild(front_facing_surface);
468 auto back_facing_surface = Layer::Create();
469 root->AddChild(back_facing_surface);
470 auto front_facing_child_of_front_facing_surface = Layer::Create();
471 front_facing_surface->AddChild(front_facing_child_of_front_facing_surface);
472 auto back_facing_child_of_front_facing_surface = Layer::Create();
473 front_facing_surface->AddChild(back_facing_child_of_front_facing_surface);
474 auto front_facing_child_of_back_facing_surface = Layer::Create();
475 back_facing_surface->AddChild(front_facing_child_of_back_facing_surface);
476 auto back_facing_child_of_back_facing_surface = Layer::Create();
477 back_facing_surface->AddChild(back_facing_child_of_back_facing_surface);
478
479 // Nothing is double-sided
480 front_facing_child->SetDoubleSided(false);
481 back_facing_child->SetDoubleSided(false);
482 front_facing_surface->SetDoubleSided(false);
483 back_facing_surface->SetDoubleSided(false);
484 front_facing_child_of_front_facing_surface->SetDoubleSided(false);
485 back_facing_child_of_front_facing_surface->SetDoubleSided(false);
486 front_facing_child_of_back_facing_surface->SetDoubleSided(false);
487 back_facing_child_of_back_facing_surface->SetDoubleSided(false);
488
489 // Everything draws content.
490 front_facing_child->SetIsDrawable(true);
491 back_facing_child->SetIsDrawable(true);
492 front_facing_surface->SetIsDrawable(true);
493 back_facing_surface->SetIsDrawable(true);
494 front_facing_child_of_front_facing_surface->SetIsDrawable(true);
495 back_facing_child_of_front_facing_surface->SetIsDrawable(true);
496 front_facing_child_of_back_facing_surface->SetIsDrawable(true);
497 back_facing_child_of_back_facing_surface->SetIsDrawable(true);
498
499 gfx::Transform backface_matrix;
500 backface_matrix.Translate(50.0, 50.0);
501 backface_matrix.RotateAboutYAxis(180.0);
502 backface_matrix.Translate(-50.0, -50.0);
503
504 root->SetBounds(gfx::Size(100, 100));
505 front_facing_child->SetBounds(gfx::Size(100, 100));
506 back_facing_child->SetBounds(gfx::Size(100, 100));
507 front_facing_surface->SetBounds(gfx::Size(100, 100));
508 back_facing_surface->SetBounds(gfx::Size(100, 100));
509 front_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100));
510 back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100));
511 front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100));
512 back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100));
513
514 front_facing_surface->SetForceRenderSurfaceForTesting(true);
515 back_facing_surface->SetForceRenderSurfaceForTesting(true);
516
517 back_facing_child->SetTransform(backface_matrix);
518 back_facing_surface->SetTransform(backface_matrix);
519 back_facing_child_of_front_facing_surface->SetTransform(backface_matrix);
520 back_facing_child_of_back_facing_surface->SetTransform(backface_matrix);
521
522 // Note: No layers preserve 3d. According to current W3C CSS gfx::Transforms
523 // spec, these layers should blindly use their own local transforms to
524 // determine back-face culling.
525 CommitAndActivate();
526
527 // Verify which render surfaces were created.
528 EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child),
529 GetRenderSurfaceImpl(root));
530 EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child),
531 GetRenderSurfaceImpl(root));
532 EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface),
533 GetRenderSurfaceImpl(root));
534 EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface),
535 GetRenderSurfaceImpl(root));
536 EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface),
537 GetRenderSurfaceImpl(front_facing_surface));
538 EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface),
539 GetRenderSurfaceImpl(front_facing_surface));
540 EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface),
541 GetRenderSurfaceImpl(front_facing_surface));
542 EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface),
543 GetRenderSurfaceImpl(back_facing_surface));
544 EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface),
545 GetRenderSurfaceImpl(back_facing_surface));
546
547 EXPECT_EQ(3u, update_layer_impl_list().size());
548 EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id()));
549 EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id()));
550 EXPECT_TRUE(UpdateLayerImplListContains(
551 front_facing_child_of_front_facing_surface->id()));
552}
553
Xianzhu Wang66e13e02019-09-18 20:39:12554// Verify that layers are appropriately culled when their back face is showing
555// and they are not double sided, while animations are going on.
556// Even layers that are animating get culled if their back face is showing and
557// they are not double sided.
558TEST_F(PropertyTreeBuilderTest, BackFaceCullingWithAnimatingTransforms) {
559 auto root = Layer::Create();
560 host()->SetRootLayer(root);
561 auto child = Layer::Create();
562 root->AddChild(child);
563 auto animating_surface = Layer::Create();
564 root->AddChild(animating_surface);
565 auto child_of_animating_surface = Layer::Create();
566 animating_surface->AddChild(child_of_animating_surface);
567 auto animating_child = Layer::Create();
568 root->AddChild(animating_child);
569 auto child2 = Layer::Create();
570 root->AddChild(child2);
571
572 // Nothing is double-sided
573 child->SetDoubleSided(false);
574 child2->SetDoubleSided(false);
575 animating_surface->SetDoubleSided(false);
576 child_of_animating_surface->SetDoubleSided(false);
577 animating_child->SetDoubleSided(false);
578
579 // Everything draws content.
580 child->SetIsDrawable(true);
581 child2->SetIsDrawable(true);
582 animating_surface->SetIsDrawable(true);
583 child_of_animating_surface->SetIsDrawable(true);
584 animating_child->SetIsDrawable(true);
585
586 gfx::Transform backface_matrix;
587 backface_matrix.Translate(50.0, 50.0);
588 backface_matrix.RotateAboutYAxis(180.0);
589 backface_matrix.Translate(-50.0, -50.0);
590
591 host()->SetElementIdsForTesting();
592
593 // Animate the transform on the render surface.
594 AddAnimatedTransformToElementWithAnimation(animating_surface->element_id(),
595 timeline(), 10.0, 30, 0);
596 // This is just an animating layer, not a surface.
597 AddAnimatedTransformToElementWithAnimation(animating_child->element_id(),
598 timeline(), 10.0, 30, 0);
599
600 root->SetBounds(gfx::Size(100, 100));
601 child->SetBounds(gfx::Size(100, 100));
602 child->SetTransform(backface_matrix);
603 animating_surface->SetBounds(gfx::Size(100, 100));
604 animating_surface->SetTransform(backface_matrix);
605 animating_surface->SetForceRenderSurfaceForTesting(true);
606 child_of_animating_surface->SetBounds(gfx::Size(100, 100));
607 child_of_animating_surface->SetTransform(backface_matrix);
608 animating_child->SetBounds(gfx::Size(100, 100));
609 animating_child->SetTransform(backface_matrix);
610 child2->SetBounds(gfx::Size(100, 100));
611
612 CommitAndActivate();
613
614 EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root));
615 EXPECT_TRUE(GetRenderSurfaceImpl(animating_surface));
616 EXPECT_EQ(GetRenderSurfaceImpl(child_of_animating_surface),
617 GetRenderSurfaceImpl(animating_surface));
618 EXPECT_EQ(GetRenderSurfaceImpl(animating_child), GetRenderSurfaceImpl(root));
619 EXPECT_EQ(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root));
620
621 EXPECT_EQ(1u, update_layer_impl_list().size());
622
623 // The back facing layers are culled from the layer list, and have an empty
624 // visible rect.
625 EXPECT_TRUE(UpdateLayerImplListContains(child2->id()));
626 EXPECT_TRUE(ImplOf(child)->visible_layer_rect().IsEmpty());
627 EXPECT_TRUE(ImplOf(animating_surface)->visible_layer_rect().IsEmpty());
628 EXPECT_TRUE(
629 ImplOf(child_of_animating_surface)->visible_layer_rect().IsEmpty());
630 EXPECT_TRUE(ImplOf(animating_child)->visible_layer_rect().IsEmpty());
631
632 EXPECT_EQ(gfx::Rect(100, 100), ImplOf(child2)->visible_layer_rect());
633}
634
Xianzhu Wang66e13e02019-09-18 20:39:12635// Verify that having animated opacity but current opacity 1 still creates
636// a render surface.
637TEST_F(PropertyTreeBuilderTest, AnimatedOpacityCreatesRenderSurface) {
638 auto root = Layer::Create();
639 host()->SetRootLayer(root);
640 auto child = Layer::Create();
641 root->AddChild(child);
642 auto grandchild = Layer::Create();
643 child->AddChild(grandchild);
644
645 root->SetBounds(gfx::Size(50, 50));
646 child->SetBounds(gfx::Size(50, 50));
647 child->SetIsDrawable(true);
648 grandchild->SetBounds(gfx::Size(50, 50));
649 grandchild->SetIsDrawable(true);
650
651 host()->SetElementIdsForTesting();
652 AddOpacityTransitionToElementWithAnimation(child->element_id(), timeline(),
653 10.0, 1.f, 0.2f, false);
654 CommitAndActivate();
655
656 EXPECT_EQ(1.f, ImplOf(child)->Opacity());
657 EXPECT_TRUE(GetRenderSurfaceImpl(root));
658 EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root));
659 EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child));
660}
661
662static bool FilterIsAnimating(LayerImpl* layer) {
663 MutatorHost* host = layer->layer_tree_impl()->mutator_host();
664 return host->IsAnimatingFilterProperty(layer->element_id(),
665 layer->GetElementTypeForAnimation());
666}
667
668// Verify that having an animated filter (but no current filter, as these
669// are mutually exclusive) correctly creates a render surface.
670TEST_F(PropertyTreeBuilderTest, AnimatedFilterCreatesRenderSurface) {
671 auto root = Layer::Create();
672 host()->SetRootLayer(root);
673 auto child = Layer::Create();
674 root->AddChild(child);
675 auto grandchild = Layer::Create();
676 child->AddChild(grandchild);
677
678 root->SetBounds(gfx::Size(50, 50));
679 child->SetBounds(gfx::Size(50, 50));
680 grandchild->SetBounds(gfx::Size(50, 50));
681
682 host()->SetElementIdsForTesting();
683 AddAnimatedFilterToElementWithAnimation(child->element_id(), timeline(), 10.0,
684 0.1f, 0.2f);
685 CommitAndActivate();
686
687 EXPECT_TRUE(GetRenderSurfaceImpl(root));
688 EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root));
689 EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child));
690
691 EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty());
692 EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty());
693
694 EXPECT_FALSE(FilterIsAnimating(ImplOf(root)));
695 EXPECT_TRUE(FilterIsAnimating(ImplOf(child)));
696 EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild)));
697}
698
699bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) {
700 MutatorHost* host = layer.layer_tree_impl()->mutator_host();
701 return host->HasPotentiallyRunningFilterAnimation(
702 layer.element_id(), layer.GetElementTypeForAnimation());
703}
704
705// Verify that having a filter animation with a delayed start time creates a
706// render surface.
707TEST_F(PropertyTreeBuilderTest, DelayedFilterAnimationCreatesRenderSurface) {
708 auto root = Layer::Create();
709 host()->SetRootLayer(root);
710 auto child = Layer::Create();
711 root->AddChild(child);
712 auto grandchild = Layer::Create();
713 child->AddChild(grandchild);
714
715 root->SetBounds(gfx::Size(50, 50));
716 child->SetBounds(gfx::Size(50, 50));
717 grandchild->SetBounds(gfx::Size(50, 50));
718
719 host()->SetElementIdsForTesting();
720
721 std::unique_ptr<KeyframedFilterAnimationCurve> curve(
722 KeyframedFilterAnimationCurve::Create());
723 FilterOperations start_filters;
724 start_filters.Append(FilterOperation::CreateBrightnessFilter(0.1f));
725 FilterOperations end_filters;
726 end_filters.Append(FilterOperation::CreateBrightnessFilter(0.3f));
727 curve->AddKeyframe(
728 FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr));
729 curve->AddKeyframe(FilterKeyframe::Create(
730 base::TimeDelta::FromMilliseconds(100), end_filters, nullptr));
731 std::unique_ptr<KeyframeModel> keyframe_model =
732 KeyframeModel::Create(std::move(curve), 0, 1, TargetProperty::FILTER);
733 keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
734 keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
735
736 AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(),
737 std::move(keyframe_model));
738 CommitAndActivate();
739
740 EXPECT_TRUE(GetRenderSurfaceImpl(root));
741 EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root));
742 EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child));
743
744 EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty());
745 EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty());
746
747 EXPECT_FALSE(FilterIsAnimating(ImplOf(root)));
748 EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(root)));
749 EXPECT_FALSE(FilterIsAnimating(ImplOf(child)));
750 EXPECT_TRUE(HasPotentiallyRunningFilterAnimation(*ImplOf(child)));
751 EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild)));
752 EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(grandchild)));
753}
754
755TEST_F(PropertyTreeBuilderTest, ChangingAxisAlignmentTriggersRebuild) {
756 gfx::Transform translate;
757 gfx::Transform rotate;
758
759 translate.Translate(10, 10);
760 rotate.Rotate(45);
761
762 scoped_refptr<Layer> root = Layer::Create();
763 root->SetBounds(gfx::Size(800, 800));
764
765 host()->SetRootLayer(root);
766
767 UpdateMainDrawProperties();
768 EXPECT_FALSE(host()->property_trees()->needs_rebuild);
769
770 root->SetTransform(translate);
771 EXPECT_FALSE(host()->property_trees()->needs_rebuild);
772
773 root->SetTransform(rotate);
774 EXPECT_TRUE(host()->property_trees()->needs_rebuild);
775}
776
777TEST_F(PropertyTreeBuilderTest, ResetPropertyTreeIndices) {
778 scoped_refptr<Layer> root = Layer::Create();
779 root->SetBounds(gfx::Size(800, 800));
780
781 gfx::Transform translate_z;
782 translate_z.Translate3d(0, 0, 10);
783
784 scoped_refptr<Layer> child = Layer::Create();
785 child->SetTransform(translate_z);
786 child->SetBounds(gfx::Size(100, 100));
787
788 root->AddChild(child);
789
790 host()->SetRootLayer(root);
791
792 UpdateMainDrawProperties();
793 EXPECT_NE(-1, child->transform_tree_index());
794
795 child->RemoveFromParent();
796
797 UpdateMainDrawProperties();
798 EXPECT_EQ(-1, child->transform_tree_index());
799}
800
801TEST_F(PropertyTreeBuilderTest, RenderSurfaceClipsSubtree) {
802 // Ensure that a Clip Node is added when a render surface applies clip.
803 auto root = Layer::Create();
804 host()->SetRootLayer(root);
805 auto significant_transform = Layer::Create();
806 root->AddChild(significant_transform);
807 auto layer_clips_subtree = Layer::Create();
808 significant_transform->AddChild(layer_clips_subtree);
809 auto render_surface = Layer::Create();
810 layer_clips_subtree->AddChild(render_surface);
811 auto test_layer = Layer::Create();
812 render_surface->AddChild(test_layer);
813
814 // This transform should be a significant one so that a transform node is
815 // formed for it.
816 gfx::Transform transform1;
817 transform1.RotateAboutYAxis(45);
818 transform1.RotateAboutXAxis(30);
819 // This transform should be a 3d transform as we want the render surface
820 // to flatten the transform
821 gfx::Transform transform2;
822 transform2.Translate3d(10, 10, 10);
823
824 root->SetBounds(gfx::Size(30, 30));
825 significant_transform->SetTransform(transform1);
826 significant_transform->SetBounds(gfx::Size(30, 30));
827 layer_clips_subtree->SetBounds(gfx::Size(30, 30));
828 layer_clips_subtree->SetMasksToBounds(true);
829 layer_clips_subtree->SetForceRenderSurfaceForTesting(true);
830 render_surface->SetTransform(transform2);
831 render_surface->SetBounds(gfx::Size(30, 30));
832 render_surface->SetForceRenderSurfaceForTesting(true);
833 test_layer->SetBounds(gfx::Size(30, 30));
834 test_layer->SetIsDrawable(true);
835
836 CommitAndActivate();
837
838 EXPECT_TRUE(GetRenderSurfaceImpl(root));
839 EXPECT_EQ(GetRenderSurfaceImpl(significant_transform),
840 GetRenderSurfaceImpl(root));
841 EXPECT_TRUE(GetRenderSurfaceImpl(layer_clips_subtree));
842 EXPECT_NE(GetRenderSurfaceImpl(render_surface), GetRenderSurfaceImpl(root));
843 EXPECT_EQ(GetRenderSurfaceImpl(test_layer),
844 GetRenderSurfaceImpl(render_surface));
845
846 EXPECT_EQ(gfx::Rect(30, 20), ImplOf(test_layer)->visible_layer_rect());
847}
848
849TEST_F(PropertyTreeBuilderTest, PropertyTreesRebuildWithOpacityChanges) {
850 scoped_refptr<Layer> root = Layer::Create();
851 scoped_refptr<Layer> child = Layer::Create();
852 child->SetIsDrawable(true);
853 root->AddChild(child);
854 host()->SetRootLayer(root);
855
856 root->SetBounds(gfx::Size(100, 100));
857 child->SetBounds(gfx::Size(20, 20));
858 UpdateMainDrawProperties();
859
860 // Changing the opacity from 1 to non-1 value should trigger rebuild of
861 // property trees as a new effect node will be created.
862 child->SetOpacity(0.5f);
863 PropertyTrees* property_trees = host()->property_trees();
864 EXPECT_TRUE(property_trees->needs_rebuild);
865
866 UpdateMainDrawProperties();
867 EXPECT_NE(child->effect_tree_index(), root->effect_tree_index());
868
869 // child already has an effect node. Changing its opacity shouldn't trigger
870 // a property trees rebuild.
871 child->SetOpacity(0.8f);
872 property_trees = host()->property_trees();
873 EXPECT_FALSE(property_trees->needs_rebuild);
874
875 UpdateMainDrawProperties();
876 EXPECT_NE(child->effect_tree_index(), root->effect_tree_index());
877
878 // Changing the opacity from non-1 value to 1 should trigger a rebuild of
879 // property trees as the effect node may no longer be needed.
880 child->SetOpacity(1.f);
881 property_trees = host()->property_trees();
882 EXPECT_TRUE(property_trees->needs_rebuild);
883
884 UpdateMainDrawProperties();
885 EXPECT_EQ(child->effect_tree_index(), root->effect_tree_index());
886}
887
888TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForTrilinearFiltering) {
889 auto root = Layer::Create();
890 host()->SetRootLayer(root);
891 auto parent = Layer::Create();
892 root->AddChild(parent);
893 auto child1 = Layer::Create();
894 parent->AddChild(child1);
895 auto child2 = Layer::Create();
896 parent->AddChild(child2);
897
898 gfx::Transform scale_matrix;
899 scale_matrix.Scale(.25f, .25f);
900
901 root->SetBounds(gfx::Size(200, 200));
902 parent->SetTransform(scale_matrix);
903 parent->SetTrilinearFiltering(true);
904 child1->SetBounds(gfx::Size(50, 50));
905 child1->SetIsDrawable(true);
906 child1->SetForceRenderSurfaceForTesting(true);
907 child2->SetPosition(gfx::PointF(50, 50));
908 child2->SetBounds(gfx::Size(50, 50));
909 child2->SetIsDrawable(true);
910 child2->SetForceRenderSurfaceForTesting(true);
911
912 CommitAndActivate();
913
914 ASSERT_TRUE(GetRenderSurfaceImpl(parent));
915 EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors());
916 EXPECT_EQ(4U, GetRenderSurfaceList().size());
917
918 // The rectangle enclosing child1 and child2 (0,0 100x100), scaled by the
919 // scale matrix to (0,0 25x25).
920 EXPECT_EQ(gfx::RectF(0, 0, 25, 25),
921 GetRenderSurfaceImpl(parent)->DrawableContentRect());
922}
923
924TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) {
925 // Layer Tree:
926 // +root
927 // +--render surface
928 // +----rounded corner layer 1 [should trigger render surface]
929 // +----layer 1
930 // +--rounded corner layer 2 [should trigger render surface]
931 // +----layer 2
932 // +------rounded corner layer 3 [should trigger render surface]
933 // +--------rounded corner layer 4 [should trigger render surface]
934
935 constexpr int kRoundedCorner1Radius = 2;
936 constexpr int kRoundedCorner2Radius = 5;
937 constexpr int kRoundedCorner3Radius = 1;
938 constexpr int kRoundedCorner4Radius = 1;
939
940 constexpr gfx::RectF kRoundedCornerLayer1Bound(15.f, 15.f, 20.f, 20.f);
941 constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f);
942 constexpr gfx::RectF kRoundedCornerLayer3Bound(0.f, 15.f, 5.f, 5.f);
943 constexpr gfx::RectF kRoundedCornerLayer4Bound(1.f, 1.f, 3.f, 3.f);
944
945 constexpr float kDeviceScale = 1.6f;
946
947 scoped_refptr<Layer> root = Layer::Create();
948 scoped_refptr<Layer> render_surface = Layer::Create();
949 scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create();
950 scoped_refptr<Layer> layer_1 = Layer::Create();
951 scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create();
952 scoped_refptr<Layer> layer_2 = Layer::Create();
953 scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create();
954 scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create();
955
956 // Set up layer tree
957 root->AddChild(render_surface);
958 root->AddChild(rounded_corner_layer_2);
959
960 render_surface->AddChild(rounded_corner_layer_1);
961 render_surface->AddChild(layer_1);
962
963 rounded_corner_layer_2->AddChild(layer_2);
964
965 layer_2->AddChild(rounded_corner_layer_3);
966
967 rounded_corner_layer_3->AddChild(rounded_corner_layer_4);
968
969 // Set the root layer on host.
970 host()->SetRootLayer(root);
971
972 // Set layer positions.
973 render_surface->SetPosition(gfx::PointF(0, 0));
974 rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin());
975 layer_1->SetPosition(gfx::PointF(10.f, 10.f));
976 rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin());
977 layer_2->SetPosition(gfx::PointF(30.f, 30.f));
978 rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin());
979 rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin());
980
981 // Set up layer bounds.
982 root->SetBounds(gfx::Size(100, 100));
983 render_surface->SetBounds(gfx::Size(50, 50));
984 rounded_corner_layer_1->SetBounds(
985 gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size()));
986 layer_1->SetBounds(gfx::Size(10, 10));
987 rounded_corner_layer_2->SetBounds(
988 gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size()));
989 layer_2->SetBounds(gfx::Size(25, 25));
990 rounded_corner_layer_3->SetBounds(
991 gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size()));
992 rounded_corner_layer_4->SetBounds(
993 gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size()));
994
995 // Add Layer transforms.
996 gfx::Transform layer_2_transform;
997 constexpr gfx::Vector2dF kLayer2Translation(10.f, 10.f);
998 layer_2_transform.Translate(kLayer2Translation);
999 layer_2->SetTransform(layer_2_transform);
1000
1001 gfx::Transform rounded_corner_layer_3_transform;
1002 constexpr float kRoundedCorner3Scale = 2.f;
1003 rounded_corner_layer_3_transform.Scale(kRoundedCorner3Scale,
1004 kRoundedCorner3Scale);
1005 rounded_corner_layer_3->SetTransform(rounded_corner_layer_3_transform);
1006
1007 // Set the layer properties
1008 render_surface->SetForceRenderSurfaceForTesting(true);
1009
1010 root->SetIsDrawable(true);
1011 render_surface->SetIsDrawable(true);
1012 rounded_corner_layer_1->SetIsDrawable(true);
1013 layer_1->SetIsDrawable(true);
1014 rounded_corner_layer_2->SetIsDrawable(true);
1015 layer_2->SetIsDrawable(true);
1016 rounded_corner_layer_3->SetIsDrawable(true);
1017 rounded_corner_layer_4->SetIsDrawable(true);
1018
1019 // Set Rounded corners
1020 rounded_corner_layer_1->SetRoundedCorner(
1021 {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius,
1022 kRoundedCorner1Radius});
1023 rounded_corner_layer_2->SetRoundedCorner(
1024 {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius,
1025 kRoundedCorner2Radius});
1026 rounded_corner_layer_3->SetRoundedCorner(
1027 {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius,
1028 kRoundedCorner3Radius});
1029 rounded_corner_layer_4->SetRoundedCorner(
1030 {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius,
1031 kRoundedCorner4Radius});
1032
1033 UpdateMainDrawProperties(kDeviceScale);
1034
1035 // Since this effect node has no descendants that draw and no descendant that
1036 // has a rounded corner, it does not need a render surface.
1037 const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
1038 gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
1039 EXPECT_FALSE(effect_node->HasRenderSurface());
1040 EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
1041 kRoundedCorner1Radius);
1042 EXPECT_EQ(rounded_corner_bounds_1.rect(),
1043 gfx::RectF(kRoundedCornerLayer1Bound.size()));
1044
1045 // Since this node has descendants with roudned corners, it needs a render
1046 // surface. It also has 2 descendants that draw.
1047 effect_node = GetEffectNode(rounded_corner_layer_2.get());
1048 gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
1049 EXPECT_TRUE(effect_node->HasRenderSurface());
1050 EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
1051 kRoundedCorner2Radius);
1052 EXPECT_EQ(rounded_corner_bounds_2.rect(),
1053 gfx::RectF(kRoundedCornerLayer2Bound.size()));
1054
1055 // Since this node has a descendant that has a rounded corner, it will trigger
1056 // the creation of a render surface.
1057 effect_node = GetEffectNode(rounded_corner_layer_3.get());
1058 gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
1059 EXPECT_TRUE(effect_node->HasRenderSurface());
1060 EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
1061 kRoundedCorner3Radius);
1062 EXPECT_EQ(rounded_corner_bounds_3.rect(),
1063 gfx::RectF(kRoundedCornerLayer3Bound.size()));
1064
1065 // Since this node has no descendants that draw nor any descendant that has a
1066 // rounded corner, it does not need a render surface.
1067 effect_node = GetEffectNode(rounded_corner_layer_4.get());
1068 gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
1069 EXPECT_FALSE(effect_node->HasRenderSurface());
1070 EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
1071 kRoundedCorner4Radius);
1072 EXPECT_EQ(rounded_corner_bounds_4.rect(),
1073 gfx::RectF(kRoundedCornerLayer4Bound.size()));
1074
1075 CommitAndActivate(kDeviceScale);
1076 LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
1077
1078 // Get the layer impl for each Layer.
1079 LayerImpl* rounded_corner_layer_1_impl =
1080 layer_tree_impl->LayerById(rounded_corner_layer_1->id());
1081 LayerImpl* rounded_corner_layer_2_impl =
1082 layer_tree_impl->LayerById(rounded_corner_layer_2->id());
1083 LayerImpl* rounded_corner_layer_3_impl =
1084 layer_tree_impl->LayerById(rounded_corner_layer_3->id());
1085 LayerImpl* rounded_corner_layer_4_impl =
1086 layer_tree_impl->LayerById(rounded_corner_layer_4->id());
1087
1088 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
1089
1090 // Rounded corner layer 1
1091 // The render target for this layer is |render_surface|, hence its target
1092 // bounds are relative to |render_surface|.
1093 // The offset from the origin of the render target is [15, 15] and the device
1094 // scale factor is 1.6 thus giving the target space origin of [24, 24]. The
1095 // corner radius is also scaled by a factor of 1.6.
1096 const gfx::RRectF actual_rrect_1 =
1097 rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds;
1098 gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
1099 bounds_in_target_space.Scale(kDeviceScale);
1100 EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space);
1101 EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(),
1102 kRoundedCorner1Radius * kDeviceScale);
1103
1104 // Rounded corner layer 2
1105 // The render target for this layer is |root|.
1106 // The offset from the origin of the render target is [40, 40] and the device
1107 // scale factor is 1.6 thus giving the target space origin of [64, 64]. The
1108 // corner radius is also scaled by a factor of 1.6.
1109 const gfx::RRectF actual_self_rrect_2 =
1110 rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds;
1111 EXPECT_TRUE(actual_self_rrect_2.IsEmpty());
1112
1113 bounds_in_target_space = kRoundedCornerLayer2Bound;
1114 bounds_in_target_space.Scale(kDeviceScale);
1115 const gfx::RRectF actual_render_target_rrect_2 =
1116 rounded_corner_layer_2_impl->render_target()->rounded_corner_bounds();
1117 EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space);
1118 EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(),
1119 kRoundedCorner2Radius * kDeviceScale);
1120
1121 // Rounded corner layer 3
1122 // The render target for this layer is |rounded_corner_2|.
1123 // The net offset from the origin of the render target is [40, 55] and the
1124 // device scale factor is 1.6 thus giving the target space origin of [64, 88].
1125 // The corner radius is also scaled by a factor of 1.6 * transform scale.
1126 const gfx::RRectF actual_self_rrect_3 =
1127 rounded_corner_layer_3_impl->draw_properties().rounded_corner_bounds;
1128 EXPECT_TRUE(actual_self_rrect_3.IsEmpty());
1129
1130 bounds_in_target_space = kRoundedCornerLayer3Bound;
1131 bounds_in_target_space +=
1132 layer_2->position().OffsetFromOrigin() + kLayer2Translation;
1133 bounds_in_target_space.Scale(kDeviceScale);
1134 gfx::SizeF transformed_size = bounds_in_target_space.size();
1135 transformed_size.Scale(kRoundedCorner3Scale);
1136 bounds_in_target_space.set_size(transformed_size);
1137
1138 const gfx::RRectF actual_render_target_rrect_3 =
1139 rounded_corner_layer_3_impl->render_target()->rounded_corner_bounds();
1140 EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space);
1141 EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(),
1142 kRoundedCorner3Radius * kDeviceScale * kRoundedCorner3Scale);
1143
1144 // Rounded corner layer 4
1145 // The render target for this layer is |rounded_corner_3|.
1146 // The net offset from the origin of the render target is [1, 1] and the
1147 // net scale is 1.6 * transform scale = 3.2 thus giving the target space o
1148 // rigin of [3.2, 3.2].
1149 // The corner radius is also scaled by a factor of 3.2.
1150 const gfx::RRectF actual_rrect_4 =
1151 rounded_corner_layer_4_impl->draw_properties().rounded_corner_bounds;
1152 bounds_in_target_space = kRoundedCornerLayer4Bound;
1153 bounds_in_target_space.Scale(kDeviceScale * kRoundedCorner3Scale);
1154 EXPECT_EQ(actual_rrect_4.rect(), bounds_in_target_space);
1155 EXPECT_FLOAT_EQ(actual_rrect_4.GetSimpleRadius(),
1156 kRoundedCorner4Radius * kDeviceScale * kRoundedCorner3Scale);
1157}
1158
1159TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsInterveningRenderTarget) {
1160 // Layer Tree:
1161 // +root
1162 // +--rounded corner layer 1 [should not trigger render surface]
1163 // +----render surface [Does not draw]
1164 // +------rounded corner layer 2 [should not trigger render surface]
1165
1166 constexpr int kRoundedCorner1Radius = 2;
1167 constexpr int kRoundedCorner2Radius = 5;
1168
1169 constexpr gfx::RectF kRoundedCornerLayer1Bound(60.f, 0.f, 40.f, 30.f);
1170 constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 30.f, 20.f);
1171
1172 constexpr float kDeviceScale = 1.6f;
1173
1174 scoped_refptr<Layer> root = Layer::Create();
1175 scoped_refptr<Layer> render_surface = Layer::Create();
1176 scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create();
1177 scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create();
1178
1179 // Set up layer tree
1180 root->AddChild(rounded_corner_layer_1);
1181 rounded_corner_layer_1->AddChild(render_surface);
1182 render_surface->AddChild(rounded_corner_layer_2);
1183
1184 // Set the root layer on host.
1185 host()->SetRootLayer(root);
1186
1187 // Set layer positions.
1188 rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin());
1189 render_surface->SetPosition(gfx::PointF(0, 0));
1190 rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin());
1191
1192 // Set up layer bounds.
1193 root->SetBounds(gfx::Size(100, 100));
1194 rounded_corner_layer_1->SetBounds(
1195 gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size()));
1196 render_surface->SetBounds(gfx::Size(30, 30));
1197 rounded_corner_layer_2->SetBounds(
1198 gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size()));
1199
1200 // Set the layer properties
1201 render_surface->SetForceRenderSurfaceForTesting(true);
1202
1203 root->SetIsDrawable(true);
1204 rounded_corner_layer_1->SetIsDrawable(true);
1205 rounded_corner_layer_2->SetIsDrawable(true);
1206
1207 // Set Rounded corners
1208 rounded_corner_layer_1->SetRoundedCorner(
1209 {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius,
1210 kRoundedCorner1Radius});
1211 rounded_corner_layer_2->SetRoundedCorner(
1212 {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius,
1213 kRoundedCorner2Radius});
1214
1215 UpdateMainDrawProperties(kDeviceScale);
1216
1217 // Since this effect node has only 1 descendant that draws and no descendant
1218 // that has a rounded corner before the render surface, it does not need a
1219 // render surface.
1220 const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
1221 gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
1222 EXPECT_FALSE(effect_node->HasRenderSurface());
1223 EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
1224 kRoundedCorner1Radius);
1225 EXPECT_EQ(rounded_corner_bounds_1.rect(),
1226 gfx::RectF(kRoundedCornerLayer1Bound.size()));
1227
1228 // Since this effect node has no descendants that draw and no descendant that
1229 // has a rounded corner, it does not need a render surface.
1230 effect_node = GetEffectNode(rounded_corner_layer_2.get());
1231 gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
1232 EXPECT_FALSE(effect_node->HasRenderSurface());
1233 EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
1234 kRoundedCorner2Radius);
1235 EXPECT_EQ(rounded_corner_bounds_2.rect(),
1236 gfx::RectF(kRoundedCornerLayer2Bound.size()));
1237
1238 CommitAndActivate(kDeviceScale);
1239 LayerTreeImpl* layer_tree_impl = host_impl()->active_tree();
1240
1241 // Get the layer impl for each Layer.
1242 LayerImpl* rounded_corner_layer_1_impl =
1243 layer_tree_impl->LayerById(rounded_corner_layer_1->id());
1244 LayerImpl* rounded_corner_layer_2_impl =
1245 layer_tree_impl->LayerById(rounded_corner_layer_2->id());
1246
1247 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
1248
1249 // Rounded corner layer 1
1250 // The render target for this layer is |root|, hence its target
1251 // bounds are relative to |root|.
1252 // The offset from the origin of the render target is [60, 0] and the device
1253 // scale factor is 1.6 thus giving the target space origin of [96, 0]. The
1254 // corner radius is also scaled by a factor of 1.6.
1255 const gfx::RRectF actual_rrect_1 =
1256 rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds;
1257 gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
1258 bounds_in_target_space.Scale(kDeviceScale);
1259 EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space);
1260 EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(),
1261 kRoundedCorner1Radius * kDeviceScale);
1262
1263 // Rounded corner layer 2
1264 // The render target for this layer is |render_surface|.
1265 // The offset from the origin of the render target is [0, 0].
1266 const gfx::RRectF actual_rrect_2 =
1267 rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds;
1268 bounds_in_target_space = kRoundedCornerLayer2Bound;
1269 bounds_in_target_space.Scale(kDeviceScale);
1270 EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space);
1271 EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(),
1272 kRoundedCorner2Radius * kDeviceScale);
1273}
1274
1275TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsSiblingRenderTarget) {
1276 // Layer Tree:
1277 // +root
1278 // +--rounded corner layer 1 [should trigger render surface]
1279 // +----render surface [Does not draw]
1280 // +----rounded corner layer 2 [should not trigger render surface]
1281
1282 constexpr int kRoundedCorner1Radius = 2;
1283 constexpr int kRoundedCorner2Radius = 5;
1284
1285 constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 60.f, 30.f, 40.f);
1286 constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 20.f, 30.f);
1287
1288 constexpr float kDeviceScale = 1.6f;
1289
1290 scoped_refptr<Layer> root = Layer::Create();
1291 scoped_refptr<Layer> render_surface = Layer::Create();
1292 scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create();
1293 scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create();
1294
1295 // Set up layer tree
1296 root->AddChild(rounded_corner_layer_1);
1297 rounded_corner_layer_1->AddChild(render_surface);
1298 rounded_corner_layer_1->AddChild(rounded_corner_layer_2);
1299
1300 // Set the root layer on host.
1301 host()->SetRootLayer(root);
1302
1303 // Set layer positions.
1304 rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin());
1305 render_surface->SetPosition(gfx::PointF(0, 0));
1306 rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin());
1307
1308 // Set up layer bounds.
1309 root->SetBounds(gfx::Size(100, 100));
1310 rounded_corner_layer_1->SetBounds(
1311 gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size()));
1312 render_surface->SetBounds(gfx::Size(30, 30));
1313 rounded_corner_layer_2->SetBounds(
1314 gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size()));
1315
1316 // Set the layer properties
1317 render_surface->SetForceRenderSurfaceForTesting(true);
1318
1319 root->SetIsDrawable(true);
1320 rounded_corner_layer_1->SetIsDrawable(true);
1321 rounded_corner_layer_2->SetIsDrawable(true);
1322
1323 // Set Rounded corners
1324 rounded_corner_layer_1->SetRoundedCorner(
1325 {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius,
1326 kRoundedCorner1Radius});
1327 rounded_corner_layer_2->SetRoundedCorner(
1328 {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius,
1329 kRoundedCorner2Radius});
1330
1331 UpdateMainDrawProperties(kDeviceScale);
1332
1333 // Since this effect node has 1 descendant with a rounded corner without a
1334 // render surface along the chain, it need a render surface.
1335 const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
1336 gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
1337 EXPECT_TRUE(effect_node->HasRenderSurface());
1338 EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
1339 kRoundedCorner1Radius);
1340 EXPECT_EQ(rounded_corner_bounds_1.rect(),
1341 gfx::RectF(kRoundedCornerLayer1Bound.size()));
1342
1343 // Since this effect node has no descendants that draw and no descendant that
1344 // has a rounded corner, it does not need a render surface.
1345 effect_node = GetEffectNode(rounded_corner_layer_2.get());
1346 gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
1347 EXPECT_FALSE(effect_node->HasRenderSurface());
1348 EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
1349 kRoundedCorner2Radius);
1350 EXPECT_EQ(rounded_corner_bounds_2.rect(),
1351 gfx::RectF(kRoundedCornerLayer2Bound.size()));
1352
1353 CommitAndActivate(kDeviceScale);
1354 LayerTreeImpl* layer_tree_impl = host_impl()->active_tree();
1355
1356 // Get the layer impl for each Layer.
1357 LayerImpl* rounded_corner_layer_1_impl =
1358 layer_tree_impl->LayerById(rounded_corner_layer_1->id());
1359 LayerImpl* rounded_corner_layer_2_impl =
1360 layer_tree_impl->LayerById(rounded_corner_layer_2->id());
1361
1362 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
1363
1364 // Rounded corner layer 1
1365 // The render target for this layer is |root|, hence its target
1366 // bounds are relative to |root|.
1367 // The offset from the origin of the render target is [0, 60] and the device
1368 // scale factor is 1.6 thus giving the target space origin of [0, 96]. The
1369 // corner radius is also scaled by a factor of 1.6.
1370 const gfx::RRectF actual_self_rrect_1 =
1371 rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds;
1372 EXPECT_TRUE(actual_self_rrect_1.IsEmpty());
1373
1374 gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
1375 bounds_in_target_space.Scale(kDeviceScale);
1376 const gfx::RRectF actual_render_target_rrect_1 =
1377 rounded_corner_layer_1_impl->render_target()->rounded_corner_bounds();
1378 EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space);
1379 EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(),
1380 kRoundedCorner1Radius * kDeviceScale);
1381
1382 // Rounded corner layer 2
1383 // The render target for this layer is |render_surface|.
1384 // The offset from the origin of the render target is [0, 0].
1385 const gfx::RRectF actual_rrect_2 =
1386 rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds;
1387 bounds_in_target_space = kRoundedCornerLayer2Bound;
1388 bounds_in_target_space.Scale(kDeviceScale);
1389 EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space);
1390 EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(),
1391 kRoundedCorner2Radius * kDeviceScale);
1392}
1393
1394TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) {
1395 // Layer Tree:
1396 // +root
1397 // +--fast rounded corner layer [should not trigger render surface]
1398 // +----layer 1
1399 // +----layer 2
1400 // +--rounded corner layer [should trigger render surface]
1401 // +----layer 3
1402 // +----layer 4
1403
1404 constexpr int kRoundedCorner1Radius = 2;
1405 constexpr int kRoundedCorner2Radius = 5;
1406
1407 constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 0.f, 50.f, 50.f);
1408 constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f);
1409
1410 constexpr float kDeviceScale = 1.6f;
1411
1412 scoped_refptr<Layer> root = Layer::Create();
1413 scoped_refptr<Layer> fast_rounded_corner_layer = Layer::Create();
1414 scoped_refptr<Layer> layer_1 = Layer::Create();
1415 scoped_refptr<Layer> layer_2 = Layer::Create();
1416 scoped_refptr<Layer> rounded_corner_layer = Layer::Create();
1417 scoped_refptr<Layer> layer_3 = Layer::Create();
1418 scoped_refptr<Layer> layer_4 = Layer::Create();
1419
1420 // Set up layer tree
1421 root->AddChild(fast_rounded_corner_layer);
1422 root->AddChild(rounded_corner_layer);
1423
1424 fast_rounded_corner_layer->AddChild(layer_1);
1425 fast_rounded_corner_layer->AddChild(layer_2);
1426
1427 rounded_corner_layer->AddChild(layer_3);
1428 rounded_corner_layer->AddChild(layer_4);
1429
1430 // Set the root layer on host.
1431 host()->SetRootLayer(root);
1432
1433 // Set layer positions.
1434 fast_rounded_corner_layer->SetPosition(kRoundedCornerLayer1Bound.origin());
1435 layer_1->SetPosition(gfx::PointF(0.f, 0.f));
1436 layer_2->SetPosition(gfx::PointF(25.f, 0.f));
1437 rounded_corner_layer->SetPosition(kRoundedCornerLayer2Bound.origin());
1438 layer_3->SetPosition(gfx::PointF(0.f, 0.f));
1439 layer_4->SetPosition(gfx::PointF(30.f, 0.f));
1440
1441 // Set up layer bounds.
1442 root->SetBounds(gfx::Size(100, 100));
1443 fast_rounded_corner_layer->SetBounds(
1444 gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size()));
1445 layer_1->SetBounds(gfx::Size(25, 25));
1446 layer_2->SetBounds(gfx::Size(25, 25));
1447 rounded_corner_layer->SetBounds(
1448 gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size()));
1449 layer_3->SetBounds(gfx::Size(30, 60));
1450 layer_4->SetBounds(gfx::Size(30, 60));
1451
1452 root->SetIsDrawable(true);
1453 fast_rounded_corner_layer->SetIsDrawable(true);
1454 layer_1->SetIsDrawable(true);
1455 layer_2->SetIsDrawable(true);
1456 rounded_corner_layer->SetIsDrawable(true);
1457 layer_3->SetIsDrawable(true);
1458 layer_4->SetIsDrawable(true);
1459
1460 // Set Rounded corners
1461 fast_rounded_corner_layer->SetRoundedCorner(
1462 {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius,
1463 kRoundedCorner1Radius});
1464 rounded_corner_layer->SetRoundedCorner(
1465 {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius,
1466 kRoundedCorner2Radius});
1467
1468 fast_rounded_corner_layer->SetIsFastRoundedCorner(true);
1469
1470 UpdateMainDrawProperties(kDeviceScale);
1471
1472 // Since this layer has a fast rounded corner, it should not have a render
1473 // surface even though it has 2 layers in the subtree that draws content.
1474 const EffectNode* effect_node =
1475 GetEffectNode(fast_rounded_corner_layer.get());
1476 gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
1477 EXPECT_FALSE(effect_node->HasRenderSurface());
1478 EXPECT_TRUE(effect_node->is_fast_rounded_corner);
1479 EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
1480 kRoundedCorner1Radius);
1481 EXPECT_EQ(rounded_corner_bounds_1.rect(),
1482 gfx::RectF(kRoundedCornerLayer1Bound.size()));
1483
1484 // Since this node has 2 descendants that draw, it will have a rounded corner.
1485 effect_node = GetEffectNode(rounded_corner_layer.get());
1486 gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
1487 EXPECT_TRUE(effect_node->HasRenderSurface());
1488 EXPECT_FALSE(effect_node->is_fast_rounded_corner);
1489 EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
1490 kRoundedCorner2Radius);
1491 EXPECT_EQ(rounded_corner_bounds_2.rect(),
1492 gfx::RectF(kRoundedCornerLayer2Bound.size()));
1493
1494 CommitAndActivate(kDeviceScale);
1495 LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
1496
1497 // Get the layer impl for each Layer.
1498 LayerImpl* fast_rounded_corner_layer_impl =
1499 layer_tree_impl->LayerById(fast_rounded_corner_layer->id());
1500 LayerImpl* layer_1_impl = layer_tree_impl->LayerById(layer_1->id());
1501 LayerImpl* layer_2_impl = layer_tree_impl->LayerById(layer_2->id());
1502 LayerImpl* rounded_corner_layer_impl =
1503 layer_tree_impl->LayerById(rounded_corner_layer->id());
1504 LayerImpl* layer_3_impl = layer_tree_impl->LayerById(layer_3->id());
1505 LayerImpl* layer_4_impl = layer_tree_impl->LayerById(layer_4->id());
1506
1507 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
1508
1509 // Fast rounded corner layer.
1510 // The render target for this layer is |root|, hence its target bounds are
1511 // relative to |root|.
1512 // The offset from the origin of the render target is [0, 0] and the device
1513 // scale factor is 1.6.
1514 const gfx::RRectF actual_rrect_1 =
1515 fast_rounded_corner_layer_impl->draw_properties().rounded_corner_bounds;
1516 gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
1517 bounds_in_target_space.Scale(kDeviceScale);
1518 EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space);
1519 EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(),
1520 kRoundedCorner1Radius * kDeviceScale);
1521
1522 // Layer 1 and layer 2 rounded corner bounds
1523 // This should have the same rounded corner boudns as fast rounded corner
1524 // layer.
1525 const gfx::RRectF layer_1_rrect =
1526 layer_1_impl->draw_properties().rounded_corner_bounds;
1527 const gfx::RRectF layer_2_rrect =
1528 layer_2_impl->draw_properties().rounded_corner_bounds;
1529 EXPECT_EQ(actual_rrect_1, layer_1_rrect);
1530 EXPECT_EQ(actual_rrect_1, layer_2_rrect);
1531
1532 // Rounded corner layer
1533 // The render target for this layer is |root|.
1534 // The offset from the origin of the render target is [40, 40] and the device
1535 // scale factor is 1.6 thus giving the target space origin of [64, 64]. The
1536 // corner radius is also scaled by a factor of 1.6.
1537 const gfx::RRectF actual_self_rrect_2 =
1538 rounded_corner_layer_impl->draw_properties().rounded_corner_bounds;
1539 EXPECT_TRUE(actual_self_rrect_2.IsEmpty());
1540
1541 bounds_in_target_space = kRoundedCornerLayer2Bound;
1542 bounds_in_target_space.Scale(kDeviceScale);
1543 const gfx::RRectF actual_render_target_rrect_2 =
1544 rounded_corner_layer_impl->render_target()->rounded_corner_bounds();
1545 EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space);
1546 EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(),
1547 kRoundedCorner2Radius * kDeviceScale);
1548
1549 // Layer 3 and layer 4 should have no rounded corner bounds set as their
1550 // parent is a render surface.
1551 const gfx::RRectF layer_3_rrect =
1552 layer_3_impl->draw_properties().rounded_corner_bounds;
1553 const gfx::RRectF layer_4_rrect =
1554 layer_4_impl->draw_properties().rounded_corner_bounds;
1555 EXPECT_TRUE(layer_3_rrect.IsEmpty());
1556 EXPECT_TRUE(layer_4_rrect.IsEmpty());
1557}
1558
1559TEST_F(PropertyTreeBuilderTest,
1560 FastRoundedCornerTriggersRenderSurfaceInAncestor) {
1561 // Layer Tree:
1562 // +root
1563 // +--rounded corner layer [1] [should trigger render surface]
1564 // +----fast rounded corner layer [2] [should not trigger render surface]
1565 // +--rounded corner layer [3] [should trigger render surface]
1566 // +----rounded corner layer [4] [should not trigger render surface]
1567
1568 constexpr int kRoundedCorner1Radius = 2;
1569 constexpr int kRoundedCorner2Radius = 5;
1570 constexpr int kRoundedCorner3Radius = 1;
1571 constexpr int kRoundedCorner4Radius = 3;
1572
1573 constexpr gfx::RectF kRoundedCornerLayer1Bound(5.f, 5.f, 50.f, 50.f);
1574 constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 25.f, 25.f);
1575 constexpr gfx::RectF kRoundedCornerLayer3Bound(40.f, 40.f, 60.f, 60.f);
1576 constexpr gfx::RectF kRoundedCornerLayer4Bound(30.f, 0.f, 30.f, 60.f);
1577
1578 constexpr float kDeviceScale = 1.6f;
1579
1580 scoped_refptr<Layer> root = Layer::Create();
1581 scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create();
1582 scoped_refptr<Layer> fast_rounded_corner_layer_2 = Layer::Create();
1583 scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create();
1584 scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create();
1585
1586 // Set up layer tree
1587 root->AddChild(rounded_corner_layer_1);
1588 root->AddChild(rounded_corner_layer_3);
1589
1590 rounded_corner_layer_1->AddChild(fast_rounded_corner_layer_2);
1591
1592 rounded_corner_layer_3->AddChild(rounded_corner_layer_4);
1593
1594 // Set the root layer on host.
1595 host()->SetRootLayer(root);
1596
1597 // Set layer positions.
1598 rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin());
1599 fast_rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin());
1600 rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin());
1601 rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin());
1602
1603 // Set up layer bounds.
1604 root->SetBounds(gfx::Size(100, 100));
1605 rounded_corner_layer_1->SetBounds(
1606 gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size()));
1607 fast_rounded_corner_layer_2->SetBounds(
1608 gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size()));
1609 rounded_corner_layer_3->SetBounds(
1610 gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size()));
1611 rounded_corner_layer_4->SetBounds(
1612 gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size()));
1613
1614 root->SetIsDrawable(true);
1615 rounded_corner_layer_1->SetIsDrawable(true);
1616 fast_rounded_corner_layer_2->SetIsDrawable(true);
1617 rounded_corner_layer_3->SetIsDrawable(true);
1618 rounded_corner_layer_4->SetIsDrawable(true);
1619
1620 // Set Rounded corners
1621 rounded_corner_layer_1->SetRoundedCorner(
1622 {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius,
1623 kRoundedCorner1Radius});
1624 fast_rounded_corner_layer_2->SetRoundedCorner(
1625 {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius,
1626 kRoundedCorner2Radius});
1627 rounded_corner_layer_3->SetRoundedCorner(
1628 {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius,
1629 kRoundedCorner3Radius});
1630 rounded_corner_layer_4->SetRoundedCorner(
1631 {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius,
1632 kRoundedCorner4Radius});
1633
1634 fast_rounded_corner_layer_2->SetIsFastRoundedCorner(true);
1635
1636 UpdateMainDrawProperties(kDeviceScale);
1637
1638 // Since this layer has a descendant that has rounded corner, this node will
1639 // require a render surface.
1640 const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get());
1641 gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
1642 EXPECT_TRUE(effect_node->HasRenderSurface());
1643 EXPECT_FALSE(effect_node->is_fast_rounded_corner);
1644 EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
1645 kRoundedCorner1Radius);
1646 EXPECT_EQ(rounded_corner_bounds_1.rect(),
1647 gfx::RectF(kRoundedCornerLayer1Bound.size()));
1648
1649 // Since this layer has no descendant with rounded corner or drawable, it will
1650 // not have a render surface.
1651 effect_node = GetEffectNode(fast_rounded_corner_layer_2.get());
1652 gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
1653 EXPECT_FALSE(effect_node->HasRenderSurface());
1654 EXPECT_TRUE(effect_node->is_fast_rounded_corner);
1655 EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
1656 kRoundedCorner2Radius);
1657 EXPECT_EQ(rounded_corner_bounds_2.rect(),
1658 gfx::RectF(kRoundedCornerLayer2Bound.size()));
1659
1660 // Since this layer has 1 descendant with a rounded corner, it should have a
1661 // render surface.
1662 effect_node = GetEffectNode(rounded_corner_layer_3.get());
1663 gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
1664 EXPECT_TRUE(effect_node->HasRenderSurface());
1665 EXPECT_FALSE(effect_node->is_fast_rounded_corner);
1666 EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
1667 kRoundedCorner3Radius);
1668 EXPECT_EQ(rounded_corner_bounds_3.rect(),
1669 gfx::RectF(kRoundedCornerLayer3Bound.size()));
1670
1671 // Since this layer no descendants, it would no thave a render pass.
1672 effect_node = GetEffectNode(rounded_corner_layer_4.get());
1673 gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
1674 EXPECT_FALSE(effect_node->HasRenderSurface());
1675 EXPECT_FALSE(effect_node->is_fast_rounded_corner);
1676 EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
1677 kRoundedCorner4Radius);
1678 EXPECT_EQ(rounded_corner_bounds_4.rect(),
1679 gfx::RectF(kRoundedCornerLayer4Bound.size()));
1680
1681 CommitAndActivate(kDeviceScale);
1682 LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
1683
1684 // Get the layer impl for each Layer.
1685 LayerImpl* rounded_corner_layer_impl_1 =
1686 layer_tree_impl->LayerById(rounded_corner_layer_1->id());
1687 LayerImpl* fast_rounded_corner_layer_impl_2 =
1688 layer_tree_impl->LayerById(fast_rounded_corner_layer_2->id());
1689 LayerImpl* rounded_corner_layer_impl_3 =
1690 layer_tree_impl->LayerById(rounded_corner_layer_3->id());
1691 LayerImpl* rounded_corner_layer_impl_4 =
1692 layer_tree_impl->LayerById(rounded_corner_layer_4->id());
1693
1694 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
1695
1696 // Rounded corner layer 1.
1697 // The render target for this layer is |root|, hence its target bounds are
1698 // relative to |root|.
1699 // The offset from the origin of the render target is [5, 5] and the device
1700 // scale factor is 1.6 giving a total offset of [8, 8].
1701 const gfx::RRectF actual_self_rrect_1 =
1702 rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds;
1703 EXPECT_TRUE(actual_self_rrect_1.IsEmpty());
1704
1705 gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
1706 bounds_in_target_space.Scale(kDeviceScale);
1707 const gfx::RRectF actual_render_target_rrect_1 =
1708 rounded_corner_layer_impl_1->render_target()->rounded_corner_bounds();
1709 EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space);
1710 EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(),
1711 kRoundedCorner1Radius * kDeviceScale);
1712
1713 // Fast rounded corner layer 2
1714 // The render target for this layer is |rounded_corner_layer_1|.
1715 // The offset from the origin of the render target is [0, 0] and the device
1716 // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6.
1717 const gfx::RRectF actual_self_rrect_2 =
1718 fast_rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds;
1719 bounds_in_target_space = kRoundedCornerLayer2Bound;
1720 bounds_in_target_space.Scale(kDeviceScale);
1721 EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space);
1722 EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(),
1723 kRoundedCorner2Radius * kDeviceScale);
1724
1725 // Rounded corner layer 3
1726 // The render target for this layer is |root|.
1727 // The offset from the origin of the render target is [40, 40] and the device
1728 // scale factor is 1.6 thus giving the target space origin of [64, 64]. The
1729 // corner radius is also scaled by a factor of 1.6.
1730 const gfx::RRectF actual_self_rrect_3 =
1731 rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds;
1732 EXPECT_TRUE(actual_self_rrect_3.IsEmpty());
1733
1734 bounds_in_target_space = kRoundedCornerLayer3Bound;
1735 bounds_in_target_space.Scale(kDeviceScale);
1736 const gfx::RRectF actual_render_target_rrect_3 =
1737 rounded_corner_layer_impl_3->render_target()->rounded_corner_bounds();
1738 EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space);
1739 EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(),
1740 kRoundedCorner3Radius * kDeviceScale);
1741
1742 // Rounded corner layer 4
1743 // The render target for this layer is |rounded_corner_layer_3|.
1744 // The offset from the origin of the render target is [30, 0] and the device
1745 // scale factor is 1.6 thus giving the target space origin of [48, 0]. The
1746 // corner radius is also scaled by a factor of 1.6.
1747 const gfx::RRectF actual_self_rrect_4 =
1748 rounded_corner_layer_impl_4->draw_properties().rounded_corner_bounds;
1749 bounds_in_target_space = kRoundedCornerLayer4Bound;
1750 bounds_in_target_space.Scale(kDeviceScale);
1751 EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space);
1752 EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(),
1753 kRoundedCorner4Radius * kDeviceScale);
1754}
1755
1756TEST_F(PropertyTreeBuilderTest,
1757 FastRoundedCornerDoesNotTriggerRenderSurfaceFromSubtree) {
1758 // Layer Tree:
1759 // +root
1760 // +--fast rounded corner layer 1 [should trigger render surface]
1761 // +----rounded corner layer 1 [should not trigger render surface]
1762 // +--rounded corner layer 2 [should trigger render surface]
1763 // +----rounded corner layer 3 [should not trigger render surface]
1764 constexpr int kRoundedCorner1Radius = 2;
1765 constexpr int kRoundedCorner2Radius = 5;
1766 constexpr int kRoundedCorner3Radius = 4;
1767 constexpr int kRoundedCorner4Radius = 5;
1768
1769 constexpr gfx::RectF kRoundedCornerLayer1Bound(10.f, 5.f, 45.f, 50.f);
1770 constexpr gfx::RectF kRoundedCornerLayer2Bound(5.f, 5.f, 20.f, 20.f);
1771 constexpr gfx::RectF kRoundedCornerLayer3Bound(60.f, 5.f, 40.f, 25.f);
1772 constexpr gfx::RectF kRoundedCornerLayer4Bound(0.f, 10.f, 10.f, 20.f);
1773
1774 constexpr float kDeviceScale = 1.6f;
1775
1776 scoped_refptr<Layer> root = Layer::Create();
1777 scoped_refptr<Layer> fast_rounded_corner_layer_1 = Layer::Create();
1778 scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create();
1779 scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create();
1780 scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create();
1781
1782 // Set up layer tree
1783 root->AddChild(fast_rounded_corner_layer_1);
1784 root->AddChild(rounded_corner_layer_2);
1785
1786 fast_rounded_corner_layer_1->AddChild(rounded_corner_layer_1);
1787 rounded_corner_layer_2->AddChild(rounded_corner_layer_3);
1788
1789 // Set the root layer on host.
1790 host()->SetRootLayer(root);
1791
1792 // Set layer positions.
1793 fast_rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin());
1794 rounded_corner_layer_1->SetPosition(kRoundedCornerLayer2Bound.origin());
1795 rounded_corner_layer_2->SetPosition(kRoundedCornerLayer3Bound.origin());
1796 rounded_corner_layer_3->SetPosition(kRoundedCornerLayer4Bound.origin());
1797
1798 // Set up layer bounds.
1799 root->SetBounds(gfx::Size(100, 100));
1800 fast_rounded_corner_layer_1->SetBounds(
1801 gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size()));
1802 rounded_corner_layer_1->SetBounds(
1803 gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size()));
1804 rounded_corner_layer_2->SetBounds(
1805 gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size()));
1806 rounded_corner_layer_3->SetBounds(
1807 gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size()));
1808
1809 root->SetIsDrawable(true);
1810 fast_rounded_corner_layer_1->SetIsDrawable(true);
1811 rounded_corner_layer_1->SetIsDrawable(true);
1812 rounded_corner_layer_2->SetIsDrawable(true);
1813 rounded_corner_layer_3->SetIsDrawable(true);
1814
1815 // Set Rounded corners
1816 fast_rounded_corner_layer_1->SetRoundedCorner(
1817 {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius,
1818 kRoundedCorner1Radius});
1819 rounded_corner_layer_1->SetRoundedCorner(
1820 {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius,
1821 kRoundedCorner2Radius});
1822 rounded_corner_layer_2->SetRoundedCorner(
1823 {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius,
1824 kRoundedCorner3Radius});
1825 rounded_corner_layer_3->SetRoundedCorner(
1826 {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius,
1827 kRoundedCorner4Radius});
1828
1829 fast_rounded_corner_layer_1->SetIsFastRoundedCorner(true);
1830
1831 UpdateMainDrawProperties(kDeviceScale);
1832
1833 // Since this layer has a descendant with rounded corner, it needs a render
1834 // surface.
1835 const EffectNode* effect_node =
1836 GetEffectNode(fast_rounded_corner_layer_1.get());
1837 gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds;
1838 EXPECT_TRUE(effect_node->HasRenderSurface());
1839 EXPECT_TRUE(effect_node->is_fast_rounded_corner);
1840 EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(),
1841 kRoundedCorner1Radius);
1842 EXPECT_EQ(rounded_corner_bounds_1.rect(),
1843 gfx::RectF(kRoundedCornerLayer1Bound.size()));
1844
1845 // Since this layer has no descendant with rounded corner or drawable, it will
1846 // not have a render surface.
1847 effect_node = GetEffectNode(rounded_corner_layer_1.get());
1848 gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds;
1849 EXPECT_FALSE(effect_node->HasRenderSurface());
1850 EXPECT_FALSE(effect_node->is_fast_rounded_corner);
1851 EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(),
1852 kRoundedCorner2Radius);
1853 EXPECT_EQ(rounded_corner_bounds_2.rect(),
1854 gfx::RectF(kRoundedCornerLayer2Bound.size()));
1855
1856 // Since this layer has a descendant with rounded corner, it should have a
1857 // render surface.
1858 effect_node = GetEffectNode(rounded_corner_layer_2.get());
1859 gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds;
1860 EXPECT_TRUE(effect_node->HasRenderSurface());
1861 EXPECT_FALSE(effect_node->is_fast_rounded_corner);
1862 EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(),
1863 kRoundedCorner3Radius);
1864 EXPECT_EQ(rounded_corner_bounds_3.rect(),
1865 gfx::RectF(kRoundedCornerLayer3Bound.size()));
1866
1867 // Since this layer has no descendant, it does not need a render surface.
1868 effect_node = GetEffectNode(rounded_corner_layer_3.get());
1869 gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds;
1870 EXPECT_FALSE(effect_node->HasRenderSurface());
1871 EXPECT_FALSE(effect_node->is_fast_rounded_corner);
1872 EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(),
1873 kRoundedCorner4Radius);
1874 EXPECT_EQ(rounded_corner_bounds_4.rect(),
1875 gfx::RectF(kRoundedCornerLayer4Bound.size()));
1876
1877 CommitAndActivate(kDeviceScale);
1878 LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
1879
1880 // Get the layer impl for each Layer.
1881 LayerImpl* fast_rounded_corner_layer_impl_1 =
1882 layer_tree_impl->LayerById(fast_rounded_corner_layer_1->id());
1883 LayerImpl* rounded_corner_layer_impl_1 =
1884 layer_tree_impl->LayerById(rounded_corner_layer_1->id());
1885 LayerImpl* rounded_corner_layer_impl_2 =
1886 layer_tree_impl->LayerById(rounded_corner_layer_2->id());
1887 LayerImpl* rounded_corner_layer_impl_3 =
1888 layer_tree_impl->LayerById(rounded_corner_layer_3->id());
1889
1890 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
1891
1892 // Fast rounded corner layer 1.
1893 // The render target for this layer is |root|, hence its target bounds are
1894 // relative to |root|.
1895 // The offset from the origin of the render target is [5, 5] and the device
1896 // scale factor is 1.6.
1897 const gfx::RRectF actual_self_rrect_1 =
1898 fast_rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds;
1899 EXPECT_TRUE(actual_self_rrect_1.IsEmpty());
1900
1901 gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound;
1902 bounds_in_target_space.Scale(kDeviceScale);
1903 const gfx::RRectF actual_render_target_rrect_1 =
1904 fast_rounded_corner_layer_impl_1->render_target()
1905 ->rounded_corner_bounds();
1906 EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space);
1907 EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(),
1908 kRoundedCorner1Radius * kDeviceScale);
1909
1910 // Rounded corner layer 1
1911 // The render target for this layer is |fast_rounded_corner_layer_1|.
1912 // The offset from the origin of the render target is [0, 0] and the device
1913 // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6.
1914 const gfx::RRectF actual_self_rrect_2 =
1915 rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds;
1916 bounds_in_target_space = kRoundedCornerLayer2Bound;
1917 bounds_in_target_space.Scale(kDeviceScale);
1918 EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space);
1919 EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(),
1920 kRoundedCorner2Radius * kDeviceScale);
1921
1922 // Rounded corner layer 3
1923 // The render target for this layer is |root|.
1924 // The offset from the origin of the render target is [5, 5] and the device
1925 // scale factor is 1.6 thus giving the target space origin of [8, 8]. The
1926 // corner radius is also scaled by a factor of 1.6.
1927 const gfx::RRectF actual_self_rrect_3 =
1928 rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds;
1929 EXPECT_TRUE(actual_self_rrect_3.IsEmpty());
1930
1931 bounds_in_target_space = kRoundedCornerLayer3Bound;
1932 bounds_in_target_space.Scale(kDeviceScale);
1933 const gfx::RRectF actual_render_target_rrect_3 =
1934 rounded_corner_layer_impl_2->render_target()->rounded_corner_bounds();
1935 EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space);
1936 EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(),
1937 kRoundedCorner3Radius * kDeviceScale);
1938
1939 // Rounded corner layer 4
1940 // The render target for this layer is |rounded_corner_layer_2|.
1941 // The offset from the origin of the render target is [0, 5] and the device
1942 // scale factor is 1.6 thus giving the target space origin of [0, 8]. The
1943 // corner radius is also scaled by a factor of 1.6.
1944 const gfx::RRectF actual_self_rrect_4 =
1945 rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds;
1946 bounds_in_target_space = kRoundedCornerLayer4Bound;
1947 bounds_in_target_space.Scale(kDeviceScale);
1948 EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space);
1949 EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(),
1950 kRoundedCorner4Radius * kDeviceScale);
1951}
1952
1953} // namespace
1954} // namespace cc