blob: f02a40f70e15f53495bd5ca2cf72f463c0947795 [file] [log] [blame]
ajumae2b7a5c2015-09-30 21:41:421// Copyright 2011 The Chromium Authors. All rights reserved.
[email protected]94f206c12012-08-25 00:09:142// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
avi02a4d172015-12-21 06:14:365#include <stddef.h>
6
danakj6496cba2014-10-16 01:31:087#include <algorithm>
danakj25c52c32016-04-12 21:51:088#include <memory>
[email protected]995708c52013-10-17 20:52:599#include <set>
Victor Costanaeb7f8e2018-04-06 19:05:2610#include <tuple>
vmpstra370ef52015-11-18 10:41:2811#include <vector>
[email protected]995708c52013-10-17 20:52:5912
danakj60bc3bc2016-04-09 00:24:4813#include "base/memory/ptr_util.h"
HyeockJinKim5d475242018-08-22 20:06:4414#include "base/stl_util.h"
loyso968163c92016-01-04 23:18:4815#include "cc/animation/animation_host.h"
16#include "cc/animation/animation_id_provider.h"
ajuma315a4782015-07-24 21:16:3417#include "cc/animation/keyframed_animation_curve.h"
Yi Guaa830ff2018-02-22 03:09:1118#include "cc/animation/single_keyframe_effect_animation.h"
[email protected]1c3626e2014-04-09 17:49:2219#include "cc/animation/transform_operations.h"
[email protected]681ccff2013-03-18 06:13:5220#include "cc/base/math_util.h"
[email protected]cc3cfaa2013-03-18 09:05:5221#include "cc/layers/content_layer_client.h"
ajuma956219582017-04-04 19:58:1422#include "cc/layers/effect_tree_layer_list_iterator.h"
[email protected]cc3cfaa2013-03-18 09:05:5223#include "cc/layers/layer.h"
[email protected]995708c52013-10-17 20:52:5924#include "cc/layers/layer_client.h"
[email protected]cc3cfaa2013-03-18 09:05:5225#include "cc/layers/layer_impl.h"
[email protected]50761e92013-03-29 20:51:2826#include "cc/layers/render_surface_impl.h"
[email protected]101441ce2012-10-16 01:45:0327#include "cc/test/animation_test_common.h"
vollick2175fae82015-04-27 21:18:1228#include "cc/test/fake_content_layer_client.h"
sohan.jyotie3bd6192014-10-13 07:13:5929#include "cc/test/fake_picture_layer.h"
30#include "cc/test/fake_picture_layer_impl.h"
[email protected]101441ce2012-10-16 01:45:0331#include "cc/test/geometry_test_utils.h"
Xianzhu Wang66e13e02019-09-18 20:39:1232#include "cc/test/layer_tree_impl_test_base.h"
trchendba8b1502016-07-08 09:47:0133#include "cc/trees/clip_node.h"
ennef6903532015-08-18 05:10:1534#include "cc/trees/draw_property_utils.h"
trchendba8b1502016-07-08 09:47:0135#include "cc/trees/effect_node.h"
trchendba8b1502016-07-08 09:47:0136#include "cc/trees/scroll_node.h"
trchendba8b1502016-07-08 09:47:0137#include "cc/trees/transform_node.h"
danakjf20f4502017-09-26 17:13:3138#include "components/viz/common/frame_sinks/copy_output_request.h"
39#include "components/viz/common/frame_sinks/copy_output_result.h"
[email protected]7f0c53db2012-10-02 00:23:1840#include "testing/gtest/include/gtest/gtest.h"
heejin.r.chungd28506ba2014-10-23 16:36:2041#include "ui/gfx/geometry/quad_f.h"
Malay Keshav178ce8c2019-03-09 01:40:2842#include "ui/gfx/geometry/rect_conversions.h"
43#include "ui/gfx/geometry/size_conversions.h"
miletus2c78036b2015-01-29 20:52:3744#include "ui/gfx/geometry/vector2d_conversions.h"
[email protected]c8686a02012-11-27 08:29:0045#include "ui/gfx/transform.h"
[email protected]94f206c12012-08-25 00:09:1446
[email protected]ba565742012-11-10 09:29:4847namespace cc {
[email protected]94f206c12012-08-25 00:09:1448namespace {
49
danakj402b3892018-06-13 00:13:0250bool LayerSubtreeHasCopyRequest(Layer* layer) {
Xianzhu Wang5b429f02019-08-29 20:45:2751 return GetEffectNode(layer)->subtree_has_copy_request;
danakj402b3892018-06-13 00:13:0252}
53
Xianzhu Wang66e13e02019-09-18 20:39:1254class DrawPropertiesTestBase : public LayerTreeImplTestBase {
danakj59931942016-07-26 22:11:2955 public:
Xianzhu Wang66e13e02019-09-18 20:39:1256 DrawPropertiesTestBase() = default;
57 explicit DrawPropertiesTestBase(const LayerTreeSettings& settings)
58 : LayerTreeImplTestBase(settings) {}
danakj59931942016-07-26 22:11:2959
60 static void SetScrollOffsetDelta(LayerImpl* layer_impl,
61 const gfx::Vector2dF& delta) {
62 if (layer_impl->layer_tree_impl()
63 ->property_trees()
pdr54d038192017-06-08 22:44:1364 ->scroll_tree.SetScrollOffsetDeltaForTesting(
65 layer_impl->element_id(), delta))
66 layer_impl->layer_tree_impl()->DidUpdateScrollOffset(
67 layer_impl->element_id());
danakj59931942016-07-26 22:11:2968 }
69
70 static float GetMaximumAnimationScale(LayerImpl* layer_impl) {
71 return layer_impl->layer_tree_impl()
72 ->property_trees()
73 ->GetAnimationScales(layer_impl->transform_tree_index(),
74 layer_impl->layer_tree_impl())
75 .maximum_animation_scale;
76 }
77
78 static float GetStartingAnimationScale(LayerImpl* layer_impl) {
79 return layer_impl->layer_tree_impl()
80 ->property_trees()
81 ->GetAnimationScales(layer_impl->transform_tree_index(),
82 layer_impl->layer_tree_impl())
83 .starting_animation_scale;
84 }
85
Xianzhu Wang66e13e02019-09-18 20:39:1286 void UpdateMainDrawProperties(float device_scale_factor = 1.0f) {
87 SetDeviceScaleAndUpdateViewportRect(host(), device_scale_factor);
88 UpdateDrawProperties(host(), &update_layer_list_);
Xianzhu Wangc62ecebf2019-08-31 15:54:1389 }
90
91 LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) {
92 return layer ? host_impl()->active_tree()->LayerById(layer->id()) : nullptr;
93 }
94 LayerImpl* PendingImplOf(const scoped_refptr<Layer>& layer) {
95 return layer ? host_impl()->pending_tree()->LayerById(layer->id())
96 : nullptr;
97 }
98 RenderSurfaceImpl* GetRenderSurfaceImpl(const scoped_refptr<Layer>& layer) {
99 return GetRenderSurface(ImplOf(layer));
100 }
101
102 // Updates main thread draw properties, commits main thread tree to
103 // impl-side pending tree, and updates pending tree draw properties.
Xianzhu Wang66e13e02019-09-18 20:39:12104 void Commit(float device_scale_factor = 1.0f) {
105 UpdateMainDrawProperties(device_scale_factor);
Xianzhu Wangc62ecebf2019-08-31 15:54:13106 if (!host_impl()->pending_tree())
107 host_impl()->CreatePendingTree();
108 host()->CommitAndCreatePendingTree();
109 // TODO(https://crbug.com/939968) This call should be handled by
110 // FakeLayerTreeHost instead of manually pushing the properties from the
111 // layer tree host to the pending tree.
112 host()->PushLayerTreePropertiesTo(host_impl()->pending_tree());
Xianzhu Wang66e13e02019-09-18 20:39:12113
114 UpdateDrawProperties(host_impl()->pending_tree());
Xianzhu Wangc62ecebf2019-08-31 15:54:13115 }
116
117 // Calls Commit(), then activates the pending tree, and updates active tree
118 // draw properties.
Xianzhu Wang66e13e02019-09-18 20:39:12119 void CommitAndActivate(float device_scale_factor = 1.0f) {
120 Commit(device_scale_factor);
Xianzhu Wangc62ecebf2019-08-31 15:54:13121 host_impl()->ActivateSyncTree();
Xianzhu Wang66e13e02019-09-18 20:39:12122 DCHECK_EQ(device_scale_factor,
123 host_impl()->active_tree()->device_scale_factor());
124 UpdateActiveTreeDrawProperties(device_scale_factor);
danakj59931942016-07-26 22:11:29125 }
126
127 bool UpdateLayerListContains(int id) const {
128 for (const auto& layer : update_layer_list_) {
129 if (layer->id() == id)
130 return true;
131 }
132 return false;
133 }
134
danakj59931942016-07-26 22:11:29135 const LayerList& update_layer_list() const { return update_layer_list_; }
136
Xianzhu Wang66e13e02019-09-18 20:39:12137 const RenderSurfaceList& GetRenderSurfaceList() {
138 return host_impl()->active_tree()->GetRenderSurfaceList();
139 }
140
141 void SetDeviceTransform(const gfx::Transform& device_transform) {
142 host_impl()->OnDraw(device_transform, host_impl()->external_viewport(),
143 false, false);
144 }
145
danakj59931942016-07-26 22:11:29146 private:
danakj59931942016-07-26 22:11:29147 LayerList update_layer_list_;
danakj59931942016-07-26 22:11:29148};
149
Xianzhu Wang66e13e02019-09-18 20:39:12150class DrawPropertiesTest : public DrawPropertiesTestBase,
151 public testing::Test {};
danakj59931942016-07-26 22:11:29152
Xianzhu Wang66e13e02019-09-18 20:39:12153class DrawPropertiesTestWithLayerTree : public DrawPropertiesTestBase,
154 public testing::Test {
enne637715732015-07-07 02:05:26155 public:
Xianzhu Wang66e13e02019-09-18 20:39:12156 DrawPropertiesTestWithLayerTree()
157 : DrawPropertiesTestBase(LayerTreeSettings()) {}
enne637715732015-07-07 02:05:26158};
159
Xianzhu Wang66e13e02019-09-18 20:39:12160class DrawPropertiesDrawRectsTest : public DrawPropertiesTest {
weiliangc6da32862016-04-20 16:40:11161 public:
Xianzhu Wang66e13e02019-09-18 20:39:12162 DrawPropertiesDrawRectsTest() : DrawPropertiesTest() {}
weiliangc6da32862016-04-20 16:40:11163
Xianzhu Wang5b429f02019-08-29 20:45:27164 void SetUp() override {
Xianzhu Wangd6a62d82019-09-09 22:35:36165 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27166 root->SetDrawsContent(true);
167 root->SetBounds(gfx::Size(500, 500));
Xianzhu Wang5b429f02019-08-29 20:45:27168 }
169
weiliangc6da32862016-04-20 16:40:11170 LayerImpl* TestVisibleRectAndDrawableContentRect(
171 const gfx::Rect& target_rect,
172 const gfx::Transform& layer_transform,
173 const gfx::Rect& layer_rect) {
Xianzhu Wangd6a62d82019-09-09 22:35:36174 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27175 LayerImpl* target = AddLayer<LayerImpl>();
176 LayerImpl* drawing_layer = AddLayer<LayerImpl>();
weiliangc6da32862016-04-20 16:40:11177
weiliangc6da32862016-04-20 16:40:11178 target->SetDrawsContent(true);
179 target->SetMasksToBounds(true);
180 drawing_layer->SetDrawsContent(true);
181
danakje4fa7b72016-07-25 22:00:06182 target->SetBounds(target_rect.size());
danakje4fa7b72016-07-25 22:00:06183 drawing_layer->SetBounds(layer_rect.size());
weiliangc6da32862016-04-20 16:40:11184
Xianzhu Wang5b429f02019-08-29 20:45:27185 CopyProperties(root, target);
186 CreateTransformNode(target).post_translation =
187 gfx::PointF(target_rect.origin()).OffsetFromOrigin();
188 CreateEffectNode(target).render_surface_reason = RenderSurfaceReason::kTest;
189 CreateClipNode(target);
190 CopyProperties(target, drawing_layer);
191 auto& drawing_layer_transform_node = CreateTransformNode(drawing_layer);
192 drawing_layer_transform_node.local = layer_transform;
193 drawing_layer_transform_node.post_translation =
194 gfx::PointF(layer_rect.origin()).OffsetFromOrigin();
195 drawing_layer_transform_node.flattens_inherited_transform = false;
196
Xianzhu Wang66e13e02019-09-18 20:39:12197 UpdateActiveTreeDrawProperties();
weiliangc6da32862016-04-20 16:40:11198
199 return drawing_layer;
200 }
201};
202
Xianzhu Wang5b429f02019-08-29 20:45:27203// Sanity check: For layers positioned at zero, with zero size,
204// and with identity transforms, then the draw transform,
205// screen space transform, and the hierarchy passed on to children
206// layers should also be identity transforms.
Xianzhu Wang66e13e02019-09-18 20:39:12207TEST_F(DrawPropertiesTest, TransformsForNoOpLayer) {
Xianzhu Wangd6a62d82019-09-09 22:35:36208 LayerImpl* parent = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27209 LayerImpl* child = AddLayer<LayerImpl>();
210 LayerImpl* grand_child = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:28211
danakje4fa7b72016-07-25 22:00:06212 parent->SetBounds(gfx::Size(100, 100));
[email protected]94f206c12012-08-25 00:09:14213
Xianzhu Wang5b429f02019-08-29 20:45:27214 CopyProperties(parent, child);
215 CopyProperties(child, grand_child);
216
Xianzhu Wang66e13e02019-09-18 20:39:12217 UpdateActiveTreeDrawProperties();
[email protected]94f206c12012-08-25 00:09:14218
danakjf78fb272016-07-26 19:06:15219 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform());
220 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
sunxdfd920f3f2016-04-05 16:17:51221 child->ScreenSpaceTransform());
danakjf78fb272016-07-26 19:06:15222 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
sunxdfd920f3f2016-04-05 16:17:51223 grand_child->DrawTransform());
danakjf78fb272016-07-26 19:06:15224 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
sunxdfd920f3f2016-04-05 16:17:51225 grand_child->ScreenSpaceTransform());
[email protected]94f206c12012-08-25 00:09:14226}
227
Xianzhu Wang66e13e02019-09-18 20:39:12228TEST_F(DrawPropertiesTest, TransformsForSingleLayer) {
Xianzhu Wangd6a62d82019-09-09 22:35:36229 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27230 LayerImpl* layer = AddLayer<LayerImpl>();
[email protected]94f206c12012-08-25 00:09:14231
jaydasikabaede2d92016-07-20 00:34:32232 TransformTree& transform_tree =
sunxdfd920f3f2016-04-05 16:17:51233 host_impl()->active_tree()->property_trees()->transform_tree;
jaydasikabaede2d92016-07-20 00:34:32234 EffectTree& effect_tree =
235 host_impl()->active_tree()->property_trees()->effect_tree;
enne826452722015-08-18 22:22:31236
danakje4fa7b72016-07-25 22:00:06237 root->SetBounds(gfx::Size(1, 2));
Xianzhu Wang5b429f02019-08-29 20:45:27238 CopyProperties(root, layer);
danakje4fa7b72016-07-25 22:00:06239
240 // Case 1: Setting the bounds of the layer should not affect either the draw
[email protected]fb661802013-03-25 01:59:32241 // transform or the screenspace transform.
danakje4fa7b72016-07-25 22:00:06242 layer->SetBounds(gfx::Size(10, 12));
Xianzhu Wang66e13e02019-09-18 20:39:12243 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31244 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15245 gfx::Transform(),
jaydasikabaede2d92016-07-20 00:34:32246 draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31247 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15248 gfx::Transform(),
jaydasikabaede2d92016-07-20 00:34:32249 draw_property_utils::ScreenSpaceTransform(layer, transform_tree));
[email protected]94f206c12012-08-25 00:09:14250
danakje4fa7b72016-07-25 22:00:06251 // Case 2: The anchor point by itself (without a layer transform) should have
[email protected]fb661802013-03-25 01:59:32252 // no effect on the transforms.
Xianzhu Wang5b429f02019-08-29 20:45:27253 CreateTransformNode(layer).origin = gfx::Point3F(2.5f, 3.0f, 0.f);
danakje4fa7b72016-07-25 22:00:06254 layer->SetBounds(gfx::Size(10, 12));
Xianzhu Wang66e13e02019-09-18 20:39:12255 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31256 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15257 gfx::Transform(),
jaydasikabaede2d92016-07-20 00:34:32258 draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31259 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15260 gfx::Transform(),
jaydasikabaede2d92016-07-20 00:34:32261 draw_property_utils::ScreenSpaceTransform(layer, transform_tree));
[email protected]94f206c12012-08-25 00:09:14262
danakje4fa7b72016-07-25 22:00:06263 // Case 3: A change in actual position affects both the draw transform and
[email protected]fb661802013-03-25 01:59:32264 // screen space transform.
265 gfx::Transform position_transform;
[email protected]6138db702013-09-25 03:25:05266 position_transform.Translate(0.f, 1.2f);
Xianzhu Wang5b429f02019-08-29 20:45:27267 SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f));
Xianzhu Wang66e13e02019-09-18 20:39:12268 UpdateActiveTreeDrawProperties();
sunxdfd920f3f2016-04-05 16:17:51269 EXPECT_TRANSFORMATION_MATRIX_EQ(
jaydasikabaede2d92016-07-20 00:34:32270 position_transform,
271 draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31272 EXPECT_TRANSFORMATION_MATRIX_EQ(
weiliangcc97575c2016-03-03 18:34:27273 position_transform,
jaydasikabaede2d92016-07-20 00:34:32274 draw_property_utils::ScreenSpaceTransform(layer, transform_tree));
[email protected]94f206c12012-08-25 00:09:14275
danakje4fa7b72016-07-25 22:00:06276 // Case 4: In the correct sequence of transforms, the layer transform should
277 // pre-multiply the translation-to-center. This is easily tested by using a
[email protected]fb661802013-03-25 01:59:32278 // scale transform, because scale and translation are not commutative.
279 gfx::Transform layer_transform;
280 layer_transform.Scale3d(2.0, 2.0, 1.0);
Xianzhu Wang5b429f02019-08-29 20:45:27281 SetTransform(layer, layer_transform);
282 SetTransformOrigin(layer, gfx::Point3F());
283 SetPostTranslation(layer, gfx::Vector2dF());
Xianzhu Wang66e13e02019-09-18 20:39:12284 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31285 EXPECT_TRANSFORMATION_MATRIX_EQ(
jaydasikabaede2d92016-07-20 00:34:32286 layer_transform,
287 draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31288 EXPECT_TRANSFORMATION_MATRIX_EQ(
jaydasikabaede2d92016-07-20 00:34:32289 layer_transform,
290 draw_property_utils::ScreenSpaceTransform(layer, transform_tree));
[email protected]94f206c12012-08-25 00:09:14291
danakje4fa7b72016-07-25 22:00:06292 // Case 5: The layer transform should occur with respect to the anchor point.
[email protected]fb661802013-03-25 01:59:32293 gfx::Transform translation_to_anchor;
294 translation_to_anchor.Translate(5.0, 0.0);
295 gfx::Transform expected_result =
296 translation_to_anchor * layer_transform * Inverse(translation_to_anchor);
Xianzhu Wang5b429f02019-08-29 20:45:27297 SetTransformOrigin(layer, gfx::Point3F(5.f, 0.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:12298 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31299 EXPECT_TRANSFORMATION_MATRIX_EQ(
jaydasikabaede2d92016-07-20 00:34:32300 expected_result,
301 draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31302 EXPECT_TRANSFORMATION_MATRIX_EQ(
jaydasikabaede2d92016-07-20 00:34:32303 expected_result,
304 draw_property_utils::ScreenSpaceTransform(layer, transform_tree));
[email protected]94f206c12012-08-25 00:09:14305
danakje4fa7b72016-07-25 22:00:06306 // Case 6: Verify that position pre-multiplies the layer transform. The
[email protected]fb661802013-03-25 01:59:32307 // current implementation of CalculateDrawProperties does this implicitly, but
308 // it is still worth testing to detect accidental regressions.
309 expected_result = position_transform * translation_to_anchor *
310 layer_transform * Inverse(translation_to_anchor);
Xianzhu Wang5b429f02019-08-29 20:45:27311 SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f));
Xianzhu Wang66e13e02019-09-18 20:39:12312 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31313 EXPECT_TRANSFORMATION_MATRIX_EQ(
jaydasikabaede2d92016-07-20 00:34:32314 expected_result,
315 draw_property_utils::DrawTransform(layer, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31316 EXPECT_TRANSFORMATION_MATRIX_EQ(
jaydasikabaede2d92016-07-20 00:34:32317 expected_result,
318 draw_property_utils::ScreenSpaceTransform(layer, transform_tree));
[email protected]94f206c12012-08-25 00:09:14319}
320
Xianzhu Wang66e13e02019-09-18 20:39:12321TEST_F(DrawPropertiesTest, TransformsAboutScrollOffset) {
miletusf57925d2014-10-01 19:38:13322 const gfx::ScrollOffset kScrollOffset(50, 100);
[email protected]fb661802013-03-25 01:59:32323 const gfx::Vector2dF kScrollDelta(2.34f, 5.67f);
[email protected]d30700f12013-07-31 08:21:01324 const gfx::Vector2d kMaxScrollOffset(200, 200);
[email protected]fb661802013-03-25 01:59:32325 const gfx::PointF kScrollLayerPosition(-kScrollOffset.x(),
326 -kScrollOffset.y());
jaydasikaa534a472016-03-31 01:12:16327 float page_scale = 0.888f;
[email protected]fb661802013-03-25 01:59:32328 const float kDeviceScale = 1.666f;
[email protected]657b24c2013-03-06 09:01:20329
Xianzhu Wang5b429f02019-08-29 20:45:27330 LayerImpl* sublayer = AddLayer<LayerImpl>();
jaydasika0d98ba92015-11-17 05:17:28331 sublayer->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:06332 sublayer->SetBounds(gfx::Size(500, 500));
[email protected]657b24c2013-03-06 09:01:20333
Xianzhu Wang5b429f02019-08-29 20:45:27334 LayerImpl* scroll_layer = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:06335 scroll_layer->SetBounds(gfx::Size(10, 20));
[email protected]adeda572014-01-31 00:49:47336
pdr54d038192017-06-08 22:44:13337 scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id()));
pdrbbfd8822017-06-27 22:44:52338 scroll_layer->SetScrollable(
[email protected]adeda572014-01-31 00:49:47339 gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(),
340 scroll_layer->bounds().height() + kMaxScrollOffset.y()));
pdrd09da8e2017-08-01 17:54:52341
Xianzhu Wangd6a62d82019-09-09 22:35:36342 LayerImpl* root = root_layer();
343 root->SetBounds(gfx::Size(3, 4));
Xianzhu Wangc9badff2019-10-01 23:47:22344 SetupViewport(root, gfx::Size(3, 4), gfx::Size(500, 500));
Xianzhu Wang5b429f02019-08-29 20:45:27345
Xianzhu Wangc9badff2019-10-01 23:47:22346 CopyProperties(OuterViewportScrollLayer(), scroll_layer);
Xianzhu Wang5b429f02019-08-29 20:45:27347 CreateTransformNode(scroll_layer);
348 CreateScrollNode(scroll_layer);
349 CopyProperties(scroll_layer, sublayer);
350
351 auto& scroll_tree = GetPropertyTrees(scroll_layer)->scroll_tree;
pdrd09da8e2017-08-01 17:54:52352 scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
353 kScrollOffset);
354 SetScrollOffsetDelta(scroll_layer, kScrollDelta);
Xianzhu Wang66e13e02019-09-18 20:39:12355 host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale);
356 UpdateActiveTreeDrawProperties(kDeviceScale);
357
danakjf78fb272016-07-26 19:06:15358 gfx::Transform expected_transform;
[email protected]fb661802013-03-25 01:59:32359 gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta;
Peter Kasting8c3adfb2017-09-13 08:07:39360 expected_transform.Translate(
361 std::round(sub_layer_screen_position.x() * page_scale * kDeviceScale),
362 std::round(sub_layer_screen_position.y() * page_scale * kDeviceScale));
jaydasikaa534a472016-03-31 01:12:16363 expected_transform.Scale(page_scale * kDeviceScale,
364 page_scale * kDeviceScale);
[email protected]fb661802013-03-25 01:59:32365 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
ajumad9432e32015-11-30 19:43:44366 sublayer->DrawTransform());
[email protected]fb661802013-03-25 01:59:32367 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
ajumab6aa1c62015-12-01 21:01:10368 sublayer->ScreenSpaceTransform());
[email protected]657b24c2013-03-06 09:01:20369
[email protected]fb661802013-03-25 01:59:32370 gfx::Transform arbitrary_translate;
371 const float kTranslateX = 10.6f;
372 const float kTranslateY = 20.6f;
373 arbitrary_translate.Translate(kTranslateX, kTranslateY);
Xianzhu Wang5b429f02019-08-29 20:45:27374 SetTransform(scroll_layer, arbitrary_translate);
Xianzhu Wang66e13e02019-09-18 20:39:12375 UpdateActiveTreeDrawProperties(kDeviceScale);
[email protected]fb661802013-03-25 01:59:32376 expected_transform.MakeIdentity();
377 expected_transform.Translate(
Peter Kasting8c3adfb2017-09-13 08:07:39378 std::round(kTranslateX * page_scale * kDeviceScale +
379 sub_layer_screen_position.x() * page_scale * kDeviceScale),
380 std::round(kTranslateY * page_scale * kDeviceScale +
381 sub_layer_screen_position.y() * page_scale * kDeviceScale));
jaydasikaa534a472016-03-31 01:12:16382 expected_transform.Scale(page_scale * kDeviceScale,
383 page_scale * kDeviceScale);
384 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
385 sublayer->DrawTransform());
386
387 // Test that page scale is updated even when we don't rebuild property trees.
388 page_scale = 1.888f;
pdr53abb452017-05-19 01:59:42389
Xianzhu Wang66e13e02019-09-18 20:39:12390 host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale);
391 EXPECT_FALSE(host_impl()->active_tree()->property_trees()->needs_rebuild);
392 UpdateActiveTreeDrawProperties(kDeviceScale);
jaydasikaa534a472016-03-31 01:12:16393
394 expected_transform.MakeIdentity();
395 expected_transform.Translate(
Peter Kasting8c3adfb2017-09-13 08:07:39396 std::round(kTranslateX * page_scale * kDeviceScale +
397 sub_layer_screen_position.x() * page_scale * kDeviceScale),
398 std::round(kTranslateY * page_scale * kDeviceScale +
399 sub_layer_screen_position.y() * page_scale * kDeviceScale));
jaydasikaa534a472016-03-31 01:12:16400 expected_transform.Scale(page_scale * kDeviceScale,
401 page_scale * kDeviceScale);
[email protected]fb661802013-03-25 01:59:32402 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform,
ajumad9432e32015-11-30 19:43:44403 sublayer->DrawTransform());
[email protected]657b24c2013-03-06 09:01:20404}
405
Xianzhu Wang66e13e02019-09-18 20:39:12406TEST_F(DrawPropertiesTest, TransformsForSimpleHierarchy) {
Xianzhu Wangd6a62d82019-09-09 22:35:36407 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27408 LayerImpl* parent = AddLayer<LayerImpl>();
409 LayerImpl* child = AddLayer<LayerImpl>();
410 LayerImpl* grand_child = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:28411
[email protected]fb661802013-03-25 01:59:32412 // One-time setup of root layer
danakje4fa7b72016-07-25 22:00:06413 root->SetBounds(gfx::Size(1, 2));
enne826452722015-08-18 22:22:31414
jaydasikabaede2d92016-07-20 00:34:32415 TransformTree& transform_tree =
sunxdfd920f3f2016-04-05 16:17:51416 host_impl()->active_tree()->property_trees()->transform_tree;
jaydasikabaede2d92016-07-20 00:34:32417 EffectTree& effect_tree =
418 host_impl()->active_tree()->property_trees()->effect_tree;
[email protected]ecc12622012-10-30 20:45:42419
[email protected]fb661802013-03-25 01:59:32420 // Case 1: parent's anchor point should not affect child or grand_child.
danakje4fa7b72016-07-25 22:00:06421 parent->SetBounds(gfx::Size(10, 12));
422 child->SetBounds(gfx::Size(16, 18));
423 grand_child->SetBounds(gfx::Size(76, 78));
Xianzhu Wang5b429f02019-08-29 20:45:27424
Xianzhu Wang5b429f02019-08-29 20:45:27425 CopyProperties(root, parent);
426 CreateTransformNode(parent).origin = gfx::Point3F(2.5f, 3.0f, 0.f);
427 CopyProperties(parent, child);
428 CopyProperties(child, grand_child);
429
Xianzhu Wang66e13e02019-09-18 20:39:12430 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31431
432 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15433 gfx::Transform(),
jaydasikabaede2d92016-07-20 00:34:32434 draw_property_utils::DrawTransform(child, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31435 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15436 gfx::Transform(),
jaydasikabaede2d92016-07-20 00:34:32437 draw_property_utils::ScreenSpaceTransform(child, transform_tree));
438 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15439 gfx::Transform(), draw_property_utils::DrawTransform(
440 grand_child, transform_tree, effect_tree));
jaydasikabaede2d92016-07-20 00:34:32441 EXPECT_TRANSFORMATION_MATRIX_EQ(
danakjf78fb272016-07-26 19:06:15442 gfx::Transform(),
jaydasikabaede2d92016-07-20 00:34:32443 draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree));
[email protected]94f206c12012-08-25 00:09:14444
[email protected]fb661802013-03-25 01:59:32445 // Case 2: parent's position affects child and grand_child.
446 gfx::Transform parent_position_transform;
[email protected]6138db702013-09-25 03:25:05447 parent_position_transform.Translate(0.f, 1.2f);
Xianzhu Wang5b429f02019-08-29 20:45:27448 SetPostTranslation(parent, gfx::Vector2dF(0.f, 1.2f));
Xianzhu Wang66e13e02019-09-18 20:39:12449 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31450 EXPECT_TRANSFORMATION_MATRIX_EQ(
451 parent_position_transform,
jaydasikabaede2d92016-07-20 00:34:32452 draw_property_utils::DrawTransform(child, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31453 EXPECT_TRANSFORMATION_MATRIX_EQ(
454 parent_position_transform,
jaydasikabaede2d92016-07-20 00:34:32455 draw_property_utils::ScreenSpaceTransform(child, transform_tree));
456 EXPECT_TRANSFORMATION_MATRIX_EQ(
457 parent_position_transform, draw_property_utils::DrawTransform(
458 grand_child, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31459 EXPECT_TRANSFORMATION_MATRIX_EQ(
460 parent_position_transform,
jaydasikabaede2d92016-07-20 00:34:32461 draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree));
[email protected]94f206c12012-08-25 00:09:14462
[email protected]fb661802013-03-25 01:59:32463 // Case 3: parent's local transform affects child and grandchild
464 gfx::Transform parent_layer_transform;
465 parent_layer_transform.Scale3d(2.0, 2.0, 1.0);
466 gfx::Transform parent_translation_to_anchor;
467 parent_translation_to_anchor.Translate(2.5, 3.0);
468 gfx::Transform parent_composite_transform =
469 parent_translation_to_anchor * parent_layer_transform *
470 Inverse(parent_translation_to_anchor);
Xianzhu Wang5b429f02019-08-29 20:45:27471 SetTransform(parent, parent_layer_transform);
472 SetPostTranslation(parent, gfx::Vector2dF());
Xianzhu Wang66e13e02019-09-18 20:39:12473 UpdateActiveTreeDrawProperties();
enne826452722015-08-18 22:22:31474 EXPECT_TRANSFORMATION_MATRIX_EQ(
475 parent_composite_transform,
jaydasikabaede2d92016-07-20 00:34:32476 draw_property_utils::DrawTransform(child, transform_tree, effect_tree));
enne826452722015-08-18 22:22:31477 EXPECT_TRANSFORMATION_MATRIX_EQ(
478 parent_composite_transform,
jaydasikabaede2d92016-07-20 00:34:32479 draw_property_utils::ScreenSpaceTransform(child, transform_tree));
enne826452722015-08-18 22:22:31480 EXPECT_TRANSFORMATION_MATRIX_EQ(
481 parent_composite_transform,
jaydasikabaede2d92016-07-20 00:34:32482 draw_property_utils::DrawTransform(grand_child, transform_tree,
483 effect_tree));
enne826452722015-08-18 22:22:31484 EXPECT_TRANSFORMATION_MATRIX_EQ(
485 parent_composite_transform,
jaydasikabaede2d92016-07-20 00:34:32486 draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree));
[email protected]94f206c12012-08-25 00:09:14487}
488
Xianzhu Wang66e13e02019-09-18 20:39:12489TEST_F(DrawPropertiesTest, TransformsForSingleRenderSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:36490 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27491 LayerImpl* parent = AddLayer<LayerImpl>();
492 LayerImpl* child = AddLayer<LayerImpl>();
493 LayerImpl* grand_child = AddLayer<LayerImpl>();
[email protected]94f206c12012-08-25 00:09:14494
[email protected]fb661802013-03-25 01:59:32495 gfx::Transform parent_layer_transform;
[email protected]6138db702013-09-25 03:25:05496 parent_layer_transform.Scale3d(1.f, 0.9f, 1.f);
[email protected]fb661802013-03-25 01:59:32497 gfx::Transform parent_translation_to_anchor;
498 parent_translation_to_anchor.Translate(25.0, 30.0);
[email protected]aedf4e52013-01-09 23:24:44499
[email protected]fb661802013-03-25 01:59:32500 gfx::Transform parent_composite_transform =
501 parent_translation_to_anchor * parent_layer_transform *
[email protected]baf64d062014-02-16 22:10:39502 Inverse(parent_translation_to_anchor);
[email protected]fb661802013-03-25 01:59:32503 gfx::Vector2dF parent_composite_scale =
504 MathUtil::ComputeTransform2dScaleComponents(parent_composite_transform,
505 1.f);
506 gfx::Transform surface_sublayer_transform;
507 surface_sublayer_transform.Scale(parent_composite_scale.x(),
508 parent_composite_scale.y());
509 gfx::Transform surface_sublayer_composite_transform =
510 parent_composite_transform * Inverse(surface_sublayer_transform);
[email protected]94f206c12012-08-25 00:09:14511
danakje4fa7b72016-07-25 22:00:06512 root->SetBounds(gfx::Size(1, 2));
danakje4fa7b72016-07-25 22:00:06513 parent->SetBounds(gfx::Size(100, 120));
514 child->SetBounds(gfx::Size(16, 18));
danakje4fa7b72016-07-25 22:00:06515 grand_child->SetBounds(gfx::Size(8, 10));
516 grand_child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27517
Xianzhu Wang5b429f02019-08-29 20:45:27518 CopyProperties(root, parent);
519 auto& parent_transform_node = CreateTransformNode(parent);
520 parent_transform_node.origin = gfx::Point3F(2.5f, 30.f, 0.f);
521 parent_transform_node.local = parent_layer_transform;
522 CopyProperties(parent, child);
523 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
524 CopyProperties(child, grand_child);
525
Xianzhu Wang66e13e02019-09-18 20:39:12526 UpdateActiveTreeDrawProperties();
[email protected]94f206c12012-08-25 00:09:14527
[email protected]fb661802013-03-25 01:59:32528 // Render surface should have been created now.
chrishtr7e3aaf22017-05-04 15:04:01529 ASSERT_TRUE(GetRenderSurface(child));
530 ASSERT_EQ(GetRenderSurface(child), child->render_target());
[email protected]94f206c12012-08-25 00:09:14531
[email protected]fb661802013-03-25 01:59:32532 // The child layer's draw transform should refer to its new render surface.
533 // The screen-space transform, however, should still refer to the root.
534 EXPECT_TRANSFORMATION_MATRIX_EQ(surface_sublayer_transform,
ajumad9432e32015-11-30 19:43:44535 child->DrawTransform());
[email protected]fb661802013-03-25 01:59:32536 EXPECT_TRANSFORMATION_MATRIX_EQ(parent_composite_transform,
ajumab6aa1c62015-12-01 21:01:10537 child->ScreenSpaceTransform());
[email protected]94f206c12012-08-25 00:09:14538
[email protected]fb661802013-03-25 01:59:32539 // Because the grand_child is the only drawable content, the child's render
540 // surface will tighten its bounds to the grand_child. The scale at which the
541 // surface's subtree is drawn must be removed from the composite transform.
weiliangc189c1a12016-04-11 16:16:25542 EXPECT_TRANSFORMATION_MATRIX_EQ(surface_sublayer_composite_transform,
543 child->render_target()->draw_transform());
[email protected]94f206c12012-08-25 00:09:14544
[email protected]fb661802013-03-25 01:59:32545 // The screen space is the same as the target since the child surface draws
546 // into the root.
547 EXPECT_TRANSFORMATION_MATRIX_EQ(
548 surface_sublayer_composite_transform,
weiliangc189c1a12016-04-11 16:16:25549 child->render_target()->screen_space_transform());
[email protected]94f206c12012-08-25 00:09:14550}
551
Xianzhu Wang66e13e02019-09-18 20:39:12552TEST_F(DrawPropertiesTest, TransformsForRenderSurfaceHierarchy) {
[email protected]fb661802013-03-25 01:59:32553 // This test creates a more complex tree and verifies it all at once. This
554 // covers the following cases:
555 // - layers that are described w.r.t. a render surface: should have draw
556 // transforms described w.r.t. that surface
557 // - A render surface described w.r.t. an ancestor render surface: should
558 // have a draw transform described w.r.t. that ancestor surface
[email protected]fb661802013-03-25 01:59:32559 // - Sanity check on recursion: verify transforms of layers described w.r.t.
560 // a render surface that is described w.r.t. an ancestor render surface.
561 // - verifying that each layer has a reference to the correct render surface
562 // and render target values.
563
Xianzhu Wangd6a62d82019-09-09 22:35:36564 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27565 LayerImpl* parent = AddLayer<LayerImpl>();
jaydasika8640f9f2015-11-10 01:34:36566 parent->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27567 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
jaydasika8640f9f2015-11-10 01:34:36568 render_surface1->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27569 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
jaydasika8640f9f2015-11-10 01:34:36570 render_surface2->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27571 LayerImpl* child_of_root = AddLayer<LayerImpl>();
jaydasika8640f9f2015-11-10 01:34:36572 child_of_root->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27573 LayerImpl* child_of_rs1 = AddLayer<LayerImpl>();
jaydasika8640f9f2015-11-10 01:34:36574 child_of_rs1->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27575 LayerImpl* child_of_rs2 = AddLayer<LayerImpl>();
jaydasika8640f9f2015-11-10 01:34:36576 child_of_rs2->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27577 LayerImpl* grand_child_of_root = AddLayer<LayerImpl>();
jaydasika8640f9f2015-11-10 01:34:36578 grand_child_of_root->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27579 LayerImpl* grand_child_of_rs1 = AddLayer<LayerImpl>();
enne25dea3f2015-07-27 16:44:28580 grand_child_of_rs1->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27581 LayerImpl* grand_child_of_rs2 = AddLayer<LayerImpl>();
enne25dea3f2015-07-27 16:44:28582 grand_child_of_rs2->SetDrawsContent(true);
[email protected]fb661802013-03-25 01:59:32583
[email protected]fb661802013-03-25 01:59:32584 // All layers in the tree are initialized with an anchor at .25 and a size of
wangxianzhu932d7f12016-09-30 05:47:00585 // (10,10). Matrix "A" is the composite layer transform used in all layers.
[email protected]fb661802013-03-25 01:59:32586 gfx::Transform translation_to_anchor;
587 translation_to_anchor.Translate(2.5, 0.0);
588 gfx::Transform layer_transform;
589 layer_transform.Translate(1.0, 1.0);
[email protected]fb661802013-03-25 01:59:32590
591 gfx::Transform A =
592 translation_to_anchor * layer_transform * Inverse(translation_to_anchor);
[email protected]fb661802013-03-25 01:59:32593
594 gfx::Vector2dF surface1_parent_transform_scale =
[email protected]baf64d062014-02-16 22:10:39595 MathUtil::ComputeTransform2dScaleComponents(A, 1.f);
[email protected]fb661802013-03-25 01:59:32596 gfx::Transform surface1_sublayer_transform;
597 surface1_sublayer_transform.Scale(surface1_parent_transform_scale.x(),
598 surface1_parent_transform_scale.y());
599
600 // SS1 = transform given to the subtree of render_surface1
601 gfx::Transform SS1 = surface1_sublayer_transform;
602 // S1 = transform to move from render_surface1 pixels to the layer space of
603 // the owning layer
604 gfx::Transform S1 = Inverse(surface1_sublayer_transform);
605
606 gfx::Vector2dF surface2_parent_transform_scale =
[email protected]baf64d062014-02-16 22:10:39607 MathUtil::ComputeTransform2dScaleComponents(SS1 * A, 1.f);
[email protected]fb661802013-03-25 01:59:32608 gfx::Transform surface2_sublayer_transform;
609 surface2_sublayer_transform.Scale(surface2_parent_transform_scale.x(),
610 surface2_parent_transform_scale.y());
611
612 // SS2 = transform given to the subtree of render_surface2
613 gfx::Transform SS2 = surface2_sublayer_transform;
614 // S2 = transform to move from render_surface2 pixels to the layer space of
615 // the owning layer
616 gfx::Transform S2 = Inverse(surface2_sublayer_transform);
617
danakje4fa7b72016-07-25 22:00:06618 root->SetBounds(gfx::Size(1, 2));
danakje4fa7b72016-07-25 22:00:06619 parent->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06620 render_surface1->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06621 render_surface2->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06622 child_of_root->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06623 child_of_rs1->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06624 child_of_rs2->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06625 grand_child_of_root->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06626 grand_child_of_rs1->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06627 grand_child_of_rs2->SetBounds(gfx::Size(10, 10));
[email protected]fb661802013-03-25 01:59:32628
Xianzhu Wang5b429f02019-08-29 20:45:27629 CopyProperties(root, parent);
630 auto& parent_transform_node = CreateTransformNode(parent);
631 parent_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
632 parent_transform_node.local = layer_transform;
633 CopyProperties(parent, child_of_root);
634 auto& child_of_root_transform_node = CreateTransformNode(child_of_root);
635 child_of_root_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
636 child_of_root_transform_node.local = layer_transform;
637 CopyProperties(child_of_root, grand_child_of_root);
638 auto& grand_child_of_root_transform_node =
639 CreateTransformNode(grand_child_of_root);
640 grand_child_of_root_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
641 grand_child_of_root_transform_node.local = layer_transform;
642 CopyProperties(parent, render_surface1);
643 auto& render_surface1_transform_node = CreateTransformNode(render_surface1);
644 render_surface1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
645 render_surface1_transform_node.local = layer_transform;
646 auto& render_surface1_effect_node = CreateEffectNode(render_surface1);
647 render_surface1_effect_node.render_surface_reason =
648 RenderSurfaceReason::kTest;
649 render_surface1_effect_node.opacity = 0.5f;
650 CopyProperties(render_surface1, child_of_rs1);
651 auto& child_of_rs1_transform_node = CreateTransformNode(child_of_rs1);
652 child_of_rs1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
653 child_of_rs1_transform_node.local = layer_transform;
654 CopyProperties(child_of_rs1, grand_child_of_rs1);
655 auto& grand_child_of_rs1_transform_node =
656 CreateTransformNode(grand_child_of_rs1);
657 grand_child_of_rs1_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
658 grand_child_of_rs1_transform_node.local = layer_transform;
659 CopyProperties(render_surface1, render_surface2);
660 auto& render_surface2_transform_node = CreateTransformNode(render_surface2);
661 render_surface2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
662 render_surface2_transform_node.local = layer_transform;
663 auto& render_surface2_effect_node = CreateEffectNode(render_surface2);
664 render_surface2_effect_node.render_surface_reason =
665 RenderSurfaceReason::kTest;
666 render_surface2_effect_node.opacity = 0.33f;
667 CopyProperties(render_surface2, child_of_rs2);
668 auto& child_of_rs2_transform_node = CreateTransformNode(child_of_rs2);
669 child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
670 child_of_rs2_transform_node.local = layer_transform;
671 CopyProperties(child_of_rs2, grand_child_of_rs2);
672 auto& grand_child_of_rs2_transform_node =
673 CreateTransformNode(grand_child_of_rs2);
674 grand_child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f);
675 grand_child_of_rs2_transform_node.local = layer_transform;
676
Xianzhu Wang66e13e02019-09-18 20:39:12677 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:32678
679 // Only layers that are associated with render surfaces should have an actual
680 // RenderSurface() value.
chrishtr7e3aaf22017-05-04 15:04:01681 ASSERT_TRUE(GetRenderSurface(root));
chrishtr5f60ca02017-05-11 23:09:49682 ASSERT_EQ(GetRenderSurface(child_of_root), GetRenderSurface(root));
683 ASSERT_EQ(GetRenderSurface(grand_child_of_root), GetRenderSurface(root));
[email protected]fb661802013-03-25 01:59:32684
chrishtr5f60ca02017-05-11 23:09:49685 ASSERT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root));
686 ASSERT_EQ(GetRenderSurface(child_of_rs1), GetRenderSurface(render_surface1));
687 ASSERT_EQ(GetRenderSurface(grand_child_of_rs1),
688 GetRenderSurface(render_surface1));
[email protected]fb661802013-03-25 01:59:32689
chrishtr5f60ca02017-05-11 23:09:49690 ASSERT_NE(GetRenderSurface(render_surface2), GetRenderSurface(root));
691 ASSERT_NE(GetRenderSurface(render_surface2),
692 GetRenderSurface(render_surface1));
693 ASSERT_EQ(GetRenderSurface(child_of_rs2), GetRenderSurface(render_surface2));
694 ASSERT_EQ(GetRenderSurface(grand_child_of_rs2),
695 GetRenderSurface(render_surface2));
[email protected]fb661802013-03-25 01:59:32696
697 // Verify all render target accessors
chrishtr7e3aaf22017-05-04 15:04:01698 EXPECT_EQ(GetRenderSurface(root), parent->render_target());
699 EXPECT_EQ(GetRenderSurface(root), child_of_root->render_target());
700 EXPECT_EQ(GetRenderSurface(root), grand_child_of_root->render_target());
[email protected]fb661802013-03-25 01:59:32701
chrishtr7e3aaf22017-05-04 15:04:01702 EXPECT_EQ(GetRenderSurface(render_surface1),
weiliangc189c1a12016-04-11 16:16:25703 render_surface1->render_target());
chrishtr7e3aaf22017-05-04 15:04:01704 EXPECT_EQ(GetRenderSurface(render_surface1), child_of_rs1->render_target());
705 EXPECT_EQ(GetRenderSurface(render_surface1),
weiliangc189c1a12016-04-11 16:16:25706 grand_child_of_rs1->render_target());
[email protected]fb661802013-03-25 01:59:32707
chrishtr7e3aaf22017-05-04 15:04:01708 EXPECT_EQ(GetRenderSurface(render_surface2),
weiliangc189c1a12016-04-11 16:16:25709 render_surface2->render_target());
chrishtr7e3aaf22017-05-04 15:04:01710 EXPECT_EQ(GetRenderSurface(render_surface2), child_of_rs2->render_target());
711 EXPECT_EQ(GetRenderSurface(render_surface2),
weiliangc189c1a12016-04-11 16:16:25712 grand_child_of_rs2->render_target());
[email protected]fb661802013-03-25 01:59:32713
714 // Verify layer draw transforms note that draw transforms are described with
715 // respect to the nearest ancestor render surface but screen space transforms
716 // are described with respect to the root.
ajumad9432e32015-11-30 19:43:44717 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->DrawTransform());
718 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A, child_of_root->DrawTransform());
[email protected]baf64d062014-02-16 22:10:39719 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
ajumad9432e32015-11-30 19:43:44720 grand_child_of_root->DrawTransform());
[email protected]fb661802013-03-25 01:59:32721
ajumad9432e32015-11-30 19:43:44722 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1, render_surface1->DrawTransform());
723 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * A, child_of_rs1->DrawTransform());
[email protected]baf64d062014-02-16 22:10:39724 EXPECT_TRANSFORMATION_MATRIX_EQ(SS1 * A * A,
ajumad9432e32015-11-30 19:43:44725 grand_child_of_rs1->DrawTransform());
[email protected]fb661802013-03-25 01:59:32726
ajumad9432e32015-11-30 19:43:44727 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2, render_surface2->DrawTransform());
728 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * A, child_of_rs2->DrawTransform());
[email protected]baf64d062014-02-16 22:10:39729 EXPECT_TRANSFORMATION_MATRIX_EQ(SS2 * A * A,
ajumad9432e32015-11-30 19:43:44730 grand_child_of_rs2->DrawTransform());
[email protected]fb661802013-03-25 01:59:32731
732 // Verify layer screen-space transforms
733 //
ajumab6aa1c62015-12-01 21:01:10734 EXPECT_TRANSFORMATION_MATRIX_EQ(A, parent->ScreenSpaceTransform());
735 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A, child_of_root->ScreenSpaceTransform());
736 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
737 grand_child_of_root->ScreenSpaceTransform());
[email protected]fb661802013-03-25 01:59:32738
[email protected]baf64d062014-02-16 22:10:39739 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A,
ajumab6aa1c62015-12-01 21:01:10740 render_surface1->ScreenSpaceTransform());
[email protected]baf64d062014-02-16 22:10:39741 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
ajumab6aa1c62015-12-01 21:01:10742 child_of_rs1->ScreenSpaceTransform());
[email protected]baf64d062014-02-16 22:10:39743 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A * A,
ajumab6aa1c62015-12-01 21:01:10744 grand_child_of_rs1->ScreenSpaceTransform());
[email protected]fb661802013-03-25 01:59:32745
[email protected]baf64d062014-02-16 22:10:39746 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A,
ajumab6aa1c62015-12-01 21:01:10747 render_surface2->ScreenSpaceTransform());
[email protected]baf64d062014-02-16 22:10:39748 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A * A,
ajumab6aa1c62015-12-01 21:01:10749 child_of_rs2->ScreenSpaceTransform());
[email protected]baf64d062014-02-16 22:10:39750 EXPECT_TRANSFORMATION_MATRIX_EQ(A * A * A * A * A,
ajumab6aa1c62015-12-01 21:01:10751 grand_child_of_rs2->ScreenSpaceTransform());
[email protected]fb661802013-03-25 01:59:32752
753 // Verify render surface transforms.
754 //
755 // Draw transform of render surface 1 is described with respect to root.
756 EXPECT_TRANSFORMATION_MATRIX_EQ(
chrishtr7e3aaf22017-05-04 15:04:01757 A * A * S1, GetRenderSurface(render_surface1)->draw_transform());
[email protected]fb661802013-03-25 01:59:32758 EXPECT_TRANSFORMATION_MATRIX_EQ(
chrishtr7e3aaf22017-05-04 15:04:01759 A * A * S1, GetRenderSurface(render_surface1)->screen_space_transform());
[email protected]fb661802013-03-25 01:59:32760 // Draw transform of render surface 2 is described with respect to render
761 // surface 1.
762 EXPECT_TRANSFORMATION_MATRIX_EQ(
chrishtr7e3aaf22017-05-04 15:04:01763 SS1 * A * S2, GetRenderSurface(render_surface2)->draw_transform());
[email protected]fb661802013-03-25 01:59:32764 EXPECT_TRANSFORMATION_MATRIX_EQ(
[email protected]baf64d062014-02-16 22:10:39765 A * A * A * S2,
chrishtr7e3aaf22017-05-04 15:04:01766 GetRenderSurface(render_surface2)->screen_space_transform());
[email protected]fb661802013-03-25 01:59:32767
768 // Sanity check. If these fail there is probably a bug in the test itself. It
769 // is expected that we correctly set up transforms so that the y-component of
770 // the screen-space transform encodes the "depth" of the layer in the tree.
ajumab6aa1c62015-12-01 21:01:10771 EXPECT_FLOAT_EQ(1.0, parent->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]803f6b52013-09-12 00:51:26772 EXPECT_FLOAT_EQ(2.0,
ajumab6aa1c62015-12-01 21:01:10773 child_of_root->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:32774 EXPECT_FLOAT_EQ(
ajumab6aa1c62015-12-01 21:01:10775 3.0, grand_child_of_root->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:32776
[email protected]803f6b52013-09-12 00:51:26777 EXPECT_FLOAT_EQ(2.0,
ajumab6aa1c62015-12-01 21:01:10778 render_surface1->ScreenSpaceTransform().matrix().get(1, 3));
779 EXPECT_FLOAT_EQ(3.0, child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:32780 EXPECT_FLOAT_EQ(
ajumab6aa1c62015-12-01 21:01:10781 4.0, grand_child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:32782
[email protected]803f6b52013-09-12 00:51:26783 EXPECT_FLOAT_EQ(3.0,
ajumab6aa1c62015-12-01 21:01:10784 render_surface2->ScreenSpaceTransform().matrix().get(1, 3));
785 EXPECT_FLOAT_EQ(4.0, child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:32786 EXPECT_FLOAT_EQ(
ajumab6aa1c62015-12-01 21:01:10787 5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:32788}
789
Xianzhu Wang66e13e02019-09-18 20:39:12790TEST_F(DrawPropertiesTest, LayerFullyContainedWithinClipInTargetSpace) {
Xianzhu Wangd6a62d82019-09-09 22:35:36791 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27792 LayerImpl* child = AddLayer<LayerImpl>();
793 LayerImpl* grand_child = AddLayer<LayerImpl>();
ajumadbd92cb2015-07-16 13:47:06794
795 gfx::Transform child_transform;
796 child_transform.Translate(50.0, 50.0);
797 child_transform.RotateAboutZAxis(30.0);
798
799 gfx::Transform grand_child_transform;
800 grand_child_transform.RotateAboutYAxis(90.0);
801
danakje4fa7b72016-07-25 22:00:06802 root->SetBounds(gfx::Size(200, 200));
danakje4fa7b72016-07-25 22:00:06803 child->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:06804 grand_child->SetBounds(gfx::Size(100, 100));
jaydasika6f972de2016-04-07 16:16:14805 grand_child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:27806
Xianzhu Wang5b429f02019-08-29 20:45:27807 CopyProperties(root, child);
808 CreateTransformNode(child).local = child_transform;
809 CopyProperties(child, grand_child);
810 auto& grand_child_transform_node = CreateTransformNode(grand_child);
811 grand_child_transform_node.flattens_inherited_transform = false;
812 grand_child_transform_node.local = grand_child_transform;
813
Xianzhu Wang66e13e02019-09-18 20:39:12814 UpdateActiveTreeDrawProperties();
ajumadbd92cb2015-07-16 13:47:06815
petermayo9711f032017-03-30 19:17:26816 // Mapping grand_child's bounds to screen space produces an empty rect, but
817 // only because it is turned sideways. The entire rect is contained inside
818 // the clip, and is only empty so long as the numerical precision of the
819 // transform is effectively perfect. Currently we do the calculation the
820 // other way around, and the Projection of the screen space clip into layer
821 // space includes the entire bounds.
822 EXPECT_EQ(gfx::Rect(grand_child->bounds()),
823 grand_child->visible_layer_rect());
ajumadbd92cb2015-07-16 13:47:06824}
825
Xianzhu Wang66e13e02019-09-18 20:39:12826TEST_F(DrawPropertiesTest, TransformsForDegenerateIntermediateLayer) {
[email protected]fb661802013-03-25 01:59:32827 // A layer that is empty in one axis, but not the other, was accidentally
828 // skipping a necessary translation. Without that translation, the coordinate
829 // space of the layer's draw transform is incorrect.
830 //
831 // Normally this isn't a problem, because the layer wouldn't be drawn anyway,
832 // but if that layer becomes a render surface, then its draw transform is
833 // implicitly inherited by the rest of the subtree, which then is positioned
834 // incorrectly as a result.
835
Xianzhu Wangd6a62d82019-09-09 22:35:36836 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27837 LayerImpl* child = AddLayer<LayerImpl>();
838 LayerImpl* grand_child = AddLayer<LayerImpl>();
ennec1332992015-08-24 19:45:09839 grand_child->SetDrawsContent(true);
[email protected]fb661802013-03-25 01:59:32840
danakje4fa7b72016-07-25 22:00:06841 root->SetBounds(gfx::Size(100, 100));
[email protected]fb661802013-03-25 01:59:32842 // The child height is zero, but has non-zero width that should be accounted
843 // for while computing draw transforms.
danakje4fa7b72016-07-25 22:00:06844 child->SetBounds(gfx::Size(10, 0));
danakje4fa7b72016-07-25 22:00:06845 grand_child->SetBounds(gfx::Size(10, 10));
Xianzhu Wang5b429f02019-08-29 20:45:27846
Xianzhu Wang5b429f02019-08-29 20:45:27847 CopyProperties(root, child);
848 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
849 CopyProperties(child, grand_child);
850
Xianzhu Wang66e13e02019-09-18 20:39:12851 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:32852
chrishtr7e3aaf22017-05-04 15:04:01853 ASSERT_TRUE(GetRenderSurface(child));
[email protected]fb661802013-03-25 01:59:32854 // This is the real test, the rest are sanity checks.
danakje4fa7b72016-07-25 22:00:06855 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:01856 GetRenderSurface(child)->draw_transform());
danakje4fa7b72016-07-25 22:00:06857 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform());
858 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
ajumad9432e32015-11-30 19:43:44859 grand_child->DrawTransform());
[email protected]fb661802013-03-25 01:59:32860}
861
Xianzhu Wang66e13e02019-09-18 20:39:12862TEST_F(DrawPropertiesTest, RenderSurfaceWithSublayerScale) {
Xianzhu Wangd6a62d82019-09-09 22:35:36863 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27864 LayerImpl* render_surface = AddLayer<LayerImpl>();
865 LayerImpl* child = AddLayer<LayerImpl>();
866 LayerImpl* grand_child = AddLayer<LayerImpl>();
jaydasika9bbee9b2016-01-13 00:36:48867
jaydasika9bbee9b2016-01-13 00:36:48868 gfx::Transform translate;
869 translate.Translate3d(5, 5, 5);
danakje4fa7b72016-07-25 22:00:06870
871 root->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:06872 render_surface->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:06873 child->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:06874 grand_child->SetBounds(gfx::Size(100, 100));
jaydasika9bbee9b2016-01-13 00:36:48875 grand_child->SetDrawsContent(true);
876
Xianzhu Wang5b429f02019-08-29 20:45:27877 CopyProperties(root, render_surface);
878 CreateTransformNode(render_surface).local = translate;
879 CreateEffectNode(render_surface).render_surface_reason =
880 RenderSurfaceReason::kTest;
881 CopyProperties(render_surface, child);
882 CreateTransformNode(child).local = translate;
883 CopyProperties(child, grand_child);
884 CreateTransformNode(grand_child).local = translate;
885
jaydasika9bbee9b2016-01-13 00:36:48886 // render_surface will have a sublayer scale because of device scale factor.
887 float device_scale_factor = 2.0f;
Xianzhu Wang66e13e02019-09-18 20:39:12888 UpdateActiveTreeDrawProperties(device_scale_factor);
jaydasika9bbee9b2016-01-13 00:36:48889
890 // Between grand_child and render_surface, we translate by (10, 10) and scale
891 // by a factor of 2.
892 gfx::Vector2dF expected_translation(20.0f, 20.0f);
893 EXPECT_EQ(grand_child->DrawTransform().To2dTranslation(),
894 expected_translation);
895}
896
Xianzhu Wang66e13e02019-09-18 20:39:12897TEST_F(DrawPropertiesTest, TransformAboveRootLayer) {
[email protected]f224cc92013-06-06 23:23:32898 // Transformations applied at the root of the tree should be forwarded
899 // to child layers instead of applied to the root RenderSurface.
Xianzhu Wangd6a62d82019-09-09 22:35:36900 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27901 LayerImpl* child = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:06902
903 root->SetDrawsContent(true);
jaydasikab874eddc2016-11-02 22:34:28904 root->SetBounds(gfx::Size(100, 100));
enned3f61fb02015-08-18 22:54:39905 child->SetDrawsContent(true);
jaydasikab874eddc2016-11-02 22:34:28906 child->SetBounds(gfx::Size(100, 100));
907 child->SetMasksToBounds(true);
[email protected]f224cc92013-06-06 23:23:32908
Xianzhu Wang5b429f02019-08-29 20:45:27909 CopyProperties(root, child);
910 CreateClipNode(child);
911
Xianzhu Wangc62ecebf2019-08-31 15:54:13912 float device_scale_factor = 1.0f;
[email protected]f224cc92013-06-06 23:23:32913 gfx::Transform translate;
914 translate.Translate(50, 50);
[email protected]989386c2013-07-18 21:37:23915 {
Xianzhu Wang66e13e02019-09-18 20:39:12916 SetDeviceTransform(translate);
917 UpdateActiveTreeDrawProperties(device_scale_factor);
weiliangcc3517722016-06-28 22:52:02918 EXPECT_TRANSFORMATION_MATRIX_EQ(
919 translate, root->draw_properties().target_space_transform);
920 EXPECT_TRANSFORMATION_MATRIX_EQ(
921 translate, child->draw_properties().target_space_transform);
danakjf78fb272016-07-26 19:06:15922 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:01923 GetRenderSurface(root)->draw_transform());
jaydasikab874eddc2016-11-02 22:34:28924 EXPECT_TRANSFORMATION_MATRIX_EQ(translate, child->ScreenSpaceTransform());
925 EXPECT_EQ(gfx::Rect(50, 50, 100, 100), child->clip_rect());
[email protected]989386c2013-07-18 21:37:23926 }
[email protected]f224cc92013-06-06 23:23:32927
928 gfx::Transform scale;
929 scale.Scale(2, 2);
[email protected]989386c2013-07-18 21:37:23930 {
Xianzhu Wang66e13e02019-09-18 20:39:12931 SetDeviceTransform(scale);
932 UpdateActiveTreeDrawProperties(device_scale_factor);
weiliangcc3517722016-06-28 22:52:02933 EXPECT_TRANSFORMATION_MATRIX_EQ(
934 scale, root->draw_properties().target_space_transform);
935 EXPECT_TRANSFORMATION_MATRIX_EQ(
936 scale, child->draw_properties().target_space_transform);
danakjf78fb272016-07-26 19:06:15937 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:01938 GetRenderSurface(root)->draw_transform());
jaydasikab874eddc2016-11-02 22:34:28939 EXPECT_TRANSFORMATION_MATRIX_EQ(scale, child->ScreenSpaceTransform());
940 EXPECT_EQ(gfx::Rect(0, 0, 200, 200), child->clip_rect());
[email protected]989386c2013-07-18 21:37:23941 }
[email protected]f224cc92013-06-06 23:23:32942
943 gfx::Transform rotate;
944 rotate.Rotate(2);
[email protected]989386c2013-07-18 21:37:23945 {
Xianzhu Wang66e13e02019-09-18 20:39:12946 SetDeviceTransform(rotate);
947 UpdateActiveTreeDrawProperties(device_scale_factor);
weiliangcc3517722016-06-28 22:52:02948 EXPECT_TRANSFORMATION_MATRIX_EQ(
949 rotate, root->draw_properties().target_space_transform);
950 EXPECT_TRANSFORMATION_MATRIX_EQ(
951 rotate, child->draw_properties().target_space_transform);
danakjf78fb272016-07-26 19:06:15952 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:01953 GetRenderSurface(root)->draw_transform());
jaydasikab874eddc2016-11-02 22:34:28954 EXPECT_TRANSFORMATION_MATRIX_EQ(rotate, child->ScreenSpaceTransform());
955 EXPECT_EQ(gfx::Rect(-4, 0, 104, 104), child->clip_rect());
[email protected]989386c2013-07-18 21:37:23956 }
[email protected]f224cc92013-06-06 23:23:32957
958 gfx::Transform composite;
959 composite.ConcatTransform(translate);
960 composite.ConcatTransform(scale);
961 composite.ConcatTransform(rotate);
[email protected]989386c2013-07-18 21:37:23962 {
Xianzhu Wang66e13e02019-09-18 20:39:12963 SetDeviceTransform(composite);
964 UpdateActiveTreeDrawProperties(device_scale_factor);
weiliangcc3517722016-06-28 22:52:02965 EXPECT_TRANSFORMATION_MATRIX_EQ(
966 composite, root->draw_properties().target_space_transform);
967 EXPECT_TRANSFORMATION_MATRIX_EQ(
968 composite, child->draw_properties().target_space_transform);
danakjf78fb272016-07-26 19:06:15969 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:01970 GetRenderSurface(root)->draw_transform());
jaydasikab874eddc2016-11-02 22:34:28971 EXPECT_TRANSFORMATION_MATRIX_EQ(composite, child->ScreenSpaceTransform());
972 EXPECT_EQ(gfx::Rect(89, 103, 208, 208), child->clip_rect());
[email protected]989386c2013-07-18 21:37:23973 }
[email protected]f224cc92013-06-06 23:23:32974
[email protected]9781afa2013-07-17 23:15:32975 // Verify it composes correctly with device scale.
Xianzhu Wangc62ecebf2019-08-31 15:54:13976 device_scale_factor = 1.5f;
[email protected]989386c2013-07-18 21:37:23977
978 {
Xianzhu Wang66e13e02019-09-18 20:39:12979 SetDeviceTransform(translate);
980 UpdateActiveTreeDrawProperties(device_scale_factor);
[email protected]989386c2013-07-18 21:37:23981 gfx::Transform device_scaled_translate = translate;
jaydasika18ea2722016-10-27 23:47:10982 device_scaled_translate.Scale(device_scale_factor, device_scale_factor);
weiliangcc3517722016-06-28 22:52:02983 EXPECT_TRANSFORMATION_MATRIX_EQ(
984 device_scaled_translate,
985 root->draw_properties().target_space_transform);
986 EXPECT_TRANSFORMATION_MATRIX_EQ(
987 device_scaled_translate,
988 child->draw_properties().target_space_transform);
danakjf78fb272016-07-26 19:06:15989 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:01990 GetRenderSurface(root)->draw_transform());
jaydasikab874eddc2016-11-02 22:34:28991 EXPECT_TRANSFORMATION_MATRIX_EQ(device_scaled_translate,
992 child->ScreenSpaceTransform());
993 EXPECT_EQ(gfx::Rect(50, 50, 150, 150), child->clip_rect());
[email protected]989386c2013-07-18 21:37:23994 }
[email protected]f224cc92013-06-06 23:23:32995}
996
Xianzhu Wang66e13e02019-09-18 20:39:12997TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilter) {
Xianzhu Wangd6a62d82019-09-09 22:35:36998 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:27999 LayerImpl* child = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:061000
1001 root->SetBounds(gfx::Size(100, 100));
1002 child->SetBounds(gfx::Size(25, 25));
jbroman1c44d5b52016-06-06 21:19:301003 child->SetDrawsContent(true);
jbroman1c44d5b52016-06-06 21:19:301004 FilterOperations filters;
1005 filters.Append(FilterOperation::CreateReferenceFilter(
Khushal7865b5be2017-11-22 03:12:061006 sk_make_sp<OffsetPaintFilter>(50, 50, nullptr)));
Xianzhu Wang5b429f02019-08-29 20:45:271007
Xianzhu Wang5b429f02019-08-29 20:45:271008 CopyProperties(root, child);
1009 auto& child_effect_node = CreateEffectNode(child);
1010 child_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
1011 child_effect_node.filters = filters;
1012
Xianzhu Wang66e13e02019-09-18 20:39:121013 UpdateActiveTreeDrawProperties();
jbroman1c44d5b52016-06-06 21:19:301014
1015 // The render surface's size should be unaffected by the offset image filter;
1016 // it need only have a drawable content rect large enough to contain the
1017 // contents (at the new offset).
chrishtr7e3aaf22017-05-04 15:04:011018 ASSERT_TRUE(GetRenderSurface(child));
jbroman1c44d5b52016-06-06 21:19:301019 EXPECT_EQ(gfx::RectF(50, 50, 25, 25),
chrishtr7e3aaf22017-05-04 15:04:011020 GetRenderSurface(child)->DrawableContentRect());
jbroman1c44d5b52016-06-06 21:19:301021}
1022
Xianzhu Wang66e13e02019-09-18 20:39:121023TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilterHighDpi) {
jbroman1c44d5b52016-06-06 21:19:301024 const float device_scale_factor = 2.0f;
1025
Xianzhu Wangd6a62d82019-09-09 22:35:361026 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271027 LayerImpl* child = AddLayer<LayerImpl>();
jbroman1c44d5b52016-06-06 21:19:301028
danakje4fa7b72016-07-25 22:00:061029 root->SetBounds(gfx::Size(100, 100));
1030 child->SetBounds(gfx::Size(25, 25));
1031 child->SetDrawsContent(true);
jbroman1c44d5b52016-06-06 21:19:301032
1033 FilterOperations filters;
1034 filters.Append(FilterOperation::CreateReferenceFilter(
Khushal7865b5be2017-11-22 03:12:061035 sk_make_sp<OffsetPaintFilter>(50, 50, nullptr)));
Xianzhu Wang5b429f02019-08-29 20:45:271036
Xianzhu Wang5b429f02019-08-29 20:45:271037 CopyProperties(root, child);
1038 auto& child_effect_node = CreateEffectNode(child);
1039 child_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
1040 child_effect_node.filters = filters;
jbroman1c44d5b52016-06-06 21:19:301041
Xianzhu Wang66e13e02019-09-18 20:39:121042 UpdateActiveTreeDrawProperties(device_scale_factor);
jbroman1c44d5b52016-06-06 21:19:301043
1044 // The render surface's size should be unaffected by the offset image filter;
1045 // it need only have a drawable content rect large enough to contain the
1046 // contents (at the new offset). All coordinates should be scaled by 2,
1047 // corresponding to the device scale factor.
chrishtr7e3aaf22017-05-04 15:04:011048 ASSERT_TRUE(GetRenderSurface(child));
jbroman1c44d5b52016-06-06 21:19:301049 EXPECT_EQ(gfx::RectF(100, 100, 50, 50),
chrishtr7e3aaf22017-05-04 15:04:011050 GetRenderSurface(child)->DrawableContentRect());
jbroman1c44d5b52016-06-06 21:19:301051}
1052
Xianzhu Wang66e13e02019-09-18 20:39:121053TEST_F(DrawPropertiesTest, RenderSurfaceForBlendMode) {
Xianzhu Wangd6a62d82019-09-09 22:35:361054 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271055 LayerImpl* child = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:061056
1057 root->SetBounds(gfx::Size(10, 10));
1058 child->SetBounds(gfx::Size(10, 10));
enned5f4ddd2015-08-18 16:50:061059 child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:271060
Xianzhu Wang5b429f02019-08-29 20:45:271061 CopyProperties(root, child);
1062 auto& child_effect_node = CreateEffectNode(child);
1063 child_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
1064 child_effect_node.blend_mode = SkBlendMode::kMultiply;
1065 child_effect_node.opacity = 0.5f;
1066
Xianzhu Wang66e13e02019-09-18 20:39:121067 UpdateActiveTreeDrawProperties();
rosca948d29d2014-11-09 10:25:131068
1069 // Since the child layer has a blend mode other than normal, it should get
jaydasika815ffdb82017-04-10 18:19:461070 // its own render surface.
chrishtr7e3aaf22017-05-04 15:04:011071 ASSERT_TRUE(GetRenderSurface(child));
weiliangc451b818f2015-07-24 17:52:291072 EXPECT_EQ(1.0f, child->draw_opacity());
chrishtr7e3aaf22017-05-04 15:04:011073 EXPECT_EQ(0.5f, GetRenderSurface(child)->draw_opacity());
1074 EXPECT_EQ(SkBlendMode::kMultiply, GetRenderSurface(child)->BlendMode());
rosca948d29d2014-11-09 10:25:131075}
1076
Xianzhu Wang66e13e02019-09-18 20:39:121077TEST_F(DrawPropertiesTest, RenderSurfaceDrawOpacity) {
Xianzhu Wangd6a62d82019-09-09 22:35:361078 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271079 LayerImpl* surface1 = AddLayer<LayerImpl>();
1080 LayerImpl* not_surface = AddLayer<LayerImpl>();
1081 LayerImpl* surface2 = AddLayer<LayerImpl>();
jaydasikafbdb86e2016-01-21 18:57:511082
danakje4fa7b72016-07-25 22:00:061083 root->SetBounds(gfx::Size(10, 10));
1084 surface1->SetBounds(gfx::Size(10, 10));
jaydasikafbdb86e2016-01-21 18:57:511085 surface1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:061086 not_surface->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061087 surface2->SetBounds(gfx::Size(10, 10));
1088 surface2->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:271089
Xianzhu Wang5b429f02019-08-29 20:45:271090 CopyProperties(root, surface1);
1091 auto& surface1_effect_node = CreateEffectNode(surface1);
1092 surface1_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
1093 surface1_effect_node.opacity = 0.5f;
1094 CopyProperties(surface1, not_surface);
1095 CreateEffectNode(not_surface).opacity = 0.5f;
1096 CopyProperties(not_surface, surface2);
1097 auto& surface2_effect_node = CreateEffectNode(surface2);
1098 surface2_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
1099 surface2_effect_node.opacity = 0.5f;
1100
Xianzhu Wang66e13e02019-09-18 20:39:121101 UpdateActiveTreeDrawProperties();
jaydasikafbdb86e2016-01-21 18:57:511102
chrishtr7e3aaf22017-05-04 15:04:011103 ASSERT_TRUE(GetRenderSurface(surface1));
chrishtr5f60ca02017-05-11 23:09:491104 ASSERT_EQ(GetRenderSurface(not_surface), GetRenderSurface(surface1));
chrishtr7e3aaf22017-05-04 15:04:011105 ASSERT_TRUE(GetRenderSurface(surface2));
1106 EXPECT_EQ(0.5f, GetRenderSurface(surface1)->draw_opacity());
jaydasikafbdb86e2016-01-21 18:57:511107 // surface2's draw opacity should include the opacity of not-surface and
1108 // itself, but not the opacity of surface1.
chrishtr7e3aaf22017-05-04 15:04:011109 EXPECT_EQ(0.25f, GetRenderSurface(surface2)->draw_opacity());
jaydasikafbdb86e2016-01-21 18:57:511110}
1111
Xianzhu Wang66e13e02019-09-18 20:39:121112TEST_F(DrawPropertiesTest, ClipRectCullsRenderSurfaces) {
[email protected]fb661802013-03-25 01:59:321113 // The entire subtree of layers that are outside the clip rect should be
Xianzhu Wang66e13e02019-09-18 20:39:121114 // culled away, and should not affect the GetRenderSurfaceList.
[email protected]fb661802013-03-25 01:59:321115 //
1116 // The test tree is set up as follows:
1117 // - all layers except the leaf_nodes are forced to be a new render surface
1118 // that have something to draw.
1119 // - parent is a large container layer.
danakje4fa7b72016-07-25 22:00:061120 // - child has MasksToBounds=true to cause clipping.
[email protected]fb661802013-03-25 01:59:321121 // - grand_child is positioned outside of the child's bounds
1122 // - great_grand_child is also kept outside child's bounds.
1123 //
1124 // In this configuration, grand_child and great_grand_child are completely
1125 // outside the clip rect, and they should never get scheduled on the list of
1126 // render surfaces.
[email protected]fb661802013-03-25 01:59:321127
Xianzhu Wangd6a62d82019-09-09 22:35:361128 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271129 LayerImpl* child = AddLayer<LayerImpl>();
1130 LayerImpl* grand_child = AddLayer<LayerImpl>();
1131 LayerImpl* great_grand_child = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:281132
Xianzhu Wang66e13e02019-09-18 20:39:121133 // leaf_node1 ensures that root and child are kept on the
1134 // GetRenderSurfaceList, even though grand_child and great_grand_child should
1135 // be clipped.
Xianzhu Wang5b429f02019-08-29 20:45:271136 LayerImpl* leaf_node1 = AddLayer<LayerImpl>();
1137 LayerImpl* leaf_node2 = AddLayer<LayerImpl>();
[email protected]fb661802013-03-25 01:59:321138
danakje4fa7b72016-07-25 22:00:061139 root->SetBounds(gfx::Size(500, 500));
1140 child->SetBounds(gfx::Size(20, 20));
[email protected]fb661802013-03-25 01:59:321141 child->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:061142 grand_child->SetBounds(gfx::Size(10, 10));
1143 great_grand_child->SetBounds(gfx::Size(10, 10));
1144 leaf_node1->SetBounds(gfx::Size(500, 500));
1145 leaf_node1->SetDrawsContent(true);
1146 leaf_node1->SetBounds(gfx::Size(20, 20));
1147 leaf_node2->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:271148
Xianzhu Wang5b429f02019-08-29 20:45:271149 CopyProperties(root, child);
1150 CreateClipNode(child);
1151 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
1152 CopyProperties(child, leaf_node1);
1153 CopyProperties(child, grand_child);
1154 grand_child->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f));
1155 CopyProperties(grand_child, great_grand_child);
1156 great_grand_child->SetOffsetToTransformParent(
1157 grand_child->offset_to_transform_parent());
1158 CopyProperties(great_grand_child, leaf_node2);
1159 leaf_node2->SetOffsetToTransformParent(
1160 great_grand_child->offset_to_transform_parent());
1161
Xianzhu Wang66e13e02019-09-18 20:39:121162 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:321163
Xianzhu Wang66e13e02019-09-18 20:39:121164 ASSERT_EQ(2U, GetRenderSurfaceList().size());
Chris Harrelson9bdbcce2017-06-02 03:12:141165 EXPECT_EQ(static_cast<uint64_t>(root->id()),
Xianzhu Wang66e13e02019-09-18 20:39:121166 GetRenderSurfaceList().at(0)->id());
Chris Harrelson9bdbcce2017-06-02 03:12:141167 EXPECT_EQ(static_cast<uint64_t>(child->id()),
Xianzhu Wang66e13e02019-09-18 20:39:121168 GetRenderSurfaceList().at(1)->id());
[email protected]fb661802013-03-25 01:59:321169}
1170
Xianzhu Wang66e13e02019-09-18 20:39:121171TEST_F(DrawPropertiesTest, ClipRectCullsSurfaceWithoutVisibleContent) {
[email protected]fb661802013-03-25 01:59:321172 // When a render surface has a clip rect, it is used to clip the content rect
weiliangcfb3d5eaa2015-07-28 23:54:571173 // of the surface.
[email protected]fb661802013-03-25 01:59:321174
1175 // The test tree is set up as follows:
danakje4fa7b72016-07-25 22:00:061176 // - root is a container layer that masksToBounds=true to cause clipping.
[email protected]fb661802013-03-25 01:59:321177 // - child is a render surface, which has a clip rect set to the bounds of
danakje4fa7b72016-07-25 22:00:061178 // the root.
[email protected]fb661802013-03-25 01:59:321179 // - grand_child is a render surface, and the only visible content in child.
danakje4fa7b72016-07-25 22:00:061180 // It is positioned outside of the clip rect from root.
[email protected]fb661802013-03-25 01:59:321181
1182 // In this configuration, grand_child should be outside the clipped
1183 // content rect of the child, making grand_child not appear in the
Xianzhu Wang66e13e02019-09-18 20:39:121184 // GetRenderSurfaceList.
weiliangcfb3d5eaa2015-07-28 23:54:571185
Xianzhu Wangd6a62d82019-09-09 22:35:361186 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271187 LayerImpl* child = AddLayer<LayerImpl>();
1188 LayerImpl* grand_child = AddLayer<LayerImpl>();
1189 LayerImpl* leaf_node = AddLayer<LayerImpl>();
[email protected]fb661802013-03-25 01:59:321190
danakje4fa7b72016-07-25 22:00:061191 root->SetMasksToBounds(true);
1192 root->SetBounds(gfx::Size(100, 100));
1193 child->SetBounds(gfx::Size(20, 20));
danakje4fa7b72016-07-25 22:00:061194 grand_child->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061195 leaf_node->SetBounds(gfx::Size(10, 10));
1196 leaf_node->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:271197
Xianzhu Wang5b429f02019-08-29 20:45:271198 CreateClipNode(root);
1199 CopyProperties(root, child);
1200 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
1201 CopyProperties(child, grand_child);
1202 grand_child->SetOffsetToTransformParent(gfx::Vector2dF(200.f, 200.f));
1203 CreateEffectNode(grand_child).render_surface_reason =
1204 RenderSurfaceReason::kTest;
1205 CopyProperties(grand_child, leaf_node);
1206 leaf_node->SetOffsetToTransformParent(
1207 grand_child->offset_to_transform_parent());
1208
Xianzhu Wang66e13e02019-09-18 20:39:121209 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:321210
Xianzhu Wang66e13e02019-09-18 20:39:121211 // We should cull child and grand_child from the GetRenderSurfaceList.
1212 ASSERT_EQ(1U, GetRenderSurfaceList().size());
Chris Harrelson9bdbcce2017-06-02 03:12:141213 EXPECT_EQ(static_cast<uint64_t>(root->id()),
Xianzhu Wang66e13e02019-09-18 20:39:121214 GetRenderSurfaceList().at(0)->id());
[email protected]fb661802013-03-25 01:59:321215}
1216
Xianzhu Wang66e13e02019-09-18 20:39:121217TEST_F(DrawPropertiesTest, IsClippedIsSetCorrectlyLayerImpl) {
ajumae2b7a5c2015-09-30 21:41:421218 // Tests that LayerImpl's IsClipped() property is set to true when:
[email protected]fb661802013-03-25 01:59:321219 // - the layer clips its subtree, e.g. masks to bounds,
1220 // - the layer is clipped by an ancestor that contributes to the same
1221 // render target,
1222 // - a surface is clipped by an ancestor that contributes to the same
1223 // render target.
1224 //
1225 // In particular, for a layer that owns a render surface:
1226 // - the render surface inherits any clip from ancestors, and does NOT
1227 // pass that clipped status to the layer itself.
1228 // - but if the layer itself masks to bounds, it is considered clipped
1229 // and propagates the clip to the subtree.
1230
Xianzhu Wangd6a62d82019-09-09 22:35:361231 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271232 LayerImpl* parent = AddLayer<LayerImpl>();
1233 LayerImpl* child1 = AddLayer<LayerImpl>();
1234 LayerImpl* child2 = AddLayer<LayerImpl>();
1235 LayerImpl* grand_child = AddLayer<LayerImpl>();
1236 LayerImpl* leaf_node1 = AddLayer<LayerImpl>();
1237 LayerImpl* leaf_node2 = AddLayer<LayerImpl>();
enne76bf8982015-08-18 17:55:331238
danakje4fa7b72016-07-25 22:00:061239 root->SetBounds(gfx::Size(100, 100));
1240 parent->SetBounds(gfx::Size(100, 100));
1241 parent->SetDrawsContent(true);
1242 child1->SetBounds(gfx::Size(100, 100));
1243 child1->SetDrawsContent(true);
1244 child2->SetBounds(gfx::Size(100, 100));
1245 child2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:061246 grand_child->SetBounds(gfx::Size(100, 100));
1247 grand_child->SetDrawsContent(true);
1248 leaf_node1->SetBounds(gfx::Size(100, 100));
1249 leaf_node1->SetDrawsContent(true);
1250 leaf_node2->SetBounds(gfx::Size(100, 100));
1251 leaf_node2->SetDrawsContent(true);
enne76bf8982015-08-18 17:55:331252
Xianzhu Wang5b429f02019-08-29 20:45:271253 CopyProperties(root, parent);
1254 CopyProperties(parent, child1);
1255 CopyProperties(child1, grand_child);
1256 CopyProperties(grand_child, leaf_node1);
1257 CopyProperties(parent, child2);
1258 CreateTransformNode(child2);
1259 CreateEffectNode(child2).render_surface_reason = RenderSurfaceReason::kTest;
1260 CopyProperties(child2, leaf_node2);
1261
enne76bf8982015-08-18 17:55:331262 // Case 1: nothing is clipped except the root render surface.
Xianzhu Wang66e13e02019-09-18 20:39:121263 UpdateActiveTreeDrawProperties();
enne76bf8982015-08-18 17:55:331264
chrishtr7e3aaf22017-05-04 15:04:011265 ASSERT_TRUE(GetRenderSurface(root));
1266 ASSERT_TRUE(GetRenderSurface(child2));
enne76bf8982015-08-18 17:55:331267
weiliangce3f09a612016-03-16 17:02:521268 EXPECT_FALSE(root->is_clipped());
chrishtr7e3aaf22017-05-04 15:04:011269 EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
weiliangce3f09a612016-03-16 17:02:521270 EXPECT_FALSE(parent->is_clipped());
1271 EXPECT_FALSE(child1->is_clipped());
1272 EXPECT_FALSE(child2->is_clipped());
chrishtr7e3aaf22017-05-04 15:04:011273 EXPECT_FALSE(GetRenderSurface(child2)->is_clipped());
weiliangce3f09a612016-03-16 17:02:521274 EXPECT_FALSE(grand_child->is_clipped());
1275 EXPECT_FALSE(leaf_node1->is_clipped());
1276 EXPECT_FALSE(leaf_node2->is_clipped());
enne76bf8982015-08-18 17:55:331277
danakje4fa7b72016-07-25 22:00:061278 // Case 2: parent MasksToBounds, so the parent, child1, and child2's
enne76bf8982015-08-18 17:55:331279 // surface are clipped. But layers that contribute to child2's surface are
1280 // not clipped explicitly because child2's surface already accounts for
1281 // that clip.
weiliangce3f09a612016-03-16 17:02:521282 parent->SetMasksToBounds(true);
Xianzhu Wang5b429f02019-08-29 20:45:271283 CreateClipNode(parent);
1284 child1->SetClipTreeIndex(parent->clip_tree_index());
1285 grand_child->SetClipTreeIndex(parent->clip_tree_index());
1286 leaf_node1->SetClipTreeIndex(parent->clip_tree_index());
1287 child2->SetClipTreeIndex(parent->clip_tree_index());
1288 GetEffectNode(child2)->clip_id = parent->clip_tree_index();
1289 leaf_node2->SetClipTreeIndex(parent->clip_tree_index());
enne76bf8982015-08-18 17:55:331290
Xianzhu Wang66e13e02019-09-18 20:39:121291 host_impl()->active_tree()->set_needs_update_draw_properties();
1292 UpdateActiveTreeDrawProperties();
enne76bf8982015-08-18 17:55:331293
chrishtr7e3aaf22017-05-04 15:04:011294 ASSERT_TRUE(GetRenderSurface(root));
1295 ASSERT_TRUE(GetRenderSurface(child2));
enne76bf8982015-08-18 17:55:331296
weiliangce3f09a612016-03-16 17:02:521297 EXPECT_FALSE(root->is_clipped());
chrishtr7e3aaf22017-05-04 15:04:011298 EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
weiliangce3f09a612016-03-16 17:02:521299 EXPECT_TRUE(parent->is_clipped());
1300 EXPECT_TRUE(child1->is_clipped());
1301 EXPECT_FALSE(child2->is_clipped());
chrishtr7e3aaf22017-05-04 15:04:011302 EXPECT_TRUE(GetRenderSurface(child2)->is_clipped());
weiliangce3f09a612016-03-16 17:02:521303 EXPECT_TRUE(grand_child->is_clipped());
1304 EXPECT_TRUE(leaf_node1->is_clipped());
1305 EXPECT_FALSE(leaf_node2->is_clipped());
enne76bf8982015-08-18 17:55:331306
weiliangce3f09a612016-03-16 17:02:521307 parent->SetMasksToBounds(false);
Xianzhu Wang5b429f02019-08-29 20:45:271308 parent->SetClipTreeIndex(root->clip_tree_index());
1309 child1->SetClipTreeIndex(root->clip_tree_index());
1310 grand_child->SetClipTreeIndex(root->clip_tree_index());
1311 leaf_node1->SetClipTreeIndex(root->clip_tree_index());
1312 child2->SetClipTreeIndex(root->clip_tree_index());
1313 GetEffectNode(child2)->clip_id = root->clip_tree_index();
1314 leaf_node2->SetClipTreeIndex(root->clip_tree_index());
enne76bf8982015-08-18 17:55:331315
danakje4fa7b72016-07-25 22:00:061316 // Case 3: child2 MasksToBounds. The layer and subtree are clipped, and
enne76bf8982015-08-18 17:55:331317 // child2's render surface is not clipped.
weiliangce3f09a612016-03-16 17:02:521318 child2->SetMasksToBounds(true);
Xianzhu Wang5b429f02019-08-29 20:45:271319 CreateClipNode(child2);
1320 leaf_node2->SetClipTreeIndex(child2->clip_tree_index());
enne76bf8982015-08-18 17:55:331321
Xianzhu Wang66e13e02019-09-18 20:39:121322 host_impl()->active_tree()->set_needs_update_draw_properties();
1323 UpdateActiveTreeDrawProperties();
enne76bf8982015-08-18 17:55:331324
chrishtr7e3aaf22017-05-04 15:04:011325 ASSERT_TRUE(GetRenderSurface(root));
1326 ASSERT_TRUE(GetRenderSurface(child2));
enne76bf8982015-08-18 17:55:331327
weiliangce3f09a612016-03-16 17:02:521328 EXPECT_FALSE(root->is_clipped());
chrishtr7e3aaf22017-05-04 15:04:011329 EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
weiliangce3f09a612016-03-16 17:02:521330 EXPECT_FALSE(parent->is_clipped());
1331 EXPECT_FALSE(child1->is_clipped());
1332 EXPECT_TRUE(child2->is_clipped());
chrishtr7e3aaf22017-05-04 15:04:011333 EXPECT_FALSE(GetRenderSurface(child2)->is_clipped());
weiliangce3f09a612016-03-16 17:02:521334 EXPECT_FALSE(grand_child->is_clipped());
1335 EXPECT_FALSE(leaf_node1->is_clipped());
1336 EXPECT_TRUE(leaf_node2->is_clipped());
1337}
1338
Xianzhu Wang66e13e02019-09-18 20:39:121339TEST_F(DrawPropertiesTest, UpdateClipRectCorrectly) {
weiliangce3f09a612016-03-16 17:02:521340 // Tests that when as long as layer is clipped, it's clip rect is set to
1341 // correct value.
Xianzhu Wangd6a62d82019-09-09 22:35:361342 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271343 LayerImpl* parent = AddLayer<LayerImpl>();
1344 LayerImpl* child = AddLayer<LayerImpl>();
weiliangce3f09a612016-03-16 17:02:521345
danakje4fa7b72016-07-25 22:00:061346 root->SetBounds(gfx::Size(100, 100));
weiliangce3f09a612016-03-16 17:02:521347 root->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:061348 parent->SetBounds(gfx::Size(100, 100));
weiliangce3f09a612016-03-16 17:02:521349 parent->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:061350 child->SetBounds(gfx::Size(100, 100));
weiliangce3f09a612016-03-16 17:02:521351 child->SetDrawsContent(true);
weiliangce3f09a612016-03-16 17:02:521352 child->SetMasksToBounds(true);
1353
Xianzhu Wang5b429f02019-08-29 20:45:271354 CopyProperties(root, parent);
1355 CopyProperties(parent, child);
1356 CreateClipNode(child);
1357
Xianzhu Wang66e13e02019-09-18 20:39:121358 UpdateActiveTreeDrawProperties();
weiliangce3f09a612016-03-16 17:02:521359
1360 EXPECT_FALSE(root->is_clipped());
1361 EXPECT_FALSE(parent->is_clipped());
1362 EXPECT_TRUE(child->is_clipped());
1363 EXPECT_EQ(gfx::Rect(100, 100), child->clip_rect());
1364
1365 parent->SetMasksToBounds(true);
Xianzhu Wang5b429f02019-08-29 20:45:271366 CreateClipNode(parent);
1367 GetClipNode(child)->parent_id = parent->clip_tree_index();
1368 child->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f));
1369 GetClipNode(child)->clip += gfx::Vector2dF(100.f, 100.f);
weiliangce3f09a612016-03-16 17:02:521370
Xianzhu Wang66e13e02019-09-18 20:39:121371 host_impl()->active_tree()->set_needs_update_draw_properties();
1372 UpdateActiveTreeDrawProperties();
weiliangce3f09a612016-03-16 17:02:521373
1374 EXPECT_FALSE(root->is_clipped());
1375 EXPECT_TRUE(parent->is_clipped());
1376 EXPECT_TRUE(child->is_clipped());
1377 EXPECT_EQ(gfx::Rect(), child->clip_rect());
[email protected]fb661802013-03-25 01:59:321378}
1379
Xianzhu Wang66e13e02019-09-18 20:39:121380TEST_F(DrawPropertiesTest, DrawableContentRectForLayers) {
[email protected]fb661802013-03-25 01:59:321381 // Verify that layers get the appropriate DrawableContentRect when their
danakje4fa7b72016-07-25 22:00:061382 // parent MasksToBounds is true.
[email protected]fb661802013-03-25 01:59:321383 //
1384 // grand_child1 - completely inside the region; DrawableContentRect should
1385 // be the layer rect expressed in target space.
danakje4fa7b72016-07-25 22:00:061386 // grand_child2 - partially clipped but NOT MasksToBounds; the clip rect
[email protected]fb661802013-03-25 01:59:321387 // will be the intersection of layer bounds and the mask region.
danakje4fa7b72016-07-25 22:00:061388 // grand_child3 - partially clipped and MasksToBounds; the
[email protected]fb661802013-03-25 01:59:321389 // DrawableContentRect will still be the intersection of layer bounds and
1390 // the mask region.
1391 // grand_child4 - outside parent's clip rect; the DrawableContentRect should
1392 // be empty.
[email protected]fb661802013-03-25 01:59:321393
Xianzhu Wangd6a62d82019-09-09 22:35:361394 LayerImpl* parent = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271395 LayerImpl* child = AddLayer<LayerImpl>();
1396 LayerImpl* grand_child1 = AddLayer<LayerImpl>();
1397 LayerImpl* grand_child2 = AddLayer<LayerImpl>();
1398 LayerImpl* grand_child3 = AddLayer<LayerImpl>();
1399 LayerImpl* grand_child4 = AddLayer<LayerImpl>();
[email protected]fb661802013-03-25 01:59:321400
danakje4fa7b72016-07-25 22:00:061401 parent->SetBounds(gfx::Size(500, 500));
[email protected]fb661802013-03-25 01:59:321402 child->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:061403 child->SetBounds(gfx::Size(20, 20));
danakje4fa7b72016-07-25 22:00:061404 grand_child1->SetBounds(gfx::Size(10, 10));
1405 grand_child1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:061406 grand_child2->SetBounds(gfx::Size(10, 10));
1407 grand_child2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:061408 grand_child3->SetBounds(gfx::Size(10, 10));
Xianzhu Wang5b429f02019-08-29 20:45:271409 grand_child3->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:061410 grand_child3->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:061411 grand_child4->SetBounds(gfx::Size(10, 10));
1412 grand_child4->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:271413
Xianzhu Wang5b429f02019-08-29 20:45:271414 CopyProperties(parent, child);
1415 CreateTransformNode(child);
1416 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
1417 CreateClipNode(child);
1418 CopyProperties(child, grand_child1);
1419 grand_child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
1420 CopyProperties(child, grand_child2);
1421 grand_child2->SetOffsetToTransformParent(gfx::Vector2dF(15.f, 15.f));
1422 CopyProperties(child, grand_child3);
1423 grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(15.f, 15.f));
1424 CreateClipNode(grand_child3);
1425 CopyProperties(child, grand_child4);
1426 grand_child4->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f));
1427
Xianzhu Wang66e13e02019-09-18 20:39:121428 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:321429
hush6b614212014-12-04 22:37:321430 EXPECT_EQ(gfx::Rect(5, 5, 10, 10), grand_child1->drawable_content_rect());
1431 EXPECT_EQ(gfx::Rect(15, 15, 5, 5), grand_child3->drawable_content_rect());
1432 EXPECT_EQ(gfx::Rect(15, 15, 5, 5), grand_child3->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321433 EXPECT_TRUE(grand_child4->drawable_content_rect().IsEmpty());
1434}
1435
Xianzhu Wang66e13e02019-09-18 20:39:121436TEST_F(DrawPropertiesTest, ClipRectIsPropagatedCorrectlyToSurfaces) {
[email protected]fb661802013-03-25 01:59:321437 // Verify that render surfaces (and their layers) get the appropriate
danakje4fa7b72016-07-25 22:00:061438 // clip rects when their parent MasksToBounds is true.
[email protected]fb661802013-03-25 01:59:321439 //
1440 // Layers that own render surfaces (at least for now) do not inherit any
1441 // clipping; instead the surface will enforce the clip for the entire subtree.
1442 // They may still have a clip rect of their own layer bounds, however, if
danakje4fa7b72016-07-25 22:00:061443 // MasksToBounds was true.
Xianzhu Wangd6a62d82019-09-09 22:35:361444 LayerImpl* parent = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271445 LayerImpl* child = AddLayer<LayerImpl>();
1446 LayerImpl* grand_child1 = AddLayer<LayerImpl>();
1447 LayerImpl* grand_child2 = AddLayer<LayerImpl>();
1448 LayerImpl* grand_child3 = AddLayer<LayerImpl>();
1449 LayerImpl* grand_child4 = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:061450 // The leaf nodes ensure that these grand_children become render surfaces for
[email protected]fb661802013-03-25 01:59:321451 // this test.
Xianzhu Wang5b429f02019-08-29 20:45:271452 LayerImpl* leaf_node1 = AddLayer<LayerImpl>();
1453 LayerImpl* leaf_node2 = AddLayer<LayerImpl>();
1454 LayerImpl* leaf_node3 = AddLayer<LayerImpl>();
1455 LayerImpl* leaf_node4 = AddLayer<LayerImpl>();
[email protected]fb661802013-03-25 01:59:321456
danakje4fa7b72016-07-25 22:00:061457 parent->SetBounds(gfx::Size(500, 500));
1458 child->SetBounds(gfx::Size(20, 20));
[email protected]fb661802013-03-25 01:59:321459 child->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:061460 grand_child1->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061461 grand_child2->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061462 grand_child3->SetBounds(gfx::Size(10, 10));
[email protected]fb661802013-03-25 01:59:321463 grand_child3->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:061464 grand_child4->SetBounds(gfx::Size(10, 10));
[email protected]fb661802013-03-25 01:59:321465 grand_child4->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:061466 leaf_node1->SetBounds(gfx::Size(10, 10));
1467 leaf_node1->SetDrawsContent(true);
1468 leaf_node2->SetBounds(gfx::Size(10, 10));
1469 leaf_node2->SetDrawsContent(true);
1470 leaf_node3->SetBounds(gfx::Size(10, 10));
1471 leaf_node3->SetDrawsContent(true);
1472 leaf_node4->SetBounds(gfx::Size(10, 10));
1473 leaf_node4->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:271474
Xianzhu Wang5b429f02019-08-29 20:45:271475 CopyProperties(parent, child);
1476 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
1477 CreateClipNode(child);
1478 CopyProperties(child, grand_child1);
1479 CreateTransformNode(grand_child1).post_translation = gfx::Vector2dF(5.f, 5.f);
1480 CreateEffectNode(grand_child1).render_surface_reason =
1481 RenderSurfaceReason::kTest;
1482 CopyProperties(grand_child1, leaf_node1);
1483 CopyProperties(child, grand_child2);
1484 CreateTransformNode(grand_child2).post_translation =
1485 gfx::Vector2dF(15.f, 15.f);
1486 CreateEffectNode(grand_child2).render_surface_reason =
1487 RenderSurfaceReason::kTest;
1488 CopyProperties(grand_child2, leaf_node2);
1489 CopyProperties(child, grand_child3);
1490 CreateTransformNode(grand_child3).post_translation =
1491 gfx::Vector2dF(15.f, 15.f);
1492 CreateEffectNode(grand_child3).render_surface_reason =
1493 RenderSurfaceReason::kTest;
1494 CreateClipNode(grand_child3);
1495 CopyProperties(grand_child3, leaf_node3);
1496 CopyProperties(child, grand_child4);
1497 CreateTransformNode(grand_child4).post_translation =
1498 gfx::Vector2dF(45.f, 45.f);
1499 CreateEffectNode(grand_child4).render_surface_reason =
1500 RenderSurfaceReason::kTest;
1501 CreateClipNode(grand_child4);
1502 CopyProperties(grand_child4, leaf_node4);
1503
Xianzhu Wang66e13e02019-09-18 20:39:121504 UpdateActiveTreeDrawProperties();
weiliangcfb3d5eaa2015-07-28 23:54:571505
chrishtr7e3aaf22017-05-04 15:04:011506 ASSERT_TRUE(GetRenderSurface(grand_child1));
1507 ASSERT_TRUE(GetRenderSurface(grand_child2));
1508 ASSERT_TRUE(GetRenderSurface(grand_child3));
[email protected]fb661802013-03-25 01:59:321509
1510 // Surfaces are clipped by their parent, but un-affected by the owning layer's
danakje4fa7b72016-07-25 22:00:061511 // MasksToBounds.
hush6b614212014-12-04 22:37:321512 EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
chrishtr7e3aaf22017-05-04 15:04:011513 GetRenderSurface(grand_child1)->clip_rect());
hush6b614212014-12-04 22:37:321514 EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
chrishtr7e3aaf22017-05-04 15:04:011515 GetRenderSurface(grand_child2)->clip_rect());
hush6b614212014-12-04 22:37:321516 EXPECT_EQ(gfx::Rect(0, 0, 20, 20),
chrishtr7e3aaf22017-05-04 15:04:011517 GetRenderSurface(grand_child3)->clip_rect());
[email protected]fb661802013-03-25 01:59:321518}
1519
Xianzhu Wang66e13e02019-09-18 20:39:121520TEST_F(DrawPropertiesTest, AnimationsForRenderSurfaceHierarchy) {
Xianzhu Wangd6a62d82019-09-09 22:35:361521 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271522 LayerImpl* top = AddLayer<LayerImpl>();
1523 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
1524 LayerImpl* child_of_rs1 = AddLayer<LayerImpl>();
1525 LayerImpl* grand_child_of_rs1 = AddLayer<LayerImpl>();
1526 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
1527 LayerImpl* child_of_rs2 = AddLayer<LayerImpl>();
1528 LayerImpl* grand_child_of_rs2 = AddLayer<LayerImpl>();
1529 LayerImpl* child_of_top = AddLayer<LayerImpl>();
1530 LayerImpl* grand_child_of_top = AddLayer<LayerImpl>();
Xianzhu Wangc62ecebf2019-08-31 15:54:131531 SetElementIdsForTesting();
[email protected]fb661802013-03-25 01:59:321532
Xianzhu Wang1ff8cf382019-08-19 17:33:101533 top->SetDrawsContent(true);
jaydasika8640f9f2015-11-10 01:34:361534 render_surface1->SetDrawsContent(true);
1535 child_of_rs1->SetDrawsContent(true);
enneab0fee42015-07-07 17:36:421536 grand_child_of_rs1->SetDrawsContent(true);
jaydasika8640f9f2015-11-10 01:34:361537 render_surface2->SetDrawsContent(true);
1538 child_of_rs2->SetDrawsContent(true);
enneab0fee42015-07-07 17:36:421539 grand_child_of_rs2->SetDrawsContent(true);
Xianzhu Wang1ff8cf382019-08-19 17:33:101540 child_of_top->SetDrawsContent(true);
1541 grand_child_of_top->SetDrawsContent(true);
[email protected]fb661802013-03-25 01:59:321542
1543 gfx::Transform layer_transform;
1544 layer_transform.Translate(1.0, 1.0);
[email protected]fb661802013-03-25 01:59:321545
danakje4fa7b72016-07-25 22:00:061546 root->SetBounds(gfx::Size(10, 10));
Xianzhu Wang1ff8cf382019-08-19 17:33:101547 top->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061548 render_surface1->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061549 render_surface2->SetBounds(gfx::Size(10, 10));
Xianzhu Wang1ff8cf382019-08-19 17:33:101550 child_of_top->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061551 child_of_rs1->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061552 child_of_rs2->SetBounds(gfx::Size(10, 10));
Xianzhu Wang1ff8cf382019-08-19 17:33:101553 grand_child_of_top->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061554 grand_child_of_rs1->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061555 grand_child_of_rs2->SetBounds(gfx::Size(10, 10));
[email protected]fb661802013-03-25 01:59:321556
Xianzhu Wang5b429f02019-08-29 20:45:271557 CopyProperties(root, top);
1558 CreateTransformNode(top).local = layer_transform;
1559 CopyProperties(top, render_surface1);
1560 auto& render_surface1_transform_node = CreateTransformNode(render_surface1);
1561 render_surface1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1562 render_surface1_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
1563 render_surface1_transform_node.local = layer_transform;
1564 CreateEffectNode(render_surface1).render_surface_reason =
1565 RenderSurfaceReason::kTest;
1566 CopyProperties(render_surface1, child_of_rs1);
1567 auto& child_of_rs1_transform_node = CreateTransformNode(child_of_rs1);
1568 child_of_rs1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1569 child_of_rs1_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
1570 child_of_rs1_transform_node.local = layer_transform;
1571 CopyProperties(child_of_rs1, grand_child_of_rs1);
1572 auto& grand_child_of_rs1_transform_node =
1573 CreateTransformNode(grand_child_of_rs1);
1574 grand_child_of_rs1_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1575 grand_child_of_rs1_transform_node.post_translation =
1576 gfx::Vector2dF(2.5f, 0.f);
1577 grand_child_of_rs1_transform_node.local = layer_transform;
1578 CopyProperties(render_surface1, render_surface2);
1579 auto& render_surface2_transform_node = CreateTransformNode(render_surface2);
1580 render_surface2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1581 render_surface2_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
1582 render_surface2_transform_node.local = layer_transform;
1583 CreateEffectNode(render_surface2).render_surface_reason =
1584 RenderSurfaceReason::kTest;
1585 CopyProperties(render_surface2, child_of_rs2);
1586 auto& child_of_rs2_transform_node = CreateTransformNode(child_of_rs2);
1587 child_of_rs2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1588 child_of_rs2_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
1589 child_of_rs2_transform_node.local = layer_transform;
1590 CopyProperties(child_of_rs2, grand_child_of_rs2);
1591 auto& grand_child_of_rs2_transform_node =
1592 CreateTransformNode(grand_child_of_rs2);
1593 grand_child_of_rs2_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1594 grand_child_of_rs2_transform_node.post_translation =
1595 gfx::Vector2dF(2.5f, 0.f);
1596 grand_child_of_rs2_transform_node.local = layer_transform;
1597 CopyProperties(top, child_of_top);
1598 auto& child_of_top_transform_node = CreateTransformNode(child_of_top);
1599 child_of_top_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1600 child_of_top_transform_node.post_translation = gfx::Vector2dF(2.5f, 0.f);
1601 child_of_top_transform_node.local = layer_transform;
1602 CopyProperties(child_of_top, grand_child_of_top);
1603 auto& grand_child_of_top_transform_node =
1604 CreateTransformNode(grand_child_of_top);
1605 grand_child_of_top_transform_node.origin = gfx::Point3F(0.25f, 0.f, 0.f);
1606 grand_child_of_top_transform_node.post_translation =
1607 gfx::Vector2dF(2.5f, 0.f);
1608 grand_child_of_top_transform_node.local = layer_transform;
jaydasika9cb21c772016-05-10 22:37:081609
loyso9556c732016-03-11 07:54:581610 // Put an animated opacity on the render surface.
Yi Guaa830ff2018-02-22 03:09:111611 AddOpacityTransitionToElementWithAnimation(
vollickef2ae922016-06-29 17:54:271612 render_surface1->element_id(), timeline_impl(), 10.0, 1.f, 0.f, false);
[email protected]fb661802013-03-25 01:59:321613
loyso9556c732016-03-11 07:54:581614 // Also put an animated opacity on a layer without descendants.
Xianzhu Wang1ff8cf382019-08-19 17:33:101615 AddOpacityTransitionToElementWithAnimation(
1616 grand_child_of_top->element_id(), timeline_impl(), 10.0, 1.f, 0.f, false);
[email protected]fb661802013-03-25 01:59:321617
loyso9556c732016-03-11 07:54:581618 // Put a transform animation on the render surface.
Yi Guaa830ff2018-02-22 03:09:111619 AddAnimatedTransformToElementWithAnimation(render_surface2->element_id(),
1620 timeline_impl(), 10.0, 30, 0);
[email protected]fb661802013-03-25 01:59:321621
Xianzhu Wang1ff8cf382019-08-19 17:33:101622 // Also put transform animations on grand_child_of_top, and
loyso9556c732016-03-11 07:54:581623 // grand_child_of_rs2
Xianzhu Wang1ff8cf382019-08-19 17:33:101624 AddAnimatedTransformToElementWithAnimation(grand_child_of_top->element_id(),
Yi Guaa830ff2018-02-22 03:09:111625 timeline_impl(), 10.0, 30, 0);
1626 AddAnimatedTransformToElementWithAnimation(grand_child_of_rs2->element_id(),
1627 timeline_impl(), 10.0, 30, 0);
[email protected]fb661802013-03-25 01:59:321628
Xianzhu Wang66e13e02019-09-18 20:39:121629 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:321630
1631 // Only layers that are associated with render surfaces should have an actual
1632 // RenderSurface() value.
chrishtr7e3aaf22017-05-04 15:04:011633 ASSERT_TRUE(GetRenderSurface(root));
Xianzhu Wang1ff8cf382019-08-19 17:33:101634 ASSERT_EQ(GetRenderSurface(top), GetRenderSurface(root));
1635 ASSERT_EQ(GetRenderSurface(child_of_top), GetRenderSurface(root));
1636 ASSERT_EQ(GetRenderSurface(grand_child_of_top), GetRenderSurface(root));
[email protected]fb661802013-03-25 01:59:321637
chrishtr5f60ca02017-05-11 23:09:491638 ASSERT_NE(GetRenderSurface(render_surface1), GetRenderSurface(root));
1639 ASSERT_EQ(GetRenderSurface(child_of_rs1), GetRenderSurface(render_surface1));
1640 ASSERT_EQ(GetRenderSurface(grand_child_of_rs1),
1641 GetRenderSurface(render_surface1));
[email protected]fb661802013-03-25 01:59:321642
chrishtr5f60ca02017-05-11 23:09:491643 ASSERT_NE(GetRenderSurface(render_surface2), GetRenderSurface(root));
1644 ASSERT_NE(GetRenderSurface(render_surface2),
1645 GetRenderSurface(render_surface1));
1646 ASSERT_EQ(GetRenderSurface(child_of_rs2), GetRenderSurface(render_surface2));
1647 ASSERT_EQ(GetRenderSurface(grand_child_of_rs2),
1648 GetRenderSurface(render_surface2));
[email protected]fb661802013-03-25 01:59:321649
1650 // Verify all render target accessors
chrishtr7e3aaf22017-05-04 15:04:011651 EXPECT_EQ(GetRenderSurface(root), root->render_target());
Xianzhu Wang1ff8cf382019-08-19 17:33:101652 EXPECT_EQ(GetRenderSurface(root), top->render_target());
1653 EXPECT_EQ(GetRenderSurface(root), child_of_top->render_target());
1654 EXPECT_EQ(GetRenderSurface(root), grand_child_of_top->render_target());
[email protected]fb661802013-03-25 01:59:321655
chrishtr7e3aaf22017-05-04 15:04:011656 EXPECT_EQ(GetRenderSurface(render_surface1),
weiliangc189c1a12016-04-11 16:16:251657 render_surface1->render_target());
chrishtr7e3aaf22017-05-04 15:04:011658 EXPECT_EQ(GetRenderSurface(render_surface1), child_of_rs1->render_target());
1659 EXPECT_EQ(GetRenderSurface(render_surface1),
weiliangc189c1a12016-04-11 16:16:251660 grand_child_of_rs1->render_target());
[email protected]fb661802013-03-25 01:59:321661
chrishtr7e3aaf22017-05-04 15:04:011662 EXPECT_EQ(GetRenderSurface(render_surface2),
weiliangc189c1a12016-04-11 16:16:251663 render_surface2->render_target());
chrishtr7e3aaf22017-05-04 15:04:011664 EXPECT_EQ(GetRenderSurface(render_surface2), child_of_rs2->render_target());
1665 EXPECT_EQ(GetRenderSurface(render_surface2),
weiliangc189c1a12016-04-11 16:16:251666 grand_child_of_rs2->render_target());
[email protected]fb661802013-03-25 01:59:321667
[email protected]fb661802013-03-25 01:59:321668 // Verify screen_space_transform_is_animating values
danakje4fa7b72016-07-25 22:00:061669 EXPECT_FALSE(root->screen_space_transform_is_animating());
Xianzhu Wang1ff8cf382019-08-19 17:33:101670 EXPECT_FALSE(child_of_top->screen_space_transform_is_animating());
1671 EXPECT_TRUE(grand_child_of_top->screen_space_transform_is_animating());
[email protected]fb661802013-03-25 01:59:321672 EXPECT_FALSE(render_surface1->screen_space_transform_is_animating());
[email protected]fb661802013-03-25 01:59:321673 EXPECT_FALSE(child_of_rs1->screen_space_transform_is_animating());
1674 EXPECT_FALSE(grand_child_of_rs1->screen_space_transform_is_animating());
1675 EXPECT_TRUE(render_surface2->screen_space_transform_is_animating());
[email protected]fb661802013-03-25 01:59:321676 EXPECT_TRUE(child_of_rs2->screen_space_transform_is_animating());
1677 EXPECT_TRUE(grand_child_of_rs2->screen_space_transform_is_animating());
1678
1679 // Sanity check. If these fail there is probably a bug in the test itself.
1680 // It is expected that we correctly set up transforms so that the y-component
1681 // of the screen-space transform encodes the "depth" of the layer in the tree.
Xianzhu Wang1ff8cf382019-08-19 17:33:101682 EXPECT_FLOAT_EQ(1.0, top->ScreenSpaceTransform().matrix().get(1, 3));
1683 EXPECT_FLOAT_EQ(2.0, child_of_top->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:321684 EXPECT_FLOAT_EQ(
Xianzhu Wang1ff8cf382019-08-19 17:33:101685 3.0, grand_child_of_top->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:321686
[email protected]803f6b52013-09-12 00:51:261687 EXPECT_FLOAT_EQ(2.0,
ajumab6aa1c62015-12-01 21:01:101688 render_surface1->ScreenSpaceTransform().matrix().get(1, 3));
1689 EXPECT_FLOAT_EQ(3.0, child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:321690 EXPECT_FLOAT_EQ(
ajumab6aa1c62015-12-01 21:01:101691 4.0, grand_child_of_rs1->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:321692
[email protected]803f6b52013-09-12 00:51:261693 EXPECT_FLOAT_EQ(3.0,
ajumab6aa1c62015-12-01 21:01:101694 render_surface2->ScreenSpaceTransform().matrix().get(1, 3));
1695 EXPECT_FLOAT_EQ(4.0, child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:321696 EXPECT_FLOAT_EQ(
ajumab6aa1c62015-12-01 21:01:101697 5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3));
[email protected]fb661802013-03-25 01:59:321698}
1699
Xianzhu Wang66e13e02019-09-18 20:39:121700TEST_F(DrawPropertiesTest, LargeTransforms) {
Xianzhu Wangd6a62d82019-09-09 22:35:361701 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271702 LayerImpl* child = AddLayer<LayerImpl>();
1703 LayerImpl* grand_child = AddLayer<LayerImpl>();
ajuma9384b9c22015-09-17 20:35:031704
ajuma9384b9c22015-09-17 20:35:031705 gfx::Transform large_transform;
1706 large_transform.Scale(SkDoubleToMScalar(1e37), SkDoubleToMScalar(1e37));
1707
danakje4fa7b72016-07-25 22:00:061708 root->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061709 child->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:061710 grand_child->SetBounds(gfx::Size(10, 10));
1711 grand_child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:271712
Xianzhu Wang5b429f02019-08-29 20:45:271713 CopyProperties(root, child);
1714 CreateTransformNode(child).local = large_transform;
1715 CopyProperties(child, grand_child);
1716 CreateTransformNode(grand_child).local = large_transform;
1717
Xianzhu Wang66e13e02019-09-18 20:39:121718 UpdateActiveTreeDrawProperties();
ajuma9384b9c22015-09-17 20:35:031719
1720 EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect());
1721}
1722
wkorman15d86862017-05-12 18:18:241723static bool TransformIsAnimating(LayerImpl* layer) {
danakj3d35a7812018-06-18 20:08:011724 MutatorHost* host = layer->layer_tree_impl()->mutator_host();
1725 return host->IsAnimatingTransformProperty(
wkorman15d86862017-05-12 18:18:241726 layer->element_id(), layer->GetElementTypeForAnimation());
1727}
1728
Walter Kormanaf60f632017-08-24 22:52:391729static bool HasPotentiallyRunningTransformAnimation(LayerImpl* layer) {
danakj3d35a7812018-06-18 20:08:011730 MutatorHost* host = layer->layer_tree_impl()->mutator_host();
1731 return host->HasPotentiallyRunningTransformAnimation(
Walter Kormanaf60f632017-08-24 22:52:391732 layer->element_id(), layer->GetElementTypeForAnimation());
1733}
1734
Xianzhu Wang66e13e02019-09-18 20:39:121735TEST_F(DrawPropertiesTest,
ajuma315a4782015-07-24 21:16:341736 ScreenSpaceTransformIsAnimatingWithDelayedAnimation) {
Xianzhu Wangd6a62d82019-09-09 22:35:361737 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:271738 LayerImpl* child = AddLayer<LayerImpl>();
1739 LayerImpl* grand_child = AddLayer<LayerImpl>();
1740 LayerImpl* great_grand_child = AddLayer<LayerImpl>();
ajuma315a4782015-07-24 21:16:341741
danakje4fa7b72016-07-25 22:00:061742 root->SetDrawsContent(true);
ajuma315a4782015-07-24 21:16:341743 child->SetDrawsContent(true);
1744 grand_child->SetDrawsContent(true);
1745 great_grand_child->SetDrawsContent(true);
1746
danakje4fa7b72016-07-25 22:00:061747 root->SetBounds(gfx::Size(10, 10));
1748 child->SetBounds(gfx::Size(10, 10));
1749 grand_child->SetBounds(gfx::Size(10, 10));
1750 great_grand_child->SetBounds(gfx::Size(10, 10));
ajuma315a4782015-07-24 21:16:341751
vollickef2ae922016-06-29 17:54:271752 SetElementIdsForTesting();
1753
Xianzhu Wang5b429f02019-08-29 20:45:271754 CopyProperties(root, child);
1755 CopyProperties(child, grand_child);
1756 CreateTransformNode(grand_child); // for animation.
1757 CopyProperties(grand_child, great_grand_child);
1758
ajuma315a4782015-07-24 21:16:341759 // Add a transform animation with a start delay to |grand_child|.
Yi Gu3904dc22018-02-15 18:35:241760 std::unique_ptr<KeyframeModel> keyframe_model = KeyframeModel::Create(
danakj60bc3bc2016-04-09 00:24:481761 std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)), 0, 1,
loyso0c8e4402016-02-25 04:12:301762 TargetProperty::TRANSFORM);
Yi Gu3904dc22018-02-15 18:35:241763 keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
1764 keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
Yi Guaa830ff2018-02-22 03:09:111765 AddKeyframeModelToElementWithAnimation(
Yi Gu3904dc22018-02-15 18:35:241766 grand_child->element_id(), timeline_impl(), std::move(keyframe_model));
Xianzhu Wang5b429f02019-08-29 20:45:271767
Xianzhu Wang66e13e02019-09-18 20:39:121768 UpdateActiveTreeDrawProperties();
ajuma315a4782015-07-24 21:16:341769
danakje4fa7b72016-07-25 22:00:061770 EXPECT_FALSE(root->screen_space_transform_is_animating());
ajuma315a4782015-07-24 21:16:341771 EXPECT_FALSE(child->screen_space_transform_is_animating());
1772
wkorman15d86862017-05-12 18:18:241773 EXPECT_FALSE(TransformIsAnimating(grand_child));
Walter Kormanaf60f632017-08-24 22:52:391774 EXPECT_TRUE(HasPotentiallyRunningTransformAnimation(grand_child));
ajuma315a4782015-07-24 21:16:341775 EXPECT_TRUE(grand_child->screen_space_transform_is_animating());
1776 EXPECT_TRUE(great_grand_child->screen_space_transform_is_animating());
1777}
1778
Xianzhu Wang5b429f02019-08-29 20:45:271779// Test visible layer rect and drawable content rect are calculated correctly
1780// for identity transforms.
Xianzhu Wang66e13e02019-09-18 20:39:121781TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForIdentityTransform) {
[email protected]2c7c6702013-03-26 03:14:051782 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
[email protected]fb661802013-03-25 01:59:321783 gfx::Transform layer_to_surface_transform;
1784
1785 // Case 1: Layer is contained within the surface.
[email protected]989386c2013-07-18 21:37:231786 gfx::Rect layer_content_rect = gfx::Rect(10, 10, 30, 30);
weiliangc6da32862016-04-20 16:40:111787 gfx::Rect expected_visible_layer_rect = gfx::Rect(30, 30);
1788 gfx::Rect expected_drawable_content_rect = gfx::Rect(10, 10, 30, 30);
1789 LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
1790 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1791 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1792 EXPECT_EQ(expected_drawable_content_rect,
1793 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321794
1795 // Case 2: Layer is outside the surface rect.
[email protected]2c7c6702013-03-26 03:14:051796 layer_content_rect = gfx::Rect(120, 120, 30, 30);
weiliangc6da32862016-04-20 16:40:111797 expected_visible_layer_rect = gfx::Rect();
1798 expected_drawable_content_rect = gfx::Rect();
1799 drawing_layer = TestVisibleRectAndDrawableContentRect(
1800 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1801 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1802 EXPECT_EQ(expected_drawable_content_rect,
1803 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321804
1805 // Case 3: Layer is partially overlapping the surface rect.
[email protected]2c7c6702013-03-26 03:14:051806 layer_content_rect = gfx::Rect(80, 80, 30, 30);
weiliangc6da32862016-04-20 16:40:111807 expected_visible_layer_rect = gfx::Rect(20, 20);
1808 expected_drawable_content_rect = gfx::Rect(80, 80, 20, 20);
1809 drawing_layer = TestVisibleRectAndDrawableContentRect(
1810 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1811 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1812 EXPECT_EQ(expected_drawable_content_rect,
1813 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321814}
1815
Xianzhu Wang5b429f02019-08-29 20:45:271816// Test visible layer rect and drawable content rect are calculated correctly
1817// for rotations about z-axis (i.e. 2D rotations).
Xianzhu Wang66e13e02019-09-18 20:39:121818TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor2DRotations) {
[email protected]2c7c6702013-03-26 03:14:051819 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
1820 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30);
[email protected]fb661802013-03-25 01:59:321821 gfx::Transform layer_to_surface_transform;
1822
1823 // Case 1: Layer is contained within the surface.
1824 layer_to_surface_transform.MakeIdentity();
1825 layer_to_surface_transform.Translate(50.0, 50.0);
1826 layer_to_surface_transform.Rotate(45.0);
weiliangc6da32862016-04-20 16:40:111827 gfx::Rect expected_visible_layer_rect = gfx::Rect(30, 30);
1828 gfx::Rect expected_drawable_content_rect = gfx::Rect(28, 50, 44, 43);
1829 LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
1830 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1831 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1832 EXPECT_EQ(expected_drawable_content_rect,
1833 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321834
1835 // Case 2: Layer is outside the surface rect.
1836 layer_to_surface_transform.MakeIdentity();
1837 layer_to_surface_transform.Translate(-50.0, 0.0);
1838 layer_to_surface_transform.Rotate(45.0);
weiliangc6da32862016-04-20 16:40:111839 expected_visible_layer_rect = gfx::Rect();
1840 expected_drawable_content_rect = gfx::Rect();
1841 drawing_layer = TestVisibleRectAndDrawableContentRect(
1842 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1843 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1844 EXPECT_EQ(expected_drawable_content_rect,
1845 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321846
1847 // Case 3: The layer is rotated about its top-left corner. In surface space,
1848 // the layer is oriented diagonally, with the left half outside of the render
1849 // surface. In this case, the g should still be the entire layer
1850 // (remember the g is computed in layer space); both the top-left
1851 // and bottom-right corners of the layer are still visible.
1852 layer_to_surface_transform.MakeIdentity();
1853 layer_to_surface_transform.Rotate(45.0);
weiliangc6da32862016-04-20 16:40:111854 expected_visible_layer_rect = gfx::Rect(30, 30);
1855 expected_drawable_content_rect = gfx::Rect(22, 43);
1856 drawing_layer = TestVisibleRectAndDrawableContentRect(
1857 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1858 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1859 EXPECT_EQ(expected_drawable_content_rect,
1860 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321861
1862 // Case 4: The layer is rotated about its top-left corner, and translated
1863 // upwards. In surface space, the layer is oriented diagonally, with only the
1864 // top corner of the surface overlapping the layer. In layer space, the render
1865 // surface overlaps the right side of the layer. The g should be
1866 // the layer's right half.
1867 layer_to_surface_transform.MakeIdentity();
1868 layer_to_surface_transform.Translate(0.0, -sqrt(2.0) * 15.0);
1869 layer_to_surface_transform.Rotate(45.0);
weiliangc6da32862016-04-20 16:40:111870 // Right half of layer bounds.
1871 expected_visible_layer_rect = gfx::Rect(15, 0, 15, 30);
1872 expected_drawable_content_rect = gfx::Rect(22, 22);
1873 drawing_layer = TestVisibleRectAndDrawableContentRect(
1874 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1875 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1876 EXPECT_EQ(expected_drawable_content_rect,
1877 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321878}
1879
Xianzhu Wang5b429f02019-08-29 20:45:271880// Test visible layer rect and drawable content rect are calculated correctly
1881// for 3d transforms.
Xianzhu Wang66e13e02019-09-18 20:39:121882TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dOrthographicTransform) {
[email protected]2c7c6702013-03-26 03:14:051883 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
1884 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
[email protected]fb661802013-03-25 01:59:321885 gfx::Transform layer_to_surface_transform;
1886
1887 // Case 1: Orthographic projection of a layer rotated about y-axis by 45
1888 // degrees, should be fully contained in the render surface.
weiliangc6da32862016-04-20 16:40:111889 // 100 is the un-rotated layer width; divided by sqrt(2) is the rotated width.
[email protected]fb661802013-03-25 01:59:321890 layer_to_surface_transform.MakeIdentity();
1891 layer_to_surface_transform.RotateAboutYAxis(45.0);
weiliangc6da32862016-04-20 16:40:111892 gfx::Rect expected_visible_layer_rect = gfx::Rect(100, 100);
1893 gfx::Rect expected_drawable_content_rect = gfx::Rect(71, 100);
1894 LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
1895 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1896 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1897 EXPECT_EQ(expected_drawable_content_rect,
1898 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321899
1900 // Case 2: Orthographic projection of a layer rotated about y-axis by 45
1901 // degrees, but shifted to the side so only the right-half the layer would be
1902 // visible on the surface.
weiliangc6da32862016-04-20 16:40:111903 // 50 is the un-rotated layer width; divided by sqrt(2) is the rotated width.
[email protected]803f6b52013-09-12 00:51:261904 SkMScalar half_width_of_rotated_layer =
1905 SkDoubleToMScalar((100.0 / sqrt(2.0)) * 0.5);
[email protected]fb661802013-03-25 01:59:321906 layer_to_surface_transform.MakeIdentity();
1907 layer_to_surface_transform.Translate(-half_width_of_rotated_layer, 0.0);
[email protected]989386c2013-07-18 21:37:231908 layer_to_surface_transform.RotateAboutYAxis(45.0); // Rotates about the left
1909 // edge of the layer.
weiliangc6da32862016-04-20 16:40:111910 // Tight half of the layer.
1911 expected_visible_layer_rect = gfx::Rect(50, 0, 50, 100);
1912 expected_drawable_content_rect = gfx::Rect(36, 100);
1913 drawing_layer = TestVisibleRectAndDrawableContentRect(
1914 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1915 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1916 EXPECT_EQ(expected_drawable_content_rect,
1917 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321918}
1919
Xianzhu Wang5b429f02019-08-29 20:45:271920// Test visible layer rect and drawable content rect are calculated correctly
1921// when the layer has a perspective projection onto the target surface.
Xianzhu Wang66e13e02019-09-18 20:39:121922TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveTransform) {
[email protected]2c7c6702013-03-26 03:14:051923 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
1924 gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200);
[email protected]fb661802013-03-25 01:59:321925 gfx::Transform layer_to_surface_transform;
1926
1927 // Case 1: Even though the layer is twice as large as the surface, due to
1928 // perspective foreshortening, the layer will fit fully in the surface when
1929 // its translated more than the perspective amount.
1930 layer_to_surface_transform.MakeIdentity();
1931
1932 // The following sequence of transforms applies the perspective about the
1933 // center of the surface.
1934 layer_to_surface_transform.Translate(50.0, 50.0);
1935 layer_to_surface_transform.ApplyPerspectiveDepth(9.0);
1936 layer_to_surface_transform.Translate(-50.0, -50.0);
1937
1938 // This translate places the layer in front of the surface's projection plane.
1939 layer_to_surface_transform.Translate3d(0.0, 0.0, -27.0);
1940
weiliangc6da32862016-04-20 16:40:111941 // Layer position is (-50, -50), visible rect in layer space is layer bounds
1942 // offset by layer position.
1943 gfx::Rect expected_visible_layer_rect = gfx::Rect(50, 50, 150, 150);
1944 gfx::Rect expected_drawable_content_rect = gfx::Rect(38, 38);
1945 LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
1946 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1947 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1948 EXPECT_EQ(expected_drawable_content_rect,
1949 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321950
1951 // Case 2: same projection as before, except that the layer is also translated
1952 // to the side, so that only the right half of the layer should be visible.
1953 //
1954 // Explanation of expected result: The perspective ratio is (z distance
1955 // between layer and camera origin) / (z distance between projection plane and
1956 // camera origin) == ((-27 - 9) / 9) Then, by similar triangles, if we want to
weiliangc6da32862016-04-20 16:40:111957 // move a layer by translating -25 units in projected surface units (so that
[email protected]fb661802013-03-25 01:59:321958 // only half of it is visible), then we would need to translate by (-36 / 9) *
weiliangc6da32862016-04-20 16:40:111959 // -25 == -100 in the layer's units.
1960 layer_to_surface_transform.Translate3d(-100.0, 0.0, 0.0);
1961 // Visible layer rect is moved by 100, and drawable content rect is in target
1962 // space and is moved by 25.
1963 expected_visible_layer_rect = gfx::Rect(150, 50, 50, 150);
1964 expected_drawable_content_rect = gfx::Rect(13, 38);
1965 drawing_layer = TestVisibleRectAndDrawableContentRect(
1966 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1967 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1968 EXPECT_EQ(expected_drawable_content_rect,
1969 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321970}
1971
Xianzhu Wang5b429f02019-08-29 20:45:271972// There is currently no explicit concept of an orthographic projection plane
1973// in our code (nor in the CSS spec to my knowledge). Therefore, layers that
1974// are technically behind the surface in an orthographic world should not be
1975// clipped when they are flattened to the surface.
Xianzhu Wang66e13e02019-09-18 20:39:121976TEST_F(DrawPropertiesDrawRectsTest,
weiliangc6da32862016-04-20 16:40:111977 DrawRectsFor3dOrthographicIsNotClippedBehindSurface) {
[email protected]2c7c6702013-03-26 03:14:051978 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100);
1979 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100);
[email protected]fb661802013-03-25 01:59:321980 gfx::Transform layer_to_surface_transform;
1981
1982 // This sequence of transforms effectively rotates the layer about the y-axis
1983 // at the center of the layer.
1984 layer_to_surface_transform.MakeIdentity();
1985 layer_to_surface_transform.Translate(50.0, 0.0);
1986 layer_to_surface_transform.RotateAboutYAxis(45.0);
1987 layer_to_surface_transform.Translate(-50.0, 0.0);
1988
weiliangc6da32862016-04-20 16:40:111989 // Layer is rotated about Y Axis, and its width is 100/sqrt(2) in surface
1990 // space.
1991 gfx::Rect expected_visible_layer_rect = gfx::Rect(100, 100);
1992 gfx::Rect expected_drawable_content_rect = gfx::Rect(14, 0, 72, 100);
1993 LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
1994 target_surface_rect, layer_to_surface_transform, layer_content_rect);
1995 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
1996 EXPECT_EQ(expected_drawable_content_rect,
1997 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:321998}
1999
Xianzhu Wang5b429f02019-08-29 20:45:272000// Test visible layer rect and drawable content rect are calculated correctly
2001// when projecting a surface onto a layer, but the layer is partially behind
2002// the camera (not just behind the projection plane). In this case, the
2003// cartesian coordinates may seem to be valid, but actually they are not. The
2004// visible rect needs to be properly clipped by the w = 0 plane in homogeneous
2005// coordinates before converting to cartesian coordinates. The drawable
2006// content rect would be entire surface rect because layer is rotated at the
2007// camera position.
Xianzhu Wang66e13e02019-09-18 20:39:122008TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveWhenClippedByW) {
weiliangc6da32862016-04-20 16:40:112009 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 200, 200);
2010 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 2);
[email protected]fb661802013-03-25 01:59:322011 gfx::Transform layer_to_surface_transform;
2012
2013 // The layer is positioned so that the right half of the layer should be in
2014 // front of the camera, while the other half is behind the surface's
2015 // projection plane. The following sequence of transforms applies the
2016 // perspective and rotation about the center of the layer.
2017 layer_to_surface_transform.MakeIdentity();
2018 layer_to_surface_transform.ApplyPerspectiveDepth(1.0);
weiliangc6da32862016-04-20 16:40:112019 layer_to_surface_transform.Translate3d(10.0, 0.0, 1.0);
2020 layer_to_surface_transform.RotateAboutYAxis(-45.0);
2021 layer_to_surface_transform.Translate(-10, -1);
[email protected]fb661802013-03-25 01:59:322022
2023 // Sanity check that this transform does indeed cause w < 0 when applying the
2024 // transform, otherwise this code is not testing the intended scenario.
2025 bool clipped;
2026 MathUtil::MapQuad(layer_to_surface_transform,
Xianzhu Wang5b429f02019-08-29 20:45:272027 gfx::QuadF(gfx::RectF(layer_content_rect)), &clipped);
[email protected]fb661802013-03-25 01:59:322028 ASSERT_TRUE(clipped);
2029
weiliangc6da32862016-04-20 16:40:112030 gfx::Rect expected_visible_layer_rect = gfx::Rect(0, 1, 10, 1);
2031 gfx::Rect expected_drawable_content_rect = target_surface_rect;
2032 LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
2033 target_surface_rect, layer_to_surface_transform, layer_content_rect);
2034 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
2035 EXPECT_EQ(expected_drawable_content_rect,
2036 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322037}
2038
petermayoca9b8202017-03-17 18:54:102039static bool ProjectionClips(const gfx::Transform& map_transform,
2040 const gfx::RectF& mapped_rect) {
2041 gfx::Transform inverse(Inverse(map_transform));
2042 bool clipped = false;
2043 if (!clipped)
2044 MathUtil::ProjectPoint(inverse, mapped_rect.top_right(), &clipped);
2045 if (!clipped)
2046 MathUtil::ProjectPoint(inverse, mapped_rect.origin(), &clipped);
2047 if (!clipped)
2048 MathUtil::ProjectPoint(inverse, mapped_rect.bottom_right(), &clipped);
2049 if (!clipped)
2050 MathUtil::ProjectPoint(inverse, mapped_rect.bottom_left(), &clipped);
2051 return clipped;
2052}
2053
Xianzhu Wang5b429f02019-08-29 20:45:272054// To determine visible rect in layer space, there needs to be an
2055// un-projection from surface space to layer space. When the original
2056// transform was a perspective projection that was clipped, it returns a rect
2057// that encloses the clipped bounds. Un-projecting this new rect may require
2058// clipping again.
Xianzhu Wang66e13e02019-09-18 20:39:122059TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForPerspectiveUnprojection) {
[email protected]fb661802013-03-25 01:59:322060 // This sequence of transforms causes one corner of the layer to protrude
2061 // across the w = 0 plane, and should be clipped.
weiliangc6da32862016-04-20 16:40:112062 gfx::Rect target_surface_rect = gfx::Rect(0, 0, 150, 150);
2063 gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 20);
[email protected]fb661802013-03-25 01:59:322064 gfx::Transform layer_to_surface_transform;
2065 layer_to_surface_transform.MakeIdentity();
weiliangc6da32862016-04-20 16:40:112066 layer_to_surface_transform.Translate(10, 10);
[email protected]fb661802013-03-25 01:59:322067 layer_to_surface_transform.ApplyPerspectiveDepth(1.0);
2068 layer_to_surface_transform.Translate3d(0.0, 0.0, -5.0);
2069 layer_to_surface_transform.RotateAboutYAxis(45.0);
2070 layer_to_surface_transform.RotateAboutXAxis(80.0);
weiliangc6da32862016-04-20 16:40:112071 layer_to_surface_transform.Translate(-10, -10);
[email protected]fb661802013-03-25 01:59:322072
2073 // Sanity check that un-projection does indeed cause w < 0, otherwise this
2074 // code is not testing the intended scenario.
danakj5e6ff6d2015-09-05 04:43:442075 gfx::RectF clipped_rect = MathUtil::MapClippedRect(
2076 layer_to_surface_transform, gfx::RectF(layer_content_rect));
petermayoca9b8202017-03-17 18:54:102077 ASSERT_TRUE(ProjectionClips(layer_to_surface_transform, clipped_rect));
[email protected]fb661802013-03-25 01:59:322078
2079 // Only the corner of the layer is not visible on the surface because of being
2080 // clipped. But, the net result of rounding visible region to an axis-aligned
2081 // rect is that the entire layer should still be considered visible.
weiliangc6da32862016-04-20 16:40:112082 gfx::Rect expected_visible_layer_rect = layer_content_rect;
2083 gfx::Rect expected_drawable_content_rect = target_surface_rect;
2084 LayerImpl* drawing_layer = TestVisibleRectAndDrawableContentRect(
2085 target_surface_rect, layer_to_surface_transform, layer_content_rect);
2086 EXPECT_EQ(expected_visible_layer_rect, drawing_layer->visible_layer_rect());
2087 EXPECT_EQ(expected_drawable_content_rect,
2088 drawing_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322089}
2090
Xianzhu Wang66e13e02019-09-18 20:39:122091TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSimpleLayers) {
Xianzhu Wangd6a62d82019-09-09 22:35:362092 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272093 LayerImpl* child1_layer = AddLayer<LayerImpl>();
2094 LayerImpl* child2_layer = AddLayer<LayerImpl>();
2095 LayerImpl* child3_layer = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:062096
2097 root->SetBounds(gfx::Size(100, 100));
2098 child1_layer->SetBounds(gfx::Size(50, 50));
2099 child1_layer->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062100 child2_layer->SetBounds(gfx::Size(50, 50));
2101 child2_layer->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062102 child3_layer->SetBounds(gfx::Size(50, 50));
weiliangc0dece732015-07-27 19:06:172103 child3_layer->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272104
Xianzhu Wang5b429f02019-08-29 20:45:272105 CopyProperties(root, child1_layer);
2106 CopyProperties(root, child2_layer);
2107 child2_layer->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
2108 CopyProperties(root, child3_layer);
2109 child3_layer->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));
2110
Xianzhu Wang66e13e02019-09-18 20:39:122111 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:322112
danakj5e6ff6d2015-09-05 04:43:442113 EXPECT_EQ(gfx::RectF(100.f, 100.f),
chrishtr7e3aaf22017-05-04 15:04:012114 GetRenderSurface(root)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322115
danakj64767d902015-06-19 00:10:432116 // Layers that do not draw content should have empty visible_layer_rects.
2117 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322118
danakj64767d902015-06-19 00:10:432119 // layer visible_layer_rects are clipped by their target surface.
weiliangc0dece732015-07-27 19:06:172120 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1_layer->visible_layer_rect());
2121 EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2_layer->visible_layer_rect());
2122 EXPECT_TRUE(child3_layer->visible_layer_rect().IsEmpty());
[email protected]fb661802013-03-25 01:59:322123
2124 // layer drawable_content_rects are not clipped.
weiliangc0dece732015-07-27 19:06:172125 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1_layer->drawable_content_rect());
2126 EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2_layer->drawable_content_rect());
2127 EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3_layer->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322128}
2129
Xianzhu Wang66e13e02019-09-18 20:39:122130TEST_F(DrawPropertiesTest,
[email protected]989386c2013-07-18 21:37:232131 DrawableAndVisibleContentRectsForLayersClippedByLayer) {
Xianzhu Wangd6a62d82019-09-09 22:35:362132 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272133 LayerImpl* child = AddLayer<LayerImpl>();
2134 LayerImpl* grand_child1 = AddLayer<LayerImpl>();
2135 LayerImpl* grand_child2 = AddLayer<LayerImpl>();
2136 LayerImpl* grand_child3 = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:282137
danakje4fa7b72016-07-25 22:00:062138 root->SetBounds(gfx::Size(100, 100));
2139 child->SetBounds(gfx::Size(100, 100));
[email protected]fb661802013-03-25 01:59:322140 child->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:062141 grand_child1->SetBounds(gfx::Size(50, 50));
2142 grand_child1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062143 grand_child2->SetBounds(gfx::Size(50, 50));
2144 grand_child2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062145 grand_child3->SetBounds(gfx::Size(50, 50));
2146 grand_child3->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272147
Xianzhu Wang5b429f02019-08-29 20:45:272148 CopyProperties(root, child);
2149 CreateClipNode(child);
2150 CopyProperties(child, grand_child1);
2151 grand_child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
2152 CopyProperties(child, grand_child2);
2153 grand_child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
2154 CopyProperties(child, grand_child3);
2155 grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));
2156
Xianzhu Wang66e13e02019-09-18 20:39:122157 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:322158
danakj5e6ff6d2015-09-05 04:43:442159 EXPECT_EQ(gfx::RectF(100.f, 100.f),
chrishtr7e3aaf22017-05-04 15:04:012160 GetRenderSurface(root)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322161
2162 // Layers that do not draw content should have empty visible content rects.
danakj64767d902015-06-19 00:10:432163 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
2164 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322165
2166 // All grandchild visible content rects should be clipped by child.
danakj64767d902015-06-19 00:10:432167 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), grand_child1->visible_layer_rect());
2168 EXPECT_EQ(gfx::Rect(0, 0, 25, 25), grand_child2->visible_layer_rect());
2169 EXPECT_TRUE(grand_child3->visible_layer_rect().IsEmpty());
[email protected]fb661802013-03-25 01:59:322170
2171 // All grandchild DrawableContentRects should also be clipped by child.
hush6b614212014-12-04 22:37:322172 EXPECT_EQ(gfx::Rect(5, 5, 50, 50), grand_child1->drawable_content_rect());
2173 EXPECT_EQ(gfx::Rect(75, 75, 25, 25), grand_child2->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322174 EXPECT_TRUE(grand_child3->drawable_content_rect().IsEmpty());
2175}
2176
Xianzhu Wang66e13e02019-09-18 20:39:122177TEST_F(DrawPropertiesTest, VisibleContentRectWithClippingAndScaling) {
Xianzhu Wangd6a62d82019-09-09 22:35:362178 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272179 LayerImpl* child = AddLayer<LayerImpl>();
2180 LayerImpl* grand_child = AddLayer<LayerImpl>();
ajuma27442dd2015-03-30 19:19:482181
ajuma27442dd2015-03-30 19:19:482182 gfx::Transform child_scale_matrix;
2183 child_scale_matrix.Scale(0.25f, 0.25f);
2184 gfx::Transform grand_child_scale_matrix;
2185 grand_child_scale_matrix.Scale(0.246f, 0.246f);
ajuma27442dd2015-03-30 19:19:482186
danakje4fa7b72016-07-25 22:00:062187 root->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:062188 child->SetBounds(gfx::Size(10, 10));
ajuma27442dd2015-03-30 19:19:482189 child->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:062190 grand_child->SetBounds(gfx::Size(100, 100));
jaydasika6f972de2016-04-07 16:16:142191 grand_child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272192
Xianzhu Wang5b429f02019-08-29 20:45:272193 CopyProperties(root, child);
2194 CreateTransformNode(child).local = child_scale_matrix;
2195 CreateClipNode(child);
2196 CopyProperties(child, grand_child);
2197 CreateTransformNode(grand_child).local = grand_child_scale_matrix;
2198
Xianzhu Wang66e13e02019-09-18 20:39:122199 UpdateActiveTreeDrawProperties();
ajuma27442dd2015-03-30 19:19:482200
weiliangcd15784432016-06-07 17:57:332201 // The visible rect is expanded to integer coordinates.
2202 EXPECT_EQ(gfx::Rect(41, 41), grand_child->visible_layer_rect());
ajuma27442dd2015-03-30 19:19:482203}
2204
Xianzhu Wang66e13e02019-09-18 20:39:122205TEST_F(DrawPropertiesTest, ClipRectWithClipParent) {
Xianzhu Wangd6a62d82019-09-09 22:35:362206 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272207 LayerImpl* clip = AddLayer<LayerImpl>();
2208 LayerImpl* child1 = AddLayer<LayerImpl>();
2209 LayerImpl* child2 = AddLayer<LayerImpl>();
ajumae947a352017-01-10 19:17:492210
2211 root->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc8189212019-08-28 01:32:282212 CreateClipNode(root);
2213
ajumae947a352017-01-10 19:17:492214 clip->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:282215 CopyProperties(root, clip);
2216 CreateClipNode(clip);
2217
Xianzhu Wang5b429f02019-08-29 20:45:272218 child1->SetBounds(gfx::Size(20, 20));
2219 child1->SetDrawsContent(true);
2220 CopyProperties(clip, child1);
2221 child1->SetClipTreeIndex(root->clip_tree_index());
ajumae947a352017-01-10 19:17:492222
Xianzhu Wang5b429f02019-08-29 20:45:272223 child2->SetBounds(gfx::Size(20, 20));
2224 child2->SetDrawsContent(true);
2225 CopyProperties(clip, child2);
ajumae947a352017-01-10 19:17:492226
Xianzhu Wang66e13e02019-09-18 20:39:122227 UpdateActiveTreeDrawProperties();
Xianzhu Wangc8189212019-08-28 01:32:282228
Xianzhu Wang5b429f02019-08-29 20:45:272229 EXPECT_TRUE(child1->is_clipped());
2230 EXPECT_TRUE(child2->is_clipped());
2231 EXPECT_EQ(gfx::Rect(100, 100), child1->clip_rect());
2232 EXPECT_EQ(gfx::Rect(10, 10), child2->clip_rect());
ajumae947a352017-01-10 19:17:492233}
2234
Xianzhu Wang66e13e02019-09-18 20:39:122235TEST_F(DrawPropertiesTest, ClipRectWithClippedDescendantOfFilter) {
Xianzhu Wangd6a62d82019-09-09 22:35:362236 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272237 LayerImpl* filter = AddLayer<LayerImpl>();
2238 LayerImpl* clip = AddLayer<LayerImpl>();
2239 LayerImpl* filter_grand_child = AddLayer<LayerImpl>();
ajumae947a352017-01-10 19:17:492240
2241 root->SetBounds(gfx::Size(100, 100));
ajumae947a352017-01-10 19:17:492242 clip->SetBounds(gfx::Size(10, 10));
2243 clip->SetMasksToBounds(true);
ajumae947a352017-01-10 19:17:492244 filter_grand_child->SetBounds(gfx::Size(20, 20));
2245 filter_grand_child->SetDrawsContent(true);
2246
Xianzhu Wang5b429f02019-08-29 20:45:272247 CopyProperties(root, filter);
2248 CreateEffectNode(filter).render_surface_reason = RenderSurfaceReason::kTest;
2249 CopyProperties(filter, clip);
2250 CreateClipNode(clip);
2251 CopyProperties(clip, filter_grand_child);
2252
Xianzhu Wang66e13e02019-09-18 20:39:122253 UpdateActiveTreeDrawProperties();
ajumae947a352017-01-10 19:17:492254 EXPECT_TRUE(filter_grand_child->is_clipped());
2255 EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect());
2256
2257 FilterOperations blur_filter;
2258 blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f));
Xianzhu Wang5b429f02019-08-29 20:45:272259 SetFilter(filter, blur_filter);
ajumae947a352017-01-10 19:17:492260
Xianzhu Wang66e13e02019-09-18 20:39:122261 UpdateActiveTreeDrawProperties();
ajumae947a352017-01-10 19:17:492262
2263 EXPECT_TRUE(filter_grand_child->is_clipped());
2264 EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect());
2265}
2266
Xianzhu Wang66e13e02019-09-18 20:39:122267TEST_F(DrawPropertiesTest,
[email protected]989386c2013-07-18 21:37:232268 DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:362269 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272270 LayerImpl* render_surface = AddLayer<LayerImpl>();
2271 LayerImpl* child1 = AddLayer<LayerImpl>();
2272 LayerImpl* child2 = AddLayer<LayerImpl>();
2273 LayerImpl* child3 = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:062274
2275 root->SetBounds(gfx::Size(100, 100));
2276 render_surface->SetBounds(gfx::Size(3, 4));
danakje4fa7b72016-07-25 22:00:062277 child1->SetBounds(gfx::Size(50, 50));
2278 child1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062279 child2->SetBounds(gfx::Size(50, 50));
2280 child2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062281 child3->SetBounds(gfx::Size(50, 50));
weiliangc0dece732015-07-27 19:06:172282 child3->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272283
Xianzhu Wang5b429f02019-08-29 20:45:272284 CopyProperties(root, render_surface);
2285 CreateEffectNode(render_surface).render_surface_reason =
2286 RenderSurfaceReason::kTest;
2287 CopyProperties(render_surface, child1);
2288 child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
2289 CopyProperties(render_surface, child2);
2290 child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
2291 CopyProperties(render_surface, child3);
2292 child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));
2293
Xianzhu Wang66e13e02019-09-18 20:39:122294 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:322295
chrishtr7e3aaf22017-05-04 15:04:012296 ASSERT_TRUE(GetRenderSurface(render_surface));
[email protected]fb661802013-03-25 01:59:322297
danakj5e6ff6d2015-09-05 04:43:442298 EXPECT_EQ(gfx::RectF(100.f, 100.f),
chrishtr7e3aaf22017-05-04 15:04:012299 GetRenderSurface(root)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322300
2301 // Layers that do not draw content should have empty visible content rects.
danakj64767d902015-06-19 00:10:432302 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
weiliangc0dece732015-07-27 19:06:172303 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322304
2305 // An unclipped surface grows its DrawableContentRect to include all drawable
2306 // regions of the subtree.
danakj5e6ff6d2015-09-05 04:43:442307 EXPECT_EQ(gfx::RectF(5.f, 5.f, 170.f, 170.f),
chrishtr7e3aaf22017-05-04 15:04:012308 GetRenderSurface(render_surface)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322309
2310 // All layers that draw content into the unclipped surface are also unclipped.
jaydasika94bebdd2016-09-16 22:11:182311 // Only the viewport clip should apply
danakj64767d902015-06-19 00:10:432312 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
jaydasika94bebdd2016-09-16 22:11:182313 EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
2314 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322315
hush6b614212014-12-04 22:37:322316 EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
2317 EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
2318 EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322319}
2320
Xianzhu Wang66e13e02019-09-18 20:39:122321TEST_F(DrawPropertiesTest, VisibleContentRectsForClippedSurfaceWithEmptyClip) {
Xianzhu Wangd6a62d82019-09-09 22:35:362322 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272323 LayerImpl* child1 = AddLayer<LayerImpl>();
2324 LayerImpl* child2 = AddLayer<LayerImpl>();
2325 LayerImpl* child3 = AddLayer<LayerImpl>();
hush887bb542014-12-02 22:49:022326
danakje4fa7b72016-07-25 22:00:062327 root->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:062328 child1->SetBounds(gfx::Size(50, 50));
2329 child1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062330 child2->SetBounds(gfx::Size(50, 50));
2331 child2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062332 child3->SetBounds(gfx::Size(50, 50));
2333 child3->SetDrawsContent(true);
hush887bb542014-12-02 22:49:022334
Xianzhu Wang5b429f02019-08-29 20:45:272335 CopyProperties(root, child1);
2336 child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
2337 CopyProperties(root, child2);
2338 child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
2339 CopyProperties(root, child3);
2340 child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));
2341
hush887bb542014-12-02 22:49:022342 // Now set the root render surface an empty clip.
Xianzhu Wang66e13e02019-09-18 20:39:122343 // Not using UpdateActiveTreeDrawProperties() because we want a special
2344 // device viewport rect.
2345 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect());
2346 UpdateDrawProperties(host_impl()->active_tree());
hush887bb542014-12-02 22:49:022347
chrishtr7e3aaf22017-05-04 15:04:012348 ASSERT_TRUE(GetRenderSurface(root));
hush887bb542014-12-02 22:49:022349 EXPECT_FALSE(root->is_clipped());
2350
2351 gfx::Rect empty;
chrishtr7e3aaf22017-05-04 15:04:012352 EXPECT_EQ(empty, GetRenderSurface(root)->clip_rect());
2353 EXPECT_TRUE(GetRenderSurface(root)->is_clipped());
hush887bb542014-12-02 22:49:022354
2355 // Visible content rect calculation will check if the target surface is
2356 // clipped or not. An empty clip rect does not indicate the render surface
2357 // is unclipped.
danakj64767d902015-06-19 00:10:432358 EXPECT_EQ(empty, child1->visible_layer_rect());
2359 EXPECT_EQ(empty, child2->visible_layer_rect());
2360 EXPECT_EQ(empty, child3->visible_layer_rect());
hush887bb542014-12-02 22:49:022361}
2362
Xianzhu Wang66e13e02019-09-18 20:39:122363TEST_F(DrawPropertiesTest,
[email protected]989386c2013-07-18 21:37:232364 DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) {
Xianzhu Wangd6a62d82019-09-09 22:35:362365 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272366 LayerImpl* child = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:062367
2368 root->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:062369 child->SetBounds(gfx::Size(50, 50));
weiliangc0dece732015-07-27 19:06:172370 child->SetDrawsContent(true);
[email protected]d600df7d2013-08-03 02:34:282371
[email protected]630ddad2013-08-16 03:01:322372 // Case 1: a truly degenerate matrix
[email protected]451107a32013-04-10 05:12:472373 gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
[email protected]630ddad2013-08-16 03:01:322374 ASSERT_FALSE(uninvertible_matrix.IsInvertible());
[email protected]451107a32013-04-10 05:12:472375
Xianzhu Wang5b429f02019-08-29 20:45:272376 CopyProperties(root, child);
2377 CreateTransformNode(child).local = uninvertible_matrix;
2378
Xianzhu Wang66e13e02019-09-18 20:39:122379 UpdateActiveTreeDrawProperties();
[email protected]451107a32013-04-10 05:12:472380
danakj64767d902015-06-19 00:10:432381 EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
[email protected]451107a32013-04-10 05:12:472382 EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
[email protected]630ddad2013-08-16 03:01:322383
[email protected]08bdf1b2014-04-16 23:23:292384 // Case 2: a matrix with flattened z, uninvertible and not visible according
2385 // to the CSS spec.
[email protected]630ddad2013-08-16 03:01:322386 uninvertible_matrix.MakeIdentity();
[email protected]803f6b52013-09-12 00:51:262387 uninvertible_matrix.matrix().set(2, 2, 0.0);
[email protected]630ddad2013-08-16 03:01:322388 ASSERT_FALSE(uninvertible_matrix.IsInvertible());
2389
Xianzhu Wang5b429f02019-08-29 20:45:272390 SetTransform(child, uninvertible_matrix);
Xianzhu Wang66e13e02019-09-18 20:39:122391 UpdateActiveTreeDrawProperties();
[email protected]630ddad2013-08-16 03:01:322392
danakj64767d902015-06-19 00:10:432393 EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
[email protected]08bdf1b2014-04-16 23:23:292394 EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
[email protected]630ddad2013-08-16 03:01:322395
[email protected]08bdf1b2014-04-16 23:23:292396 // Case 3: a matrix with flattened z, also uninvertible and not visible.
[email protected]630ddad2013-08-16 03:01:322397 uninvertible_matrix.MakeIdentity();
2398 uninvertible_matrix.Translate(500.0, 0.0);
[email protected]803f6b52013-09-12 00:51:262399 uninvertible_matrix.matrix().set(2, 2, 0.0);
[email protected]630ddad2013-08-16 03:01:322400 ASSERT_FALSE(uninvertible_matrix.IsInvertible());
2401
Xianzhu Wang5b429f02019-08-29 20:45:272402 SetTransform(child, uninvertible_matrix);
Xianzhu Wang66e13e02019-09-18 20:39:122403 UpdateActiveTreeDrawProperties();
[email protected]630ddad2013-08-16 03:01:322404
danakj64767d902015-06-19 00:10:432405 EXPECT_TRUE(child->visible_layer_rect().IsEmpty());
[email protected]08bdf1b2014-04-16 23:23:292406 EXPECT_TRUE(child->drawable_content_rect().IsEmpty());
[email protected]451107a32013-04-10 05:12:472407}
2408
Xianzhu Wang66e13e02019-09-18 20:39:122409TEST_F(DrawPropertiesTest,
ajumaae0dc2d2015-08-05 21:55:562410 VisibleContentRectForLayerWithUninvertibleDrawTransform) {
Xianzhu Wangd6a62d82019-09-09 22:35:362411 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272412 LayerImpl* child = AddLayer<LayerImpl>();
2413 LayerImpl* grand_child = AddLayer<LayerImpl>();
ajumaae0dc2d2015-08-05 21:55:562414
ajumaae0dc2d2015-08-05 21:55:562415 gfx::Transform perspective;
2416 perspective.ApplyPerspectiveDepth(SkDoubleToMScalar(1e-12));
2417
2418 gfx::Transform rotation;
2419 rotation.RotateAboutYAxis(45.0);
2420
danakje4fa7b72016-07-25 22:00:062421 root->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:062422 child->SetBounds(gfx::Size(100, 100));
2423 child->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062424 grand_child->SetBounds(gfx::Size(100, 100));
2425 grand_child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272426
Xianzhu Wang5b429f02019-08-29 20:45:272427 CopyProperties(root, child);
2428 auto& child_transform_node = CreateTransformNode(child);
2429 child_transform_node.flattens_inherited_transform = false;
2430 child_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f);
2431 child_transform_node.sorting_context_id = 1;
2432 child_transform_node.local = perspective;
2433 CopyProperties(child, grand_child);
2434 auto& grand_child_transform_node = CreateTransformNode(grand_child);
2435 grand_child_transform_node.flattens_inherited_transform = false;
2436 grand_child_transform_node.sorting_context_id = 1;
2437 grand_child_transform_node.local = rotation;
2438
Xianzhu Wang66e13e02019-09-18 20:39:122439 UpdateActiveTreeDrawProperties();
ajumaae0dc2d2015-08-05 21:55:562440
2441 // Though all layers have invertible transforms, matrix multiplication using
2442 // floating-point math makes the draw transform uninvertible.
Xianzhu Wang5b429f02019-08-29 20:45:272443 EXPECT_FALSE(GetTransformNode(grand_child)->ancestors_are_invertible);
ajumaae0dc2d2015-08-05 21:55:562444
sunxd71aea3e2016-04-01 23:48:052445 // CalcDrawProps skips a subtree when a layer's screen space transform is
2446 // uninvertible
2447 EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect());
ajumaae0dc2d2015-08-05 21:55:562448}
2449
Xianzhu Wang5b429f02019-08-29 20:45:272450// Needs layer tree mode: mask layer.
Xianzhu Wang66e13e02019-09-18 20:39:122451TEST_F(DrawPropertiesTestWithLayerTree, OcclusionBySiblingOfTarget) {
Xianzhu Wangc62ecebf2019-08-31 15:54:132452 auto root = Layer::Create();
2453 auto child = Layer::Create();
2454 FakeContentLayerClient client;
2455 auto surface = PictureLayer::Create(&client);
2456 auto surface_child = PictureLayer::Create(&client);
2457 auto surface_sibling = PictureLayer::Create(&client);
2458 auto surface_child_mask = PictureLayer::Create(&client);
jaydasika69c77aa2016-07-14 22:48:482459
Xianzhu Wangc62ecebf2019-08-31 15:54:132460 surface->SetIsDrawable(true);
2461 surface_child->SetIsDrawable(true);
2462 surface_sibling->SetIsDrawable(true);
2463 surface_child_mask->SetIsDrawable(true);
jaydasika69c77aa2016-07-14 22:48:482464 surface->SetContentsOpaque(true);
2465 surface_child->SetContentsOpaque(true);
2466 surface_sibling->SetContentsOpaque(true);
2467 surface_child_mask->SetContentsOpaque(true);
2468
jaydasika69c77aa2016-07-14 22:48:482469 gfx::Transform translate;
2470 translate.Translate(20.f, 20.f);
2471
danakje4fa7b72016-07-25 22:00:062472 root->SetBounds(gfx::Size(1000, 1000));
2473 child->SetBounds(gfx::Size(300, 300));
Xianzhu Wangc62ecebf2019-08-31 15:54:132474 surface->SetTransform(translate);
danakje4fa7b72016-07-25 22:00:062475 surface->SetBounds(gfx::Size(300, 300));
Xianzhu Wangc62ecebf2019-08-31 15:54:132476 surface->SetForceRenderSurfaceForTesting(true);
danakje4fa7b72016-07-25 22:00:062477 surface_child->SetBounds(gfx::Size(300, 300));
Xianzhu Wangc62ecebf2019-08-31 15:54:132478 surface_child->SetForceRenderSurfaceForTesting(true);
danakje4fa7b72016-07-25 22:00:062479 surface_sibling->SetBounds(gfx::Size(200, 200));
Xianzhu Wangc62ecebf2019-08-31 15:54:132480 surface_child_mask->SetBounds(gfx::Size(300, 300));
jaydasika69c77aa2016-07-14 22:48:482481
Xianzhu Wangc62ecebf2019-08-31 15:54:132482 surface_child->SetMaskLayer(surface_child_mask);
2483 surface->AddChild(surface_child);
2484 child->AddChild(surface);
2485 child->AddChild(surface_sibling);
2486 root->AddChild(child);
2487 host()->SetRootLayer(root);
jaydasika69c77aa2016-07-14 22:48:482488
Xianzhu Wangc62ecebf2019-08-31 15:54:132489 CommitAndActivate();
jaydasika69c77aa2016-07-14 22:48:482490
2491 EXPECT_TRANSFORMATION_MATRIX_EQ(
Xianzhu Wangc62ecebf2019-08-31 15:54:132492 GetRenderSurfaceImpl(surface)->draw_transform(), translate);
jaydasika69c77aa2016-07-14 22:48:482493 // surface_sibling draws into the root render surface and occludes
2494 // surface_child's contents.
2495 Occlusion actual_occlusion =
Xianzhu Wangc62ecebf2019-08-31 15:54:132496 GetRenderSurfaceImpl(surface_child)->occlusion_in_content_space();
Xianzhu Wangdf85eae2019-09-17 18:56:082497 Occlusion expected_occlusion(translate, SimpleEnclosedRegion(),
jaydasika69c77aa2016-07-14 22:48:482498 SimpleEnclosedRegion(gfx::Rect(200, 200)));
2499 EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion));
2500
Xianzhu Wangdf85eae2019-09-17 18:56:082501 // Mask layer's occlusion is different because we create transform and render
2502 // surface for it in layer tree mode.
jaydasika69c77aa2016-07-14 22:48:482503 actual_occlusion =
Xianzhu Wangc62ecebf2019-08-31 15:54:132504 ImplOf(surface_child_mask)->draw_properties().occlusion_in_content_space;
Xianzhu Wangdf85eae2019-09-17 18:56:082505 expected_occlusion = Occlusion(
2506 gfx::Transform(), SimpleEnclosedRegion(gfx::Rect(-20, -20, 200, 200)),
2507 SimpleEnclosedRegion());
jaydasika69c77aa2016-07-14 22:48:482508 EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion));
2509}
2510
Xianzhu Wang66e13e02019-09-18 20:39:122511TEST_F(DrawPropertiesTest, OcclusionForLayerWithUninvertibleDrawTransform) {
Xianzhu Wangd6a62d82019-09-09 22:35:362512 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272513 LayerImpl* child = AddLayer<LayerImpl>();
2514 LayerImpl* grand_child = AddLayer<LayerImpl>();
2515 LayerImpl* occluding_child = AddLayer<LayerImpl>();
ajumaae0dc2d2015-08-05 21:55:562516
ajumaae0dc2d2015-08-05 21:55:562517 gfx::Transform perspective;
2518 perspective.ApplyPerspectiveDepth(SkDoubleToMScalar(1e-12));
2519
2520 gfx::Transform rotation;
2521 rotation.RotateAboutYAxis(45.0);
2522
danakje4fa7b72016-07-25 22:00:062523 root->SetBounds(gfx::Size(1000, 1000));
danakje4fa7b72016-07-25 22:00:062524 child->SetBounds(gfx::Size(300, 300));
danakje4fa7b72016-07-25 22:00:062525 grand_child->SetBounds(gfx::Size(200, 200));
danakje4fa7b72016-07-25 22:00:062526 occluding_child->SetBounds(gfx::Size(200, 200));
danakje4fa7b72016-07-25 22:00:062527
2528 child->SetDrawsContent(true);
2529 grand_child->SetDrawsContent(true);
2530 occluding_child->SetDrawsContent(true);
2531 occluding_child->SetContentsOpaque(true);
ajumaae0dc2d2015-08-05 21:55:562532
Xianzhu Wang5b429f02019-08-29 20:45:272533 CopyProperties(root, child);
2534 auto& child_transform_node = CreateTransformNode(child);
2535 child_transform_node.flattens_inherited_transform = false;
2536 child_transform_node.post_translation = gfx::Vector2dF(10.f, 10.f);
2537 child_transform_node.sorting_context_id = 1;
2538 child_transform_node.local = perspective;
2539 CopyProperties(child, grand_child);
2540 auto& grand_child_transform_node = CreateTransformNode(grand_child);
2541 grand_child_transform_node.flattens_inherited_transform = false;
2542 grand_child_transform_node.sorting_context_id = 1;
2543 grand_child_transform_node.local = rotation;
2544 CopyProperties(root, occluding_child);
2545 CreateTransformNode(occluding_child).flattens_inherited_transform = false;
ajumaae0dc2d2015-08-05 21:55:562546
Xianzhu Wang66e13e02019-09-18 20:39:122547 UpdateActiveTreeDrawProperties();
ajumaae0dc2d2015-08-05 21:55:562548
2549 // Though all layers have invertible transforms, matrix multiplication using
2550 // floating-point math makes the draw transform uninvertible.
Xianzhu Wang5b429f02019-08-29 20:45:272551 EXPECT_FALSE(GetTransformNode(grand_child)->ancestors_are_invertible);
ajumaae0dc2d2015-08-05 21:55:562552
sunxd71aea3e2016-04-01 23:48:052553 // Since |grand_child| has an uninvertible screen space transform, it is
2554 // skipped so
2555 // that we are not computing its occlusion_in_content_space.
2556 gfx::Rect layer_bounds = gfx::Rect();
ajumaae0dc2d2015-08-05 21:55:562557 EXPECT_EQ(
2558 layer_bounds,
Xianzhu Wang5b429f02019-08-29 20:45:272559 grand_child->draw_properties()
ajumaae0dc2d2015-08-05 21:55:562560 .occlusion_in_content_space.GetUnoccludedContentRect(layer_bounds));
2561}
2562
Xianzhu Wang66e13e02019-09-18 20:39:122563TEST_F(DrawPropertiesTest,
[email protected]989386c2013-07-18 21:37:232564 DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:362565 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272566 LayerImpl* render_surface = AddLayer<LayerImpl>();
2567 LayerImpl* child1 = AddLayer<LayerImpl>();
2568 LayerImpl* child2 = AddLayer<LayerImpl>();
2569 LayerImpl* child3 = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:282570
danakje4fa7b72016-07-25 22:00:062571 root->SetBounds(gfx::Size(100, 100));
[email protected]fb661802013-03-25 01:59:322572 root->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:062573 render_surface->SetBounds(gfx::Size(3, 4));
danakje4fa7b72016-07-25 22:00:062574 child1->SetBounds(gfx::Size(50, 50));
2575 child1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062576 child2->SetBounds(gfx::Size(50, 50));
2577 child2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062578 child3->SetBounds(gfx::Size(50, 50));
2579 child3->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272580
Xianzhu Wang5b429f02019-08-29 20:45:272581 CreateClipNode(root);
2582 CopyProperties(root, render_surface);
2583 CreateEffectNode(render_surface).render_surface_reason =
2584 RenderSurfaceReason::kTest;
2585 CopyProperties(render_surface, child1);
2586 child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
2587 CopyProperties(render_surface, child2);
2588 child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
2589 CopyProperties(render_surface, child3);
2590 child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));
2591
Xianzhu Wang66e13e02019-09-18 20:39:122592 UpdateActiveTreeDrawProperties();
weiliangc0dece732015-07-27 19:06:172593
chrishtr7e3aaf22017-05-04 15:04:012594 ASSERT_TRUE(GetRenderSurface(render_surface));
[email protected]fb661802013-03-25 01:59:322595
danakj5e6ff6d2015-09-05 04:43:442596 EXPECT_EQ(gfx::RectF(100.f, 100.f),
chrishtr7e3aaf22017-05-04 15:04:012597 GetRenderSurface(root)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322598
2599 // Layers that do not draw content should have empty visible content rects.
danakj64767d902015-06-19 00:10:432600 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
weiliangc0dece732015-07-27 19:06:172601 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322602
2603 // A clipped surface grows its DrawableContentRect to include all drawable
2604 // regions of the subtree, but also gets clamped by the ancestor's clip.
danakj5e6ff6d2015-09-05 04:43:442605 EXPECT_EQ(gfx::RectF(5.f, 5.f, 95.f, 95.f),
chrishtr7e3aaf22017-05-04 15:04:012606 GetRenderSurface(render_surface)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322607
2608 // All layers that draw content into the surface have their visible content
2609 // rect clipped by the surface clip rect.
danakj64767d902015-06-19 00:10:432610 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
2611 EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
2612 EXPECT_TRUE(child3->visible_layer_rect().IsEmpty());
[email protected]fb661802013-03-25 01:59:322613
2614 // But the DrawableContentRects are unclipped.
hush6b614212014-12-04 22:37:322615 EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
2616 EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
2617 EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322618}
2619
Xianzhu Wang5b429f02019-08-29 20:45:272620// Check that clipping does not propagate down surfaces.
Xianzhu Wang66e13e02019-09-18 20:39:122621TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSurfaceHierarchy) {
Xianzhu Wangd6a62d82019-09-09 22:35:362622 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272623 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
2624 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
2625 LayerImpl* child1 = AddLayer<LayerImpl>();
2626 LayerImpl* child2 = AddLayer<LayerImpl>();
2627 LayerImpl* child3 = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:282628
danakje4fa7b72016-07-25 22:00:062629 root->SetBounds(gfx::Size(100, 100));
[email protected]fb661802013-03-25 01:59:322630 root->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:062631 render_surface1->SetBounds(gfx::Size(3, 4));
danakje4fa7b72016-07-25 22:00:062632 render_surface2->SetBounds(gfx::Size(7, 13));
danakje4fa7b72016-07-25 22:00:062633 child1->SetBounds(gfx::Size(50, 50));
2634 child1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062635 child2->SetBounds(gfx::Size(50, 50));
2636 child2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062637 child3->SetBounds(gfx::Size(50, 50));
2638 child3->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272639
Xianzhu Wang5b429f02019-08-29 20:45:272640 CreateClipNode(root);
2641 CopyProperties(root, render_surface1);
2642 CreateEffectNode(render_surface1).render_surface_reason =
2643 RenderSurfaceReason::kTest;
2644 CopyProperties(render_surface1, render_surface2);
2645 CreateEffectNode(render_surface2).render_surface_reason =
2646 RenderSurfaceReason::kTest;
2647 CopyProperties(render_surface2, child1);
2648 child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
2649 CopyProperties(render_surface2, child2);
2650 child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
2651 CopyProperties(render_surface2, child3);
2652 child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));
2653
Xianzhu Wang66e13e02019-09-18 20:39:122654 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:322655
chrishtr7e3aaf22017-05-04 15:04:012656 ASSERT_TRUE(GetRenderSurface(render_surface1));
2657 ASSERT_TRUE(GetRenderSurface(render_surface2));
[email protected]fb661802013-03-25 01:59:322658
danakj5e6ff6d2015-09-05 04:43:442659 EXPECT_EQ(gfx::RectF(100.f, 100.f),
chrishtr7e3aaf22017-05-04 15:04:012660 GetRenderSurface(root)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322661
2662 // Layers that do not draw content should have empty visible content rects.
danakj64767d902015-06-19 00:10:432663 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
2664 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface1->visible_layer_rect());
2665 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface2->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322666
2667 // A clipped surface grows its DrawableContentRect to include all drawable
2668 // regions of the subtree, but also gets clamped by the ancestor's clip.
danakj5e6ff6d2015-09-05 04:43:442669 EXPECT_EQ(gfx::RectF(5.f, 5.f, 95.f, 95.f),
chrishtr7e3aaf22017-05-04 15:04:012670 GetRenderSurface(render_surface1)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322671
2672 // render_surface1 lives in the "unclipped universe" of render_surface1, and
2673 // is only implicitly clipped by render_surface1's content rect. So,
2674 // render_surface2 grows to enclose all drawable content of its subtree.
danakj5e6ff6d2015-09-05 04:43:442675 EXPECT_EQ(gfx::RectF(5.f, 5.f, 170.f, 170.f),
chrishtr7e3aaf22017-05-04 15:04:012676 GetRenderSurface(render_surface2)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322677
jaydasika94bebdd2016-09-16 22:11:182678 // All layers that draw content into render_surface2 think they are unclipped
2679 // by the surface. So, only the viewport clip applies.
danakj64767d902015-06-19 00:10:432680 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
jaydasika94bebdd2016-09-16 22:11:182681 EXPECT_EQ(gfx::Rect(0, 0, 25, 25), child2->visible_layer_rect());
2682 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322683
2684 // DrawableContentRects are also unclipped.
hush6b614212014-12-04 22:37:322685 EXPECT_EQ(gfx::Rect(5, 5, 50, 50), child1->drawable_content_rect());
2686 EXPECT_EQ(gfx::Rect(75, 75, 50, 50), child2->drawable_content_rect());
2687 EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322688}
2689
Xianzhu Wang66e13e02019-09-18 20:39:122690TEST_F(DrawPropertiesTest,
jaydasika27d0f2e2015-10-16 23:52:462691 VisibleRectsForClippedDescendantsOfUnclippedSurfaces) {
Xianzhu Wangd6a62d82019-09-09 22:35:362692 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272693 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
2694 LayerImpl* child1 = AddLayer<LayerImpl>();
2695 LayerImpl* child2 = AddLayer<LayerImpl>();
2696 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
jaydasika27d0f2e2015-10-16 23:52:462697
danakje4fa7b72016-07-25 22:00:062698 root->SetBounds(gfx::Size(100, 100));
2699 render_surface1->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:062700 child1->SetBounds(gfx::Size(500, 500));
2701 child1->SetDrawsContent(true);
2702 child2->SetBounds(gfx::Size(700, 700));
2703 child2->SetDrawsContent(true);
2704 render_surface2->SetBounds(gfx::Size(1000, 1000));
danakje4fa7b72016-07-25 22:00:062705 render_surface2->SetDrawsContent(true);
jaydasika27d0f2e2015-10-16 23:52:462706
2707 child1->SetMasksToBounds(true);
2708 child2->SetMasksToBounds(true);
Xianzhu Wang5b429f02019-08-29 20:45:272709
Xianzhu Wang5b429f02019-08-29 20:45:272710 CopyProperties(root, render_surface1);
2711 CreateEffectNode(render_surface1).render_surface_reason =
2712 RenderSurfaceReason::kTest;
2713 CopyProperties(render_surface1, child1);
2714 CreateClipNode(child1);
2715 CopyProperties(child1, child2);
2716 CreateClipNode(child2);
2717 CopyProperties(child2, render_surface2);
2718 CreateEffectNode(render_surface2).render_surface_reason =
2719 RenderSurfaceReason::kTest;
2720
Xianzhu Wang66e13e02019-09-18 20:39:122721 UpdateActiveTreeDrawProperties();
jaydasika526eae0a2016-09-02 01:47:592722 EXPECT_EQ(gfx::Rect(100, 100), child1->visible_layer_rect());
jaydasika27d0f2e2015-10-16 23:52:462723 EXPECT_EQ(gfx::Rect(100, 100), render_surface2->visible_layer_rect());
2724}
2725
Xianzhu Wang66e13e02019-09-18 20:39:122726TEST_F(DrawPropertiesTest,
jaydasika27d0f2e2015-10-16 23:52:462727 VisibleRectsWhenClipChildIsBetweenTwoRenderSurfaces) {
Xianzhu Wangd6a62d82019-09-09 22:35:362728 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272729 LayerImpl* clip_parent = AddLayer<LayerImpl>();
2730 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
2731 LayerImpl* clip_child = AddLayer<LayerImpl>();
2732 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
jaydasika27d0f2e2015-10-16 23:52:462733
danakje4fa7b72016-07-25 22:00:062734 root->SetBounds(gfx::Size(100, 100));
2735
2736 clip_parent->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:282737 CopyProperties(root, clip_parent);
2738 CreateClipNode(clip_parent);
danakje4fa7b72016-07-25 22:00:062739
2740 render_surface1->SetBounds(gfx::Size(20, 20));
jaydasika27d0f2e2015-10-16 23:52:462741 render_surface1->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:282742 CopyProperties(clip_parent, render_surface1);
2743 CreateEffectNode(render_surface1).render_surface_reason =
2744 RenderSurfaceReason::kTest;
2745 CreateClipNode(render_surface1);
danakje4fa7b72016-07-25 22:00:062746
2747 clip_child->SetBounds(gfx::Size(60, 60));
jaydasika27d0f2e2015-10-16 23:52:462748 clip_child->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:282749 CopyProperties(render_surface1, clip_child);
2750 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
jaydasika27d0f2e2015-10-16 23:52:462751
danakje4fa7b72016-07-25 22:00:062752 render_surface2->SetBounds(gfx::Size(60, 60));
2753 render_surface2->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:282754 CopyProperties(clip_child, render_surface2);
2755 CreateEffectNode(render_surface2).render_surface_reason =
2756 RenderSurfaceReason::kTest;
jaydasika27d0f2e2015-10-16 23:52:462757
Xianzhu Wang66e13e02019-09-18 20:39:122758 UpdateActiveTreeDrawProperties();
jaydasika27d0f2e2015-10-16 23:52:462759 EXPECT_EQ(gfx::Rect(20, 20), render_surface1->visible_layer_rect());
2760 EXPECT_EQ(gfx::Rect(50, 50), clip_child->visible_layer_rect());
2761 EXPECT_EQ(gfx::Rect(50, 50), render_surface2->visible_layer_rect());
2762}
2763
Xianzhu Wang66e13e02019-09-18 20:39:122764TEST_F(DrawPropertiesTest, ClipRectOfSurfaceWhoseParentIsAClipChild) {
Xianzhu Wangd6a62d82019-09-09 22:35:362765 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272766 LayerImpl* clip_parent = AddLayer<LayerImpl>();
2767 LayerImpl* clip_layer = AddLayer<LayerImpl>();
2768 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
2769 LayerImpl* clip_child = AddLayer<LayerImpl>();
2770 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
jaydasika1f5312d2015-10-21 21:34:322771
danakje4fa7b72016-07-25 22:00:062772 root->SetBounds(gfx::Size(100, 100));
2773
danakje4fa7b72016-07-25 22:00:062774 clip_parent->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:282775 clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(2, 2));
2776 CopyProperties(root, clip_parent);
2777 CreateClipNode(clip_parent);
danakje4fa7b72016-07-25 22:00:062778
jaydasika1553a142017-04-05 00:37:092779 clip_layer->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:282780 clip_layer->SetOffsetToTransformParent(gfx::Vector2dF(2, 2));
2781 CopyProperties(clip_parent, clip_layer);
2782 CreateClipNode(clip_layer);
jaydasika1553a142017-04-05 00:37:092783
danakje4fa7b72016-07-25 22:00:062784 render_surface1->SetBounds(gfx::Size(20, 20));
jaydasika1f5312d2015-10-21 21:34:322785 render_surface1->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:282786 CopyProperties(clip_layer, render_surface1);
2787 CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(2, 2);
2788 CreateEffectNode(render_surface1).render_surface_reason =
2789 RenderSurfaceReason::kTest;
2790 CreateClipNode(render_surface1);
danakje4fa7b72016-07-25 22:00:062791
2792 clip_child->SetBounds(gfx::Size(60, 60));
jaydasika1f5312d2015-10-21 21:34:322793 clip_child->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:282794 CopyProperties(render_surface1, clip_child);
2795 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
jaydasika1f5312d2015-10-21 21:34:322796
danakje4fa7b72016-07-25 22:00:062797 render_surface2->SetBounds(gfx::Size(60, 60));
2798 render_surface2->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:282799 CopyProperties(clip_child, render_surface2);
2800 CreateTransformNode(render_surface2);
2801 CreateEffectNode(render_surface2).render_surface_reason =
2802 RenderSurfaceReason::kTest;
jaydasika1f5312d2015-10-21 21:34:322803
jaydasika44b074e2017-03-07 21:11:382804 float device_scale_factor = 1.f;
Xianzhu Wang66e13e02019-09-18 20:39:122805 UpdateActiveTreeDrawProperties(device_scale_factor);
chrishtr7e3aaf22017-05-04 15:04:012806 EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(render_surface2)->clip_rect());
Xianzhu Wangc8189212019-08-28 01:32:282807
jaydasika44b074e2017-03-07 21:11:382808 device_scale_factor = 2.f;
Xianzhu Wang66e13e02019-09-18 20:39:122809 UpdateActiveTreeDrawProperties(device_scale_factor);
2810
jaydasika44b074e2017-03-07 21:11:382811 EXPECT_EQ(gfx::Rect(100, 100),
chrishtr7e3aaf22017-05-04 15:04:012812 GetRenderSurface(render_surface2)->clip_rect());
jaydasika1f5312d2015-10-21 21:34:322813}
2814
Xianzhu Wang5b429f02019-08-29 20:45:272815// Test that only drawn layers contribute to render surface content rect.
Xianzhu Wang66e13e02019-09-18 20:39:122816TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWhenLayerNotDrawn) {
Xianzhu Wangd6a62d82019-09-09 22:35:362817 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272818 LayerImpl* surface = AddLayer<LayerImpl>();
2819 LayerImpl* test_layer = AddLayer<LayerImpl>();
jaydasika77a4a072015-10-20 21:47:272820
danakje4fa7b72016-07-25 22:00:062821 root->SetBounds(gfx::Size(200, 200));
2822 surface->SetBounds(gfx::Size(100, 100));
jaydasika77a4a072015-10-20 21:47:272823 surface->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:062824 test_layer->SetBounds(gfx::Size(150, 150));
jaydasika77a4a072015-10-20 21:47:272825
Xianzhu Wang5b429f02019-08-29 20:45:272826 CopyProperties(root, surface);
2827 CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
2828 CopyProperties(surface, test_layer);
2829
Xianzhu Wang66e13e02019-09-18 20:39:122830 UpdateActiveTreeDrawProperties();
chrishtr7e3aaf22017-05-04 15:04:012831 EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(surface)->content_rect());
jaydasika77a4a072015-10-20 21:47:272832
2833 test_layer->SetDrawsContent(true);
Xianzhu Wang66e13e02019-09-18 20:39:122834 UpdateActiveTreeDrawProperties();
chrishtr7e3aaf22017-05-04 15:04:012835 EXPECT_EQ(gfx::Rect(150, 150), GetRenderSurface(surface)->content_rect());
jaydasika77a4a072015-10-20 21:47:272836}
2837
Xianzhu Wang5b429f02019-08-29 20:45:272838// Tests visible rects computation when we have unclipped_surface->
2839// surface_with_unclipped_descendants->clipped_surface, checks that the bounds
2840// of surface_with_unclipped_descendants doesn't propagate to the
2841// clipped_surface below it.
Xianzhu Wang66e13e02019-09-18 20:39:122842TEST_F(DrawPropertiesTest, VisibleRectsMultipleSurfaces) {
Xianzhu Wangd6a62d82019-09-09 22:35:362843 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272844 LayerImpl* unclipped_surface = AddLayer<LayerImpl>();
2845 LayerImpl* clip_parent = AddLayer<LayerImpl>();
2846 LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
2847 LayerImpl* clip_child = AddLayer<LayerImpl>();
2848 LayerImpl* clipped_surface = AddLayer<LayerImpl>();
jaydasika27d0f2e2015-10-16 23:52:462849
danakje4fa7b72016-07-25 22:00:062850 root->SetBounds(gfx::Size(100, 100));
danakje4fa7b72016-07-25 22:00:062851 unclipped_surface->SetBounds(gfx::Size(30, 30));
2852 unclipped_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272853 clip_parent->SetBounds(gfx::Size(50, 50));
2854 unclipped_desc_surface->SetBounds(gfx::Size(20, 20));
2855 unclipped_desc_surface->SetDrawsContent(true);
2856 clip_child->SetBounds(gfx::Size(60, 60));
2857 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
2858 clipped_surface->SetBounds(gfx::Size(60, 60));
2859 clipped_surface->SetDrawsContent(true);
2860
Xianzhu Wangc8189212019-08-28 01:32:282861 CopyProperties(root, unclipped_surface);
2862 CreateEffectNode(unclipped_surface).render_surface_reason =
2863 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:282864 CopyProperties(unclipped_surface, clip_parent);
2865 CreateClipNode(clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:282866 CopyProperties(clip_parent, unclipped_desc_surface);
2867 CreateEffectNode(unclipped_desc_surface).render_surface_reason =
2868 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:282869 CopyProperties(unclipped_desc_surface, clip_child);
Xianzhu Wangc8189212019-08-28 01:32:282870 CopyProperties(clip_child, clipped_surface);
2871 CreateEffectNode(clipped_surface).render_surface_reason =
2872 RenderSurfaceReason::kTest;
jaydasika27d0f2e2015-10-16 23:52:462873
Xianzhu Wang66e13e02019-09-18 20:39:122874 UpdateActiveTreeDrawProperties();
jaydasika27d0f2e2015-10-16 23:52:462875 EXPECT_EQ(gfx::Rect(30, 30), unclipped_surface->visible_layer_rect());
2876 EXPECT_EQ(gfx::Rect(20, 20), unclipped_desc_surface->visible_layer_rect());
2877 EXPECT_EQ(gfx::Rect(50, 50), clipped_surface->visible_layer_rect());
2878}
2879
Xianzhu Wang5b429f02019-08-29 20:45:272880// Tests visible rects computation when we have unclipped_surface->
2881// surface_with_unclipped_descendants->clipped_surface, checks that the bounds
2882// of root propagate to the clipped_surface.
Xianzhu Wang66e13e02019-09-18 20:39:122883TEST_F(DrawPropertiesTest, RootClipPropagationToClippedSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:362884 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272885 LayerImpl* unclipped_surface = AddLayer<LayerImpl>();
2886 LayerImpl* clip_parent = AddLayer<LayerImpl>();
2887 LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
2888 LayerImpl* clip_child = AddLayer<LayerImpl>();
2889 LayerImpl* clipped_surface = AddLayer<LayerImpl>();
jaydasika27d0f2e2015-10-16 23:52:462890
danakje4fa7b72016-07-25 22:00:062891 root->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:062892 unclipped_surface->SetBounds(gfx::Size(50, 50));
2893 unclipped_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272894 clip_parent->SetBounds(gfx::Size(50, 50));
2895 unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
2896 unclipped_desc_surface->SetDrawsContent(true);
2897 clip_child->SetBounds(gfx::Size(100, 100));
2898 clipped_surface->SetBounds(gfx::Size(50, 50));
2899 clipped_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272900
Xianzhu Wangc8189212019-08-28 01:32:282901 CopyProperties(root, unclipped_surface);
2902 CreateEffectNode(unclipped_surface).render_surface_reason =
2903 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:282904 CopyProperties(unclipped_surface, clip_parent);
2905 CreateClipNode(clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:282906 CopyProperties(clip_parent, unclipped_desc_surface);
2907 CreateEffectNode(unclipped_desc_surface).render_surface_reason =
2908 RenderSurfaceReason::kTest;
2909 CreateClipNode(unclipped_desc_surface);
Xianzhu Wangc8189212019-08-28 01:32:282910 CopyProperties(unclipped_desc_surface, clip_child);
2911 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
Xianzhu Wangc8189212019-08-28 01:32:282912 CopyProperties(clip_child, clipped_surface);
2913 CreateEffectNode(clipped_surface).render_surface_reason =
2914 RenderSurfaceReason::kTest;
jaydasika27d0f2e2015-10-16 23:52:462915
Xianzhu Wang66e13e02019-09-18 20:39:122916 UpdateActiveTreeDrawProperties();
jaydasika94bebdd2016-09-16 22:11:182917 EXPECT_EQ(gfx::Rect(10, 10), unclipped_surface->visible_layer_rect());
jaydasika526eae0a2016-09-02 01:47:592918 EXPECT_EQ(gfx::Rect(10, 10), unclipped_desc_surface->visible_layer_rect());
jaydasika27d0f2e2015-10-16 23:52:462919 EXPECT_EQ(gfx::Rect(10, 10), clipped_surface->visible_layer_rect());
2920}
2921
Xianzhu Wang5b429f02019-08-29 20:45:272922// Layers that have non-axis aligned bounds (due to transforms) have an
2923// expanded, axis-aligned DrawableContentRect and visible content rect.
Xianzhu Wang66e13e02019-09-18 20:39:122924TEST_F(DrawPropertiesTest,
[email protected]989386c2013-07-18 21:37:232925 DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:362926 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272927 LayerImpl* render_surface = AddLayer<LayerImpl>();
2928 LayerImpl* child1 = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:282929
[email protected]fb661802013-03-25 01:59:322930 gfx::Transform child_rotation;
2931 child_rotation.Rotate(45.0);
[email protected]fb661802013-03-25 01:59:322932
danakje4fa7b72016-07-25 22:00:062933 root->SetBounds(gfx::Size(100, 100));
2934 render_surface->SetBounds(gfx::Size(3, 4));
danakje4fa7b72016-07-25 22:00:062935 child1->SetBounds(gfx::Size(50, 50));
2936 child1->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272937
Xianzhu Wang5b429f02019-08-29 20:45:272938 CopyProperties(root, render_surface);
2939 CreateEffectNode(render_surface).render_surface_reason =
2940 RenderSurfaceReason::kTest;
2941 CopyProperties(render_surface, child1);
2942 auto& child1_transform_node = CreateTransformNode(child1);
2943 child1_transform_node.origin = gfx::Point3F(25.f, 25.f, 0.f);
2944 child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f);
2945 child1_transform_node.local = child_rotation;
2946
Xianzhu Wang66e13e02019-09-18 20:39:122947 UpdateActiveTreeDrawProperties();
[email protected]fb661802013-03-25 01:59:322948
chrishtr7e3aaf22017-05-04 15:04:012949 ASSERT_TRUE(GetRenderSurface(render_surface));
[email protected]fb661802013-03-25 01:59:322950
danakj5e6ff6d2015-09-05 04:43:442951 EXPECT_EQ(gfx::RectF(100.f, 100.f),
chrishtr7e3aaf22017-05-04 15:04:012952 GetRenderSurface(root)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322953
2954 // Layers that do not draw content should have empty visible content rects.
danakj64767d902015-06-19 00:10:432955 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
weiliangc0dece732015-07-27 19:06:172956 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), render_surface->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:322957
2958 // The unclipped surface grows its DrawableContentRect to include all drawable
2959 // regions of the subtree.
2960 int diagonal_radius = ceil(sqrt(2.0) * 25.0);
2961 gfx::Rect expected_surface_drawable_content =
Xianzhu Wang66e13e02019-09-18 20:39:122962 gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2,
[email protected]803f6b52013-09-12 00:51:262963 diagonal_radius * 2);
danakj5e6ff6d2015-09-05 04:43:442964 EXPECT_EQ(gfx::RectF(expected_surface_drawable_content),
chrishtr7e3aaf22017-05-04 15:04:012965 GetRenderSurface(render_surface)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:322966
2967 // All layers that draw content into the unclipped surface are also unclipped.
danakj64767d902015-06-19 00:10:432968 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
hush6b614212014-12-04 22:37:322969 EXPECT_EQ(expected_surface_drawable_content, child1->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:322970}
2971
Xianzhu Wang5b429f02019-08-29 20:45:272972// Layers that have non-axis aligned bounds (due to transforms) have an
2973// expanded, axis-aligned DrawableContentRect and visible content rect.
Xianzhu Wang66e13e02019-09-18 20:39:122974TEST_F(DrawPropertiesTest,
[email protected]989386c2013-07-18 21:37:232975 DrawableAndVisibleContentRectsWithTransformOnClippedSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:362976 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:272977 LayerImpl* render_surface = AddLayer<LayerImpl>();
2978 LayerImpl* child1 = AddLayer<LayerImpl>();
[email protected]d600df7d2013-08-03 02:34:282979
[email protected]fb661802013-03-25 01:59:322980 gfx::Transform child_rotation;
2981 child_rotation.Rotate(45.0);
[email protected]a2566412014-06-05 03:14:202982
danakje4fa7b72016-07-25 22:00:062983 root->SetBounds(gfx::Size(50, 50));
[email protected]fb661802013-03-25 01:59:322984 root->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:062985 render_surface->SetBounds(gfx::Size(3, 4));
danakje4fa7b72016-07-25 22:00:062986 child1->SetBounds(gfx::Size(50, 50));
2987 child1->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:272988
Xianzhu Wang5b429f02019-08-29 20:45:272989 CreateClipNode(root);
2990 CopyProperties(root, render_surface);
2991 CreateEffectNode(render_surface).render_surface_reason =
2992 RenderSurfaceReason::kTest;
2993 CopyProperties(render_surface, child1);
2994 auto& child1_transform_node = CreateTransformNode(child1);
2995 child1_transform_node.origin = gfx::Point3F(25.f, 25.f, 0.f);
2996 child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f);
2997 child1_transform_node.local = child_rotation;
2998
Xianzhu Wang66e13e02019-09-18 20:39:122999 UpdateActiveTreeDrawProperties();
weiliangc0dece732015-07-27 19:06:173000
chrishtr7e3aaf22017-05-04 15:04:013001 ASSERT_TRUE(GetRenderSurface(render_surface));
[email protected]fb661802013-03-25 01:59:323002
3003 // The clipped surface clamps the DrawableContentRect that encloses the
3004 // rotated layer.
3005 int diagonal_radius = ceil(sqrt(2.0) * 25.0);
Xianzhu Wang66e13e02019-09-18 20:39:123006 gfx::Rect unclipped_surface_content =
3007 gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2,
3008 diagonal_radius * 2);
danakj5e6ff6d2015-09-05 04:43:443009 gfx::RectF expected_surface_drawable_content(
3010 gfx::IntersectRects(unclipped_surface_content, gfx::Rect(50, 50)));
hush6b614212014-12-04 22:37:323011 EXPECT_EQ(expected_surface_drawable_content,
chrishtr7e3aaf22017-05-04 15:04:013012 GetRenderSurface(render_surface)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:323013
3014 // On the clipped surface, only a quarter of the child1 is visible, but when
3015 // rotating it back to child1's content space, the actual enclosing rect ends
3016 // up covering the full left half of child1.
weiliangcd15784432016-06-07 17:57:333017 EXPECT_EQ(gfx::Rect(0, 0, 25, 50), child1->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:323018
3019 // The child's DrawableContentRect is unclipped.
hush6b614212014-12-04 22:37:323020 EXPECT_EQ(unclipped_surface_content, child1->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:323021}
3022
Xianzhu Wang66e13e02019-09-18 20:39:123023TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsInHighDPI) {
Xianzhu Wangd6a62d82019-09-09 22:35:363024 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:273025 FakePictureLayerImpl* render_surface1 = AddLayer<FakePictureLayerImpl>();
3026 FakePictureLayerImpl* render_surface2 = AddLayer<FakePictureLayerImpl>();
3027 FakePictureLayerImpl* child1 = AddLayer<FakePictureLayerImpl>();
3028 FakePictureLayerImpl* child2 = AddLayer<FakePictureLayerImpl>();
3029 FakePictureLayerImpl* child3 = AddLayer<FakePictureLayerImpl>();
[email protected]d600df7d2013-08-03 02:34:283030
danakje4fa7b72016-07-25 22:00:063031 root->SetBounds(gfx::Size(100, 100));
[email protected]fb661802013-03-25 01:59:323032 root->SetMasksToBounds(true);
danakje4fa7b72016-07-25 22:00:063033 render_surface1->SetBounds(gfx::Size(3, 4));
danakje4fa7b72016-07-25 22:00:063034 render_surface1->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:063035 render_surface2->SetBounds(gfx::Size(7, 13));
danakje4fa7b72016-07-25 22:00:063036 render_surface2->SetDrawsContent(true);
danakje4fa7b72016-07-25 22:00:063037 child1->SetBounds(gfx::Size(50, 50));
danakje4fa7b72016-07-25 22:00:063038 child1->SetDrawsContent(true);
3039 child2->SetBounds(gfx::Size(50, 50));
danakje4fa7b72016-07-25 22:00:063040 child2->SetDrawsContent(true);
3041 child3->SetBounds(gfx::Size(50, 50));
danakje4fa7b72016-07-25 22:00:063042 child3->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:273043
Xianzhu Wang5b429f02019-08-29 20:45:273044 CreateClipNode(root);
3045 CopyProperties(root, render_surface1);
3046 CreateTransformNode(render_surface1).post_translation =
3047 gfx::Vector2dF(5.f, 5.f);
3048 CreateEffectNode(render_surface1).render_surface_reason =
3049 RenderSurfaceReason::kTest;
3050 CopyProperties(render_surface1, render_surface2);
3051 CreateTransformNode(render_surface2).post_translation =
3052 gfx::Vector2dF(5.f, 5.f);
3053 CreateEffectNode(render_surface2).render_surface_reason =
3054 RenderSurfaceReason::kTest;
3055 CopyProperties(render_surface2, child1);
3056 child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f));
3057 CopyProperties(render_surface2, child2);
3058 child2->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f));
3059 CopyProperties(render_surface2, child3);
3060 child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f));
3061
danakje4fa7b72016-07-25 22:00:063062 float device_scale_factor = 2.f;
Xianzhu Wang66e13e02019-09-18 20:39:123063 UpdateActiveTreeDrawProperties(device_scale_factor);
[email protected]fb661802013-03-25 01:59:323064
chrishtr7e3aaf22017-05-04 15:04:013065 ASSERT_TRUE(GetRenderSurface(render_surface1));
3066 ASSERT_TRUE(GetRenderSurface(render_surface2));
[email protected]fb661802013-03-25 01:59:323067
3068 // drawable_content_rects for all layers and surfaces are scaled by
3069 // device_scale_factor.
danakj5e6ff6d2015-09-05 04:43:443070 EXPECT_EQ(gfx::RectF(200.f, 200.f),
chrishtr7e3aaf22017-05-04 15:04:013071 GetRenderSurface(root)->DrawableContentRect());
danakj5e6ff6d2015-09-05 04:43:443072 EXPECT_EQ(gfx::RectF(10.f, 10.f, 190.f, 190.f),
chrishtr7e3aaf22017-05-04 15:04:013073 GetRenderSurface(render_surface1)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:323074
3075 // render_surface2 lives in the "unclipped universe" of render_surface1, and
3076 // is only implicitly clipped by render_surface1.
danakj5e6ff6d2015-09-05 04:43:443077 EXPECT_EQ(gfx::RectF(10.f, 10.f, 350.f, 350.f),
chrishtr7e3aaf22017-05-04 15:04:013078 GetRenderSurface(render_surface2)->DrawableContentRect());
[email protected]fb661802013-03-25 01:59:323079
hush6b614212014-12-04 22:37:323080 EXPECT_EQ(gfx::Rect(10, 10, 100, 100), child1->drawable_content_rect());
3081 EXPECT_EQ(gfx::Rect(150, 150, 100, 100), child2->drawable_content_rect());
3082 EXPECT_EQ(gfx::Rect(250, 250, 100, 100), child3->drawable_content_rect());
[email protected]fb661802013-03-25 01:59:323083
3084 // The root layer does not actually draw content of its own.
danakj64767d902015-06-19 00:10:433085 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), root->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:323086
sohan.jyotie3bd6192014-10-13 07:13:593087 // All layer visible content rects are not expressed in content space of each
3088 // layer, so they are not scaled by the device_scale_factor.
danakj64767d902015-06-19 00:10:433089 EXPECT_EQ(gfx::Rect(0, 0, 3, 4), render_surface1->visible_layer_rect());
3090 EXPECT_EQ(gfx::Rect(0, 0, 7, 13), render_surface2->visible_layer_rect());
3091 EXPECT_EQ(gfx::Rect(0, 0, 50, 50), child1->visible_layer_rect());
jaydasika94bebdd2016-09-16 22:11:183092 EXPECT_EQ(gfx::Rect(0, 0, 15, 15), child2->visible_layer_rect());
3093 EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect());
[email protected]fb661802013-03-25 01:59:323094}
3095
Xianzhu Wang66e13e02019-09-18 20:39:123096using DrawPropertiesScalingTest = DrawPropertiesTest;
Xianzhu Wang5b429f02019-08-29 20:45:273097
3098// Verify draw and screen space transforms of layers not in a surface.
Xianzhu Wang66e13e02019-09-18 20:39:123099TEST_F(DrawPropertiesScalingTest, LayerTransformsInHighDPI) {
Xianzhu Wangd6a62d82019-09-09 22:35:363100 LayerImpl* root = root_layer();
danakje4fa7b72016-07-25 22:00:063101 root->SetBounds(gfx::Size(100, 100));
3102 root->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143103
Xianzhu Wang5b429f02019-08-29 20:45:273104 LayerImpl* child = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063105 child->SetBounds(gfx::Size(10, 10));
jaydasika8640f9f2015-11-10 01:34:363106 child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143107
Xianzhu Wang5b429f02019-08-29 20:45:273108 LayerImpl* child2 = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063109 child2->SetBounds(gfx::Size(5, 5));
jaydasika8640f9f2015-11-10 01:34:363110 child2->SetDrawsContent(true);
[email protected]d600df7d2013-08-03 02:34:283111
[email protected]fb661802013-03-25 01:59:323112 float device_scale_factor = 2.5f;
Xianzhu Wang5b429f02019-08-29 20:45:273113
Xianzhu Wang5b429f02019-08-29 20:45:273114 CopyProperties(root, child);
3115 child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f));
3116 CopyProperties(root, child2);
3117 child2->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f));
3118
Xianzhu Wang66e13e02019-09-18 20:39:123119 UpdateActiveTreeDrawProperties(device_scale_factor);
[email protected]94f206c12012-08-25 00:09:143120
danakj59931942016-07-26 22:11:293121 EXPECT_FLOAT_EQ(device_scale_factor, root->GetIdealContentsScale());
3122 EXPECT_FLOAT_EQ(device_scale_factor, child->GetIdealContentsScale());
3123 EXPECT_FLOAT_EQ(device_scale_factor, child2->GetIdealContentsScale());
[email protected]518ee582012-10-24 18:29:443124
Xianzhu Wang66e13e02019-09-18 20:39:123125 EXPECT_EQ(1u, GetRenderSurfaceList().size());
[email protected]94f206c12012-08-25 00:09:143126
danakje4fa7b72016-07-25 22:00:063127 // Verify root transforms
3128 gfx::Transform expected_root_transform;
3129 expected_root_transform.Scale(device_scale_factor, device_scale_factor);
3130 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_root_transform,
3131 root->ScreenSpaceTransform());
3132 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_root_transform,
3133 root->DrawTransform());
[email protected]94f206c12012-08-25 00:09:143134
danakje4fa7b72016-07-25 22:00:063135 // Verify results of transformed root rects
3136 gfx::RectF root_bounds(gfx::SizeF(root->bounds()));
[email protected]94f206c12012-08-25 00:09:143137
danakje4fa7b72016-07-25 22:00:063138 gfx::RectF root_draw_rect =
3139 MathUtil::MapClippedRect(root->DrawTransform(), root_bounds);
3140 gfx::RectF root_screen_space_rect =
3141 MathUtil::MapClippedRect(root->ScreenSpaceTransform(), root_bounds);
[email protected]94f206c12012-08-25 00:09:143142
danakje4fa7b72016-07-25 22:00:063143 gfx::RectF expected_root_draw_rect(gfx::SizeF(root->bounds()));
3144 expected_root_draw_rect.Scale(device_scale_factor);
3145 EXPECT_FLOAT_RECT_EQ(expected_root_draw_rect, root_draw_rect);
3146 EXPECT_FLOAT_RECT_EQ(expected_root_draw_rect, root_screen_space_rect);
[email protected]94f206c12012-08-25 00:09:143147
jaydasika8640f9f2015-11-10 01:34:363148 // Verify child and child2 transforms. They should match.
[email protected]fb661802013-03-25 01:59:323149 gfx::Transform expected_child_transform;
sohan.jyotie3bd6192014-10-13 07:13:593150 expected_child_transform.Scale(device_scale_factor, device_scale_factor);
Xianzhu Wang5b429f02019-08-29 20:45:273151 expected_child_transform.Translate(child->offset_to_transform_parent());
[email protected]fb661802013-03-25 01:59:323152 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
ajumad9432e32015-11-30 19:43:443153 child->DrawTransform());
[email protected]fb661802013-03-25 01:59:323154 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
ajumab6aa1c62015-12-01 21:01:103155 child->ScreenSpaceTransform());
[email protected]fb661802013-03-25 01:59:323156 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
ajumad9432e32015-11-30 19:43:443157 child2->DrawTransform());
[email protected]fb661802013-03-25 01:59:323158 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_transform,
ajumab6aa1c62015-12-01 21:01:103159 child2->ScreenSpaceTransform());
[email protected]94f206c12012-08-25 00:09:143160
jaydasika8640f9f2015-11-10 01:34:363161 // Verify results of transformed child and child2 rects. They should
[email protected]fb661802013-03-25 01:59:323162 // match.
danakjddaec912015-09-25 19:38:403163 gfx::RectF child_bounds(gfx::SizeF(child->bounds()));
[email protected]94f206c12012-08-25 00:09:143164
[email protected]fb661802013-03-25 01:59:323165 gfx::RectF child_draw_rect =
ajumad9432e32015-11-30 19:43:443166 MathUtil::MapClippedRect(child->DrawTransform(), child_bounds);
Dana Jansensc46d3742015-06-18 01:33:143167 gfx::RectF child_screen_space_rect =
ajumab6aa1c62015-12-01 21:01:103168 MathUtil::MapClippedRect(child->ScreenSpaceTransform(), child_bounds);
[email protected]94f206c12012-08-25 00:09:143169
jaydasika8640f9f2015-11-10 01:34:363170 gfx::RectF child2_draw_rect =
ajumad9432e32015-11-30 19:43:443171 MathUtil::MapClippedRect(child2->DrawTransform(), child_bounds);
jaydasika8640f9f2015-11-10 01:34:363172 gfx::RectF child2_screen_space_rect =
ajumab6aa1c62015-12-01 21:01:103173 MathUtil::MapClippedRect(child2->ScreenSpaceTransform(), child_bounds);
[email protected]f89f5632012-11-14 23:34:453174
Xianzhu Wang5b429f02019-08-29 20:45:273175 gfx::RectF expected_child_draw_rect(
3176 gfx::PointAtOffsetFromOrigin(child->offset_to_transform_parent()),
3177 gfx::SizeF(child->bounds()));
[email protected]fb661802013-03-25 01:59:323178 expected_child_draw_rect.Scale(device_scale_factor);
3179 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_draw_rect);
3180 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child_screen_space_rect);
jaydasika8640f9f2015-11-10 01:34:363181 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child2_draw_rect);
3182 EXPECT_FLOAT_RECT_EQ(expected_child_draw_rect, child2_screen_space_rect);
[email protected]94f206c12012-08-25 00:09:143183}
3184
Xianzhu Wang5b429f02019-08-29 20:45:273185// Verify draw and screen space transforms of layers in a surface.
Xianzhu Wang66e13e02019-09-18 20:39:123186TEST_F(DrawPropertiesScalingTest, SurfaceLayerTransformsInHighDPI) {
[email protected]fb661802013-03-25 01:59:323187 gfx::Transform perspective_matrix;
3188 perspective_matrix.ApplyPerspectiveDepth(2.0);
Xianzhu Wang5b429f02019-08-29 20:45:273189 gfx::Vector2dF perspective_surface_offset(2.f, 2.f);
[email protected]1b30e8e2012-12-21 02:59:093190
[email protected]fb661802013-03-25 01:59:323191 gfx::Transform scale_small_matrix;
[email protected]6138db702013-09-25 03:25:053192 scale_small_matrix.Scale(SK_MScalar1 / 10.f, SK_MScalar1 / 12.f);
[email protected]1b30e8e2012-12-21 02:59:093193
Xianzhu Wangd6a62d82019-09-09 22:35:363194 LayerImpl* root = root_layer();
danakje4fa7b72016-07-25 22:00:063195 root->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc9badff2019-10-01 23:47:223196 SetupViewport(root, gfx::Size(100, 100), gfx::Size(100, 100));
sunxdc5d4fb42016-05-27 04:40:093197
Xianzhu Wang5b429f02019-08-29 20:45:273198 LayerImpl* parent = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063199 parent->SetBounds(gfx::Size(100, 100));
jaydasika8640f9f2015-11-10 01:34:363200 parent->SetDrawsContent(true);
[email protected]9781afa2013-07-17 23:15:323201
Xianzhu Wang5b429f02019-08-29 20:45:273202 LayerImpl* perspective_surface = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063203 perspective_surface->SetBounds(gfx::Size(10, 10));
enne637715732015-07-07 02:05:263204 perspective_surface->SetDrawsContent(true);
[email protected]1b30e8e2012-12-21 02:59:093205
Xianzhu Wang5b429f02019-08-29 20:45:273206 LayerImpl* scale_surface = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063207 scale_surface->SetBounds(gfx::Size(10, 10));
enne637715732015-07-07 02:05:263208 scale_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:273209
Xianzhu Wangc9badff2019-10-01 23:47:223210 CopyProperties(OuterViewportScrollLayer(), parent);
Xianzhu Wang5b429f02019-08-29 20:45:273211 CopyProperties(parent, perspective_surface);
3212 auto& perspective_surface_transform =
3213 CreateTransformNode(perspective_surface);
3214 perspective_surface_transform.local = perspective_matrix * scale_small_matrix;
3215 perspective_surface_transform.post_translation = perspective_surface_offset;
3216 CreateEffectNode(perspective_surface).render_surface_reason =
3217 RenderSurfaceReason::kTest;
3218 CopyProperties(parent, scale_surface);
3219 auto& scale_surface_transform = CreateTransformNode(scale_surface);
3220 scale_surface_transform.local = scale_small_matrix;
3221 scale_surface_transform.post_translation = gfx::Vector2dF(2.f, 2.f);
3222 CreateEffectNode(scale_surface).render_surface_reason =
3223 RenderSurfaceReason::kTest;
[email protected]d600df7d2013-08-03 02:34:283224
[email protected]fb661802013-03-25 01:59:323225 float device_scale_factor = 2.5f;
3226 float page_scale_factor = 3.f;
Xianzhu Wang66e13e02019-09-18 20:39:123227 host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
Xianzhu Wang5b429f02019-08-29 20:45:273228
Xianzhu Wang66e13e02019-09-18 20:39:123229 UpdateActiveTreeDrawProperties(device_scale_factor);
[email protected]1b30e8e2012-12-21 02:59:093230
danakj59931942016-07-26 22:11:293231 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
3232 parent->GetIdealContentsScale());
3233 EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor,
3234 perspective_surface->GetIdealContentsScale());
sohan.jyotie3bd6192014-10-13 07:13:593235 // Ideal scale is the max 2d scale component of the combined transform up to
3236 // the nearest render target. Here this includes the layer transform as well
3237 // as the device and page scale factors.
3238 gfx::Transform transform = scale_small_matrix;
3239 transform.Scale(device_scale_factor * page_scale_factor,
3240 device_scale_factor * page_scale_factor);
3241 gfx::Vector2dF scales =
3242 MathUtil::ComputeTransform2dScaleComponents(transform, 0.f);
3243 float max_2d_scale = std::max(scales.x(), scales.y());
danakj59931942016-07-26 22:11:293244 EXPECT_FLOAT_EQ(max_2d_scale, scale_surface->GetIdealContentsScale());
sohan.jyotie3bd6192014-10-13 07:13:593245
3246 // The ideal scale will draw 1:1 with its render target space along
3247 // the larger-scale axis.
3248 gfx::Vector2dF target_space_transform_scales =
3249 MathUtil::ComputeTransform2dScaleComponents(
3250 scale_surface->draw_properties().target_space_transform, 0.f);
Xianzhu Wang66e13e02019-09-18 20:39:123251 EXPECT_FLOAT_EQ(max_2d_scale, std::max(target_space_transform_scales.x(),
3252 target_space_transform_scales.y()));
[email protected]1b30e8e2012-12-21 02:59:093253
Xianzhu Wang66e13e02019-09-18 20:39:123254 EXPECT_EQ(3u, GetRenderSurfaceList().size());
[email protected]1b30e8e2012-12-21 02:59:093255
[email protected]fb661802013-03-25 01:59:323256 gfx::Transform expected_parent_draw_transform;
sohan.jyotie3bd6192014-10-13 07:13:593257 expected_parent_draw_transform.Scale(device_scale_factor * page_scale_factor,
3258 device_scale_factor * page_scale_factor);
[email protected]fb661802013-03-25 01:59:323259 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_draw_transform,
ajumad9432e32015-11-30 19:43:443260 parent->DrawTransform());
[email protected]1b30e8e2012-12-21 02:59:093261
[email protected]fb661802013-03-25 01:59:323262 // The scale for the perspective surface is not known, so it is rendered 1:1
3263 // with the screen, and then scaled during drawing.
3264 gfx::Transform expected_perspective_surface_draw_transform;
3265 expected_perspective_surface_draw_transform.Translate(
Xianzhu Wang5b429f02019-08-29 20:45:273266 device_scale_factor * page_scale_factor * perspective_surface_offset.x(),
3267 device_scale_factor * page_scale_factor * perspective_surface_offset.y());
[email protected]fb661802013-03-25 01:59:323268 expected_perspective_surface_draw_transform.PreconcatTransform(
3269 perspective_matrix);
3270 expected_perspective_surface_draw_transform.PreconcatTransform(
3271 scale_small_matrix);
3272 gfx::Transform expected_perspective_surface_layer_draw_transform;
sohan.jyotie3bd6192014-10-13 07:13:593273 expected_perspective_surface_layer_draw_transform.Scale(
3274 device_scale_factor * page_scale_factor,
3275 device_scale_factor * page_scale_factor);
[email protected]fb661802013-03-25 01:59:323276 EXPECT_TRANSFORMATION_MATRIX_EQ(
3277 expected_perspective_surface_draw_transform,
chrishtr7e3aaf22017-05-04 15:04:013278 GetRenderSurface(perspective_surface)->draw_transform());
[email protected]fb661802013-03-25 01:59:323279 EXPECT_TRANSFORMATION_MATRIX_EQ(
3280 expected_perspective_surface_layer_draw_transform,
ajumad9432e32015-11-30 19:43:443281 perspective_surface->DrawTransform());
[email protected]1b30e8e2012-12-21 02:59:093282}
3283
Xianzhu Wang66e13e02019-09-18 20:39:123284TEST_F(DrawPropertiesScalingTest, SmallIdealScale) {
[email protected]35a99a12013-05-09 23:52:293285 gfx::Transform parent_scale_matrix;
[email protected]803f6b52013-09-12 00:51:263286 SkMScalar initial_parent_scale = 1.75;
[email protected]35a99a12013-05-09 23:52:293287 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
3288
3289 gfx::Transform child_scale_matrix;
[email protected]803f6b52013-09-12 00:51:263290 SkMScalar initial_child_scale = 0.25;
[email protected]35a99a12013-05-09 23:52:293291 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
3292
Xianzhu Wangd6a62d82019-09-09 22:35:363293 LayerImpl* root = root_layer();
[email protected]35a99a12013-05-09 23:52:293294 root->SetBounds(gfx::Size(100, 100));
3295
Xianzhu Wang5b429f02019-08-29 20:45:273296 LayerImpl* page_scale = AddLayer<LayerImpl>();
Xianzhu Wang1ff8cf382019-08-19 17:33:103297 page_scale->SetBounds(gfx::Size(100, 100));
3298
Xianzhu Wang5b429f02019-08-29 20:45:273299 LayerImpl* parent = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063300 parent->SetBounds(gfx::Size(100, 100));
jaydasika8640f9f2015-11-10 01:34:363301 parent->SetDrawsContent(true);
[email protected]35a99a12013-05-09 23:52:293302
Xianzhu Wang5b429f02019-08-29 20:45:273303 LayerImpl* child_scale = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063304 child_scale->SetBounds(gfx::Size(10, 10));
jaydasika8640f9f2015-11-10 01:34:363305 child_scale->SetDrawsContent(true);
[email protected]d600df7d2013-08-03 02:34:283306
[email protected]fb661802013-03-25 01:59:323307 float device_scale_factor = 2.5f;
3308 float page_scale_factor = 0.01f;
[email protected]11ec92972012-11-10 03:06:213309
Xianzhu Wang5b429f02019-08-29 20:45:273310 CopyProperties(root, page_scale);
3311 CreateTransformNode(page_scale).in_subtree_of_page_scale_layer = true;
3312 CopyProperties(page_scale, parent);
3313 CreateTransformNode(parent).local = parent_scale_matrix;
3314 CopyProperties(parent, child_scale);
3315 CreateTransformNode(child_scale).local = child_scale_matrix;
[email protected]11ec92972012-11-10 03:06:213316
Xianzhu Wangc9badff2019-10-01 23:47:223317 LayerTreeImpl::ViewportPropertyIds viewport_property_ids;
Xianzhu Wang66e13e02019-09-18 20:39:123318 viewport_property_ids.page_scale_transform =
3319 page_scale->transform_tree_index();
Xianzhu Wangc9badff2019-10-01 23:47:223320 host_impl()->active_tree()->SetViewportPropertyIds(viewport_property_ids);
Xianzhu Wang66e13e02019-09-18 20:39:123321
3322 host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
3323 UpdateActiveTreeDrawProperties(device_scale_factor);
[email protected]11ec92972012-11-10 03:06:213324
Xianzhu Wang5b429f02019-08-29 20:45:273325 // The ideal scale is able to go below 1.
3326 float expected_ideal_scale =
3327 device_scale_factor * page_scale_factor * initial_parent_scale;
3328 EXPECT_LT(expected_ideal_scale, 1.f);
3329 EXPECT_FLOAT_EQ(expected_ideal_scale, parent->GetIdealContentsScale());
3330
3331 expected_ideal_scale = device_scale_factor * page_scale_factor *
3332 initial_parent_scale * initial_child_scale;
3333 EXPECT_LT(expected_ideal_scale, 1.f);
3334 EXPECT_FLOAT_EQ(expected_ideal_scale, child_scale->GetIdealContentsScale());
[email protected]11ec92972012-11-10 03:06:213335}
3336
Xianzhu Wang66e13e02019-09-18 20:39:123337TEST_F(DrawPropertiesScalingTest, IdealScaleForAnimatingLayer) {
[email protected]fb661802013-03-25 01:59:323338 gfx::Transform parent_scale_matrix;
[email protected]803f6b52013-09-12 00:51:263339 SkMScalar initial_parent_scale = 1.75;
[email protected]fb661802013-03-25 01:59:323340 parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale);
[email protected]6a9cff92012-11-08 11:53:263341
[email protected]fb661802013-03-25 01:59:323342 gfx::Transform child_scale_matrix;
[email protected]803f6b52013-09-12 00:51:263343 SkMScalar initial_child_scale = 1.25;
[email protected]fb661802013-03-25 01:59:323344 child_scale_matrix.Scale(initial_child_scale, initial_child_scale);
[email protected]6a9cff92012-11-08 11:53:263345
Xianzhu Wangd6a62d82019-09-09 22:35:363346 LayerImpl* root = root_layer();
[email protected]35a99a12013-05-09 23:52:293347 root->SetBounds(gfx::Size(100, 100));
3348
Xianzhu Wang5b429f02019-08-29 20:45:273349 LayerImpl* parent = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063350 parent->SetBounds(gfx::Size(100, 100));
jaydasika8640f9f2015-11-10 01:34:363351 parent->SetDrawsContent(true);
[email protected]6a9cff92012-11-08 11:53:263352
Xianzhu Wang5b429f02019-08-29 20:45:273353 LayerImpl* child_scale = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063354 child_scale->SetBounds(gfx::Size(10, 10));
jaydasika8640f9f2015-11-10 01:34:363355 child_scale->SetDrawsContent(true);
[email protected]d600df7d2013-08-03 02:34:283356
Xianzhu Wang5b429f02019-08-29 20:45:273357 CopyProperties(root, parent);
3358 CreateTransformNode(parent).local = parent_scale_matrix;
3359 CopyProperties(parent, child_scale);
3360 CreateTransformNode(child_scale).local = child_scale_matrix;
3361
Xianzhu Wang66e13e02019-09-18 20:39:123362 UpdateActiveTreeDrawProperties();
[email protected]6a9cff92012-11-08 11:53:263363
danakj59931942016-07-26 22:11:293364 EXPECT_FLOAT_EQ(initial_parent_scale, parent->GetIdealContentsScale());
danakje4fa7b72016-07-25 22:00:063365 // Animating layers compute ideal scale in the same way as when
3366 // they are static.
danakj59931942016-07-26 22:11:293367 EXPECT_FLOAT_EQ(initial_child_scale * initial_parent_scale,
3368 child_scale->GetIdealContentsScale());
[email protected]6a9cff92012-11-08 11:53:263369}
3370
Xianzhu Wang66e13e02019-09-18 20:39:123371TEST_F(DrawPropertiesTest, RenderSurfaceTransformsInHighDPI) {
Xianzhu Wangd6a62d82019-09-09 22:35:363372 LayerImpl* parent = root_layer();
danakje4fa7b72016-07-25 22:00:063373 parent->SetBounds(gfx::Size(30, 30));
enneea850232015-07-27 16:43:123374 parent->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143375
Xianzhu Wang5b429f02019-08-29 20:45:273376 LayerImpl* child = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063377 child->SetBounds(gfx::Size(10, 10));
enneea850232015-07-27 16:43:123378 child->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143379
[email protected]fb661802013-03-25 01:59:323380 // This layer should end up in the same surface as child, with the same draw
3381 // and screen space transforms.
Xianzhu Wang5b429f02019-08-29 20:45:273382 LayerImpl* duplicate_child_non_owner = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063383 duplicate_child_non_owner->SetBounds(gfx::Size(10, 10));
enneea850232015-07-27 16:43:123384 duplicate_child_non_owner->SetDrawsContent(true);
[email protected]94f206c12012-08-25 00:09:143385
[email protected]fb661802013-03-25 01:59:323386 float device_scale_factor = 1.5f;
Xianzhu Wang5b429f02019-08-29 20:45:273387 gfx::Vector2dF child_offset(2.f, 2.f);
3388
Xianzhu Wang5b429f02019-08-29 20:45:273389 CopyProperties(parent, child);
3390 CreateTransformNode(child).post_translation = child_offset;
3391 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
3392 CopyProperties(child, duplicate_child_non_owner);
3393 duplicate_child_non_owner->SetOffsetToTransformParent(
3394 child->offset_to_transform_parent());
3395
Xianzhu Wang66e13e02019-09-18 20:39:123396 UpdateActiveTreeDrawProperties(device_scale_factor);
[email protected]94f206c12012-08-25 00:09:143397
[email protected]fb661802013-03-25 01:59:323398 // We should have two render surfaces. The root's render surface and child's
wangxianzhu932d7f12016-09-30 05:47:003399 // render surface (it needs one because of force_render_surface).
Xianzhu Wang66e13e02019-09-18 20:39:123400 EXPECT_EQ(2u, GetRenderSurfaceList().size());
[email protected]94f206c12012-08-25 00:09:143401
[email protected]fb661802013-03-25 01:59:323402 gfx::Transform expected_parent_transform;
sohan.jyotie3bd6192014-10-13 07:13:593403 expected_parent_transform.Scale(device_scale_factor, device_scale_factor);
[email protected]fb661802013-03-25 01:59:323404 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
ajumab6aa1c62015-12-01 21:01:103405 parent->ScreenSpaceTransform());
[email protected]fb661802013-03-25 01:59:323406 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_parent_transform,
ajumad9432e32015-11-30 19:43:443407 parent->DrawTransform());
[email protected]94f206c12012-08-25 00:09:143408
[email protected]fb661802013-03-25 01:59:323409 gfx::Transform expected_draw_transform;
sohan.jyotie3bd6192014-10-13 07:13:593410 expected_draw_transform.Scale(device_scale_factor, device_scale_factor);
[email protected]fb661802013-03-25 01:59:323411 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_draw_transform,
ajumad9432e32015-11-30 19:43:443412 child->DrawTransform());
[email protected]94f206c12012-08-25 00:09:143413
[email protected]fb661802013-03-25 01:59:323414 gfx::Transform expected_screen_space_transform;
sohan.jyotie3bd6192014-10-13 07:13:593415 expected_screen_space_transform.Scale(device_scale_factor,
3416 device_scale_factor);
Xianzhu Wang5b429f02019-08-29 20:45:273417 expected_screen_space_transform.Translate(child_offset);
[email protected]fb661802013-03-25 01:59:323418 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_screen_space_transform,
ajumab6aa1c62015-12-01 21:01:103419 child->ScreenSpaceTransform());
[email protected]94f206c12012-08-25 00:09:143420
[email protected]fb661802013-03-25 01:59:323421 gfx::Transform expected_duplicate_child_draw_transform =
ajumad9432e32015-11-30 19:43:443422 child->DrawTransform();
trchendba8b1502016-07-08 09:47:013423 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_duplicate_child_draw_transform,
ajumad9432e32015-11-30 19:43:443424 duplicate_child_non_owner->DrawTransform());
[email protected]fb661802013-03-25 01:59:323425 EXPECT_TRANSFORMATION_MATRIX_EQ(
ajumab6aa1c62015-12-01 21:01:103426 child->ScreenSpaceTransform(),
3427 duplicate_child_non_owner->ScreenSpaceTransform());
hush6b614212014-12-04 22:37:323428 EXPECT_EQ(child->drawable_content_rect(),
3429 duplicate_child_non_owner->drawable_content_rect());
Dana Jansensc46d3742015-06-18 01:33:143430 EXPECT_EQ(child->bounds(), duplicate_child_non_owner->bounds());
[email protected]94f206c12012-08-25 00:09:143431
[email protected]fb661802013-03-25 01:59:323432 gfx::Transform expected_render_surface_draw_transform;
3433 expected_render_surface_draw_transform.Translate(
Xianzhu Wang5b429f02019-08-29 20:45:273434 device_scale_factor * child_offset.x(),
3435 device_scale_factor * child_offset.y());
[email protected]fb661802013-03-25 01:59:323436 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_render_surface_draw_transform,
chrishtr7e3aaf22017-05-04 15:04:013437 GetRenderSurface(child)->draw_transform());
[email protected]94f206c12012-08-25 00:09:143438
[email protected]fb661802013-03-25 01:59:323439 gfx::Transform expected_surface_draw_transform;
3440 expected_surface_draw_transform.Translate(device_scale_factor * 2.f,
3441 device_scale_factor * 2.f);
3442 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_surface_draw_transform,
chrishtr7e3aaf22017-05-04 15:04:013443 GetRenderSurface(child)->draw_transform());
[email protected]94f206c12012-08-25 00:09:143444
[email protected]fb661802013-03-25 01:59:323445 gfx::Transform expected_surface_screen_space_transform;
3446 expected_surface_screen_space_transform.Translate(device_scale_factor * 2.f,
3447 device_scale_factor * 2.f);
3448 EXPECT_TRANSFORMATION_MATRIX_EQ(
3449 expected_surface_screen_space_transform,
chrishtr7e3aaf22017-05-04 15:04:013450 GetRenderSurface(child)->screen_space_transform());
[email protected]904e9132012-11-01 00:12:473451}
3452
Xianzhu Wang66e13e02019-09-18 20:39:123453TEST_F(DrawPropertiesTest,
Xianzhu Wang5b429f02019-08-29 20:45:273454 RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) {
Xianzhu Wangd6a62d82019-09-09 22:35:363455 LayerImpl* parent = root_layer();
danakje4fa7b72016-07-25 22:00:063456 parent->SetBounds(gfx::Size(33, 31));
enneea850232015-07-27 16:43:123457 parent->SetDrawsContent(true);
[email protected]904e9132012-11-01 00:12:473458
Xianzhu Wang5b429f02019-08-29 20:45:273459 LayerImpl* child = AddLayer<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063460 child->SetBounds(gfx::Size(13, 11));
enneea850232015-07-27 16:43:123461 child->SetDrawsContent(true);
[email protected]904e9132012-11-01 00:12:473462
[email protected]873639e2013-07-24 19:56:313463 float device_scale_factor = 1.7f;
Xianzhu Wang5b429f02019-08-29 20:45:273464
Xianzhu Wang5b429f02019-08-29 20:45:273465 CopyProperties(parent, child);
3466 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
3467
Xianzhu Wang66e13e02019-09-18 20:39:123468 UpdateActiveTreeDrawProperties(device_scale_factor);
[email protected]904e9132012-11-01 00:12:473469
[email protected]fb661802013-03-25 01:59:323470 // We should have two render surfaces. The root's render surface and child's
wangxianzhu932d7f12016-09-30 05:47:003471 // render surface (it needs one because of force_render_surface).
Xianzhu Wang66e13e02019-09-18 20:39:123472 EXPECT_EQ(2u, GetRenderSurfaceList().size());
[email protected]904e9132012-11-01 00:12:473473
danakjf78fb272016-07-26 19:06:153474 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:013475 GetRenderSurface(child)->draw_transform());
danakjf78fb272016-07-26 19:06:153476 EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(),
chrishtr7e3aaf22017-05-04 15:04:013477 GetRenderSurface(child)->draw_transform());
[email protected]fb661802013-03-25 01:59:323478 EXPECT_TRANSFORMATION_MATRIX_EQ(
chrishtr7e3aaf22017-05-04 15:04:013479 gfx::Transform(), GetRenderSurface(child)->screen_space_transform());
[email protected]94f206c12012-08-25 00:09:143480}
3481
Xianzhu Wang5b429f02019-08-29 20:45:273482// Needs layer tree mode: mask layer. Not using impl-side PropertyTreeBuilder.
Xianzhu Wang66e13e02019-09-18 20:39:123483TEST_F(DrawPropertiesTestWithLayerTree, LayerSearch) {
loyso0940d412016-03-14 01:30:313484 scoped_refptr<Layer> root = Layer::Create();
3485 scoped_refptr<Layer> child = Layer::Create();
3486 scoped_refptr<Layer> grand_child = Layer::Create();
danakj30228f52018-06-14 00:46:273487 FakeContentLayerClient client;
3488 scoped_refptr<PictureLayer> mask_layer = PictureLayer::Create(&client);
[email protected]94f206c12012-08-25 00:09:143489
[email protected]fb661802013-03-25 01:59:323490 child->AddChild(grand_child.get());
Xianzhu Wangc62ecebf2019-08-31 15:54:133491 child->SetMaskLayer(mask_layer);
[email protected]fb661802013-03-25 01:59:323492 root->AddChild(child.get());
[email protected]94f206c12012-08-25 00:09:143493
ennea7b43c32015-06-18 20:01:333494 host()->SetRootLayer(root);
[email protected]d600df7d2013-08-03 02:34:283495
[email protected]fb661802013-03-25 01:59:323496 int nonexistent_id = -1;
khushalsagarb69ba9452017-01-27 22:20:073497 EXPECT_EQ(root.get(), host()->LayerById(root->id()));
3498 EXPECT_EQ(child.get(), host()->LayerById(child->id()));
3499 EXPECT_EQ(grand_child.get(), host()->LayerById(grand_child->id()));
3500 EXPECT_EQ(mask_layer.get(), host()->LayerById(mask_layer->id()));
3501 EXPECT_FALSE(host()->LayerById(nonexistent_id));
[email protected]94f206c12012-08-25 00:09:143502}
3503
Xianzhu Wang66e13e02019-09-18 20:39:123504TEST_F(DrawPropertiesTest, TransparentChildRenderSurfaceCreation) {
Xianzhu Wangd6a62d82019-09-09 22:35:363505 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:273506 LayerImpl* child = AddLayer<LayerImpl>();
3507 LayerImpl* grand_child = AddLayer<LayerImpl>();
[email protected]498ec6e0e2012-11-30 18:24:573508
danakje4fa7b72016-07-25 22:00:063509 root->SetBounds(gfx::Size(100, 100));
3510 child->SetBounds(gfx::Size(10, 10));
danakje4fa7b72016-07-25 22:00:063511 grand_child->SetBounds(gfx::Size(10, 10));
3512 grand_child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:273513
Xianzhu Wang5b429f02019-08-29 20:45:273514 CopyProperties(root, child);
3515 CreateEffectNode(child).opacity = 0.5f;
3516 CopyProperties(child, grand_child);
3517
Xianzhu Wang66e13e02019-09-18 20:39:123518 UpdateActiveTreeDrawProperties();
chrishtr5f60ca02017-05-11 23:09:493519 EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root));
[email protected]498ec6e0e2012-11-30 18:24:573520}
3521
Xianzhu Wang66e13e02019-09-18 20:39:123522TEST_F(DrawPropertiesTest, OpacityAnimatingOnPendingTree) {
Xianzhu Wang5b429f02019-08-29 20:45:273523 host_impl()->CreatePendingTree();
3524 LayerImpl* root = EnsureRootLayerInPendingTree();
danakje4fa7b72016-07-25 22:00:063525 root->SetBounds(gfx::Size(100, 100));
[email protected]f90fc412013-03-30 20:13:163526 root->SetDrawsContent(true);
3527
Xianzhu Wang5b429f02019-08-29 20:45:273528 auto* child = AddLayerInPendingTree<LayerImpl>();
danakje4fa7b72016-07-25 22:00:063529 child->SetBounds(gfx::Size(50, 50));
[email protected]f90fc412013-03-30 20:13:163530 child->SetDrawsContent(true);
[email protected]f90fc412013-03-30 20:13:163531
Xianzhu Wang5b429f02019-08-29 20:45:273532 host_impl()->pending_tree()->SetElementIdsForTesting();
Xianzhu Wang5b429f02019-08-29 20:45:273533 CopyProperties(root, child);
3534 CreateEffectNode(child).opacity = 0.0f;
vollickef2ae922016-06-29 17:54:273535
[email protected]f90fc412013-03-30 20:13:163536 // Add opacity animation.
Xianzhu Wang5b429f02019-08-29 20:45:273537 AddOpacityTransitionToElementWithAnimation(
3538 child->element_id(), timeline_impl(), 10.0, 0.0f, 1.0f, false);
loyso968163c92016-01-04 23:18:483539
Xianzhu Wang66e13e02019-09-18 20:39:123540 UpdatePendingTreeDrawProperties();
[email protected]f90fc412013-03-30 20:13:163541
jaydasika50612fa02017-05-19 20:56:023542 // We should have one render surface and two layers. The child
3543 // layer should be included even though it is transparent.
Xianzhu Wang66e13e02019-09-18 20:39:123544 ASSERT_EQ(1u, host_impl()->pending_tree()->GetRenderSurfaceList().size());
Xianzhu Wang5b429f02019-08-29 20:45:273545 ASSERT_EQ(2, GetRenderSurface(root)->num_contributors());
jaydasika86654512016-01-27 17:05:073546
jaydasika50612fa02017-05-19 20:56:023547 // If the root itself is hidden, the child should not be drawn even if it has
3548 // an animating opacity.
Xianzhu Wang5b429f02019-08-29 20:45:273549 SetOpacity(root, 0.0f);
Xianzhu Wang66e13e02019-09-18 20:39:123550 UpdatePendingTreeDrawProperties();
jaydasika86654512016-01-27 17:05:073551
Xianzhu Wang5b429f02019-08-29 20:45:273552 EXPECT_FALSE(GetEffectNode(child)->is_drawn);
jaydasikae99e83e2016-01-29 19:35:403553
jaydasika50612fa02017-05-19 20:56:023554 // A layer should be drawn and it should contribute to drawn surface when
3555 // it has animating opacity even if it has opacity 0.
Xianzhu Wang5b429f02019-08-29 20:45:273556 SetOpacity(root, 1.0f);
3557 SetOpacity(child, 0.0f);
Xianzhu Wang66e13e02019-09-18 20:39:123558 UpdatePendingTreeDrawProperties();
jaydasikae99e83e2016-01-29 19:35:403559
Xianzhu Wang5b429f02019-08-29 20:45:273560 EXPECT_TRUE(GetEffectNode(child)->is_drawn);
3561 EXPECT_TRUE(GetPropertyTrees(root)->effect_tree.ContributesToDrawnSurface(
3562 child->effect_tree_index()));
jaydasika8185d302016-04-14 15:20:063563
jaydasika50612fa02017-05-19 20:56:023564 // But if the opacity of the layer remains 0 after activation, it should not
3565 // be drawn.
Xianzhu Wang5b429f02019-08-29 20:45:273566 host_impl()->ActivateSyncTree();
3567 LayerTreeImpl* active_tree = host_impl()->active_tree();
Xianzhu Wang5b429f02019-08-29 20:45:273568 LayerImpl* active_child = active_tree->LayerById(child->id());
jaydasika8185d302016-04-14 15:20:063569
Xianzhu Wang5b429f02019-08-29 20:45:273570 EffectTree& active_effect_tree = active_tree->property_trees()->effect_tree;
jaydasika50612fa02017-05-19 20:56:023571 EXPECT_TRUE(active_effect_tree.needs_update());
3572
Xianzhu Wang66e13e02019-09-18 20:39:123573 UpdateActiveTreeDrawProperties();
jaydasika8185d302016-04-14 15:20:063574
Xianzhu Wang5b429f02019-08-29 20:45:273575 EXPECT_FALSE(GetEffectNode(active_child)->is_drawn);
jaydasika50612fa02017-05-19 20:56:023576 EXPECT_FALSE(active_effect_tree.ContributesToDrawnSurface(
3577 active_child->effect_tree_index()));
[email protected]f90fc412013-03-30 20:13:163578}
3579
Xianzhu Wang5b429f02019-08-29 20:45:273580using LCDTextTestParam = std::tuple<bool, bool>;
Xianzhu Wang66e13e02019-09-18 20:39:123581class LCDTextTest : public DrawPropertiesTestBase,
enne637715732015-07-07 02:05:263582 public testing::TestWithParam<LCDTextTestParam> {
enneaf5bda32015-02-19 01:27:363583 public:
Xianzhu Wang66e13e02019-09-18 20:39:123584 LCDTextTest() : DrawPropertiesTestBase(LCDTextTestLayerTreeSettings()) {}
loyso968163c92016-01-04 23:18:483585
[email protected]fb661802013-03-25 01:59:323586 protected:
sunxd5a7a4032016-06-01 18:49:223587 LayerTreeSettings LCDTextTestLayerTreeSettings() {
Xianzhu Wang5b429f02019-08-29 20:45:273588 LayerListSettings settings;
sunxd5a7a4032016-06-01 18:49:223589
Victor Costanaeb7f8e2018-04-06 19:05:263590 can_use_lcd_text_ = std::get<0>(GetParam());
3591 layers_always_allowed_lcd_text_ = std::get<1>(GetParam());
sunxd5a7a4032016-06-01 18:49:223592 settings.can_use_lcd_text = can_use_lcd_text_;
3593 settings.layers_always_allowed_lcd_text = layers_always_allowed_lcd_text_;
3594 return settings;
3595 }
3596
dcheng93a52eb2014-12-23 02:14:233597 void SetUp() override {
Xianzhu Wangd6a62d82019-09-09 22:35:363598 root_ = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:273599 child_ = AddLayer<LayerImpl>();
3600 grand_child_ = AddLayer<LayerImpl>();
3601 SetElementIdsForTesting();
vollickef2ae922016-06-29 17:54:273602
fmalita51b5e202014-11-18 20:11:503603 root_->SetContentsOpaque(true);
3604 child_->SetContentsOpaque(true);
3605 grand_child_->SetContentsOpaque(true);
3606
jaydasika3f930c12015-06-30 15:18:253607 root_->SetDrawsContent(true);
3608 child_->SetDrawsContent(true);
3609 grand_child_->SetDrawsContent(true);
3610
danakje4fa7b72016-07-25 22:00:063611 root_->SetBounds(gfx::Size(1, 1));
3612 child_->SetBounds(gfx::Size(1, 1));
3613 grand_child_->SetBounds(gfx::Size(1, 1));
3614
Xianzhu Wang5b429f02019-08-29 20:45:273615 CopyProperties(root_, child_);
3616 CreateTransformNode(child_);
3617 CreateEffectNode(child_).render_surface_reason = RenderSurfaceReason::kTest;
3618 CopyProperties(child_, grand_child_);
[email protected]fb661802013-03-25 01:59:323619 }
[email protected]10aabcc32012-12-13 09:18:593620
[email protected]fb661802013-03-25 01:59:323621 bool can_use_lcd_text_;
danakj3f76ace2014-11-18 16:56:003622 bool layers_always_allowed_lcd_text_;
enneaf5bda32015-02-19 01:27:363623
danakj59931942016-07-26 22:11:293624 LayerImpl* root_ = nullptr;
3625 LayerImpl* child_ = nullptr;
3626 LayerImpl* grand_child_ = nullptr;
[email protected]10aabcc32012-12-13 09:18:593627};
3628
[email protected]fb661802013-03-25 01:59:323629TEST_P(LCDTextTest, CanUseLCDText) {
danakj3f76ace2014-11-18 16:56:003630 bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
3631 bool expect_not_lcd_text = layers_always_allowed_lcd_text_;
3632
[email protected]fb661802013-03-25 01:59:323633 // Case 1: Identity transform.
Xianzhu Wang66e13e02019-09-18 20:39:123634 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223635 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3636 EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
3637 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593638
[email protected]fb661802013-03-25 01:59:323639 // Case 2: Integral translation.
3640 gfx::Transform integral_translation;
3641 integral_translation.Translate(1.0, 2.0);
Xianzhu Wang5b429f02019-08-29 20:45:273642 SetTransform(child_, integral_translation);
3643
Xianzhu Wang66e13e02019-09-18 20:39:123644 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223645 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3646 EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
3647 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593648
[email protected]fb661802013-03-25 01:59:323649 // Case 3: Non-integral translation.
3650 gfx::Transform non_integral_translation;
3651 non_integral_translation.Translate(1.5, 2.5);
Xianzhu Wang5b429f02019-08-29 20:45:273652 SetTransform(child_, non_integral_translation);
Xianzhu Wang66e13e02019-09-18 20:39:123653 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223654 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3655 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3656 EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593657
[email protected]fb661802013-03-25 01:59:323658 // Case 4: Rotation.
3659 gfx::Transform rotation;
3660 rotation.Rotate(10.0);
Xianzhu Wang5b429f02019-08-29 20:45:273661 SetTransform(child_, rotation);
Xianzhu Wang66e13e02019-09-18 20:39:123662 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223663 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3664 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3665 EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593666
[email protected]fb661802013-03-25 01:59:323667 // Case 5: Scale.
3668 gfx::Transform scale;
3669 scale.Scale(2.0, 2.0);
Xianzhu Wang5b429f02019-08-29 20:45:273670 SetTransform(child_, scale);
Xianzhu Wang66e13e02019-09-18 20:39:123671 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223672 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3673 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3674 EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593675
[email protected]fb661802013-03-25 01:59:323676 // Case 6: Skew.
3677 gfx::Transform skew;
nainar8ca8ee62015-09-03 01:04:103678 skew.Skew(10.0, 0.0);
Xianzhu Wang5b429f02019-08-29 20:45:273679 SetTransform(child_, skew);
Xianzhu Wang66e13e02019-09-18 20:39:123680 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223681 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3682 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3683 EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593684
[email protected]fb661802013-03-25 01:59:323685 // Case 7: Translucent.
Xianzhu Wang5b429f02019-08-29 20:45:273686 SetTransform(child_, gfx::Transform());
3687 SetOpacity(child_, 0.5f);
Xianzhu Wang66e13e02019-09-18 20:39:123688 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223689 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3690 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3691 EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593692
[email protected]fb661802013-03-25 01:59:323693 // Case 8: Sanity check: restore transform and opacity.
Xianzhu Wang5b429f02019-08-29 20:45:273694 SetTransform(child_, gfx::Transform());
3695 SetOpacity(child_, 1.f);
Xianzhu Wang66e13e02019-09-18 20:39:123696 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223697 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3698 EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
3699 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
fmalita51b5e202014-11-18 20:11:503700
3701 // Case 9: Non-opaque content.
3702 child_->SetContentsOpaque(false);
Xianzhu Wang66e13e02019-09-18 20:39:123703 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223704 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3705 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3706 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
fmalita51b5e202014-11-18 20:11:503707
3708 // Case 10: Sanity check: restore content opaqueness.
3709 child_->SetContentsOpaque(true);
Xianzhu Wang66e13e02019-09-18 20:39:123710 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223711 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3712 EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
3713 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
Chris Harrelsona30af5842019-03-27 21:30:403714
3715 // Case 11: will-change: transform
3716 child_->SetHasWillChangeTransformHint(true);
Xianzhu Wang66e13e02019-09-18 20:39:123717 UpdateActiveTreeDrawProperties();
Chris Harrelsona30af5842019-03-27 21:30:403718 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3719 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3720 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593721}
3722
[email protected]fd9a3b6d2013-08-03 00:46:173723TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) {
danakj3f76ace2014-11-18 16:56:003724 bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
fmalitafcd926a2015-05-13 20:19:333725 bool expect_not_lcd_text = layers_always_allowed_lcd_text_;
danakj3f76ace2014-11-18 16:56:003726
[email protected]fb661802013-03-25 01:59:323727 // Sanity check: Make sure can_use_lcd_text_ is set on each node.
Xianzhu Wang66e13e02019-09-18 20:39:123728 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223729 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3730 EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
3731 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593732
[email protected]fb661802013-03-25 01:59:323733 // Add opacity animation.
Xianzhu Wang5b429f02019-08-29 20:45:273734 SetOpacity(child_, 0.9f);
Yi Guaa830ff2018-02-22 03:09:113735 AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(),
3736 10.0, 0.9f, 0.1f, false);
Xianzhu Wang66e13e02019-09-18 20:39:123737 UpdateActiveTreeDrawProperties();
fmalitafcd926a2015-05-13 20:19:333738 // Text LCD should be adjusted while animation is active.
sunxd5a7a4032016-06-01 18:49:223739 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3740 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3741 EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText());
fmalitafcd926a2015-05-13 20:19:333742}
3743
3744TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) {
3745 bool expect_lcd_text = can_use_lcd_text_ || layers_always_allowed_lcd_text_;
3746 bool expect_not_lcd_text = layers_always_allowed_lcd_text_;
3747
3748 // Sanity check: Make sure can_use_lcd_text_ is set on each node.
Xianzhu Wang66e13e02019-09-18 20:39:123749 UpdateActiveTreeDrawProperties();
sunxd5a7a4032016-06-01 18:49:223750 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3751 EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText());
3752 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
fmalitafcd926a2015-05-13 20:19:333753
3754 // Mark contents non-opaque within the first animation frame.
3755 child_->SetContentsOpaque(false);
Yi Guaa830ff2018-02-22 03:09:113756 AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(),
3757 10.0, 0.9f, 0.1f, false);
Xianzhu Wang66e13e02019-09-18 20:39:123758 UpdateActiveTreeDrawProperties();
fmalitafcd926a2015-05-13 20:19:333759 // LCD text should be disabled for non-opaque layers even during animations.
sunxd5a7a4032016-06-01 18:49:223760 EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText());
3761 EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText());
3762 EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText());
[email protected]10aabcc32012-12-13 09:18:593763}
3764
Xianzhu Wang66e13e02019-09-18 20:39:123765INSTANTIATE_TEST_SUITE_P(DrawPropertiesTest,
Victor Costanf492e3f5c2019-02-13 19:48:513766 LCDTextTest,
Xianzhu Wang5b429f02019-08-29 20:45:273767 testing::Combine(testing::Bool(), testing::Bool()));
[email protected]10aabcc32012-12-13 09:18:593768
Xianzhu Wang5b429f02019-08-29 20:45:273769// Needs layer tree mode: hide_layer_and_subtree.
Xianzhu Wang66e13e02019-09-18 20:39:123770TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_SingleLayerImpl) {
Xianzhu Wangc62ecebf2019-08-31 15:54:133771 auto root = Layer::Create();
danakje4fa7b72016-07-25 22:00:063772 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:133773 root->SetIsDrawable(true);
[email protected]c0ae06c12013-06-24 18:32:193774
Xianzhu Wangc62ecebf2019-08-31 15:54:133775 auto child = Layer::Create();
3776 root->AddChild(child);
danakje4fa7b72016-07-25 22:00:063777 child->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:133778 child->SetIsDrawable(true);
[email protected]c0ae06c12013-06-24 18:32:193779
Xianzhu Wangc62ecebf2019-08-31 15:54:133780 auto grand_child = Layer::Create();
3781 child->AddChild(grand_child);
danakje4fa7b72016-07-25 22:00:063782 grand_child->SetBounds(gfx::Size(30, 30));
Xianzhu Wangc62ecebf2019-08-31 15:54:133783 grand_child->SetIsDrawable(true);
3784 grand_child->SetHideLayerAndSubtree(true);
[email protected]c0ae06c12013-06-24 18:32:193785
Xianzhu Wangc62ecebf2019-08-31 15:54:133786 child->AddChild(grand_child);
3787 root->AddChild(child);
3788 host()->SetRootLayer(root);
[email protected]c0ae06c12013-06-24 18:32:193789
Xianzhu Wangc62ecebf2019-08-31 15:54:133790 CommitAndActivate();
[email protected]c0ae06c12013-06-24 18:32:193791
3792 // We should have one render surface and two layers. The grand child has
3793 // hidden itself.
Xianzhu Wang66e13e02019-09-18 20:39:123794 ASSERT_EQ(1u, GetRenderSurfaceList().size());
Xianzhu Wangc62ecebf2019-08-31 15:54:133795 ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
3796 EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
3797 EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface());
3798 EXPECT_FALSE(ImplOf(grand_child)->contributes_to_drawn_render_surface());
[email protected]c0ae06c12013-06-24 18:32:193799}
3800
Xianzhu Wang5b429f02019-08-29 20:45:273801// Needs layer tree mode: hide_layer_and_subtree.
Xianzhu Wang66e13e02019-09-18 20:39:123802TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_TwoLayersImpl) {
Xianzhu Wangc62ecebf2019-08-31 15:54:133803 auto root = Layer::Create();
danakje4fa7b72016-07-25 22:00:063804 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:133805 root->SetIsDrawable(true);
[email protected]c0ae06c12013-06-24 18:32:193806
Xianzhu Wangc62ecebf2019-08-31 15:54:133807 auto child = Layer::Create();
danakje4fa7b72016-07-25 22:00:063808 child->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:133809 child->SetIsDrawable(true);
3810 child->SetHideLayerAndSubtree(true);
[email protected]c0ae06c12013-06-24 18:32:193811
Xianzhu Wangc62ecebf2019-08-31 15:54:133812 auto grand_child = Layer::Create();
danakje4fa7b72016-07-25 22:00:063813 grand_child->SetBounds(gfx::Size(30, 30));
Xianzhu Wangc62ecebf2019-08-31 15:54:133814 grand_child->SetIsDrawable(true);
[email protected]c0ae06c12013-06-24 18:32:193815
Xianzhu Wangc62ecebf2019-08-31 15:54:133816 child->AddChild(grand_child);
3817 root->AddChild(child);
3818 host()->SetRootLayer(root);
[email protected]c0ae06c12013-06-24 18:32:193819
Xianzhu Wangc62ecebf2019-08-31 15:54:133820 CommitAndActivate();
[email protected]c0ae06c12013-06-24 18:32:193821
ajumab784ef42017-04-28 23:01:523822 // We should have one render surface and one layer. The child has
[email protected]c0ae06c12013-06-24 18:32:193823 // hidden itself and the grand child.
Xianzhu Wang66e13e02019-09-18 20:39:123824 ASSERT_EQ(1u, GetRenderSurfaceList().size());
Xianzhu Wangc62ecebf2019-08-31 15:54:133825 ASSERT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors());
3826 EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
3827 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
3828 EXPECT_FALSE(ImplOf(grand_child)->contributes_to_drawn_render_surface());
[email protected]c0ae06c12013-06-24 18:32:193829}
3830
Xianzhu Wang5b429f02019-08-29 20:45:273831// Needs layer tree mode: mask layer, hide_layer_and_subtree and copy request.
Xianzhu Wang66e13e02019-09-18 20:39:123832TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCopyRequest) {
Xianzhu Wangc62ecebf2019-08-31 15:54:133833 auto root = Layer::Create();
danakje4fa7b72016-07-25 22:00:063834 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:133835 root->SetIsDrawable(true);
[email protected]30fe19ff2013-07-04 00:54:453836
Xianzhu Wangc62ecebf2019-08-31 15:54:133837 auto copy_grand_parent = Layer::Create();
danakje4fa7b72016-07-25 22:00:063838 copy_grand_parent->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:133839 copy_grand_parent->SetIsDrawable(true);
[email protected]30fe19ff2013-07-04 00:54:453840
Xianzhu Wangc62ecebf2019-08-31 15:54:133841 auto copy_parent = Layer::Create();
danakje4fa7b72016-07-25 22:00:063842 copy_parent->SetBounds(gfx::Size(30, 30));
Xianzhu Wangc62ecebf2019-08-31 15:54:133843 copy_parent->SetIsDrawable(true);
3844 copy_parent->SetForceRenderSurfaceForTesting(true);
[email protected]30fe19ff2013-07-04 00:54:453845
Xianzhu Wangc62ecebf2019-08-31 15:54:133846 auto copy_layer = Layer::Create();
3847 copy_layer->SetBounds(gfx::Size(20, 20));
3848 copy_layer->SetIsDrawable(true);
3849 copy_layer->SetForceRenderSurfaceForTesting(true);
[email protected]30fe19ff2013-07-04 00:54:453850
Xianzhu Wangc62ecebf2019-08-31 15:54:133851 auto copy_child = Layer::Create();
danakje4fa7b72016-07-25 22:00:063852 copy_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:133853 copy_child->SetIsDrawable(true);
[email protected]30fe19ff2013-07-04 00:54:453854
Xianzhu Wangc62ecebf2019-08-31 15:54:133855 auto copy_grand_child = Layer::Create();
danakje4fa7b72016-07-25 22:00:063856 copy_grand_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:133857 copy_grand_child->SetIsDrawable(true);
jaydasika86654512016-01-27 17:05:073858
Xianzhu Wangc62ecebf2019-08-31 15:54:133859 auto copy_grand_parent_sibling_before = Layer::Create();
danakje4fa7b72016-07-25 22:00:063860 copy_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:133861 copy_grand_parent_sibling_before->SetIsDrawable(true);
[email protected]ac020122013-07-12 23:45:533862
Xianzhu Wangc62ecebf2019-08-31 15:54:133863 auto copy_grand_parent_sibling_after = Layer::Create();
danakje4fa7b72016-07-25 22:00:063864 copy_grand_parent_sibling_after->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:133865 copy_grand_parent_sibling_after->SetIsDrawable(true);
[email protected]ac020122013-07-12 23:45:533866
Xianzhu Wangc62ecebf2019-08-31 15:54:133867 copy_child->AddChild(copy_grand_child);
3868 copy_layer->AddChild(copy_child);
3869 copy_parent->AddChild(copy_layer);
3870 copy_grand_parent->AddChild(copy_parent);
3871 root->AddChild(copy_grand_parent_sibling_before);
3872 root->AddChild(copy_grand_parent);
3873 root->AddChild(copy_grand_parent_sibling_after);
3874 host()->SetRootLayer(root);
[email protected]d600df7d2013-08-03 02:34:283875
[email protected]30fe19ff2013-07-04 00:54:453876 // Hide the copy_grand_parent and its subtree. But make a copy request in that
jaydasika86654512016-01-27 17:05:073877 // hidden subtree on copy_layer. Also hide the copy grand child and its
3878 // subtree.
Xianzhu Wangc62ecebf2019-08-31 15:54:133879 copy_grand_parent->SetHideLayerAndSubtree(true);
3880 copy_grand_parent_sibling_before->SetHideLayerAndSubtree(true);
3881 copy_grand_parent_sibling_after->SetHideLayerAndSubtree(true);
3882 copy_grand_child->SetHideLayerAndSubtree(true);
weiliangc51fb255d2015-07-24 15:32:303883
Xianzhu Wangc62ecebf2019-08-31 15:54:133884 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:503885 viz::CopyOutputRequest::CreateStubForTesting());
[email protected]30fe19ff2013-07-04 00:54:453886
Xianzhu Wangc62ecebf2019-08-31 15:54:133887 CommitAndActivate();
[email protected]30fe19ff2013-07-04 00:54:453888
Xianzhu Wangc62ecebf2019-08-31 15:54:133889 EXPECT_TRUE(GetEffectNode(ImplOf(root))->subtree_has_copy_request);
3890 EXPECT_TRUE(
3891 GetEffectNode(ImplOf(copy_grand_parent))->subtree_has_copy_request);
3892 EXPECT_TRUE(GetEffectNode(ImplOf(copy_parent))->subtree_has_copy_request);
3893 EXPECT_TRUE(GetEffectNode(ImplOf(copy_layer))->subtree_has_copy_request);
[email protected]ac020122013-07-12 23:45:533894
jaydasika86654512016-01-27 17:05:073895 // We should have four render surfaces, one for the root, one for the grand
3896 // parent since it has opacity and two drawing descendants, one for the parent
[email protected]30fe19ff2013-07-04 00:54:453897 // since it owns a surface, and one for the copy_layer.
Xianzhu Wang66e13e02019-09-18 20:39:123898 ASSERT_EQ(4u, GetRenderSurfaceList().size());
Xianzhu Wangc62ecebf2019-08-31 15:54:133899 EXPECT_EQ(static_cast<uint64_t>(root->id()),
Xianzhu Wang66e13e02019-09-18 20:39:123900 GetRenderSurfaceList().at(0)->id());
Xianzhu Wangc62ecebf2019-08-31 15:54:133901 EXPECT_EQ(static_cast<uint64_t>(copy_grand_parent->id()),
Xianzhu Wang66e13e02019-09-18 20:39:123902 GetRenderSurfaceList().at(1)->id());
Xianzhu Wangc62ecebf2019-08-31 15:54:133903 EXPECT_EQ(static_cast<uint64_t>(copy_parent->id()),
Xianzhu Wang66e13e02019-09-18 20:39:123904 GetRenderSurfaceList().at(2)->id());
Chris Harrelson9bdbcce2017-06-02 03:12:143905 EXPECT_EQ(static_cast<uint64_t>(copy_layer->id()),
Xianzhu Wang66e13e02019-09-18 20:39:123906 GetRenderSurfaceList().at(3)->id());
[email protected]30fe19ff2013-07-04 00:54:453907
jaydasika86654512016-01-27 17:05:073908 // The root render surface should have 2 contributing layers.
Xianzhu Wangc62ecebf2019-08-31 15:54:133909 EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
3910 EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
3911 EXPECT_FALSE(
3912 ImplOf(copy_grand_parent)->contributes_to_drawn_render_surface());
3913 EXPECT_FALSE(ImplOf(copy_grand_parent_sibling_before)
ajuma651848a2017-05-01 21:23:453914 ->contributes_to_drawn_render_surface());
Xianzhu Wangc62ecebf2019-08-31 15:54:133915 EXPECT_FALSE(ImplOf(copy_grand_parent_sibling_after)
ajuma651848a2017-05-01 21:23:453916 ->contributes_to_drawn_render_surface());
[email protected]30fe19ff2013-07-04 00:54:453917
[email protected]7392c7b2014-02-07 08:28:283918 // Nothing actually draws into the copy parent, so only the copy_layer will
[email protected]30fe19ff2013-07-04 00:54:453919 // appear in its list, since it needs to be drawn for the copy request.
Xianzhu Wangc62ecebf2019-08-31 15:54:133920 ASSERT_EQ(1, GetRenderSurfaceImpl(copy_parent)->num_contributors());
3921 EXPECT_FALSE(ImplOf(copy_parent)->contributes_to_drawn_render_surface());
[email protected]30fe19ff2013-07-04 00:54:453922
ajumab784ef42017-04-28 23:01:523923 // The copy layer's render surface should have 2 contributing layers.
Xianzhu Wangc62ecebf2019-08-31 15:54:133924 ASSERT_EQ(2, GetRenderSurfaceImpl(copy_layer)->num_contributors());
3925 EXPECT_TRUE(ImplOf(copy_layer)->contributes_to_drawn_render_surface());
3926 EXPECT_TRUE(ImplOf(copy_child)->contributes_to_drawn_render_surface());
3927 EXPECT_FALSE(ImplOf(copy_grand_child)->contributes_to_drawn_render_surface());
jaydasika86654512016-01-27 17:05:073928
3929 // copy_grand_parent, copy_parent shouldn't be drawn because they are hidden,
3930 // but the copy_layer and copy_child should be drawn for the copy request.
3931 // copy grand child should not be drawn as its hidden even in the copy
3932 // request.
Xianzhu Wangc62ecebf2019-08-31 15:54:133933 EXPECT_FALSE(GetEffectNode(ImplOf(copy_grand_parent))->is_drawn);
3934 EXPECT_FALSE(GetEffectNode(ImplOf(copy_parent))->is_drawn);
3935 EXPECT_TRUE(GetEffectNode(ImplOf(copy_layer))->is_drawn);
3936 EXPECT_TRUE(GetEffectNode(ImplOf(copy_child))->is_drawn);
3937 EXPECT_FALSE(GetEffectNode(ImplOf(copy_grand_child))->is_drawn);
jaydasika86654512016-01-27 17:05:073938
3939 // Though copy_layer is drawn, it shouldn't contribute to drawn surface as its
3940 // actually hidden.
Xianzhu Wangc62ecebf2019-08-31 15:54:133941 EXPECT_FALSE(
3942 GetRenderSurfaceImpl(copy_layer)->contributes_to_drawn_surface());
[email protected]30fe19ff2013-07-04 00:54:453943}
3944
Xianzhu Wang5b429f02019-08-29 20:45:273945// Needs layer tree mode: copy request.
Xianzhu Wang66e13e02019-09-18 20:39:123946TEST_F(DrawPropertiesTestWithLayerTree, ClippedOutCopyRequest) {
Xianzhu Wangc62ecebf2019-08-31 15:54:133947 auto root = Layer::Create();
danakje4fa7b72016-07-25 22:00:063948 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:133949 root->SetIsDrawable(true);
[email protected]30fe19ff2013-07-04 00:54:453950
Xianzhu Wangc62ecebf2019-08-31 15:54:133951 auto copy_parent = Layer::Create();
3952 copy_parent->SetIsDrawable(true);
[email protected]30fe19ff2013-07-04 00:54:453953 copy_parent->SetMasksToBounds(true);
3954
Xianzhu Wangc62ecebf2019-08-31 15:54:133955 auto copy_layer = Layer::Create();
danakje4fa7b72016-07-25 22:00:063956 copy_layer->SetBounds(gfx::Size(30, 30));
Xianzhu Wangc62ecebf2019-08-31 15:54:133957 copy_layer->SetIsDrawable(true);
3958 copy_layer->SetForceRenderSurfaceForTesting(true);
[email protected]30fe19ff2013-07-04 00:54:453959
Xianzhu Wangc62ecebf2019-08-31 15:54:133960 auto copy_child = Layer::Create();
danakje4fa7b72016-07-25 22:00:063961 copy_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:133962 copy_child->SetIsDrawable(true);
[email protected]30fe19ff2013-07-04 00:54:453963
Xianzhu Wangc62ecebf2019-08-31 15:54:133964 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:503965 viz::CopyOutputRequest::CreateStubForTesting());
[email protected]30fe19ff2013-07-04 00:54:453966
Xianzhu Wangc62ecebf2019-08-31 15:54:133967 copy_layer->AddChild(copy_child);
3968 copy_parent->AddChild(copy_layer);
3969 root->AddChild(copy_parent);
weiliangc51fb255d2015-07-24 15:32:303970
Xianzhu Wangc62ecebf2019-08-31 15:54:133971 host()->SetRootLayer(root);
3972
3973 CommitAndActivate();
[email protected]30fe19ff2013-07-04 00:54:453974
xjze19f76402015-11-06 21:48:443975 // We should have two render surface, as the others are clipped out.
Xianzhu Wang66e13e02019-09-18 20:39:123976 ASSERT_EQ(2u, GetRenderSurfaceList().size());
Xianzhu Wangc62ecebf2019-08-31 15:54:133977 EXPECT_EQ(static_cast<uint64_t>(root->id()),
Xianzhu Wang66e13e02019-09-18 20:39:123978 GetRenderSurfaceList().at(0)->id());
[email protected]30fe19ff2013-07-04 00:54:453979
ajumab784ef42017-04-28 23:01:523980 // The root render surface should have only 2 contributing layer, since the
3981 // other layers are clipped away.
Xianzhu Wangc62ecebf2019-08-31 15:54:133982 ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
3983 EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
[email protected]30fe19ff2013-07-04 00:54:453984}
3985
Xianzhu Wang5b429f02019-08-29 20:45:273986// Needs layer tree mode: copy request.
Xianzhu Wang66e13e02019-09-18 20:39:123987TEST_F(DrawPropertiesTestWithLayerTree, SingularTransformAndCopyRequests) {
Xianzhu Wangc62ecebf2019-08-31 15:54:133988 auto root = Layer::Create();
3989 host()->SetRootLayer(root);
jaydasika96e69462017-05-03 23:06:453990 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:133991 root->SetIsDrawable(true);
jaydasika96e69462017-05-03 23:06:453992
Xianzhu Wangc62ecebf2019-08-31 15:54:133993 auto singular_transform_layer = Layer::Create();
3994 root->AddChild(singular_transform_layer);
jaydasika96e69462017-05-03 23:06:453995 singular_transform_layer->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc62ecebf2019-08-31 15:54:133996 singular_transform_layer->SetIsDrawable(true);
jaydasika96e69462017-05-03 23:06:453997 gfx::Transform singular;
3998 singular.Scale3d(6.f, 6.f, 0.f);
Xianzhu Wangc62ecebf2019-08-31 15:54:133999 singular_transform_layer->SetTransform(singular);
jaydasika96e69462017-05-03 23:06:454000
Xianzhu Wangc62ecebf2019-08-31 15:54:134001 auto copy_layer = Layer::Create();
4002 singular_transform_layer->AddChild(copy_layer);
jaydasika96e69462017-05-03 23:06:454003 copy_layer->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc62ecebf2019-08-31 15:54:134004 copy_layer->SetIsDrawable(true);
4005 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:504006 viz::CopyOutputRequest::CreateStubForTesting());
jaydasika96e69462017-05-03 23:06:454007
Xianzhu Wangc62ecebf2019-08-31 15:54:134008 auto copy_child = Layer::Create();
4009 copy_layer->AddChild(copy_child);
jaydasika96e69462017-05-03 23:06:454010 copy_child->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc62ecebf2019-08-31 15:54:134011 copy_child->SetIsDrawable(true);
jaydasika96e69462017-05-03 23:06:454012
Xianzhu Wangc62ecebf2019-08-31 15:54:134013 auto copy_grand_child = Layer::Create();
4014 copy_child->AddChild(copy_grand_child);
jaydasika96e69462017-05-03 23:06:454015 copy_grand_child->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc62ecebf2019-08-31 15:54:134016 copy_grand_child->SetIsDrawable(true);
4017 copy_grand_child->SetTransform(singular);
jaydasika96e69462017-05-03 23:06:454018
Xianzhu Wangc62ecebf2019-08-31 15:54:134019 ASSERT_TRUE(copy_layer->HasCopyRequest());
4020 CommitAndActivate();
4021 ASSERT_FALSE(copy_layer->HasCopyRequest());
jaydasika96e69462017-05-03 23:06:454022
4023 // A layer with singular transform should not contribute to drawn render
4024 // surface.
Xianzhu Wangc62ecebf2019-08-31 15:54:134025 EXPECT_FALSE(
4026 ImplOf(singular_transform_layer)->contributes_to_drawn_render_surface());
jaydasika96e69462017-05-03 23:06:454027 // Even though copy_layer and copy_child have singular screen space transform,
4028 // they still contribute to drawn render surface as their transform to the
4029 // closest ancestor with copy request is not singular.
Xianzhu Wangc62ecebf2019-08-31 15:54:134030 EXPECT_TRUE(ImplOf(copy_layer)->contributes_to_drawn_render_surface());
4031 EXPECT_TRUE(ImplOf(copy_child)->contributes_to_drawn_render_surface());
jaydasika96e69462017-05-03 23:06:454032 // copy_grand_child's transform to its closest ancestor with copy request is
4033 // also singular. So, it doesn't contribute to drawn render surface.
Xianzhu Wangc62ecebf2019-08-31 15:54:134034 EXPECT_FALSE(ImplOf(copy_grand_child)->contributes_to_drawn_render_surface());
jaydasika96e69462017-05-03 23:06:454035}
4036
Xianzhu Wang5b429f02019-08-29 20:45:274037// Needs layer tree mode: copy request.
Xianzhu Wang66e13e02019-09-18 20:39:124038TEST_F(DrawPropertiesTestWithLayerTree, VisibleRectInNonRootCopyRequest) {
Xianzhu Wangc62ecebf2019-08-31 15:54:134039 auto root = Layer::Create();
4040 host()->SetRootLayer(root);
danakje4fa7b72016-07-25 22:00:064041 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:134042 root->SetIsDrawable(true);
weiliangcde7e0c32016-06-15 15:02:414043 root->SetMasksToBounds(true);
4044
Xianzhu Wangc62ecebf2019-08-31 15:54:134045 auto copy_layer = Layer::Create();
4046 root->AddChild(copy_layer);
danakje4fa7b72016-07-25 22:00:064047 copy_layer->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc62ecebf2019-08-31 15:54:134048 copy_layer->SetIsDrawable(true);
4049 copy_layer->SetForceRenderSurfaceForTesting(true);
weiliangcde7e0c32016-06-15 15:02:414050
Xianzhu Wangc62ecebf2019-08-31 15:54:134051 auto copy_child = Layer::Create();
4052 copy_layer->AddChild(copy_child);
4053 copy_child->SetPosition(gfx::PointF(40.f, 40.f));
danakje4fa7b72016-07-25 22:00:064054 copy_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:134055 copy_child->SetIsDrawable(true);
weiliangcde7e0c32016-06-15 15:02:414056
Xianzhu Wangc62ecebf2019-08-31 15:54:134057 auto copy_clip = Layer::Create();
4058 copy_layer->AddChild(copy_clip);
danakje4fa7b72016-07-25 22:00:064059 copy_clip->SetBounds(gfx::Size(55, 55));
weiliangcde7e0c32016-06-15 15:02:414060 copy_clip->SetMasksToBounds(true);
4061
Xianzhu Wangc62ecebf2019-08-31 15:54:134062 auto copy_clipped_child = Layer::Create();
4063 copy_clip->AddChild(copy_clipped_child);
4064 copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f));
danakje4fa7b72016-07-25 22:00:064065 copy_clipped_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:134066 copy_clipped_child->SetIsDrawable(true);
weiliangcde7e0c32016-06-15 15:02:414067
Xianzhu Wangc62ecebf2019-08-31 15:54:134068 auto copy_surface = Layer::Create();
4069 copy_clip->AddChild(copy_surface);
4070 copy_surface->SetPosition(gfx::PointF(45.f, 45.f));
danakje4fa7b72016-07-25 22:00:064071 copy_surface->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:134072 copy_surface->SetIsDrawable(true);
4073 copy_surface->SetForceRenderSurfaceForTesting(true);
weiliangcde7e0c32016-06-15 15:02:414074
Xianzhu Wangc62ecebf2019-08-31 15:54:134075 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:504076 viz::CopyOutputRequest::CreateStubForTesting());
Xianzhu Wangc62ecebf2019-08-31 15:54:134077 ASSERT_TRUE(copy_layer->HasCopyRequest());
4078 CommitAndActivate();
4079 ASSERT_FALSE(copy_layer->HasCopyRequest());
weiliangcde7e0c32016-06-15 15:02:414080
Xianzhu Wangc62ecebf2019-08-31 15:54:134081 EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
4082 EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
4083 EXPECT_EQ(gfx::Rect(15, 15),
4084 ImplOf(copy_clipped_child)->visible_layer_rect());
4085 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_surface)->visible_layer_rect());
weiliangcde7e0c32016-06-15 15:02:414086
4087 // Case 2: When the non root copy request layer is clipped.
4088 copy_layer->SetBounds(gfx::Size(50, 50));
4089 copy_layer->SetMasksToBounds(true);
Xianzhu Wangc62ecebf2019-08-31 15:54:134090 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:504091 viz::CopyOutputRequest::CreateStubForTesting());
Xianzhu Wangc62ecebf2019-08-31 15:54:134092 ASSERT_TRUE(copy_layer->HasCopyRequest());
4093 CommitAndActivate();
4094 ASSERT_FALSE(copy_layer->HasCopyRequest());
weiliangcde7e0c32016-06-15 15:02:414095
Xianzhu Wangc62ecebf2019-08-31 15:54:134096 EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
4097 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
4098 EXPECT_EQ(gfx::Rect(10, 10),
4099 ImplOf(copy_clipped_child)->visible_layer_rect());
4100 EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect());
weiliangc296dd9f2016-07-05 14:59:514101
4102 // Case 3: When there is device scale factor.
Xianzhu Wang66e13e02019-09-18 20:39:124103 SetDeviceScaleAndUpdateViewportRect(host(), 2.f);
Xianzhu Wangc62ecebf2019-08-31 15:54:134104 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:504105 viz::CopyOutputRequest::CreateStubForTesting());
weiliangc296dd9f2016-07-05 14:59:514106
Xianzhu Wangc62ecebf2019-08-31 15:54:134107 ASSERT_TRUE(copy_layer->HasCopyRequest());
Xianzhu Wang66e13e02019-09-18 20:39:124108 CommitAndActivate();
Xianzhu Wangc62ecebf2019-08-31 15:54:134109 ASSERT_FALSE(copy_layer->HasCopyRequest());
weiliangc296dd9f2016-07-05 14:59:514110
Xianzhu Wangc62ecebf2019-08-31 15:54:134111 EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
4112 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
4113 EXPECT_EQ(gfx::Rect(10, 10),
4114 ImplOf(copy_clipped_child)->visible_layer_rect());
4115 EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect());
weiliangcde7e0c32016-06-15 15:02:414116}
4117
Xianzhu Wang66e13e02019-09-18 20:39:124118TEST_F(DrawPropertiesTest, TransformedClipParent) {
[email protected]420fdf6e2013-08-26 20:36:384119 // Ensure that a transform between the layer and its render surface is not a
4120 // problem. Constructs the following layer tree.
4121 //
Xianzhu Wangc8189212019-08-28 01:32:284122 // Virtual layer tree:
[email protected]420fdf6e2013-08-26 20:36:384123 // root (a render surface)
4124 // + render_surface
4125 // + clip_parent (scaled)
4126 // + intervening_clipping_layer
Xianzhu Wangc8189212019-08-28 01:32:284127 // + clip_child (clipped_by_clip_parent)
[email protected]420fdf6e2013-08-26 20:36:384128 //
4129 // The render surface should be resized correctly and the clip child should
4130 // inherit the right clip rect.
Xianzhu Wangd6a62d82019-09-09 22:35:364131 LayerImpl* root = root_layer();
danakjf78fb272016-07-26 19:06:154132 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284133
Xianzhu Wang5b429f02019-08-29 20:45:274134 LayerImpl* render_surface = AddLayer<LayerImpl>();
danakjf78fb272016-07-26 19:06:154135 render_surface->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284136 CopyProperties(root, render_surface);
4137 CreateEffectNode(render_surface).render_surface_reason =
4138 RenderSurfaceReason::kTest;
4139
Xianzhu Wang5b429f02019-08-29 20:45:274140 LayerImpl* clip_parent = AddLayer<LayerImpl>();
Xianzhu Wangc8189212019-08-28 01:32:284141 clip_parent->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154142 clip_parent->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284143 CopyProperties(render_surface, clip_parent);
4144 auto& clip_parent_transform = CreateTransformNode(clip_parent);
4145 clip_parent_transform.local.Scale(2, 2);
4146 clip_parent_transform.post_translation = gfx::Vector2dF(1, 1);
4147 CreateClipNode(clip_parent);
4148
Xianzhu Wang5b429f02019-08-29 20:45:274149 LayerImpl* intervening = AddLayer<LayerImpl>();
Xianzhu Wangc8189212019-08-28 01:32:284150 intervening->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154151 intervening->SetBounds(gfx::Size(5, 5));
Xianzhu Wangc8189212019-08-28 01:32:284152 intervening->SetOffsetToTransformParent(gfx::Vector2dF(1, 1));
4153 CopyProperties(clip_parent, intervening);
4154 CreateClipNode(intervening);
4155
Xianzhu Wang5b429f02019-08-29 20:45:274156 LayerImpl* clip_child = AddLayer<LayerImpl>();
Xianzhu Wangc8189212019-08-28 01:32:284157 clip_child->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154158 clip_child->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284159 clip_child->SetOffsetToTransformParent(gfx::Vector2dF(2, 2));
4160 CopyProperties(intervening, clip_child);
4161 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
4162
Xianzhu Wang66e13e02019-09-18 20:39:124163 UpdateActiveTreeDrawProperties();
[email protected]420fdf6e2013-08-26 20:36:384164
chrishtr7e3aaf22017-05-04 15:04:014165 ASSERT_TRUE(GetRenderSurface(root));
4166 ASSERT_TRUE(GetRenderSurface(render_surface));
[email protected]420fdf6e2013-08-26 20:36:384167
4168 // Ensure that we've inherited our clip parent's clip and weren't affected
4169 // by the intervening clip layer.
jaydasika6f972de2016-04-07 16:16:144170 ASSERT_EQ(gfx::Rect(1, 1, 20, 20), clip_parent->clip_rect());
4171 ASSERT_EQ(clip_parent->clip_rect(), clip_child->clip_rect());
4172 ASSERT_EQ(gfx::Rect(3, 3, 10, 10), intervening->clip_rect());
[email protected]420fdf6e2013-08-26 20:36:384173
4174 // Ensure that the render surface reports a content rect that has been grown
4175 // to accomodate for the clip child.
jaydasika6f972de2016-04-07 16:16:144176 ASSERT_EQ(gfx::Rect(1, 1, 20, 20),
chrishtr7e3aaf22017-05-04 15:04:014177 GetRenderSurface(render_surface)->content_rect());
[email protected]420fdf6e2013-08-26 20:36:384178
4179 // The above check implies the two below, but they nicely demonstrate that
4180 // we've grown, despite the intervening layer's clip.
4181 ASSERT_TRUE(clip_parent->clip_rect().Contains(
chrishtr7e3aaf22017-05-04 15:04:014182 GetRenderSurface(render_surface)->content_rect()));
[email protected]420fdf6e2013-08-26 20:36:384183 ASSERT_FALSE(intervening->clip_rect().Contains(
chrishtr7e3aaf22017-05-04 15:04:014184 GetRenderSurface(render_surface)->content_rect()));
[email protected]420fdf6e2013-08-26 20:36:384185}
4186
Xianzhu Wang66e13e02019-09-18 20:39:124187TEST_F(DrawPropertiesTest, ClipParentWithInterveningRenderSurface) {
[email protected]420fdf6e2013-08-26 20:36:384188 // Ensure that intervening render surfaces are not a problem in the basic
4189 // case. In the following tree, both render surfaces should be resized to
4190 // accomodate for the clip child, despite an intervening clip.
4191 //
Xianzhu Wangc8189212019-08-28 01:32:284192 // Virtual layer tree:
[email protected]420fdf6e2013-08-26 20:36:384193 // root (a render surface)
Xianzhu Wangc8189212019-08-28 01:32:284194 // + clip_parent (clips)
[email protected]420fdf6e2013-08-26 20:36:384195 // + render_surface1 (sets opacity)
Xianzhu Wangc8189212019-08-28 01:32:284196 // + intervening (clips)
[email protected]420fdf6e2013-08-26 20:36:384197 // + render_surface2 (also sets opacity)
Xianzhu Wangc8189212019-08-28 01:32:284198 // + clip_child (clipped by clip_parent)
[email protected]420fdf6e2013-08-26 20:36:384199 //
Xianzhu Wangd6a62d82019-09-09 22:35:364200 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274201 LayerImpl* clip_parent = AddLayer<LayerImpl>();
4202 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
4203 LayerImpl* intervening = AddLayer<LayerImpl>();
4204 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
4205 LayerImpl* clip_child = AddLayer<LayerImpl>();
[email protected]420fdf6e2013-08-26 20:36:384206
danakjf78fb272016-07-26 19:06:154207 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284208
danakjf78fb272016-07-26 19:06:154209 clip_parent->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc8189212019-08-28 01:32:284210 clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(1, 1));
4211 CopyProperties(root, clip_parent);
4212 CreateClipNode(clip_parent);
4213
4214 render_surface1->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154215 render_surface1->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284216 CopyProperties(clip_parent, render_surface1);
4217 CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(1, 1);
4218 CreateEffectNode(render_surface1).render_surface_reason =
4219 RenderSurfaceReason::kTest;
4220
danakjf78fb272016-07-26 19:06:154221 intervening->SetBounds(gfx::Size(5, 5));
Xianzhu Wangc8189212019-08-28 01:32:284222 intervening->SetOffsetToTransformParent(gfx::Vector2dF(1, 1));
4223 CopyProperties(render_surface1, intervening);
4224 CreateClipNode(intervening);
4225
4226 render_surface2->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154227 render_surface2->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284228 CopyProperties(intervening, render_surface2);
4229 CreateTransformNode(render_surface2).post_translation = gfx::Vector2dF(1, 1);
4230 CreateEffectNode(render_surface2).render_surface_reason =
4231 RenderSurfaceReason::kTest;
4232
danakjf78fb272016-07-26 19:06:154233 clip_child->SetBounds(gfx::Size(60, 60));
Xianzhu Wangc8189212019-08-28 01:32:284234 clip_child->SetDrawsContent(true);
4235 clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10));
4236 CopyProperties(render_surface2, clip_child);
4237 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
4238
Xianzhu Wang66e13e02019-09-18 20:39:124239 UpdateActiveTreeDrawProperties();
[email protected]420fdf6e2013-08-26 20:36:384240
chrishtr7e3aaf22017-05-04 15:04:014241 EXPECT_TRUE(GetRenderSurface(root));
4242 EXPECT_TRUE(GetRenderSurface(render_surface1));
4243 EXPECT_TRUE(GetRenderSurface(render_surface2));
[email protected]420fdf6e2013-08-26 20:36:384244
jaydasika1553a142017-04-05 00:37:094245 // render_surface1 should apply the clip from clip_parent. Though there is a
4246 // clip child, render_surface1 can apply the clip as there are no clips
4247 // between the clip parent and render_surface1
4248 EXPECT_EQ(gfx::Rect(1, 1, 40, 40),
chrishtr7e3aaf22017-05-04 15:04:014249 GetRenderSurface(render_surface1)->clip_rect());
4250 EXPECT_TRUE(GetRenderSurface(render_surface1)->is_clipped());
jaydasika1553a142017-04-05 00:37:094251 EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect());
4252 EXPECT_FALSE(render_surface1->is_clipped());
4253
4254 // render_surface2 could have expanded, as there is a clip between
4255 // clip_child's clip (clip_parent) and render_surface2's clip (intervening).
4256 // So, it should not be clipped (their bounds would no longer be reliable).
4257 // We should resort to layer clipping in this case.
jaydasika6f972de2016-04-07 16:16:144258 EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
chrishtr7e3aaf22017-05-04 15:04:014259 GetRenderSurface(render_surface2)->clip_rect());
4260 EXPECT_FALSE(GetRenderSurface(render_surface2)->is_clipped());
[email protected]420fdf6e2013-08-26 20:36:384261
[email protected]420fdf6e2013-08-26 20:36:384262 // This value is inherited from the clipping ancestor layer, 'intervening'.
jaydasika6f972de2016-04-07 16:16:144263 EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect());
[email protected]420fdf6e2013-08-26 20:36:384264 EXPECT_TRUE(render_surface2->is_clipped());
4265
jaydasika1553a142017-04-05 00:37:094266 // The content rects of render_surface2 should have expanded to contain the
4267 // clip child.
jaydasika6f972de2016-04-07 16:16:144268 EXPECT_EQ(gfx::Rect(0, 0, 40, 40),
chrishtr7e3aaf22017-05-04 15:04:014269 GetRenderSurface(render_surface1)->content_rect());
jaydasika1553a142017-04-05 00:37:094270 EXPECT_EQ(gfx::Rect(-10, -10, 60, 60),
chrishtr7e3aaf22017-05-04 15:04:014271 GetRenderSurface(render_surface2)->content_rect());
[email protected]420fdf6e2013-08-26 20:36:384272
4273 // The clip child should have inherited the clip parent's clip (projected to
jaydasika1553a142017-04-05 00:37:094274 // the right space, of course), but as render_surface1 already applies that
4275 // clip, clip_child need not apply it again.
4276 EXPECT_EQ(gfx::Rect(), clip_child->clip_rect());
jaydasika6f972de2016-04-07 16:16:144277 EXPECT_EQ(gfx::Rect(9, 9, 40, 40), clip_child->visible_layer_rect());
jaydasika1553a142017-04-05 00:37:094278 EXPECT_FALSE(clip_child->is_clipped());
[email protected]420fdf6e2013-08-26 20:36:384279}
4280
Xianzhu Wang66e13e02019-09-18 20:39:124281TEST_F(DrawPropertiesTest, ClipParentScrolledInterveningLayer) {
[email protected]420fdf6e2013-08-26 20:36:384282 // Ensure that intervening render surfaces are not a problem, even if there
4283 // is a scroll involved. Note, we do _not_ have to consider any other sort
4284 // of transform.
4285 //
Xianzhu Wangc8189212019-08-28 01:32:284286 // Virtual layer tree:
[email protected]420fdf6e2013-08-26 20:36:384287 // root (a render surface)
Xianzhu Wangc8189212019-08-28 01:32:284288 // + clip_parent (clips and transforms)
4289 // + render_surface1 (has render surface)
4290 // + intervening (clips AND scrolls)
4291 // + render_surface2 (also has render surface)
4292 // + clip_child (clipped by clip_parent)
[email protected]420fdf6e2013-08-26 20:36:384293 //
Xianzhu Wangd6a62d82019-09-09 22:35:364294 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274295 LayerImpl* clip_parent = AddLayer<LayerImpl>();
4296 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
4297 LayerImpl* intervening = AddLayer<LayerImpl>();
4298 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
4299 LayerImpl* clip_child = AddLayer<LayerImpl>();
[email protected]420fdf6e2013-08-26 20:36:384300
danakjf78fb272016-07-26 19:06:154301 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284302
danakjf78fb272016-07-26 19:06:154303 clip_parent->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc8189212019-08-28 01:32:284304 CopyProperties(root, clip_parent);
4305 auto& clip_parent_transform = CreateTransformNode(clip_parent);
4306 clip_parent_transform.local.Translate(2, 2);
4307 clip_parent_transform.post_translation = gfx::Vector2dF(1, 1);
4308 CreateClipNode(clip_parent);
4309
4310 render_surface1->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154311 render_surface1->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284312 CopyProperties(clip_parent, render_surface1);
4313 CreateEffectNode(render_surface1).render_surface_reason =
4314 RenderSurfaceReason::kTest;
4315
danakjf78fb272016-07-26 19:06:154316 intervening->SetBounds(gfx::Size(5, 5));
Xianzhu Wangc8189212019-08-28 01:32:284317 intervening->SetScrollable(gfx::Size(1, 1));
4318 intervening->SetElementId(LayerIdToElementIdForTesting(intervening->id()));
4319 CopyProperties(render_surface1, intervening);
4320 CreateTransformNode(intervening).post_translation = gfx::Vector2dF(1, 1);
4321 CreateScrollNode(intervening);
4322 CreateClipNode(intervening);
4323
4324 render_surface2->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154325 render_surface2->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284326 CopyProperties(intervening, render_surface2);
4327 CreateTransformNode(render_surface2);
4328 CreateEffectNode(render_surface2).render_surface_reason =
4329 RenderSurfaceReason::kTest;
4330
danakjf78fb272016-07-26 19:06:154331 clip_child->SetBounds(gfx::Size(60, 60));
Xianzhu Wangc8189212019-08-28 01:32:284332 clip_child->SetDrawsContent(true);
4333 clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10));
4334 CopyProperties(render_surface2, clip_child);
4335 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
4336
4337 SetScrollOffset(intervening, gfx::ScrollOffset(3, 3));
Xianzhu Wang66e13e02019-09-18 20:39:124338 UpdateActiveTreeDrawProperties();
[email protected]420fdf6e2013-08-26 20:36:384339
chrishtr7e3aaf22017-05-04 15:04:014340 EXPECT_TRUE(GetRenderSurface(root));
4341 EXPECT_TRUE(GetRenderSurface(render_surface1));
4342 EXPECT_TRUE(GetRenderSurface(render_surface2));
[email protected]420fdf6e2013-08-26 20:36:384343
jaydasika1553a142017-04-05 00:37:094344 // render_surface1 should apply the clip from clip_parent. Though there is a
4345 // clip child, render_surface1 can apply the clip as there are no clips
4346 // between the clip parent and render_surface1
4347 EXPECT_EQ(gfx::Rect(3, 3, 40, 40),
chrishtr7e3aaf22017-05-04 15:04:014348 GetRenderSurface(render_surface1)->clip_rect());
4349 EXPECT_TRUE(GetRenderSurface(render_surface1)->is_clipped());
jaydasika1553a142017-04-05 00:37:094350 EXPECT_EQ(gfx::Rect(), render_surface1->clip_rect());
4351 EXPECT_FALSE(render_surface1->is_clipped());
4352
4353 // render_surface2 could have expanded, as there is a clip between
4354 // clip_child's clip (clip_parent) and render_surface2's clip (intervening).
4355 // So, it should not be clipped (their bounds would no longer be reliable).
4356 // We should resort to layer clipping in this case.
jaydasika6f972de2016-04-07 16:16:144357 EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
chrishtr7e3aaf22017-05-04 15:04:014358 GetRenderSurface(render_surface2)->clip_rect());
4359 EXPECT_FALSE(GetRenderSurface(render_surface2)->is_clipped());
[email protected]420fdf6e2013-08-26 20:36:384360 // This value is inherited from the clipping ancestor layer, 'intervening'.
jaydasika1553a142017-04-05 00:37:094361 EXPECT_EQ(gfx::Rect(0, 0, 5, 5), render_surface2->clip_rect());
[email protected]420fdf6e2013-08-26 20:36:384362 EXPECT_TRUE(render_surface2->is_clipped());
4363
jaydasika1553a142017-04-05 00:37:094364 // The content rects of render_surface2 should have expanded to contain the
4365 // clip child.
jaydasika6f972de2016-04-07 16:16:144366 EXPECT_EQ(gfx::Rect(0, 0, 40, 40),
chrishtr7e3aaf22017-05-04 15:04:014367 GetRenderSurface(render_surface1)->content_rect());
jaydasika1553a142017-04-05 00:37:094368 EXPECT_EQ(gfx::Rect(-10, -10, 60, 60),
chrishtr7e3aaf22017-05-04 15:04:014369 GetRenderSurface(render_surface2)->content_rect());
[email protected]420fdf6e2013-08-26 20:36:384370
4371 // The clip child should have inherited the clip parent's clip (projected to
jaydasika1553a142017-04-05 00:37:094372 // the right space, of course), but as render_surface1 already applies that
4373 // clip, clip_child need not apply it again.
4374 EXPECT_EQ(gfx::Rect(), clip_child->clip_rect());
jaydasika6f972de2016-04-07 16:16:144375 EXPECT_EQ(gfx::Rect(12, 12, 40, 40), clip_child->visible_layer_rect());
jaydasika1553a142017-04-05 00:37:094376 EXPECT_FALSE(clip_child->is_clipped());
[email protected]420fdf6e2013-08-26 20:36:384377}
4378
Xianzhu Wang66e13e02019-09-18 20:39:124379TEST_F(DrawPropertiesTest, DescendantsOfClipChildren) {
[email protected]420fdf6e2013-08-26 20:36:384380 // Ensures that descendants of the clip child inherit the correct clip.
4381 //
Xianzhu Wangc8189212019-08-28 01:32:284382 // Virtual layer tree:
[email protected]420fdf6e2013-08-26 20:36:384383 // root (a render surface)
Xianzhu Wangc8189212019-08-28 01:32:284384 // + clip_parent (clips)
4385 // + intervening (clips)
4386 // + clip_child (clipped by clip_parent, skipping intervening)
[email protected]420fdf6e2013-08-26 20:36:384387 // + child
4388 //
Xianzhu Wangd6a62d82019-09-09 22:35:364389 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274390 LayerImpl* clip_parent = AddLayer<LayerImpl>();
4391 LayerImpl* intervening = AddLayer<LayerImpl>();
4392 LayerImpl* clip_child = AddLayer<LayerImpl>();
4393 LayerImpl* child = AddLayer<LayerImpl>();
[email protected]420fdf6e2013-08-26 20:36:384394
danakjf78fb272016-07-26 19:06:154395 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284396
danakjf78fb272016-07-26 19:06:154397 clip_parent->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc8189212019-08-28 01:32:284398 CopyProperties(root, clip_parent);
4399 CreateClipNode(clip_parent);
4400
danakjf78fb272016-07-26 19:06:154401 intervening->SetBounds(gfx::Size(5, 5));
Xianzhu Wangc8189212019-08-28 01:32:284402 CopyProperties(clip_parent, intervening);
4403 CreateClipNode(intervening);
4404
4405 clip_child->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154406 clip_child->SetBounds(gfx::Size(60, 60));
Xianzhu Wangc8189212019-08-28 01:32:284407 CopyProperties(intervening, clip_child);
4408 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
4409
4410 child->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154411 child->SetBounds(gfx::Size(60, 60));
Xianzhu Wangc8189212019-08-28 01:32:284412 CopyProperties(clip_child, child);
[email protected]420fdf6e2013-08-26 20:36:384413
Xianzhu Wang66e13e02019-09-18 20:39:124414 UpdateActiveTreeDrawProperties();
[email protected]420fdf6e2013-08-26 20:36:384415
chrishtr7e3aaf22017-05-04 15:04:014416 EXPECT_TRUE(GetRenderSurface(root));
[email protected]420fdf6e2013-08-26 20:36:384417
4418 // Neither the clip child nor its descendant should have inherited the clip
4419 // from |intervening|.
jaydasika6f972de2016-04-07 16:16:144420 EXPECT_EQ(gfx::Rect(0, 0, 40, 40), clip_child->clip_rect());
[email protected]420fdf6e2013-08-26 20:36:384421 EXPECT_TRUE(clip_child->is_clipped());
jaydasika6f972de2016-04-07 16:16:144422 EXPECT_EQ(gfx::Rect(0, 0, 40, 40), child->visible_layer_rect());
[email protected]420fdf6e2013-08-26 20:36:384423 EXPECT_TRUE(child->is_clipped());
4424}
4425
Xianzhu Wang66e13e02019-09-18 20:39:124426TEST_F(DrawPropertiesTest,
[email protected]420fdf6e2013-08-26 20:36:384427 SurfacesShouldBeUnaffectedByNonDescendantClipChildren) {
4428 // Ensures that non-descendant clip children in the tree do not affect
4429 // render surfaces.
4430 //
4431 // root (a render surface)
Xianzhu Wangc8189212019-08-28 01:32:284432 // + clip_parent (clips)
4433 // + clip_layer (clips)
jaydasika1553a142017-04-05 00:37:094434 // + render_surface1
Xianzhu Wangc8189212019-08-28 01:32:284435 // + clip_child (clipped by clip_parent)
jaydasika1553a142017-04-05 00:37:094436 // + render_surface2
Xianzhu Wangc8189212019-08-28 01:32:284437 // + non_clip_child (in normal clip hierarchy)
[email protected]420fdf6e2013-08-26 20:36:384438 //
4439 // In this example render_surface2 should be unaffected by clip_child.
Xianzhu Wangd6a62d82019-09-09 22:35:364440 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274441 LayerImpl* clip_parent = AddLayer<LayerImpl>();
4442 LayerImpl* clip_layer = AddLayer<LayerImpl>();
4443 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
4444 LayerImpl* clip_child = AddLayer<LayerImpl>();
4445 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
4446 LayerImpl* non_clip_child = AddLayer<LayerImpl>();
danakjf78fb272016-07-26 19:06:154447
4448 root->SetBounds(gfx::Size(15, 15));
4449 clip_parent->SetBounds(gfx::Size(10, 10));
jaydasika1553a142017-04-05 00:37:094450 clip_layer->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284451 render_surface1->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154452 render_surface1->SetBounds(gfx::Size(5, 5));
Xianzhu Wang5b429f02019-08-29 20:45:274453 render_surface2->SetDrawsContent(true);
4454 render_surface2->SetBounds(gfx::Size(5, 5));
4455 clip_child->SetDrawsContent(true);
4456 clip_child->SetOffsetToTransformParent(gfx::Vector2dF(-1, 1));
4457 clip_child->SetBounds(gfx::Size(10, 10));
4458 non_clip_child->SetDrawsContent(true);
4459 non_clip_child->SetBounds(gfx::Size(5, 5));
4460
Xianzhu Wang5b429f02019-08-29 20:45:274461 CopyProperties(root, clip_parent);
4462 CreateClipNode(clip_parent);
4463 CopyProperties(clip_parent, clip_layer);
4464 CreateClipNode(clip_layer);
Xianzhu Wangc8189212019-08-28 01:32:284465 CopyProperties(clip_layer, render_surface1);
4466 CreateTransformNode(render_surface1).post_translation = gfx::Vector2dF(5, 5);
4467 CreateEffectNode(render_surface1).render_surface_reason =
4468 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:284469 CopyProperties(clip_layer, render_surface2);
4470 CreateTransformNode(render_surface2).post_translation = gfx::Vector2dF(5, 5);
4471 CreateEffectNode(render_surface2).render_surface_reason =
4472 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:284473 CopyProperties(render_surface1, clip_child);
4474 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
Xianzhu Wangc8189212019-08-28 01:32:284475 CopyProperties(render_surface2, non_clip_child);
[email protected]420fdf6e2013-08-26 20:36:384476
Xianzhu Wang66e13e02019-09-18 20:39:124477 UpdateActiveTreeDrawProperties();
[email protected]420fdf6e2013-08-26 20:36:384478
chrishtr7e3aaf22017-05-04 15:04:014479 EXPECT_TRUE(GetRenderSurface(root));
4480 EXPECT_TRUE(GetRenderSurface(render_surface1));
4481 EXPECT_TRUE(GetRenderSurface(render_surface2));
[email protected]420fdf6e2013-08-26 20:36:384482
jaydasika1553a142017-04-05 00:37:094483 EXPECT_EQ(gfx::Rect(-5, -5, 10, 10), render_surface1->clip_rect());
[email protected]420fdf6e2013-08-26 20:36:384484 EXPECT_TRUE(render_surface1->is_clipped());
4485
4486 // The render surface should not clip (it has unclipped descendants), instead
4487 // it should rely on layer clipping.
jaydasika6f972de2016-04-07 16:16:144488 EXPECT_EQ(gfx::Rect(0, 0, 0, 0),
chrishtr7e3aaf22017-05-04 15:04:014489 GetRenderSurface(render_surface1)->clip_rect());
4490 EXPECT_FALSE(GetRenderSurface(render_surface1)->is_clipped());
[email protected]420fdf6e2013-08-26 20:36:384491
jaydasika0d98ba92015-11-17 05:17:284492 // That said, it should have grown to accomodate the unclipped descendant and
4493 // its own size.
jaydasika6f972de2016-04-07 16:16:144494 EXPECT_EQ(gfx::Rect(-1, 0, 6, 5),
chrishtr7e3aaf22017-05-04 15:04:014495 GetRenderSurface(render_surface1)->content_rect());
[email protected]420fdf6e2013-08-26 20:36:384496
4497 // This render surface should clip. It has no unclipped descendants.
jaydasika6f972de2016-04-07 16:16:144498 EXPECT_EQ(gfx::Rect(0, 0, 10, 10),
chrishtr7e3aaf22017-05-04 15:04:014499 GetRenderSurface(render_surface2)->clip_rect());
4500 EXPECT_TRUE(GetRenderSurface(render_surface2)->is_clipped());
weiliangcbb2e8642016-03-04 00:24:424501 EXPECT_FALSE(render_surface2->is_clipped());
[email protected]420fdf6e2013-08-26 20:36:384502
4503 // It also shouldn't have grown to accomodate the clip child.
jaydasika6f972de2016-04-07 16:16:144504 EXPECT_EQ(gfx::Rect(0, 0, 5, 5),
chrishtr7e3aaf22017-05-04 15:04:014505 GetRenderSurface(render_surface2)->content_rect());
[email protected]420fdf6e2013-08-26 20:36:384506}
4507
Xianzhu Wang66e13e02019-09-18 20:39:124508TEST_F(DrawPropertiesTest, TransformAnimationUpdatesBackfaceVisibility) {
Xianzhu Wangd6a62d82019-09-09 22:35:364509 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274510 LayerImpl* back_facing = AddLayer<LayerImpl>();
4511 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
4512 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
sunxd59dd7da2016-05-19 20:07:474513
sunxd59dd7da2016-05-19 20:07:474514 gfx::Transform rotate_about_y;
4515 rotate_about_y.RotateAboutYAxis(180.0);
sunxd59dd7da2016-05-19 20:07:474516
danakjf78fb272016-07-26 19:06:154517 root->SetBounds(gfx::Size(50, 50));
danakjf78fb272016-07-26 19:06:154518 back_facing->SetBounds(gfx::Size(50, 50));
danakjf78fb272016-07-26 19:06:154519 render_surface1->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:154520 render_surface2->SetBounds(gfx::Size(30, 30));
weiliangcea09f3372017-03-29 16:43:244521 SetElementIdsForTesting();
Xianzhu Wang5b429f02019-08-29 20:45:274522
Xianzhu Wang5b429f02019-08-29 20:45:274523 CopyProperties(root, back_facing);
4524 auto& back_facing_transform_node = CreateTransformNode(back_facing);
4525 back_facing_transform_node.flattens_inherited_transform = false;
4526 back_facing_transform_node.sorting_context_id = 1;
4527 back_facing_transform_node.local = rotate_about_y;
4528 CopyProperties(back_facing, render_surface1);
4529 auto& render_surface1_transform_node = CreateTransformNode(render_surface1);
4530 render_surface1_transform_node.flattens_inherited_transform = false;
4531 render_surface1_transform_node.sorting_context_id = 1;
4532 auto& render_surface1_effect_node = CreateEffectNode(render_surface1);
4533 render_surface1_effect_node.render_surface_reason =
4534 RenderSurfaceReason::kTest;
4535 render_surface1_effect_node.double_sided = false;
4536 CopyProperties(back_facing, render_surface2);
4537 auto& render_surface2_transform_node = CreateTransformNode(render_surface2);
4538 render_surface2_transform_node.flattens_inherited_transform = false;
4539 render_surface2_transform_node.sorting_context_id = 1;
4540 auto& render_surface2_effect_node = CreateEffectNode(render_surface2);
4541 render_surface2_effect_node.render_surface_reason =
4542 RenderSurfaceReason::kTest;
4543 render_surface2_effect_node.double_sided = false;
4544
Xianzhu Wang66e13e02019-09-18 20:39:124545 UpdateActiveTreeDrawProperties();
sunxd59dd7da2016-05-19 20:07:474546
Xianzhu Wang5b429f02019-08-29 20:45:274547 EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility);
4548 EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility);
sunxd59dd7da2016-05-19 20:07:474549
weiliangcea09f3372017-03-29 16:43:244550 root->layer_tree_impl()->SetTransformMutated(back_facing->element_id(),
4551 gfx::Transform());
4552 root->layer_tree_impl()->SetTransformMutated(render_surface2->element_id(),
4553 rotate_about_y);
Xianzhu Wang66e13e02019-09-18 20:39:124554 UpdateActiveTreeDrawProperties();
Xianzhu Wang5b429f02019-08-29 20:45:274555 EXPECT_FALSE(GetEffectNode(render_surface1)->hidden_by_backface_visibility);
4556 EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility);
sunxd59dd7da2016-05-19 20:07:474557
weiliangcea09f3372017-03-29 16:43:244558 root->layer_tree_impl()->SetTransformMutated(render_surface1->element_id(),
4559 rotate_about_y);
Xianzhu Wang66e13e02019-09-18 20:39:124560 UpdateActiveTreeDrawProperties();
Xianzhu Wang5b429f02019-08-29 20:45:274561 EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility);
4562 EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility);
sunxd59dd7da2016-05-19 20:07:474563}
4564
Xianzhu Wang66e13e02019-09-18 20:39:124565TEST_F(DrawPropertiesTest, ScrollChildAndScrollParentDifferentTargets) {
jaydasika8ccff3d2016-01-20 19:51:304566 // Tests the computation of draw transform for the scroll child when its
Xianzhu Wangc8189212019-08-28 01:32:284567 // render surface is different from its scroll parent's render surface.
Xianzhu Wangd6a62d82019-09-09 22:35:364568 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274569 LayerImpl* scroll_child_target = AddLayer<LayerImpl>();
4570 LayerImpl* scroll_child = AddLayer<LayerImpl>();
4571 LayerImpl* scroll_parent_target = AddLayer<LayerImpl>();
4572 LayerImpl* scroll_parent = AddLayer<LayerImpl>();
jaydasika8ccff3d2016-01-20 19:51:304573
danakjf78fb272016-07-26 19:06:154574 root->SetBounds(gfx::Size(50, 50));
4575 scroll_child_target->SetBounds(gfx::Size(50, 50));
Xianzhu Wang5b429f02019-08-29 20:45:274576 scroll_parent_target->SetBounds(gfx::Size(50, 50));
4577 scroll_parent->SetBounds(gfx::Size(50, 50));
4578 scroll_parent->SetDrawsContent(true);
4579 scroll_child->SetBounds(gfx::Size(50, 50));
4580 scroll_child->SetDrawsContent(true);
4581
Xianzhu Wangc8189212019-08-28 01:32:284582 CopyProperties(root, scroll_child_target);
4583 auto& child_target_effect_node = CreateEffectNode(scroll_child_target);
4584 child_target_effect_node.render_surface_reason = RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:284585 CopyProperties(scroll_child_target, scroll_parent_target);
4586 CreateTransformNode(scroll_parent_target).post_translation =
4587 gfx::Vector2dF(10, 10);
4588 CreateScrollNode(scroll_parent_target);
4589 CreateEffectNode(scroll_parent_target).render_surface_reason =
4590 RenderSurfaceReason::kTest;
4591 CreateClipNode(scroll_parent_target);
Xianzhu Wangc8189212019-08-28 01:32:284592 CopyProperties(scroll_parent_target, scroll_parent);
Xianzhu Wangc8189212019-08-28 01:32:284593 // Let |scroll_child| inherit |scroll_parent|'s transform/clip/scroll states,
4594 CopyProperties(scroll_parent, scroll_child);
4595 // and |scroll_child_target|'s effect state.
4596 scroll_child->SetEffectTreeIndex(scroll_child_target->effect_tree_index());
4597 scroll_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10));
jaydasika8ccff3d2016-01-20 19:51:304598
jaydasika2489a442016-01-29 02:26:004599 float device_scale_factor = 1.5f;
Xianzhu Wang66e13e02019-09-18 20:39:124600 UpdateActiveTreeDrawProperties(device_scale_factor);
weiliangc1da3fb892016-03-14 20:23:524601 EXPECT_EQ(scroll_child->effect_tree_index(),
4602 scroll_child_target->effect_tree_index());
jaydasika2489a442016-01-29 02:26:004603 EXPECT_EQ(scroll_child->visible_layer_rect(), gfx::Rect(10, 10, 40, 40));
4604 EXPECT_EQ(scroll_child->clip_rect(), gfx::Rect(15, 15, 75, 75));
4605 gfx::Transform scale;
Xianzhu Wang66e13e02019-09-18 20:39:124606 scale.Scale(device_scale_factor, device_scale_factor);
weiliangcc3517722016-06-28 22:52:024607 EXPECT_TRANSFORMATION_MATRIX_EQ(scroll_child->DrawTransform(), scale);
jaydasika8ccff3d2016-01-20 19:51:304608}
4609
Xianzhu Wang66e13e02019-09-18 20:39:124610TEST_F(DrawPropertiesTest, SingularTransformSubtreesDoNotDraw) {
Xianzhu Wangd6a62d82019-09-09 22:35:364611 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274612 LayerImpl* parent = AddLayer<LayerImpl>();
4613 LayerImpl* child = AddLayer<LayerImpl>();
danakjf78fb272016-07-26 19:06:154614
4615 root->SetBounds(gfx::Size(50, 50));
4616 root->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154617 parent->SetBounds(gfx::Size(30, 30));
4618 parent->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:154619 child->SetBounds(gfx::Size(20, 20));
enneca33fed2015-07-27 18:22:194620 child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:274621
Xianzhu Wang5b429f02019-08-29 20:45:274622 CopyProperties(root, parent);
4623 CreateTransformNode(parent).sorting_context_id = 1;
4624 CreateEffectNode(parent).render_surface_reason = RenderSurfaceReason::kTest;
4625 CopyProperties(parent, child);
4626 CreateTransformNode(child).sorting_context_id = 1;
4627 CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
4628
Xianzhu Wang66e13e02019-09-18 20:39:124629 UpdateActiveTreeDrawProperties();
[email protected]08bdf1b2014-04-16 23:23:294630
Xianzhu Wang66e13e02019-09-18 20:39:124631 EXPECT_EQ(3u, GetRenderSurfaceList().size());
[email protected]08bdf1b2014-04-16 23:23:294632
4633 gfx::Transform singular_transform;
Xianzhu Wang66e13e02019-09-18 20:39:124634 singular_transform.Scale3d(SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0),
4635 SkDoubleToMScalar(0.0));
[email protected]08bdf1b2014-04-16 23:23:294636
Xianzhu Wang5b429f02019-08-29 20:45:274637 SetTransform(child, singular_transform);
Xianzhu Wang66e13e02019-09-18 20:39:124638 UpdateActiveTreeDrawProperties();
[email protected]08bdf1b2014-04-16 23:23:294639
Xianzhu Wang66e13e02019-09-18 20:39:124640 EXPECT_EQ(2u, GetRenderSurfaceList().size());
[email protected]08bdf1b2014-04-16 23:23:294641
4642 // Ensure that the entire subtree under a layer with singular transform does
4643 // not get rendered.
Xianzhu Wang5b429f02019-08-29 20:45:274644 SetTransform(parent, singular_transform);
4645 SetTransform(child, gfx::Transform());
Xianzhu Wang66e13e02019-09-18 20:39:124646 UpdateActiveTreeDrawProperties();
[email protected]08bdf1b2014-04-16 23:23:294647
Xianzhu Wang66e13e02019-09-18 20:39:124648 EXPECT_EQ(1u, GetRenderSurfaceList().size());
[email protected]08bdf1b2014-04-16 23:23:294649}
4650
Xianzhu Wang66e13e02019-09-18 20:39:124651TEST_F(DrawPropertiesTest, ScrollSnapping) {
Xianzhu Wangc8189212019-08-28 01:32:284652 // This test verifies that a scrolling layer gets scroll offset snapped to
4653 // integer coordinates.
[email protected]995708c52013-10-17 20:52:594654 //
Xianzhu Wangc8189212019-08-28 01:32:284655 // Virtual layer hierarchy:
[email protected]d81752b2013-10-25 08:32:234656 // + root
4657 // + container
4658 // + scroller
[email protected]d81752b2013-10-25 08:32:234659 //
Xianzhu Wangd6a62d82019-09-09 22:35:364660 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274661 LayerImpl* container = AddLayer<LayerImpl>();
4662 LayerImpl* scroller = AddLayer<LayerImpl>();
[email protected]d81752b2013-10-25 08:32:234663
danakjf78fb272016-07-26 19:06:154664 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284665
danakjf78fb272016-07-26 19:06:154666 container->SetBounds(gfx::Size(40, 40));
jaydasika0d98ba92015-11-17 05:17:284667 container->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:284668 CopyProperties(root, container);
4669
4670 gfx::Vector2dF container_offset(10, 20);
4671
4672 scroller->SetElementId(LayerIdToElementIdForTesting(scroller->id()));
danakjf78fb272016-07-26 19:06:154673 scroller->SetBounds(gfx::Size(30, 30));
pdrbbfd8822017-06-27 22:44:524674 scroller->SetScrollable(container->bounds());
jaydasika0d98ba92015-11-17 05:17:284675 scroller->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:284676 CopyProperties(container, scroller);
4677 CreateTransformNode(scroller).post_translation = container_offset;
4678 CreateScrollNode(scroller);
[email protected]d81752b2013-10-25 08:32:234679
4680 // Rounded to integers already.
4681 {
4682 gfx::Vector2dF scroll_delta(3.0, 5.0);
Xianzhu Wangc8189212019-08-28 01:32:284683 SetScrollOffsetDelta(scroller, scroll_delta);
Xianzhu Wang66e13e02019-09-18 20:39:124684 UpdateActiveTreeDrawProperties();
[email protected]d81752b2013-10-25 08:32:234685
Xianzhu Wangc8189212019-08-28 01:32:284686 EXPECT_VECTOR_EQ(
4687 scroller->draw_properties().screen_space_transform.To2dTranslation(),
4688 container_offset - scroll_delta);
[email protected]d81752b2013-10-25 08:32:234689 }
4690
4691 // Scroll delta requiring rounding.
4692 {
4693 gfx::Vector2dF scroll_delta(4.1f, 8.1f);
Xianzhu Wangc8189212019-08-28 01:32:284694 SetScrollOffsetDelta(scroller, scroll_delta);
Xianzhu Wang66e13e02019-09-18 20:39:124695 UpdateActiveTreeDrawProperties();
[email protected]d81752b2013-10-25 08:32:234696
4697 gfx::Vector2dF rounded_scroll_delta(4.f, 8.f);
Xianzhu Wangc8189212019-08-28 01:32:284698 EXPECT_VECTOR_EQ(
4699 scroller->draw_properties().screen_space_transform.To2dTranslation(),
4700 container_offset - rounded_scroll_delta);
[email protected]d81752b2013-10-25 08:32:234701 }
[email protected]d81752b2013-10-25 08:32:234702}
4703
Xianzhu Wang66e13e02019-09-18 20:39:124704TEST_F(DrawPropertiesTest, ScrollSnappingWithAnimatedScreenSpaceTransform) {
ajuma5e8e40d2015-07-31 01:50:504705 // This test verifies that a scrolling layer whose screen space transform is
4706 // animating doesn't get snapped to integer coordinates.
4707 //
Xianzhu Wangc8189212019-08-28 01:32:284708 // Virtual layer hierarchy:
ajuma5e8e40d2015-07-31 01:50:504709 // + root
4710 // + animated layer
4711 // + surface
4712 // + container
4713 // + scroller
4714 //
Xianzhu Wangd6a62d82019-09-09 22:35:364715 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274716 LayerImpl* animated_layer = AddLayer<FakePictureLayerImpl>();
4717 LayerImpl* surface = AddLayer<LayerImpl>();
4718 LayerImpl* container = AddLayer<LayerImpl>();
4719 LayerImpl* scroller = AddLayer<LayerImpl>();
Xianzhu Wangc8189212019-08-28 01:32:284720 SetElementIdsForTesting();
4721
4722 root->SetBounds(gfx::Size(50, 50));
ajuma5e8e40d2015-07-31 01:50:504723
ajuma5e8e40d2015-07-31 01:50:504724 gfx::Transform start_scale;
4725 start_scale.Scale(1.5f, 1.5f);
danakjf78fb272016-07-26 19:06:154726
danakjf78fb272016-07-26 19:06:154727 animated_layer->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284728 CopyProperties(root, animated_layer);
4729 CreateTransformNode(animated_layer).local = start_scale;
4730
danakjf78fb272016-07-26 19:06:154731 surface->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284732 CopyProperties(animated_layer, surface);
4733 CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
4734
danakjf78fb272016-07-26 19:06:154735 container->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284736 CopyProperties(surface, container);
4737
danakjf78fb272016-07-26 19:06:154738 scroller->SetBounds(gfx::Size(100, 100));
pdrbbfd8822017-06-27 22:44:524739 scroller->SetScrollable(container->bounds());
danakjf78fb272016-07-26 19:06:154740 scroller->SetDrawsContent(true);
Xianzhu Wangc8189212019-08-28 01:32:284741 CopyProperties(container, scroller);
4742 CreateTransformNode(scroller);
4743 CreateScrollNode(scroller);
ajuma5e8e40d2015-07-31 01:50:504744
4745 gfx::Transform end_scale;
4746 end_scale.Scale(2.f, 2.f);
4747 TransformOperations start_operations;
4748 start_operations.AppendMatrix(start_scale);
4749 TransformOperations end_operations;
4750 end_operations.AppendMatrix(end_scale);
vollickef2ae922016-06-29 17:54:274751
Yi Guaa830ff2018-02-22 03:09:114752 AddAnimatedTransformToElementWithAnimation(animated_layer->element_id(),
4753 timeline_impl(), 1.0,
4754 start_operations, end_operations);
Xianzhu Wangc8189212019-08-28 01:32:284755
ajuma5e8e40d2015-07-31 01:50:504756 gfx::Vector2dF scroll_delta(5.f, 9.f);
sunxdb7e79432016-03-09 21:13:424757 SetScrollOffsetDelta(scroller, scroll_delta);
ajuma5e8e40d2015-07-31 01:50:504758
Xianzhu Wang66e13e02019-09-18 20:39:124759 UpdateActiveTreeDrawProperties();
ajuma5e8e40d2015-07-31 01:50:504760
4761 gfx::Vector2dF expected_draw_transform_translation(-7.5f, -13.5f);
4762 EXPECT_VECTOR2DF_EQ(expected_draw_transform_translation,
ajumad9432e32015-11-30 19:43:444763 scroller->DrawTransform().To2dTranslation());
ajuma5e8e40d2015-07-31 01:50:504764}
4765
Xianzhu Wang66e13e02019-09-18 20:39:124766TEST_F(DrawPropertiesTest, ScrollSnappingWithScrollChild) {
sunxd8a9a60982016-07-29 18:46:564767 // This test verifies that a scrolling child of a scrolling layer doesn't get
4768 // snapped to integer coordinates.
4769 //
Xianzhu Wangc8189212019-08-28 01:32:284770 // Virtual layer hierarchy:
sunxd8a9a60982016-07-29 18:46:564771 // + root
4772 // + container
Xianzhu Wangc8189212019-08-28 01:32:284773 // + scroller
4774 // + scroll_child (transform parent is scroller)
sunxd8a9a60982016-07-29 18:46:564775 //
Xianzhu Wangd6a62d82019-09-09 22:35:364776 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:274777 LayerImpl* container = AddLayer<LayerImpl>();
4778 LayerImpl* scroller = AddLayer<LayerImpl>();
4779 LayerImpl* scroll_child = AddLayer<LayerImpl>();
Xianzhu Wangc8189212019-08-28 01:32:284780 SetElementIdsForTesting();
sunxd8a9a60982016-07-29 18:46:564781
sunxd8a9a60982016-07-29 18:46:564782 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284783
sunxd8a9a60982016-07-29 18:46:564784 container->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:284785 CopyProperties(root, container);
4786 gfx::Vector2dF container_offset(10.3f, 10.3f);
4787
sunxd8a9a60982016-07-29 18:46:564788 scroller->SetBounds(gfx::Size(100, 100));
pdrbbfd8822017-06-27 22:44:524789 scroller->SetScrollable(container->bounds());
Xianzhu Wangc8189212019-08-28 01:32:284790 CopyProperties(container, scroller);
4791 CreateTransformNode(scroller).post_translation = container_offset;
4792 CreateScrollNode(scroller);
4793
sunxd8a9a60982016-07-29 18:46:564794 scroll_child->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc8189212019-08-28 01:32:284795 CopyProperties(root, scroll_child);
4796 auto& scroll_child_transform =
4797 CreateTransformNode(scroll_child, scroller->transform_tree_index());
4798 scroll_child_transform.local.RotateAboutYAxis(30);
4799 scroll_child_transform.post_translation = -container_offset;
sunxd8a9a60982016-07-29 18:46:564800
sunxd8a9a60982016-07-29 18:46:564801 gfx::Vector2dF scroll_delta(5.f, 9.f);
Xianzhu Wangc8189212019-08-28 01:32:284802 SetScrollOffsetDelta(scroller, scroll_delta);
Xianzhu Wang66e13e02019-09-18 20:39:124803 UpdateActiveTreeDrawProperties();
sunxd8a9a60982016-07-29 18:46:564804
4805 gfx::Vector2dF expected_scroller_screen_space_transform_translation(5.f, 1.f);
4806 EXPECT_VECTOR2DF_EQ(expected_scroller_screen_space_transform_translation,
Xianzhu Wangc8189212019-08-28 01:32:284807 scroller->ScreenSpaceTransform().To2dTranslation());
sunxd8a9a60982016-07-29 18:46:564808
4809 gfx::Transform expected_scroll_child_screen_space_transform;
4810 expected_scroll_child_screen_space_transform.Translate(-5.3f, -9.3f);
4811 expected_scroll_child_screen_space_transform.RotateAboutYAxis(30);
4812 EXPECT_TRANSFORMATION_MATRIX_EQ(expected_scroll_child_screen_space_transform,
Xianzhu Wangc8189212019-08-28 01:32:284813 scroll_child->ScreenSpaceTransform());
sunxd8a9a60982016-07-29 18:46:564814}
4815
Xianzhu Wang66e13e02019-09-18 20:39:124816class DrawPropertiesStickyPositionTest : public DrawPropertiesTest {
Xianzhu Wang41319ab42019-08-28 01:06:364817 protected:
4818 // Setup layers and property trees.
4819 // Virtual layer hierarchy:
4820 // + root
4821 // + container
4822 // + scroller
4823 // + sticky_pos
4824 void CreateTree() {
4825 CreateRootAndScroller();
4826 sticky_pos_ = CreateSticky(scroller_.get());
4827 }
flackr2215b4e2016-09-21 20:16:014828
Xianzhu Wang41319ab42019-08-28 01:06:364829 void CreateRootAndScroller() {
4830 root_ = Layer::Create();
4831 container_ = Layer::Create();
4832 scroller_ = Layer::Create();
4833 scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id()));
4834
4835 root_->SetBounds(gfx::Size(100, 100));
4836 host()->SetRootLayer(root_);
4837 SetupRootProperties(root_.get());
4838
4839 container_->SetBounds(gfx::Size(100, 100));
4840 CopyProperties(root_.get(), container_.get());
4841 root_->AddChild(container_);
4842
4843 scroller_->SetBounds(gfx::Size(1000, 1000));
4844 scroller_->SetScrollable(container_->bounds());
4845 CopyProperties(container_.get(), scroller_.get());
Xianzhu Wangc8189212019-08-28 01:32:284846 CreateTransformNode(scroller_.get());
Xianzhu Wang41319ab42019-08-28 01:06:364847 CreateScrollNode(scroller_.get());
4848 root_->AddChild(scroller_);
4849 }
4850
4851 scoped_refptr<Layer> CreateSticky(Layer* parent) {
4852 scoped_refptr<Layer> sticky = Layer::Create();
4853 sticky->SetBounds(gfx::Size(10, 10));
4854 CopyProperties(parent, sticky.get());
4855 CreateTransformNode(sticky.get());
4856 EnsureStickyData(sticky.get()).scroll_ancestor =
4857 parent->scroll_tree_index();
4858 root_->AddChild(sticky);
4859 return sticky;
4860 }
4861
4862 void CommitAndUpdateImplPointers() {
Xianzhu Wang66e13e02019-09-18 20:39:124863 UpdateMainDrawProperties();
4864 host_impl()->CreatePendingTree();
Xianzhu Wang41319ab42019-08-28 01:06:364865 host()->CommitAndCreatePendingTree();
Xianzhu Wang66e13e02019-09-18 20:39:124866 host_impl()->ActivateSyncTree();
4867 LayerTreeImpl* layer_tree_impl = host_impl()->active_tree();
Xianzhu Wang41319ab42019-08-28 01:06:364868 root_impl_ = layer_tree_impl->LayerById(root_->id());
4869 scroller_impl_ = layer_tree_impl->LayerById(scroller_->id());
4870 sticky_pos_impl_ = layer_tree_impl->LayerById(sticky_pos_->id());
4871 }
4872
4873 StickyPositionNodeData& EnsureStickyData(Layer* layer) {
4874 return GetPropertyTrees(layer)->transform_tree.EnsureStickyPositionData(
4875 layer->transform_tree_index());
4876 }
4877
4878 scoped_refptr<Layer> root_;
4879 scoped_refptr<Layer> container_;
4880 scoped_refptr<Layer> scroller_;
4881 scoped_refptr<Layer> sticky_pos_;
4882 LayerImpl* root_impl_;
4883 LayerImpl* scroller_impl_;
4884 LayerImpl* sticky_pos_impl_;
4885};
4886
Xianzhu Wang66e13e02019-09-18 20:39:124887TEST_F(DrawPropertiesStickyPositionTest, StickyPositionTop) {
Xianzhu Wang41319ab42019-08-28 01:06:364888 CreateTree();
4889
Xianzhu Wang5b429f02019-08-29 20:45:274890 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20));
Xianzhu Wang41319ab42019-08-28 01:06:364891 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackr2215b4e2016-09-21 20:16:014892 sticky_position.is_anchored_top = true;
4893 sticky_position.top_offset = 10.0f;
4894 sticky_position.scroll_container_relative_sticky_box_rect =
4895 gfx::Rect(10, 20, 10, 10);
4896 sticky_position.scroll_container_relative_containing_block_rect =
4897 gfx::Rect(0, 0, 50, 50);
flackr2215b4e2016-09-21 20:16:014898
Xianzhu Wang41319ab42019-08-28 01:06:364899 CommitAndUpdateImplPointers();
flackr2215b4e2016-09-21 20:16:014900
flackr2215b4e2016-09-21 20:16:014901 EXPECT_VECTOR2DF_EQ(
4902 gfx::Vector2dF(10.f, 20.f),
Xianzhu Wang41319ab42019-08-28 01:06:364903 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:014904
4905 // Scroll less than sticking point, sticky element should move with scroll as
4906 // we haven't gotten to the initial sticky item location yet.
Xianzhu Wang41319ab42019-08-28 01:06:364907 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f));
Xianzhu Wang5b429f02019-08-29 20:45:274908
Xianzhu Wang66e13e02019-09-18 20:39:124909 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:014910 EXPECT_VECTOR2DF_EQ(
4911 gfx::Vector2dF(5.f, 15.f),
Xianzhu Wang41319ab42019-08-28 01:06:364912 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:014913
4914 // Scroll past the sticking point, the Y coordinate should now be clamped.
Xianzhu Wang41319ab42019-08-28 01:06:364915 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f));
Xianzhu Wang66e13e02019-09-18 20:39:124916 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:014917 EXPECT_VECTOR2DF_EQ(
4918 gfx::Vector2dF(-5.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:364919 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
4920 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 25.f));
Xianzhu Wang66e13e02019-09-18 20:39:124921 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:014922 EXPECT_VECTOR2DF_EQ(
4923 gfx::Vector2dF(-5.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:364924 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:014925
4926 // Scroll past the end of the sticky container (note: this element does not
4927 // have its own layer as it does not need to be composited).
Xianzhu Wang41319ab42019-08-28 01:06:364928 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 50.f));
Xianzhu Wang66e13e02019-09-18 20:39:124929 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:014930 EXPECT_VECTOR2DF_EQ(
4931 gfx::Vector2dF(-5.f, -10.f),
Xianzhu Wang41319ab42019-08-28 01:06:364932 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:014933}
4934
Xianzhu Wang66e13e02019-09-18 20:39:124935TEST_F(DrawPropertiesStickyPositionTest, StickyPositionSubpixelScroll) {
Xianzhu Wang41319ab42019-08-28 01:06:364936 CreateTree();
flackrd2ae03f2016-11-14 19:22:054937
Xianzhu Wang5b429f02019-08-29 20:45:274938 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 200));
Xianzhu Wang41319ab42019-08-28 01:06:364939 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackrdc5dfbe2016-10-24 21:43:384940 sticky_position.is_anchored_bottom = true;
4941 sticky_position.bottom_offset = 10.0f;
Chris Harrelson493e6b52019-06-28 20:37:174942 sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
flackrdc5dfbe2016-10-24 21:43:384943 sticky_position.scroll_container_relative_sticky_box_rect =
4944 gfx::Rect(0, 200, 10, 10);
4945 sticky_position.scroll_container_relative_containing_block_rect =
4946 gfx::Rect(0, 0, 100, 500);
flackrdc5dfbe2016-10-24 21:43:384947
Xianzhu Wang41319ab42019-08-28 01:06:364948 CommitAndUpdateImplPointers();
flackrdc5dfbe2016-10-24 21:43:384949
Xianzhu Wang41319ab42019-08-28 01:06:364950 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.8f));
Xianzhu Wang5b429f02019-08-29 20:45:274951
Xianzhu Wang66e13e02019-09-18 20:39:124952 UpdateActiveTreeDrawProperties();
flackrdc5dfbe2016-10-24 21:43:384953 EXPECT_VECTOR2DF_EQ(
4954 gfx::Vector2dF(0.f, 80.f),
Xianzhu Wang41319ab42019-08-28 01:06:364955 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackrdc5dfbe2016-10-24 21:43:384956}
4957
Xianzhu Wang66e13e02019-09-18 20:39:124958TEST_F(DrawPropertiesStickyPositionTest, StickyPositionBottom) {
Xianzhu Wang41319ab42019-08-28 01:06:364959 CreateTree();
flackr2215b4e2016-09-21 20:16:014960
Xianzhu Wang5b429f02019-08-29 20:45:274961 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 150));
Xianzhu Wang41319ab42019-08-28 01:06:364962 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackr2215b4e2016-09-21 20:16:014963 sticky_position.is_anchored_bottom = true;
4964 sticky_position.bottom_offset = 10.0f;
Chris Harrelson493e6b52019-06-28 20:37:174965 sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
flackr2215b4e2016-09-21 20:16:014966 sticky_position.scroll_container_relative_sticky_box_rect =
4967 gfx::Rect(0, 150, 10, 10);
4968 sticky_position.scroll_container_relative_containing_block_rect =
4969 gfx::Rect(0, 100, 50, 50);
flackr2215b4e2016-09-21 20:16:014970
Xianzhu Wang41319ab42019-08-28 01:06:364971 CommitAndUpdateImplPointers();
flackr2215b4e2016-09-21 20:16:014972
4973 // Initially the sticky element is moved up to the top of the container.
flackr2215b4e2016-09-21 20:16:014974 EXPECT_VECTOR2DF_EQ(
4975 gfx::Vector2dF(0.f, 100.f),
Xianzhu Wang41319ab42019-08-28 01:06:364976 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
4977 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
Xianzhu Wang5b429f02019-08-29 20:45:274978
Xianzhu Wang66e13e02019-09-18 20:39:124979 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:014980 EXPECT_VECTOR2DF_EQ(
4981 gfx::Vector2dF(0.f, 95.f),
Xianzhu Wang41319ab42019-08-28 01:06:364982 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:014983
4984 // Once we get past the top of the container it moves to be aligned 10px
4985 // up from the the bottom of the scroller.
Xianzhu Wang41319ab42019-08-28 01:06:364986 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
Xianzhu Wang66e13e02019-09-18 20:39:124987 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:014988 EXPECT_VECTOR2DF_EQ(
4989 gfx::Vector2dF(0.f, 80.f),
Xianzhu Wang41319ab42019-08-28 01:06:364990 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
4991 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
Xianzhu Wang66e13e02019-09-18 20:39:124992 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:014993 EXPECT_VECTOR2DF_EQ(
4994 gfx::Vector2dF(0.f, 80.f),
Xianzhu Wang41319ab42019-08-28 01:06:364995 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:014996
4997 // Once we scroll past its initial location, it sticks there.
Xianzhu Wang41319ab42019-08-28 01:06:364998 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 150.f));
Xianzhu Wang66e13e02019-09-18 20:39:124999 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015000 EXPECT_VECTOR2DF_EQ(
5001 gfx::Vector2dF(0.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365002 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015003}
5004
Xianzhu Wang66e13e02019-09-18 20:39:125005TEST_F(DrawPropertiesStickyPositionTest,
Xianzhu Wang41319ab42019-08-28 01:06:365006 StickyPositionBottomOuterViewportDelta) {
5007 CreateTree();
flackra283bed2016-10-31 14:49:425008
Xianzhu Wang41319ab42019-08-28 01:06:365009 GetScrollNode(scroller_.get())->scrolls_outer_viewport = true;
5010
Xianzhu Wang5b429f02019-08-29 20:45:275011 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 70));
Xianzhu Wang41319ab42019-08-28 01:06:365012 GetPropertyTrees(sticky_pos_.get())
5013 ->transform_tree.AddNodeAffectedByOuterViewportBoundsDelta(
Xianzhu Wang5b429f02019-08-29 20:45:275014 sticky_pos_->transform_tree_index());
Xianzhu Wang41319ab42019-08-28 01:06:365015 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackra283bed2016-10-31 14:49:425016 sticky_position.is_anchored_bottom = true;
5017 sticky_position.bottom_offset = 10.0f;
Chris Harrelson493e6b52019-06-28 20:37:175018 sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
flackra283bed2016-10-31 14:49:425019 sticky_position.scroll_container_relative_sticky_box_rect =
5020 gfx::Rect(0, 70, 10, 10);
5021 sticky_position.scroll_container_relative_containing_block_rect =
5022 gfx::Rect(0, 60, 100, 100);
flackra283bed2016-10-31 14:49:425023
Xianzhu Wang41319ab42019-08-28 01:06:365024 CommitAndUpdateImplPointers();
flackra283bed2016-10-31 14:49:425025
5026 // Initially the sticky element is moved to the bottom of the container.
5027 EXPECT_VECTOR2DF_EQ(
5028 gfx::Vector2dF(0.f, 70.f),
Xianzhu Wang41319ab42019-08-28 01:06:365029 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackra283bed2016-10-31 14:49:425030
5031 // We start to hide the toolbar, but not far enough that the sticky element
5032 // should be moved up yet.
Xianzhu Wang41319ab42019-08-28 01:06:365033 GetPropertyTrees(scroller_impl_)
5034 ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -10.f));
Xianzhu Wang5b429f02019-08-29 20:45:275035
Xianzhu Wang66e13e02019-09-18 20:39:125036 UpdateActiveTreeDrawProperties();
flackra283bed2016-10-31 14:49:425037 EXPECT_VECTOR2DF_EQ(
5038 gfx::Vector2dF(0.f, 70.f),
Xianzhu Wang41319ab42019-08-28 01:06:365039 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackra283bed2016-10-31 14:49:425040
5041 // On hiding more of the toolbar the sticky element starts to stick.
Xianzhu Wang41319ab42019-08-28 01:06:365042 GetPropertyTrees(scroller_impl_)
5043 ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -20.f));
Xianzhu Wang66e13e02019-09-18 20:39:125044 UpdateActiveTreeDrawProperties();
flackra283bed2016-10-31 14:49:425045
5046 // On hiding more the sticky element stops moving as it has reached its
5047 // limit.
5048 EXPECT_VECTOR2DF_EQ(
5049 gfx::Vector2dF(0.f, 60.f),
Xianzhu Wang41319ab42019-08-28 01:06:365050 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackra283bed2016-10-31 14:49:425051
Xianzhu Wang41319ab42019-08-28 01:06:365052 GetPropertyTrees(scroller_impl_)
5053 ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -30.f));
Xianzhu Wang66e13e02019-09-18 20:39:125054 UpdateActiveTreeDrawProperties();
flackra283bed2016-10-31 14:49:425055
5056 EXPECT_VECTOR2DF_EQ(
5057 gfx::Vector2dF(0.f, 60.f),
Xianzhu Wang41319ab42019-08-28 01:06:365058 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackre310f292016-10-12 21:09:285059}
5060
Xianzhu Wang66e13e02019-09-18 20:39:125061TEST_F(DrawPropertiesStickyPositionTest, StickyPositionLeftRight) {
Xianzhu Wang41319ab42019-08-28 01:06:365062 CreateTree();
flackr2215b4e2016-09-21 20:16:015063
Xianzhu Wang5b429f02019-08-29 20:45:275064 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(145, 0));
Xianzhu Wang41319ab42019-08-28 01:06:365065 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackr2215b4e2016-09-21 20:16:015066 sticky_position.is_anchored_left = true;
5067 sticky_position.is_anchored_right = true;
Xianzhu Wang41319ab42019-08-28 01:06:365068 sticky_position.left_offset = 10.0f;
5069 sticky_position.right_offset = 10.0f;
Chris Harrelson493e6b52019-06-28 20:37:175070 sticky_position.constraint_box_rect = gfx::Rect(0, 0, 100, 100);
flackr2215b4e2016-09-21 20:16:015071 sticky_position.scroll_container_relative_sticky_box_rect =
5072 gfx::Rect(145, 0, 10, 10);
5073 sticky_position.scroll_container_relative_containing_block_rect =
5074 gfx::Rect(100, 0, 100, 100);
flackr2215b4e2016-09-21 20:16:015075
Xianzhu Wang41319ab42019-08-28 01:06:365076 CommitAndUpdateImplPointers();
flackr2215b4e2016-09-21 20:16:015077
5078 // Initially the sticky element is moved the leftmost side of the container.
Xianzhu Wang5b429f02019-08-29 20:45:275079
Xianzhu Wang66e13e02019-09-18 20:39:125080 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015081 EXPECT_VECTOR2DF_EQ(
5082 gfx::Vector2dF(100.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365083 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
5084 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125085 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015086 EXPECT_VECTOR2DF_EQ(
5087 gfx::Vector2dF(95.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365088 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015089
5090 // Once we get past the left side of the container it moves to be aligned 10px
5091 // up from the the right of the scroller.
Xianzhu Wang41319ab42019-08-28 01:06:365092 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(25.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125093 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015094 EXPECT_VECTOR2DF_EQ(
5095 gfx::Vector2dF(80.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365096 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
5097 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(30.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125098 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015099 EXPECT_VECTOR2DF_EQ(
5100 gfx::Vector2dF(80.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365101 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015102
5103 // When we get to the sticky element's original position we stop sticking
5104 // to the right.
Xianzhu Wang41319ab42019-08-28 01:06:365105 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(95.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125106 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015107 EXPECT_VECTOR2DF_EQ(
5108 gfx::Vector2dF(50.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365109 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
5110 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(105.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125111 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015112 EXPECT_VECTOR2DF_EQ(
5113 gfx::Vector2dF(40.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365114 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015115
5116 // The element starts sticking to the left once we scroll far enough.
Xianzhu Wang41319ab42019-08-28 01:06:365117 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(150.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125118 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015119 EXPECT_VECTOR2DF_EQ(
5120 gfx::Vector2dF(10.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365121 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
5122 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(155.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125123 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015124 EXPECT_VECTOR2DF_EQ(
5125 gfx::Vector2dF(10.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365126 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015127
5128 // Finally it stops sticking when it hits the right side of the container.
Xianzhu Wang41319ab42019-08-28 01:06:365129 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(190.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125130 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015131 EXPECT_VECTOR2DF_EQ(
5132 gfx::Vector2dF(0.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365133 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
5134 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(195.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125135 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015136 EXPECT_VECTOR2DF_EQ(
5137 gfx::Vector2dF(-5.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365138 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015139}
5140
5141// This test ensures that the compositor sticky position code correctly accounts
5142// for the element having been given a position from the main thread sticky
5143// position code.
Xianzhu Wang66e13e02019-09-18 20:39:125144TEST_F(DrawPropertiesStickyPositionTest, StickyPositionMainThreadUpdates) {
Xianzhu Wang41319ab42019-08-28 01:06:365145 CreateTree();
flackr2215b4e2016-09-21 20:16:015146
Xianzhu Wang5b429f02019-08-29 20:45:275147 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20));
Xianzhu Wang41319ab42019-08-28 01:06:365148 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackr2215b4e2016-09-21 20:16:015149 sticky_position.is_anchored_top = true;
5150 sticky_position.top_offset = 10.0f;
5151 sticky_position.scroll_container_relative_sticky_box_rect =
5152 gfx::Rect(10, 20, 10, 10);
5153 sticky_position.scroll_container_relative_containing_block_rect =
5154 gfx::Rect(0, 0, 50, 50);
flackr2215b4e2016-09-21 20:16:015155
Xianzhu Wang41319ab42019-08-28 01:06:365156 CommitAndUpdateImplPointers();
flackr2215b4e2016-09-21 20:16:015157
flackr2215b4e2016-09-21 20:16:015158 EXPECT_VECTOR2DF_EQ(
5159 gfx::Vector2dF(10.f, 20.f),
Xianzhu Wang41319ab42019-08-28 01:06:365160 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015161
5162 // Scroll less than sticking point, sticky element should move with scroll as
5163 // we haven't gotten to the initial sticky item location yet.
Xianzhu Wang41319ab42019-08-28 01:06:365164 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f));
Xianzhu Wang5b429f02019-08-29 20:45:275165
Xianzhu Wang66e13e02019-09-18 20:39:125166 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015167 EXPECT_VECTOR2DF_EQ(
5168 gfx::Vector2dF(5.f, 15.f),
Xianzhu Wang41319ab42019-08-28 01:06:365169 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015170
5171 // Scroll past the sticking point, the Y coordinate should now be clamped.
Xianzhu Wang41319ab42019-08-28 01:06:365172 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f));
Xianzhu Wang66e13e02019-09-18 20:39:125173 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015174 EXPECT_VECTOR2DF_EQ(
5175 gfx::Vector2dF(-5.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:365176 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015177
5178 // Now the main thread commits the new position of the sticky element.
Xianzhu Wang41319ab42019-08-28 01:06:365179 SetScrollOffset(scroller_.get(), gfx::ScrollOffset(15, 15));
yigu23b68f62017-06-13 12:35:075180 // Shift the layer by -offset_for_position_sticky.
Xianzhu Wang5b429f02019-08-29 20:45:275181 SetPostTranslation(sticky_pos_.get(),
5182 gfx::PointF(10, 25) - gfx::PointF(0, 5));
Xianzhu Wang41319ab42019-08-28 01:06:365183 GetPropertyTrees(scroller_.get())->transform_tree.set_needs_update(true);
5184
5185 CommitAndUpdateImplPointers();
flackr2215b4e2016-09-21 20:16:015186
5187 // The element should still be where it was before. We reset the delta to
5188 // (0, 0) because we have synced a scroll offset of (15, 15) from the main
5189 // thread.
Xianzhu Wang41319ab42019-08-28 01:06:365190 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125191 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015192 EXPECT_VECTOR2DF_EQ(
5193 gfx::Vector2dF(-5.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:365194 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015195
5196 // And if we scroll a little further it remains there.
Xianzhu Wang41319ab42019-08-28 01:06:365197 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f));
Xianzhu Wang66e13e02019-09-18 20:39:125198 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015199 EXPECT_VECTOR2DF_EQ(
5200 gfx::Vector2dF(-5.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:365201 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015202}
5203
flackr68e1c292016-10-11 16:34:425204// This tests the main thread updates with a composited sticky container. In
5205// this case the position received from main is relative to the container but
5206// the constraint rects are relative to the ancestor scroller.
Xianzhu Wang66e13e02019-09-18 20:39:125207TEST_F(DrawPropertiesStickyPositionTest, StickyPositionCompositedContainer) {
Xianzhu Wang41319ab42019-08-28 01:06:365208 CreateRootAndScroller();
flackr68e1c292016-10-11 16:34:425209
Xianzhu Wang41319ab42019-08-28 01:06:365210 scoped_refptr<Layer> sticky_container = Layer::Create();
5211 sticky_container->SetBounds(gfx::Size(30, 30));
5212 sticky_container->SetOffsetToTransformParent(gfx::Vector2dF(20, 20));
5213 CopyProperties(scroller_.get(), sticky_container.get());
5214 root_->AddChild(sticky_container);
5215
5216 sticky_pos_ = CreateSticky(sticky_container.get());
Xianzhu Wang5b429f02019-08-29 20:45:275217 SetPostTranslation(
5218 sticky_pos_.get(),
5219 gfx::Vector2dF(0, 10) + sticky_container->offset_to_transform_parent());
Xianzhu Wang41319ab42019-08-28 01:06:365220 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackr68e1c292016-10-11 16:34:425221 sticky_position.is_anchored_top = true;
5222 sticky_position.top_offset = 10.0f;
flackr68e1c292016-10-11 16:34:425223 sticky_position.scroll_container_relative_sticky_box_rect =
5224 gfx::Rect(20, 30, 10, 10);
5225 sticky_position.scroll_container_relative_containing_block_rect =
5226 gfx::Rect(20, 20, 30, 30);
flackr68e1c292016-10-11 16:34:425227
Xianzhu Wang41319ab42019-08-28 01:06:365228 CommitAndUpdateImplPointers();
flackr68e1c292016-10-11 16:34:425229
flackr68e1c292016-10-11 16:34:425230 EXPECT_VECTOR2DF_EQ(
5231 gfx::Vector2dF(20.f, 30.f),
Xianzhu Wang41319ab42019-08-28 01:06:365232 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr68e1c292016-10-11 16:34:425233
5234 // Scroll less than sticking point, sticky element should move with scroll as
5235 // we haven't gotten to the initial sticky item location yet.
Xianzhu Wang41319ab42019-08-28 01:06:365236 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
Xianzhu Wang66e13e02019-09-18 20:39:125237 UpdateActiveTreeDrawProperties();
flackr68e1c292016-10-11 16:34:425238 EXPECT_VECTOR2DF_EQ(
5239 gfx::Vector2dF(20.f, 25.f),
Xianzhu Wang41319ab42019-08-28 01:06:365240 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr68e1c292016-10-11 16:34:425241
5242 // Scroll past the sticking point, the Y coordinate should now be clamped.
Xianzhu Wang41319ab42019-08-28 01:06:365243 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
Xianzhu Wang66e13e02019-09-18 20:39:125244 UpdateActiveTreeDrawProperties();
flackr68e1c292016-10-11 16:34:425245 EXPECT_VECTOR2DF_EQ(
5246 gfx::Vector2dF(20.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:365247 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr68e1c292016-10-11 16:34:425248
5249 // Now the main thread commits the new position of the sticky element.
Xianzhu Wang41319ab42019-08-28 01:06:365250 SetScrollOffset(scroller_.get(), gfx::ScrollOffset(0, 25));
yigu23b68f62017-06-13 12:35:075251 // Shift the layer by -offset_for_position_sticky.
Xianzhu Wang5b429f02019-08-29 20:45:275252 SetPostTranslation(sticky_pos_.get(),
5253 gfx::PointF(0, 15) - gfx::PointF(0, 5) +
5254 sticky_container->offset_to_transform_parent());
Xianzhu Wang41319ab42019-08-28 01:06:365255 CommitAndUpdateImplPointers();
flackr68e1c292016-10-11 16:34:425256
5257 // The element should still be where it was before. We reset the delta to
5258 // (0, 0) because we have synced a scroll offset of (0, 25) from the main
5259 // thread.
Xianzhu Wang41319ab42019-08-28 01:06:365260 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f));
Xianzhu Wang66e13e02019-09-18 20:39:125261 UpdateActiveTreeDrawProperties();
flackr68e1c292016-10-11 16:34:425262 EXPECT_VECTOR2DF_EQ(
5263 gfx::Vector2dF(20.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:365264 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr68e1c292016-10-11 16:34:425265
5266 // And if we scroll a little further it remains there.
Xianzhu Wang41319ab42019-08-28 01:06:365267 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
Xianzhu Wang66e13e02019-09-18 20:39:125268 UpdateActiveTreeDrawProperties();
flackr68e1c292016-10-11 16:34:425269 EXPECT_VECTOR2DF_EQ(
5270 gfx::Vector2dF(20.f, 10.f),
Xianzhu Wang41319ab42019-08-28 01:06:365271 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr68e1c292016-10-11 16:34:425272
5273 // And hits the bottom of the container.
Xianzhu Wang41319ab42019-08-28 01:06:365274 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f));
Xianzhu Wang66e13e02019-09-18 20:39:125275 UpdateActiveTreeDrawProperties();
flackr68e1c292016-10-11 16:34:425276 EXPECT_VECTOR2DF_EQ(
5277 gfx::Vector2dF(20.f, 5.f),
Xianzhu Wang41319ab42019-08-28 01:06:365278 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr68e1c292016-10-11 16:34:425279}
5280
flackr2215b4e2016-09-21 20:16:015281// A transform on a sticky element should not affect its sticky position.
Xianzhu Wang66e13e02019-09-18 20:39:125282TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledStickyBox) {
Xianzhu Wang41319ab42019-08-28 01:06:365283 CreateTree();
5284
Xianzhu Wang5b429f02019-08-29 20:45:275285 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20));
5286 gfx::Transform scale;
5287 scale.Scale(2, 2);
5288 SetTransform(sticky_pos_.get(), scale);
flackr2215b4e2016-09-21 20:16:015289
Xianzhu Wang41319ab42019-08-28 01:06:365290 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackr2215b4e2016-09-21 20:16:015291 sticky_position.is_anchored_top = true;
5292 sticky_position.top_offset = 0.0f;
5293 sticky_position.scroll_container_relative_sticky_box_rect =
5294 gfx::Rect(0, 20, 10, 10);
5295 sticky_position.scroll_container_relative_containing_block_rect =
5296 gfx::Rect(0, 0, 50, 50);
flackr2215b4e2016-09-21 20:16:015297
Xianzhu Wang41319ab42019-08-28 01:06:365298 CommitAndUpdateImplPointers();
flackr2215b4e2016-09-21 20:16:015299
flackr2215b4e2016-09-21 20:16:015300 EXPECT_VECTOR2DF_EQ(
5301 gfx::Vector2dF(0.f, 20.f),
Xianzhu Wang41319ab42019-08-28 01:06:365302 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015303
5304 // Scroll less than sticking point, sticky element should move with scroll as
5305 // we haven't gotten to the initial sticky item location yet.
Xianzhu Wang41319ab42019-08-28 01:06:365306 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f));
Xianzhu Wang5b429f02019-08-29 20:45:275307
Xianzhu Wang66e13e02019-09-18 20:39:125308 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015309 EXPECT_VECTOR2DF_EQ(
5310 gfx::Vector2dF(0.f, 5.f),
Xianzhu Wang41319ab42019-08-28 01:06:365311 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015312
5313 // Scroll past the sticking point, the box is positioned at the scroller
5314 // edge.
Xianzhu Wang41319ab42019-08-28 01:06:365315 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
Xianzhu Wang66e13e02019-09-18 20:39:125316 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015317 EXPECT_VECTOR2DF_EQ(
5318 gfx::Vector2dF(0.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365319 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
5320 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
Xianzhu Wang66e13e02019-09-18 20:39:125321 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015322 EXPECT_VECTOR2DF_EQ(
5323 gfx::Vector2dF(0.f, 0.f),
Xianzhu Wang41319ab42019-08-28 01:06:365324 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015325
5326 // Scroll past the end of the sticky container.
Xianzhu Wang41319ab42019-08-28 01:06:365327 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f));
Xianzhu Wang66e13e02019-09-18 20:39:125328 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015329 EXPECT_VECTOR2DF_EQ(
5330 gfx::Vector2dF(0.f, -10.f),
Xianzhu Wang41319ab42019-08-28 01:06:365331 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015332}
5333
5334// Tests that a transform does not affect the sticking points. The sticky
5335// element will however move relative to the viewport due to its transform.
Xianzhu Wang66e13e02019-09-18 20:39:125336TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledContainer) {
Xianzhu Wang41319ab42019-08-28 01:06:365337 CreateRootAndScroller();
5338
flackr2215b4e2016-09-21 20:16:015339 scoped_refptr<Layer> sticky_container = Layer::Create();
Xianzhu Wang41319ab42019-08-28 01:06:365340 sticky_container->SetBounds(gfx::Size(50, 50));
5341 CopyProperties(scroller_.get(), sticky_container.get());
Xianzhu Wangc8189212019-08-28 01:32:285342 CreateTransformNode(sticky_container.get()).local.Scale(2, 2);
Xianzhu Wang41319ab42019-08-28 01:06:365343 root_->AddChild(sticky_container);
flackr2215b4e2016-09-21 20:16:015344
Xianzhu Wang41319ab42019-08-28 01:06:365345 sticky_pos_ = CreateSticky(sticky_container.get());
Xianzhu Wang5b429f02019-08-29 20:45:275346 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20));
Xianzhu Wang41319ab42019-08-28 01:06:365347 auto& sticky_position = EnsureStickyData(sticky_pos_.get()).constraints;
flackr2215b4e2016-09-21 20:16:015348 sticky_position.is_anchored_top = true;
5349 sticky_position.top_offset = 0.0f;
5350 sticky_position.scroll_container_relative_sticky_box_rect =
5351 gfx::Rect(0, 20, 10, 10);
5352 sticky_position.scroll_container_relative_containing_block_rect =
5353 gfx::Rect(0, 0, 50, 50);
flackr2215b4e2016-09-21 20:16:015354
Xianzhu Wang41319ab42019-08-28 01:06:365355 CommitAndUpdateImplPointers();
flackr2215b4e2016-09-21 20:16:015356
flackr2215b4e2016-09-21 20:16:015357 EXPECT_VECTOR2DF_EQ(
5358 gfx::Vector2dF(0.f, 40.f),
Xianzhu Wang41319ab42019-08-28 01:06:365359 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015360
5361 // Scroll less than sticking point, sticky element should move with scroll as
5362 // we haven't gotten to the initial sticky item location yet.
Xianzhu Wang41319ab42019-08-28 01:06:365363 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f));
Xianzhu Wang66e13e02019-09-18 20:39:125364 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015365 EXPECT_VECTOR2DF_EQ(
5366 gfx::Vector2dF(0.f, 25.f),
Xianzhu Wang41319ab42019-08-28 01:06:365367 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015368
5369 // Scroll past the sticking point, the box is positioned at the scroller
5370 // edge but is also scaled by its container so it begins to move down.
Xianzhu Wang41319ab42019-08-28 01:06:365371 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f));
Xianzhu Wang66e13e02019-09-18 20:39:125372 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015373 EXPECT_VECTOR2DF_EQ(
5374 gfx::Vector2dF(0.f, 25.f),
Xianzhu Wang41319ab42019-08-28 01:06:365375 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
5376 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
Xianzhu Wang66e13e02019-09-18 20:39:125377 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015378 EXPECT_VECTOR2DF_EQ(
5379 gfx::Vector2dF(0.f, 30.f),
Xianzhu Wang41319ab42019-08-28 01:06:365380 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015381
5382 // Scroll past the end of the sticky container.
Xianzhu Wang41319ab42019-08-28 01:06:365383 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f));
Xianzhu Wang66e13e02019-09-18 20:39:125384 UpdateActiveTreeDrawProperties();
flackr2215b4e2016-09-21 20:16:015385 EXPECT_VECTOR2DF_EQ(
5386 gfx::Vector2dF(0.f, 30.f),
Xianzhu Wang41319ab42019-08-28 01:06:365387 sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation());
flackr2215b4e2016-09-21 20:16:015388}
5389
Xianzhu Wang66e13e02019-09-18 20:39:125390TEST_F(DrawPropertiesStickyPositionTest, StickyPositionNested) {
Xianzhu Wang41319ab42019-08-28 01:06:365391 CreateTree();
smcgruer29014ff2017-03-24 14:34:435392
Xianzhu Wang5b429f02019-08-29 20:45:275393 SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 50));
Xianzhu Wang41319ab42019-08-28 01:06:365394 auto& outer_sticky_pos = EnsureStickyData(sticky_pos_.get()).constraints;
smcgruer29014ff2017-03-24 14:34:435395 outer_sticky_pos.is_anchored_top = true;
5396 outer_sticky_pos.top_offset = 10.0f;
smcgruer29014ff2017-03-24 14:34:435397 outer_sticky_pos.scroll_container_relative_sticky_box_rect =
5398 gfx::Rect(0, 50, 10, 50);
5399 outer_sticky_pos.scroll_container_relative_containing_block_rect =
5400 gfx::Rect(0, 0, 50, 400);
smcgruer29014ff2017-03-24 14:34:435401
Xianzhu Wang41319ab42019-08-28 01:06:365402 scoped_refptr<Layer> inner_sticky = CreateSticky(sticky_pos_.get());
5403 auto& inner_sticky_pos = EnsureStickyData(inner_sticky.get()).constraints;
smcgruer29014ff2017-03-24 14:34:435404 inner_sticky_pos.is_anchored_top = true;
5405 inner_sticky_pos.top_offset = 25.0f;
smcgruer29014ff2017-03-24 14:34:435406 inner_sticky_pos.scroll_container_relative_sticky_box_rect =
5407 gfx::Rect(0, 50, 10, 10);
5408 inner_sticky_pos.scroll_container_relative_containing_block_rect =
5409 gfx::Rect(0, 50, 10, 50);
Xianzhu Wang41319ab42019-08-28 01:06:365410 EnsureStickyData(inner_sticky.get()).nearest_node_shifting_containing_block =
5411 sticky_pos_->transform_tree_index();
smcgruer29014ff2017-03-24 14:34:435412
Xianzhu Wang41319ab42019-08-28 01:06:365413 CommitAndUpdateImplPointers();
smcgruer29014ff2017-03-24 14:34:435414 LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
Xianzhu Wang41319ab42019-08-28 01:06:365415 LayerImpl* outer_sticky_impl = sticky_pos_impl_;
smcgruer29014ff2017-03-24 14:34:435416 LayerImpl* inner_sticky_impl = layer_tree_impl->LayerById(inner_sticky->id());
5417
smcgruer29014ff2017-03-24 14:34:435418 // Before any scrolling is done, the sticky elements should still be at their
5419 // original positions.
5420 EXPECT_VECTOR2DF_EQ(
5421 gfx::Vector2dF(0.f, 50.f),
5422 outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5423 EXPECT_VECTOR2DF_EQ(
5424 gfx::Vector2dF(0.f, 50.f),
5425 inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5426
5427 // Scroll less than the sticking point. Both sticky elements should move with
5428 // scroll as we haven't gotten to the sticky item locations yet.
Xianzhu Wang41319ab42019-08-28 01:06:365429 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f));
Xianzhu Wang66e13e02019-09-18 20:39:125430 UpdateActiveTreeDrawProperties();
smcgruer29014ff2017-03-24 14:34:435431 EXPECT_VECTOR2DF_EQ(
5432 gfx::Vector2dF(0.f, 45.f),
5433 outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5434 EXPECT_VECTOR2DF_EQ(
5435 gfx::Vector2dF(0.f, 45.f),
5436 inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5437
5438 // Scroll such that the inner sticky should stick, but the outer one should
5439 // keep going as it hasn't reached its position yet.
Xianzhu Wang41319ab42019-08-28 01:06:365440 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f));
Xianzhu Wang66e13e02019-09-18 20:39:125441 UpdateActiveTreeDrawProperties();
smcgruer29014ff2017-03-24 14:34:435442 EXPECT_VECTOR2DF_EQ(
5443 gfx::Vector2dF(0.f, 20.f),
5444 outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5445 EXPECT_VECTOR2DF_EQ(
5446 gfx::Vector2dF(0.f, 25.f),
5447 inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5448
5449 // Keep going, both should stick.
Xianzhu Wang41319ab42019-08-28 01:06:365450 SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 100.f));
Xianzhu Wang66e13e02019-09-18 20:39:125451 UpdateActiveTreeDrawProperties();
smcgruer29014ff2017-03-24 14:34:435452 EXPECT_VECTOR2DF_EQ(
5453 gfx::Vector2dF(0.f, 10.f),
5454 outer_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5455 EXPECT_VECTOR2DF_EQ(
5456 gfx::Vector2dF(0.f, 25.f),
5457 inner_sticky_impl->ScreenSpaceTransform().To2dTranslation());
5458}
5459
[email protected]1c3626e2014-04-09 17:49:225460class AnimationScaleFactorTrackingLayerImpl : public LayerImpl {
5461 public:
danakj60bc3bc2016-04-09 00:24:485462 static std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> Create(
[email protected]1c3626e2014-04-09 17:49:225463 LayerTreeImpl* tree_impl,
5464 int id) {
danakj60bc3bc2016-04-09 00:24:485465 return base::WrapUnique(
[email protected]1c3626e2014-04-09 17:49:225466 new AnimationScaleFactorTrackingLayerImpl(tree_impl, id));
5467 }
5468
Chris Watkinsf6353292017-12-04 02:36:055469 ~AnimationScaleFactorTrackingLayerImpl() override = default;
[email protected]1c3626e2014-04-09 17:49:225470
[email protected]1c3626e2014-04-09 17:49:225471 private:
5472 explicit AnimationScaleFactorTrackingLayerImpl(LayerTreeImpl* tree_impl,
5473 int id)
[email protected]a57cb8b12014-06-13 18:15:375474 : LayerImpl(tree_impl, id) {
[email protected]1c3626e2014-04-09 17:49:225475 SetDrawsContent(true);
5476 }
[email protected]1c3626e2014-04-09 17:49:225477};
5478
Xianzhu Wang66e13e02019-09-18 20:39:125479TEST_F(DrawPropertiesTest, MaximumAnimationScaleFactor) {
Xianzhu Wangd6a62d82019-09-09 22:35:365480 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:275481 auto* grand_parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
5482 auto* parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
5483 auto* child = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
5484 auto* grand_child = AddLayer<AnimationScaleFactorTrackingLayerImpl>();
5485 SetElementIdsForTesting();
[email protected]1c3626e2014-04-09 17:49:225486
Xianzhu Wang1ff8cf382019-08-19 17:33:105487 root->SetBounds(gfx::Size(1, 2));
danakjf78fb272016-07-26 19:06:155488 grand_parent->SetBounds(gfx::Size(1, 2));
5489 parent->SetBounds(gfx::Size(1, 2));
5490 child->SetBounds(gfx::Size(1, 2));
5491 grand_child->SetBounds(gfx::Size(1, 2));
5492
Xianzhu Wang5b429f02019-08-29 20:45:275493 CopyProperties(root, grand_parent);
5494 CreateTransformNode(grand_parent);
5495 CopyProperties(grand_parent, parent);
5496 CreateTransformNode(parent);
5497 CopyProperties(parent, child);
5498 CreateTransformNode(child);
5499 CopyProperties(child, grand_child);
5500 CreateTransformNode(grand_child);
sunxd71aea3e2016-04-01 23:48:055501
Xianzhu Wang66e13e02019-09-18 20:39:125502 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225503
5504 // No layers have animations.
Xianzhu Wang5b429f02019-08-29 20:45:275505 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5506 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
5507 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5508 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225509
Xianzhu Wang5b429f02019-08-29 20:45:275510 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5511 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
5512 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5513 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035514
[email protected]1c3626e2014-04-09 17:49:225515 TransformOperations translation;
5516 translation.AppendTranslate(1.f, 2.f, 3.f);
5517
Yi Guaa830ff2018-02-22 03:09:115518 scoped_refptr<SingleKeyframeEffectAnimation> grand_parent_animation =
5519 SingleKeyframeEffectAnimation::Create(
5520 AnimationIdProvider::NextAnimationId());
Xianzhu Wangc62ecebf2019-08-31 15:54:135521 timeline_impl()->AttachAnimation(grand_parent_animation);
Xianzhu Wang5b429f02019-08-29 20:45:275522 grand_parent_animation->AttachElement(grand_parent->element_id());
loysodb006882016-09-14 00:31:515523
Yi Guaa830ff2018-02-22 03:09:115524 scoped_refptr<SingleKeyframeEffectAnimation> parent_animation =
5525 SingleKeyframeEffectAnimation::Create(
5526 AnimationIdProvider::NextAnimationId());
Xianzhu Wangc62ecebf2019-08-31 15:54:135527 timeline_impl()->AttachAnimation(parent_animation);
Xianzhu Wang5b429f02019-08-29 20:45:275528 parent_animation->AttachElement(parent->element_id());
loysodb006882016-09-14 00:31:515529
Yi Guaa830ff2018-02-22 03:09:115530 scoped_refptr<SingleKeyframeEffectAnimation> child_animation =
5531 SingleKeyframeEffectAnimation::Create(
5532 AnimationIdProvider::NextAnimationId());
Xianzhu Wangc62ecebf2019-08-31 15:54:135533 timeline_impl()->AttachAnimation(child_animation);
Xianzhu Wang5b429f02019-08-29 20:45:275534 child_animation->AttachElement(child->element_id());
loysodb006882016-09-14 00:31:515535
Yi Guaa830ff2018-02-22 03:09:115536 scoped_refptr<SingleKeyframeEffectAnimation> grand_child_animation =
5537 SingleKeyframeEffectAnimation::Create(
5538 AnimationIdProvider::NextAnimationId());
Xianzhu Wangc62ecebf2019-08-31 15:54:135539 timeline_impl()->AttachAnimation(grand_child_animation);
Xianzhu Wang5b429f02019-08-29 20:45:275540 grand_child_animation->AttachElement(grand_child->element_id());
loysodb006882016-09-14 00:31:515541
Yi Guaa830ff2018-02-22 03:09:115542 AddAnimatedTransformToAnimation(parent_animation.get(), 1.0,
5543 TransformOperations(), translation);
[email protected]1c3626e2014-04-09 17:49:225544
5545 // No layers have scale-affecting animations.
Xianzhu Wang5b429f02019-08-29 20:45:275546 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5547 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
5548 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5549 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225550
Xianzhu Wang5b429f02019-08-29 20:45:275551 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5552 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
5553 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5554 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035555
[email protected]1c3626e2014-04-09 17:49:225556 TransformOperations scale;
5557 scale.AppendScale(5.f, 4.f, 3.f);
5558
Yi Guaa830ff2018-02-22 03:09:115559 AddAnimatedTransformToAnimation(child_animation.get(), 1.0,
5560 TransformOperations(), scale);
Xianzhu Wang66e13e02019-09-18 20:39:125561 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225562
5563 // Only |child| has a scale-affecting animation.
Xianzhu Wang5b429f02019-08-29 20:45:275564 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5565 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
5566 EXPECT_EQ(5.f, GetMaximumAnimationScale(child));
5567 EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225568
Xianzhu Wang5b429f02019-08-29 20:45:275569 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5570 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
5571 EXPECT_EQ(1.f, GetStartingAnimationScale(child));
5572 EXPECT_EQ(1.f, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035573
Yi Guaa830ff2018-02-22 03:09:115574 AddAnimatedTransformToAnimation(grand_parent_animation.get(), 1.0,
5575 TransformOperations(), scale);
Xianzhu Wang66e13e02019-09-18 20:39:125576 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225577
5578 // |grand_parent| and |child| have scale-affecting animations.
Xianzhu Wang5b429f02019-08-29 20:45:275579 EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent));
5580 EXPECT_EQ(5.f, GetMaximumAnimationScale(parent));
[email protected]1c3626e2014-04-09 17:49:225581 // We don't support combining animated scales from two nodes; 0.f means
5582 // that the maximum scale could not be computed.
Xianzhu Wang5b429f02019-08-29 20:45:275583 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5584 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225585
Xianzhu Wang5b429f02019-08-29 20:45:275586 EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent));
5587 EXPECT_EQ(1.f, GetStartingAnimationScale(parent));
5588 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5589 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035590
Yi Guaa830ff2018-02-22 03:09:115591 AddAnimatedTransformToAnimation(parent_animation.get(), 1.0,
5592 TransformOperations(), scale);
Xianzhu Wang66e13e02019-09-18 20:39:125593 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225594
5595 // |grand_parent|, |parent|, and |child| have scale-affecting animations.
Xianzhu Wang5b429f02019-08-29 20:45:275596 EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent));
5597 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
5598 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5599 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225600
Xianzhu Wang5b429f02019-08-29 20:45:275601 EXPECT_EQ(1.f, GetStartingAnimationScale(grand_parent));
5602 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
5603 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5604 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035605
Yi Gufcce1762018-07-10 14:56:495606 grand_parent_animation->AbortKeyframeModelsWithProperty(
5607 TargetProperty::TRANSFORM, false);
5608 parent_animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
5609 false);
5610 child_animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
5611 false);
[email protected]1c3626e2014-04-09 17:49:225612
5613 TransformOperations perspective;
5614 perspective.AppendPerspective(10.f);
5615
Yi Guaa830ff2018-02-22 03:09:115616 AddAnimatedTransformToAnimation(child_animation.get(), 1.0,
5617 TransformOperations(), perspective);
Xianzhu Wang66e13e02019-09-18 20:39:125618 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225619
5620 // |child| has a scale-affecting animation but computing the maximum of this
5621 // animation is not supported.
Xianzhu Wang5b429f02019-08-29 20:45:275622 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5623 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
5624 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5625 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225626
Xianzhu Wang5b429f02019-08-29 20:45:275627 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5628 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
5629 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5630 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035631
Yi Gufcce1762018-07-10 14:56:495632 child_animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
5633 false);
loysobb507792016-10-04 05:31:025634
[email protected]1c3626e2014-04-09 17:49:225635 gfx::Transform scale_matrix;
5636 scale_matrix.Scale(1.f, 2.f);
Xianzhu Wang5b429f02019-08-29 20:45:275637 SetTransform(grand_parent, scale_matrix);
5638 SetTransform(parent, scale_matrix);
loyso968163c92016-01-04 23:18:485639
Yi Guaa830ff2018-02-22 03:09:115640 AddAnimatedTransformToAnimation(parent_animation.get(), 1.0,
5641 TransformOperations(), scale);
Xianzhu Wang66e13e02019-09-18 20:39:125642 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225643
5644 // |grand_parent| and |parent| each have scale 2.f. |parent| has a scale
5645 // animation with maximum scale 5.f.
Xianzhu Wang5b429f02019-08-29 20:45:275646 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5647 EXPECT_EQ(10.f, GetMaximumAnimationScale(parent));
5648 EXPECT_EQ(10.f, GetMaximumAnimationScale(child));
5649 EXPECT_EQ(10.f, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225650
Xianzhu Wang5b429f02019-08-29 20:45:275651 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5652 EXPECT_EQ(2.f, GetStartingAnimationScale(parent));
5653 EXPECT_EQ(2.f, GetStartingAnimationScale(child));
5654 EXPECT_EQ(2.f, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035655
[email protected]1c3626e2014-04-09 17:49:225656 gfx::Transform perspective_matrix;
5657 perspective_matrix.ApplyPerspectiveDepth(2.f);
Xianzhu Wang5b429f02019-08-29 20:45:275658 SetTransform(child, perspective_matrix);
Xianzhu Wang66e13e02019-09-18 20:39:125659 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225660
5661 // |child| has a transform that's neither a translation nor a scale.
Xianzhu Wang5b429f02019-08-29 20:45:275662 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5663 EXPECT_EQ(10.f, GetMaximumAnimationScale(parent));
5664 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5665 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225666
Xianzhu Wang5b429f02019-08-29 20:45:275667 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5668 EXPECT_EQ(2.f, GetStartingAnimationScale(parent));
5669 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5670 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035671
Xianzhu Wang5b429f02019-08-29 20:45:275672 SetTransform(parent, perspective_matrix);
Xianzhu Wang66e13e02019-09-18 20:39:125673 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225674
5675 // |parent| and |child| have transforms that are neither translations nor
5676 // scales.
Xianzhu Wang5b429f02019-08-29 20:45:275677 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5678 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
5679 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5680 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225681
Xianzhu Wang5b429f02019-08-29 20:45:275682 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5683 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
5684 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5685 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035686
Xianzhu Wang5b429f02019-08-29 20:45:275687 SetTransform(parent, gfx::Transform());
5688 SetTransform(child, gfx::Transform());
5689 SetTransform(grand_parent, perspective_matrix);
[email protected]1c3626e2014-04-09 17:49:225690
Xianzhu Wang66e13e02019-09-18 20:39:125691 UpdateActiveTreeDrawProperties();
[email protected]1c3626e2014-04-09 17:49:225692
5693 // |grand_parent| has a transform that's neither a translation nor a scale.
Xianzhu Wang5b429f02019-08-29 20:45:275694 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent));
5695 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(parent));
5696 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(child));
5697 EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_child));
ajuma052892e2015-08-21 14:39:035698
Xianzhu Wang5b429f02019-08-29 20:45:275699 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_parent));
5700 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(parent));
5701 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(child));
5702 EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child));
[email protected]1c3626e2014-04-09 17:49:225703}
5704
ajuma956219582017-04-04 19:58:145705static void GatherDrawnLayers(LayerTreeImpl* tree_impl,
[email protected]390bb1ff2014-05-09 17:14:405706 std::set<LayerImpl*>* drawn_layers) {
ajuma956219582017-04-04 19:58:145707 for (EffectTreeLayerListIterator it(tree_impl);
5708 it.state() != EffectTreeLayerListIterator::State::END; ++it) {
5709 if (it.state() == EffectTreeLayerListIterator::State::LAYER)
5710 drawn_layers->insert(it.current_layer());
[email protected]390bb1ff2014-05-09 17:14:405711
ajuma956219582017-04-04 19:58:145712 if (it.state() != EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE)
[email protected]390bb1ff2014-05-09 17:14:405713 continue;
[email protected]390bb1ff2014-05-09 17:14:405714 }
5715}
5716
Xianzhu Wang5b429f02019-08-29 20:45:275717// Needs layer tree mode: mask layer.
Xianzhu Wang66e13e02019-09-18 20:39:125718TEST_F(DrawPropertiesTestWithLayerTree, RenderSurfaceLayerListMembership) {
Xianzhu Wangc62ecebf2019-08-31 15:54:135719 auto root = Layer::Create();
5720 auto grand_parent = Layer::Create();
5721 auto parent = Layer::Create();
5722 auto child = Layer::Create();
5723 auto grand_child1 = Layer::Create();
5724 auto grand_child2 = Layer::Create();
[email protected]390bb1ff2014-05-09 17:14:405725
Xianzhu Wang1ff8cf382019-08-19 17:33:105726 root->SetBounds(gfx::Size(1, 2));
danakjf78fb272016-07-26 19:06:155727 grand_parent->SetBounds(gfx::Size(1, 2));
5728 parent->SetBounds(gfx::Size(1, 2));
5729 child->SetBounds(gfx::Size(1, 2));
5730 grand_child1->SetBounds(gfx::Size(1, 2));
5731 grand_child2->SetBounds(gfx::Size(1, 2));
5732
Xianzhu Wangc62ecebf2019-08-31 15:54:135733 child->AddChild(grand_child1);
5734 child->AddChild(grand_child2);
5735 parent->AddChild(child);
5736 grand_parent->AddChild(parent);
5737 root->AddChild(grand_parent);
5738 host()->SetRootLayer(root);
[email protected]390bb1ff2014-05-09 17:14:405739
[email protected]390bb1ff2014-05-09 17:14:405740 // Start with nothing being drawn.
Xianzhu Wangc62ecebf2019-08-31 15:54:135741 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405742
Xianzhu Wangc62ecebf2019-08-31 15:54:135743 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5744 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5745 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
5746 EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5747 EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405748
5749 std::set<LayerImpl*> expected;
5750 std::set<LayerImpl*> actual;
Xianzhu Wangc62ecebf2019-08-31 15:54:135751 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405752 EXPECT_EQ(expected, actual);
5753
5754 // If we force render surface, but none of the layers are in the layer list,
5755 // then this layer should not appear in RSLL.
Xianzhu Wangc62ecebf2019-08-31 15:54:135756 grand_child1->SetForceRenderSurfaceForTesting(true);
[email protected]390bb1ff2014-05-09 17:14:405757
Xianzhu Wangc62ecebf2019-08-31 15:54:135758 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405759
Xianzhu Wangc62ecebf2019-08-31 15:54:135760 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5761 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5762 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
5763 EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5764 EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405765
5766 expected.clear();
5767 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135768 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405769 EXPECT_EQ(expected, actual);
5770
5771 // However, if we say that this layer also draws content, it will appear in
5772 // RSLL.
Xianzhu Wangc62ecebf2019-08-31 15:54:135773 grand_child1->SetIsDrawable(true);
[email protected]390bb1ff2014-05-09 17:14:405774
Xianzhu Wangc62ecebf2019-08-31 15:54:135775 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405776
Xianzhu Wangc62ecebf2019-08-31 15:54:135777 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5778 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5779 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
5780 EXPECT_TRUE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5781 EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405782
5783 expected.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135784 expected.insert(ImplOf(grand_child1));
[email protected]390bb1ff2014-05-09 17:14:405785
5786 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135787 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405788 EXPECT_EQ(expected, actual);
5789
5790 // Now child is forced to have a render surface, and one if its children draws
5791 // content.
Xianzhu Wangc62ecebf2019-08-31 15:54:135792 grand_child1->SetIsDrawable(false);
5793 grand_child1->SetForceRenderSurfaceForTesting(false);
5794 child->SetForceRenderSurfaceForTesting(true);
5795 grand_child2->SetIsDrawable(true);
[email protected]390bb1ff2014-05-09 17:14:405796
Xianzhu Wangc62ecebf2019-08-31 15:54:135797 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405798
Xianzhu Wangc62ecebf2019-08-31 15:54:135799 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5800 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5801 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
5802 EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5803 EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405804
5805 expected.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135806 expected.insert(ImplOf(grand_child2));
[email protected]390bb1ff2014-05-09 17:14:405807
5808 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135809 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405810 EXPECT_EQ(expected, actual);
5811
5812 // Add a mask layer to child.
Xianzhu Wangc62ecebf2019-08-31 15:54:135813 FakeContentLayerClient client;
5814 auto mask = PictureLayer::Create(&client);
5815 mask->SetBounds(child->bounds());
5816 child->SetMaskLayer(mask);
[email protected]390bb1ff2014-05-09 17:14:405817
Xianzhu Wangc62ecebf2019-08-31 15:54:135818 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405819
Xianzhu Wangc62ecebf2019-08-31 15:54:135820 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5821 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5822 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
5823 EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
5824 EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5825 EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405826
5827 expected.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135828 expected.insert(ImplOf(grand_child2));
5829 expected.insert(ImplOf(mask));
[email protected]390bb1ff2014-05-09 17:14:405830
5831 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135832 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405833 EXPECT_EQ(expected, actual);
5834
Xianzhu Wangc62ecebf2019-08-31 15:54:135835 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405836
Xianzhu Wangc62ecebf2019-08-31 15:54:135837 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5838 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5839 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
5840 EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
5841 EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5842 EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405843
5844 expected.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135845 expected.insert(ImplOf(grand_child2));
5846 expected.insert(ImplOf(mask));
[email protected]390bb1ff2014-05-09 17:14:405847
5848 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135849 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405850 EXPECT_EQ(expected, actual);
5851
[email protected]390bb1ff2014-05-09 17:14:405852 // With nothing drawing, we should have no layers.
Xianzhu Wangc62ecebf2019-08-31 15:54:135853 grand_child2->SetIsDrawable(false);
[email protected]390bb1ff2014-05-09 17:14:405854
Xianzhu Wangc62ecebf2019-08-31 15:54:135855 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405856
Xianzhu Wangc62ecebf2019-08-31 15:54:135857 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5858 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5859 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
Xianzhu Wangdf85eae2019-09-17 18:56:085860 // Mask layer has its own render surface in layer tree mode.
5861 EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
Xianzhu Wangc62ecebf2019-08-31 15:54:135862 EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5863 EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405864
5865 expected.clear();
Xianzhu Wangdf85eae2019-09-17 18:56:085866 expected.insert(ImplOf(mask));
[email protected]390bb1ff2014-05-09 17:14:405867 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135868 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405869 EXPECT_EQ(expected, actual);
5870
Xianzhu Wangc62ecebf2019-08-31 15:54:135871 // When the child is drawable, both the child and the mask should be in the
5872 // render surface list.
5873 child->SetIsDrawable(true);
[email protected]390bb1ff2014-05-09 17:14:405874
Xianzhu Wangc62ecebf2019-08-31 15:54:135875 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405876
Xianzhu Wangc62ecebf2019-08-31 15:54:135877 EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5878 EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface());
5879 EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface());
5880 EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
5881 EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5882 EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405883
5884 expected.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135885 expected.insert(ImplOf(child));
5886 expected.insert(ImplOf(mask));
[email protected]390bb1ff2014-05-09 17:14:405887 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135888 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405889 EXPECT_EQ(expected, actual);
5890
Xianzhu Wangc62ecebf2019-08-31 15:54:135891 child->SetMaskLayer(nullptr);
[email protected]390bb1ff2014-05-09 17:14:405892
5893 // Now everyone's a member!
Xianzhu Wangc62ecebf2019-08-31 15:54:135894 grand_parent->SetIsDrawable(true);
5895 parent->SetIsDrawable(true);
5896 child->SetIsDrawable(true);
5897 grand_child1->SetIsDrawable(true);
5898 grand_child2->SetIsDrawable(true);
[email protected]390bb1ff2014-05-09 17:14:405899
Xianzhu Wangc62ecebf2019-08-31 15:54:135900 CommitAndActivate();
[email protected]390bb1ff2014-05-09 17:14:405901
Xianzhu Wangc62ecebf2019-08-31 15:54:135902 EXPECT_TRUE(ImplOf(grand_parent)->contributes_to_drawn_render_surface());
5903 EXPECT_TRUE(ImplOf(parent)->contributes_to_drawn_render_surface());
5904 EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface());
5905 EXPECT_TRUE(ImplOf(grand_child1)->contributes_to_drawn_render_surface());
5906 EXPECT_TRUE(ImplOf(grand_child2)->contributes_to_drawn_render_surface());
[email protected]390bb1ff2014-05-09 17:14:405907
5908 expected.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135909 expected.insert(ImplOf(grand_parent));
5910 expected.insert(ImplOf(parent));
5911 expected.insert(ImplOf(child));
5912 expected.insert(ImplOf(grand_child1));
5913 expected.insert(ImplOf(grand_child2));
[email protected]390bb1ff2014-05-09 17:14:405914
5915 actual.clear();
Xianzhu Wangc62ecebf2019-08-31 15:54:135916 GatherDrawnLayers(host_impl()->active_tree(), &actual);
[email protected]390bb1ff2014-05-09 17:14:405917 EXPECT_EQ(expected, actual);
5918}
[email protected]18e69652014-06-13 12:50:585919
Xianzhu Wang5b429f02019-08-29 20:45:275920// Needs layer tree mode: mask layer.
Xianzhu Wang66e13e02019-09-18 20:39:125921TEST_F(DrawPropertiesTestWithLayerTree, DrawPropertyDeviceScale) {
Xianzhu Wangc62ecebf2019-08-31 15:54:135922 auto root = Layer::Create();
Xianzhu Wangc62ecebf2019-08-31 15:54:135923 auto child1 = Layer::Create();
5924 auto child2 = Layer::Create();
[email protected]18e69652014-06-13 12:50:585925
danakjf78fb272016-07-26 19:06:155926 gfx::Transform scale_transform_child1, scale_transform_child2;
[email protected]18e69652014-06-13 12:50:585927 scale_transform_child1.Scale(2, 3);
5928 scale_transform_child2.Scale(4, 5);
5929
danakjf78fb272016-07-26 19:06:155930 root->SetBounds(gfx::Size(1, 1));
Xianzhu Wangc62ecebf2019-08-31 15:54:135931 root->SetIsDrawable(true);
5932 child1->SetTransform(scale_transform_child1);
5933 child1->SetBounds(gfx::Size(1, 1));
5934 child1->SetIsDrawable(true);
[email protected]18e69652014-06-13 12:50:585935
Xianzhu Wangc62ecebf2019-08-31 15:54:135936 FakeContentLayerClient client;
5937 auto mask = PictureLayer::Create(&client);
5938 mask->SetBounds(child1->bounds());
5939 child1->SetMaskLayer(mask);
[email protected]18e69652014-06-13 12:50:585940
Xianzhu Wang35421fc2019-09-16 17:18:475941 root->AddChild(child1);
5942 root->AddChild(child2);
Xianzhu Wangc62ecebf2019-08-31 15:54:135943 host()->SetRootLayer(root);
5944 host()->SetElementIdsForTesting();
[email protected]18e69652014-06-13 12:50:585945
[email protected]18e69652014-06-13 12:50:585946 TransformOperations scale;
5947 scale.AppendScale(5.f, 8.f, 3.f);
5948
Xianzhu Wangc62ecebf2019-08-31 15:54:135949 child2->SetTransform(scale_transform_child2);
5950 child2->SetBounds(gfx::Size(1, 1));
5951 child2->SetIsDrawable(true);
5952 AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(),
5953 1.0, TransformOperations(), scale);
loyso968163c92016-01-04 23:18:485954
Xianzhu Wangc62ecebf2019-08-31 15:54:135955 CommitAndActivate();
vollickef2ae922016-06-29 17:54:275956
Xianzhu Wangc62ecebf2019-08-31 15:54:135957 EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
Xianzhu Wang79901dcd2019-09-14 20:45:225958 EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale());
Giovanni Ortuño Urquidibc63d69f2019-09-16 13:48:295959 EXPECT_FLOAT_EQ(3.f, ImplOf(mask)->GetIdealContentsScale());
Xianzhu Wang79901dcd2019-09-14 20:45:225960 EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale());
5961
5962 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
Xianzhu Wang35421fc2019-09-16 17:18:475963 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
5964 EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2)));
5965
5966 // Changing device-scale would affect ideal_contents_scale and
5967 // maximum_animation_contents_scale.
5968
5969 float device_scale_factor = 4.0f;
5970 CommitAndActivate(device_scale_factor);
5971
5972 EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale());
5973 EXPECT_FLOAT_EQ(12.f, ImplOf(child1)->GetIdealContentsScale());
5974 EXPECT_FLOAT_EQ(12.f, ImplOf(mask)->GetIdealContentsScale());
5975 EXPECT_FLOAT_EQ(20.f, ImplOf(child2)->GetIdealContentsScale());
5976
5977 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
5978 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
5979 EXPECT_FLOAT_EQ(32.f, GetMaximumAnimationScale(ImplOf(child2)));
5980}
5981
Xianzhu Wang66e13e02019-09-18 20:39:125982TEST_F(DrawPropertiesTest, DrawPropertyScales) {
Xianzhu Wang35421fc2019-09-16 17:18:475983 auto root = Layer::Create();
5984 auto page_scale = Layer::Create();
5985 auto child1 = Layer::Create();
5986 auto child2 = Layer::Create();
5987
5988 gfx::Transform scale_transform_child1, scale_transform_child2;
5989 scale_transform_child1.Scale(2, 3);
5990 scale_transform_child2.Scale(4, 5);
5991
5992 root->SetBounds(gfx::Size(1, 1));
5993 root->SetIsDrawable(true);
5994 child1->SetBounds(gfx::Size(1, 1));
5995 child1->SetIsDrawable(true);
5996 child2->SetBounds(gfx::Size(1, 1));
5997 child2->SetIsDrawable(true);
5998
5999 root->AddChild(child1);
6000 root->AddChild(child2);
6001 root->AddChild(page_scale);
6002 host()->SetRootLayer(root);
6003 host()->SetElementIdsForTesting();
6004
6005 SetupRootProperties(root.get());
6006 CopyProperties(root.get(), page_scale.get());
6007 CreateTransformNode(page_scale.get());
6008 CopyProperties(page_scale.get(), child1.get());
6009 CreateTransformNode(child1.get()).local = scale_transform_child1;
6010 CopyProperties(page_scale.get(), child2.get());
6011 CreateTransformNode(child2.get()).local = scale_transform_child2;
6012
Xianzhu Wang66e13e02019-09-18 20:39:126013 LayerTreeHost::ViewportPropertyIds viewport_property_ids;
6014 viewport_property_ids.page_scale_transform =
6015 page_scale->transform_tree_index();
6016 host()->RegisterViewportPropertyIds(viewport_property_ids);
6017
Xianzhu Wang35421fc2019-09-16 17:18:476018 TransformOperations scale;
6019 scale.AppendScale(5.f, 8.f, 3.f);
6020
6021 AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(),
6022 1.0, TransformOperations(), scale);
6023
6024 CommitAndActivate();
6025
6026 EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
6027 EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale());
6028 EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale());
6029 EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale());
6030
6031 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
Xianzhu Wangc62ecebf2019-08-31 15:54:136032 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale)));
6033 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
6034 EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2)));
[email protected]18e69652014-06-13 12:50:586035
[email protected]18e69652014-06-13 12:50:586036 // Changing page-scale would affect ideal_contents_scale and
6037 // maximum_animation_contents_scale.
6038
[email protected]18e69652014-06-13 12:50:586039 float device_scale_factor = 1.0f;
Xianzhu Wang66e13e02019-09-18 20:39:126040 host()->SetPageScaleFactorAndLimits(3.f, 3.f, 3.f);
6041 CommitAndActivate();
[email protected]18e69652014-06-13 12:50:586042
Xianzhu Wangc62ecebf2019-08-31 15:54:136043 EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale());
6044 EXPECT_FLOAT_EQ(3.f, ImplOf(page_scale)->GetIdealContentsScale());
6045 EXPECT_FLOAT_EQ(9.f, ImplOf(child1)->GetIdealContentsScale());
Xianzhu Wangc62ecebf2019-08-31 15:54:136046 EXPECT_FLOAT_EQ(15.f, ImplOf(child2)->GetIdealContentsScale());
[email protected]18e69652014-06-13 12:50:586047
Xianzhu Wangc62ecebf2019-08-31 15:54:136048 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
6049 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale)));
6050 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
6051 EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(ImplOf(child2)));
[email protected]18e69652014-06-13 12:50:586052
[email protected]18e69652014-06-13 12:50:586053 // Changing device-scale would affect ideal_contents_scale and
6054 // maximum_animation_contents_scale.
6055
6056 device_scale_factor = 4.0f;
Xianzhu Wang66e13e02019-09-18 20:39:126057 CommitAndActivate(device_scale_factor);
[email protected]18e69652014-06-13 12:50:586058
Xianzhu Wangc62ecebf2019-08-31 15:54:136059 EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale());
6060 EXPECT_FLOAT_EQ(12.f, ImplOf(page_scale)->GetIdealContentsScale());
6061 EXPECT_FLOAT_EQ(36.f, ImplOf(child1)->GetIdealContentsScale());
Xianzhu Wangc62ecebf2019-08-31 15:54:136062 EXPECT_FLOAT_EQ(60.f, ImplOf(child2)->GetIdealContentsScale());
[email protected]18e69652014-06-13 12:50:586063
Xianzhu Wangc62ecebf2019-08-31 15:54:136064 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root)));
6065 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale)));
6066 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1)));
6067 EXPECT_FLOAT_EQ(96.f, GetMaximumAnimationScale(ImplOf(child2)));
sunxdf468675e2016-06-30 23:56:186068}
6069
Xianzhu Wang66e13e02019-09-18 20:39:126070TEST_F(DrawPropertiesTest, AnimationScales) {
Xianzhu Wangd6a62d82019-09-09 22:35:366071 LayerImpl* root = root_layer();
Xianzhu Wang0340f14b2019-09-10 23:42:196072 auto* child1 = AddLayer<LayerImpl>();
6073 auto* child2 = AddLayer<LayerImpl>();
Xianzhu Wang5b429f02019-08-29 20:45:276074 SetElementIdsForTesting();
sunxdf468675e2016-06-30 23:56:186075
danakjf78fb272016-07-26 19:06:156076 gfx::Transform scale_transform_child1, scale_transform_child2;
sunxdf468675e2016-06-30 23:56:186077 scale_transform_child1.Scale(2, 3);
6078 scale_transform_child2.Scale(4, 5);
6079
Xianzhu Wang5b429f02019-08-29 20:45:276080 root->SetBounds(gfx::Size(1, 1));
6081 child1->SetBounds(gfx::Size(1, 1));
6082 child2->SetBounds(gfx::Size(1, 1));
6083
Xianzhu Wang5b429f02019-08-29 20:45:276084 CopyProperties(root, child1);
6085 CreateTransformNode(child1).local = scale_transform_child1;
6086 CopyProperties(child1, child2);
6087 CreateTransformNode(child2).local = scale_transform_child2;
sunxdf468675e2016-06-30 23:56:186088
6089 TransformOperations scale;
6090 scale.AppendScale(5.f, 8.f, 3.f);
6091
Xianzhu Wangc62ecebf2019-08-31 15:54:136092 AddAnimatedTransformToElementWithAnimation(
6093 child2->element_id(), timeline_impl(), 1.0, TransformOperations(), scale);
Xianzhu Wang66e13e02019-09-18 20:39:126094 UpdateActiveTreeDrawProperties();
sunxdf468675e2016-06-30 23:56:186095
Xianzhu Wang5b429f02019-08-29 20:45:276096 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root));
6097 EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1));
6098 EXPECT_FLOAT_EQ(24.f, GetMaximumAnimationScale(child2));
sunxdf468675e2016-06-30 23:56:186099
Xianzhu Wang5b429f02019-08-29 20:45:276100 EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(root));
6101 EXPECT_FLOAT_EQ(kNotScaled, GetStartingAnimationScale(child1));
6102 EXPECT_FLOAT_EQ(3.f, GetStartingAnimationScale(child2));
sunxdf468675e2016-06-30 23:56:186103
6104 // Correctly updates animation scale when layer property changes.
Xianzhu Wang5b429f02019-08-29 20:45:276105 SetTransform(child1, gfx::Transform());
6106 root->layer_tree_impl()->SetTransformMutated(child1->element_id(),
6107 gfx::Transform());
Xianzhu Wang66e13e02019-09-18 20:39:126108 UpdateActiveTreeDrawProperties();
Xianzhu Wang5b429f02019-08-29 20:45:276109 EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(child2));
6110 EXPECT_FLOAT_EQ(1.f, GetStartingAnimationScale(child2));
sunxdf468675e2016-06-30 23:56:186111
6112 // Do not update animation scale if already updated.
Xianzhu Wang5b429f02019-08-29 20:45:276113 host_impl()->active_tree()->property_trees()->SetAnimationScalesForTesting(
6114 child2->transform_tree_index(), 100.f, 100.f);
6115 EXPECT_FLOAT_EQ(100.f, GetMaximumAnimationScale(child2));
6116 EXPECT_FLOAT_EQ(100.f, GetStartingAnimationScale(child2));
sunxdf468675e2016-06-30 23:56:186117}
6118
Xianzhu Wang66e13e02019-09-18 20:39:126119TEST_F(DrawPropertiesTest, VisibleContentRectInChildRenderSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:366120 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276121 LayerImpl* clip = AddLayer<LayerImpl>();
6122 LayerImpl* content = AddLayer<LayerImpl>();
danakjf6069db2014-09-13 00:46:476123
danakjf78fb272016-07-26 19:06:156124 root->SetBounds(gfx::Size(768 / 2, 3000));
jaydasika6f972de2016-04-07 16:16:146125 root->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:156126 clip->SetBounds(gfx::Size(768 / 2, 10000));
danakjf6069db2014-09-13 00:46:476127 clip->SetMasksToBounds(true);
danakjf78fb272016-07-26 19:06:156128 content->SetBounds(gfx::Size(768 / 2, 10000));
jaydasika6f972de2016-04-07 16:16:146129 content->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:276130
Xianzhu Wang5b429f02019-08-29 20:45:276131 CopyProperties(root, clip);
6132 CreateClipNode(clip);
6133 CopyProperties(clip, content);
6134 CreateEffectNode(content).render_surface_reason = RenderSurfaceReason::kTest;
danakjf6069db2014-09-13 00:46:476135
Xianzhu Wang66e13e02019-09-18 20:39:126136 // Not calling UpdateActiveTreeDrawProperties() because we want to set a
6137 // special device viewport rect.
6138 host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(768, 582));
6139 float device_scale_factor = 2.f;
6140 host_impl()->active_tree()->SetDeviceScaleFactor(device_scale_factor);
6141 UpdateDrawProperties(host_impl()->active_tree());
danakjf6069db2014-09-13 00:46:476142
6143 // Layers in the root render surface have their visible content rect clipped
6144 // by the viewport.
Xianzhu Wang66e13e02019-09-18 20:39:126145 EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor),
6146 root->visible_layer_rect());
danakjf6069db2014-09-13 00:46:476147
6148 // Layers drawing to a child render surface should still have their visible
6149 // content rect clipped by the viewport.
Xianzhu Wang66e13e02019-09-18 20:39:126150 EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor),
6151 content->visible_layer_rect());
danakjf6069db2014-09-13 00:46:476152}
6153
Xianzhu Wang66e13e02019-09-18 20:39:126154TEST_F(DrawPropertiesTest, ViewportBoundsDeltaAffectVisibleContentRect) {
Xianzhu Wangc9badff2019-10-01 23:47:226155 gfx::Size container_size = gfx::Size(300, 500);
6156 gfx::Size scroll_size = gfx::Size(300, 1000);
timav599f4359d2014-12-05 00:12:226157
mdjones2ee41afd2016-10-27 16:50:206158 // Device viewport accomidated the root and the browser controls.
W. James MacLean7df854c2019-08-28 16:17:536159 gfx::Rect device_viewport_rect = gfx::Rect(300, 600);
timav599f4359d2014-12-05 00:12:226160
Xianzhu Wangc9badff2019-10-01 23:47:226161 LayerTreeImpl* active_tree = host_impl()->active_tree();
6162 active_tree->SetDeviceViewportRect(device_viewport_rect);
6163 active_tree->set_browser_controls_shrink_blink_size(true);
6164 active_tree->SetTopControlsHeight(50);
6165 active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 1.0f);
timav599f4359d2014-12-05 00:12:226166
Xianzhu Wangd6a62d82019-09-09 22:35:366167 LayerImpl* root = root_layer();
Xianzhu Wangc9badff2019-10-01 23:47:226168 root->SetBounds(device_viewport_rect.size());
6169 SetupViewport(root, container_size, scroll_size);
timav599f4359d2014-12-05 00:12:226170
Xianzhu Wangc9badff2019-10-01 23:47:226171 LayerImpl* scroll_layer = InnerViewportScrollLayer();
6172 scroll_layer->SetDrawsContent(true);
pdr23d381fd2017-04-25 21:06:316173
Sinan Sahinb6ffa912019-10-23 21:04:466174 active_tree->SetCurrentBrowserControlsShownRatio(1.0f, 1.0f);
Xianzhu Wangc9badff2019-10-01 23:47:226175 active_tree->UpdateViewportContainerSizes();
Xianzhu Wang66e13e02019-09-18 20:39:126176 UpdateActiveTreeDrawProperties();
Xianzhu Wangc9badff2019-10-01 23:47:226177 EXPECT_EQ(gfx::Rect(container_size), scroll_layer->visible_layer_rect());
timav599f4359d2014-12-05 00:12:226178
Sinan Sahinb6ffa912019-10-23 21:04:466179 active_tree->SetCurrentBrowserControlsShownRatio(0.0f, 0.0f);
Xianzhu Wangc9badff2019-10-01 23:47:226180 active_tree->UpdateViewportContainerSizes();
Xianzhu Wang66e13e02019-09-18 20:39:126181 UpdateActiveTreeDrawProperties();
timav599f4359d2014-12-05 00:12:226182
Xianzhu Wangc9badff2019-10-01 23:47:226183 gfx::Rect affected_by_delta(container_size.width(),
6184 container_size.height() + 50);
6185 EXPECT_EQ(affected_by_delta, scroll_layer->visible_layer_rect());
timav599f4359d2014-12-05 00:12:226186}
6187
Xianzhu Wang66e13e02019-09-18 20:39:126188TEST_F(DrawPropertiesTest, VisibleContentRectForAnimatedLayer) {
Xianzhu Wangc62ecebf2019-08-31 15:54:136189 host_impl()->CreatePendingTree();
6190 LayerImpl* root = EnsureRootLayerInPendingTree();
6191 LayerImpl* animated = AddLayerInPendingTree<LayerImpl>();
6192
6193 animated->SetDrawsContent(true);
6194 host_impl()->pending_tree()->SetElementIdsForTesting();
vollickef2ae922016-06-29 17:54:276195
danakjf78fb272016-07-26 19:06:156196 root->SetBounds(gfx::Size(100, 100));
danakjf78fb272016-07-26 19:06:156197 animated->SetBounds(gfx::Size(20, 20));
Xianzhu Wang5b429f02019-08-29 20:45:276198
Xianzhu Wang5b429f02019-08-29 20:45:276199 CopyProperties(root, animated);
Xianzhu Wangc62ecebf2019-08-31 15:54:136200 CreateEffectNode(animated).opacity = 0.f;
vollick7d83b452015-02-24 20:18:066201
Yi Guaa830ff2018-02-22 03:09:116202 AddOpacityTransitionToElementWithAnimation(
sunxd713aedbd2016-08-10 22:22:146203 animated->element_id(), timeline_impl(), 10.0, 0.f, 1.f, false);
Xianzhu Wang66e13e02019-09-18 20:39:126204 UpdatePendingTreeDrawProperties();
vollick7d83b452015-02-24 20:18:066205
sunxd713aedbd2016-08-10 22:22:146206 EXPECT_FALSE(animated->visible_layer_rect().IsEmpty());
vollick7d83b452015-02-24 20:18:066207}
6208
Xianzhu Wang66e13e02019-09-18 20:39:126209TEST_F(DrawPropertiesTest,
ajumaa92fdc12015-03-31 22:47:416210 VisibleContentRectForAnimatedLayerWithSingularTransform) {
jaydasikaaf0dcd172017-05-01 17:37:176211 host_impl()->CreatePendingTree();
Xianzhu Wang5b429f02019-08-29 20:45:276212 LayerImpl* root = EnsureRootLayerInPendingTree();
6213 LayerImpl* clip = AddLayerInPendingTree<LayerImpl>();
6214 LayerImpl* animated = AddLayerInPendingTree<LayerImpl>();
6215 LayerImpl* surface = AddLayerInPendingTree<LayerImpl>();
6216 LayerImpl* descendant_of_keyframe_model = AddLayerInPendingTree<LayerImpl>();
jaydasikaaf0dcd172017-05-01 17:37:176217 host_impl()->pending_tree()->SetElementIdsForTesting();
ajumaa92fdc12015-03-31 22:47:416218
jaydasikaaf0dcd172017-05-01 17:37:176219 root->SetDrawsContent(true);
sunxd713aedbd2016-08-10 22:22:146220 animated->SetDrawsContent(true);
6221 surface->SetDrawsContent(true);
Yi Gu3904dc22018-02-15 18:35:246222 descendant_of_keyframe_model->SetDrawsContent(true);
vollickef2ae922016-06-29 17:54:276223
ajumaa92fdc12015-03-31 22:47:416224 gfx::Transform uninvertible_matrix;
6225 uninvertible_matrix.Scale3d(6.f, 6.f, 0.f);
6226
danakjf78fb272016-07-26 19:06:156227 root->SetBounds(gfx::Size(100, 100));
6228 clip->SetBounds(gfx::Size(10, 10));
6229 clip->SetMasksToBounds(true);
danakjf78fb272016-07-26 19:06:156230 animated->SetBounds(gfx::Size(120, 120));
6231 surface->SetBounds(gfx::Size(100, 100));
Yi Gu3904dc22018-02-15 18:35:246232 descendant_of_keyframe_model->SetBounds(gfx::Size(200, 200));
ajumaa92fdc12015-03-31 22:47:416233
Xianzhu Wang5b429f02019-08-29 20:45:276234 CopyProperties(root, clip);
6235 CreateClipNode(clip);
6236 CopyProperties(clip, animated);
6237 CreateTransformNode(animated).local = uninvertible_matrix;
6238 CopyProperties(animated, surface);
6239 CreateTransformNode(surface);
6240 CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
6241 CopyProperties(surface, descendant_of_keyframe_model);
6242
ajumaa92fdc12015-03-31 22:47:416243 TransformOperations start_transform_operations;
6244 start_transform_operations.AppendMatrix(uninvertible_matrix);
6245 TransformOperations end_transform_operations;
6246
Yi Guaa830ff2018-02-22 03:09:116247 AddAnimatedTransformToElementWithAnimation(
sunxd713aedbd2016-08-10 22:22:146248 animated->element_id(), timeline_impl(), 10.0, start_transform_operations,
6249 end_transform_operations);
Xianzhu Wang66e13e02019-09-18 20:39:126250 UpdatePendingTreeDrawProperties();
jaydasikaaf0dcd172017-05-01 17:37:176251 // Since animated has singular transform, it is not be part of render
6252 // surface layer list but should be rastered.
ajuma651848a2017-05-01 21:23:456253 EXPECT_FALSE(animated->contributes_to_drawn_render_surface());
khushalsagar2fc1dbd2017-05-26 21:48:166254 EXPECT_TRUE(animated->raster_even_if_not_drawn());
ajumaa92fdc12015-03-31 22:47:416255
6256 // The animated layer has a singular transform and maps to a non-empty rect in
6257 // clipped target space, so is treated as fully visible.
sunxd713aedbd2016-08-10 22:22:146258 EXPECT_EQ(gfx::Rect(120, 120), animated->visible_layer_rect());
ajumaa92fdc12015-03-31 22:47:416259
6260 // The singular transform on |animated| is flattened when inherited by
6261 // |surface|, and this happens to make it invertible.
sunxd713aedbd2016-08-10 22:22:146262 EXPECT_EQ(gfx::Rect(2, 2), surface->visible_layer_rect());
Yi Gu3904dc22018-02-15 18:35:246263 EXPECT_EQ(gfx::Rect(2, 2),
6264 descendant_of_keyframe_model->visible_layer_rect());
ajumaa92fdc12015-03-31 22:47:416265
6266 gfx::Transform zero_matrix;
6267 zero_matrix.Scale3d(0.f, 0.f, 0.f);
weiliangcea09f3372017-03-29 16:43:246268 root->layer_tree_impl()->SetTransformMutated(animated->element_id(),
6269 zero_matrix);
Xianzhu Wang66e13e02019-09-18 20:39:126270 UpdatePendingTreeDrawProperties();
ajumaa92fdc12015-03-31 22:47:416271
jaydasika6ed869662016-09-21 14:29:596272 // The animated layer will be treated as fully visible when we combine clips
6273 // in screen space.
jaydasika3a6b14432017-03-21 23:11:196274 EXPECT_EQ(gfx::Rect(120, 120), animated->visible_layer_rect());
jaydasika6ed869662016-09-21 14:29:596275
ajumaa92fdc12015-03-31 22:47:416276 // This time, flattening does not make |animated|'s transform invertible. This
6277 // means the clip cannot be projected into |surface|'s space, so we treat
jaydasika67d7989e2015-08-06 21:55:346278 // |surface| and layers that draw into it as having empty visible rect.
jaydasika3a6b14432017-03-21 23:11:196279 EXPECT_EQ(gfx::Rect(100, 100), surface->visible_layer_rect());
Yi Gu3904dc22018-02-15 18:35:246280 EXPECT_EQ(gfx::Rect(200, 200),
6281 descendant_of_keyframe_model->visible_layer_rect());
jaydasikaaf0dcd172017-05-01 17:37:176282
6283 host_impl()->ActivateSyncTree();
6284 LayerImpl* active_root = host_impl()->active_tree()->LayerById(root->id());
Xianzhu Wang66e13e02019-09-18 20:39:126285 UpdateActiveTreeDrawProperties();
jaydasikaaf0dcd172017-05-01 17:37:176286
6287 // Since the animated has singular transform, it is not be part of render
6288 // surface layer list.
6289 LayerImpl* active_animated =
6290 host_impl()->active_tree()->LayerById(animated->id());
ajuma651848a2017-05-01 21:23:456291 EXPECT_TRUE(active_root->contributes_to_drawn_render_surface());
6292 EXPECT_FALSE(active_animated->contributes_to_drawn_render_surface());
jaydasikaaf0dcd172017-05-01 17:37:176293
6294 // Since animated has singular transform, it is not be part of render
6295 // surface layer list but should be rastered.
khushalsagar2fc1dbd2017-05-26 21:48:166296 EXPECT_TRUE(animated->raster_even_if_not_drawn());
jaydasikaaf0dcd172017-05-01 17:37:176297 EXPECT_EQ(gfx::Rect(120, 120), active_animated->visible_layer_rect());
ajumaa92fdc12015-03-31 22:47:416298}
6299
Xianzhu Wang66e13e02019-09-18 20:39:126300TEST_F(DrawPropertiesTest, ChangeTransformOrigin) {
Xianzhu Wangd6a62d82019-09-09 22:35:366301 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276302 LayerImpl* child = AddLayer<LayerImpl>();
ajumab0e0c1c2015-04-23 00:29:236303
ajumab0e0c1c2015-04-23 00:29:236304 gfx::Transform scale_matrix;
6305 scale_matrix.Scale(2.f, 2.f);
ajumab0e0c1c2015-04-23 00:29:236306
danakjf78fb272016-07-26 19:06:156307 root->SetBounds(gfx::Size(100, 100));
jaydasika6f972de2016-04-07 16:16:146308 root->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:156309 child->SetBounds(gfx::Size(10, 10));
jaydasika6f972de2016-04-07 16:16:146310 child->SetDrawsContent(true);
6311
Xianzhu Wang5b429f02019-08-29 20:45:276312 CopyProperties(root, child);
6313 CreateTransformNode(child).local = scale_matrix;
6314
Xianzhu Wang66e13e02019-09-18 20:39:126315 UpdateActiveTreeDrawProperties();
jaydasika6f972de2016-04-07 16:16:146316 EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());
ajumab0e0c1c2015-04-23 00:29:236317
Xianzhu Wang5b429f02019-08-29 20:45:276318 SetTransformOrigin(child, gfx::Point3F(10.f, 10.f, 10.f));
ajumab0e0c1c2015-04-23 00:29:236319
Xianzhu Wang66e13e02019-09-18 20:39:126320 UpdateActiveTreeDrawProperties();
jaydasika6f972de2016-04-07 16:16:146321 EXPECT_EQ(gfx::Rect(5, 5, 5, 5), child->visible_layer_rect());
ajumab0e0c1c2015-04-23 00:29:236322}
6323
Xianzhu Wang66e13e02019-09-18 20:39:126324TEST_F(DrawPropertiesTest, UpdateScrollChildPosition) {
Xianzhu Wangd6a62d82019-09-09 22:35:366325 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276326 LayerImpl* scroll_parent = AddLayer<LayerImpl>();
6327 LayerImpl* scroll_child = AddLayer<LayerImpl>();
danakjf78fb272016-07-26 19:06:156328
6329 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc8189212019-08-28 01:32:286330
danakjf78fb272016-07-26 19:06:156331 scroll_parent->SetBounds(gfx::Size(30, 30));
pdrd09da8e2017-08-01 17:54:526332 scroll_parent->SetScrollable(gfx::Size(50, 50));
6333 scroll_parent->SetElementId(
6334 LayerIdToElementIdForTesting(scroll_parent->id()));
danakjf78fb272016-07-26 19:06:156335 scroll_parent->SetDrawsContent(true);
6336
Xianzhu Wangc8189212019-08-28 01:32:286337 scroll_child->SetBounds(gfx::Size(40, 40));
6338 scroll_child->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:276339
Xianzhu Wang5b429f02019-08-29 20:45:276340 CopyProperties(root, scroll_parent);
6341 CreateTransformNode(scroll_parent);
6342 CreateScrollNode(scroll_parent);
Xianzhu Wangc8189212019-08-28 01:32:286343 CopyProperties(scroll_parent, scroll_child);
6344 CreateTransformNode(scroll_child).local.Scale(2.f, 2.f);
ajumaf09db8962015-04-24 21:55:346345
Xianzhu Wang66e13e02019-09-18 20:39:126346 UpdateActiveTreeDrawProperties();
jaydasika6f972de2016-04-07 16:16:146347 EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect());
ajumaf09db8962015-04-24 21:55:346348
Xianzhu Wangc8189212019-08-28 01:32:286349 SetScrollOffset(scroll_parent, gfx::ScrollOffset(0.f, 10.f));
Xianzhu Wang66e13e02019-09-18 20:39:126350 UpdateActiveTreeDrawProperties();
Philip Rogers4131a1c12017-07-21 19:36:506351 EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect());
pdrd09da8e2017-08-01 17:54:526352
Xianzhu Wang5b429f02019-08-29 20:45:276353 SetPostTranslation(scroll_child, gfx::Vector2dF(0, -10.f));
Xianzhu Wang66e13e02019-09-18 20:39:126354 UpdateActiveTreeDrawProperties();
pdrd09da8e2017-08-01 17:54:526355 EXPECT_EQ(gfx::Rect(0, 10, 25, 25), scroll_child->visible_layer_rect());
ajumaf09db8962015-04-24 21:55:346356}
6357
Xianzhu Wang5b429f02019-08-29 20:45:276358// Needs layer tree mode: copy request. Not using impl-side PropertyTreeBuilder.
Xianzhu Wang66e13e02019-09-18 20:39:126359TEST_F(DrawPropertiesTestWithLayerTree, HasCopyRequestsInTargetSubtree) {
loyso0940d412016-03-14 01:30:316360 scoped_refptr<Layer> root = Layer::Create();
6361 scoped_refptr<Layer> child1 = Layer::Create();
6362 scoped_refptr<Layer> child2 = Layer::Create();
6363 scoped_refptr<Layer> grandchild = Layer::Create();
6364 scoped_refptr<Layer> greatgrandchild = Layer::Create();
sunxded58688e2016-01-11 21:01:026365
6366 root->AddChild(child1);
6367 root->AddChild(child2);
6368 child1->AddChild(grandchild);
6369 grandchild->AddChild(greatgrandchild);
6370 host()->SetRootLayer(root);
6371
Xianzhu Wangc62ecebf2019-08-31 15:54:136372 root->SetBounds(gfx::Size(1, 1));
Yuri Wiitalab9ad27a2017-09-06 19:13:506373 child1->RequestCopyOfOutput(viz::CopyOutputRequest::CreateStubForTesting());
Fady Samueldfecb7d2017-07-26 11:41:046374 greatgrandchild->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:506375 viz::CopyOutputRequest::CreateStubForTesting());
sunxded58688e2016-01-11 21:01:026376 child2->SetOpacity(0.f);
Xianzhu Wang66e13e02019-09-18 20:39:126377 UpdateMainDrawProperties();
sunxded58688e2016-01-11 21:01:026378
danakj402b3892018-06-13 00:13:026379 EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get()));
6380 EXPECT_TRUE(LayerSubtreeHasCopyRequest(child1.get()));
6381 EXPECT_FALSE(LayerSubtreeHasCopyRequest(child2.get()));
6382 EXPECT_TRUE(LayerSubtreeHasCopyRequest(grandchild.get()));
6383 EXPECT_TRUE(LayerSubtreeHasCopyRequest(greatgrandchild.get()));
sunxded58688e2016-01-11 21:01:026384}
6385
Xianzhu Wang5b429f02019-08-29 20:45:276386// Needs layer tree mode: hide_layer_and_subtree, etc.
6387// Not using impl-side PropertyTreeBuilder.
Xianzhu Wang66e13e02019-09-18 20:39:126388TEST_F(DrawPropertiesTestWithLayerTree, SkippingSubtreeMain) {
chrishtr01539b802015-11-24 08:11:326389 FakeContentLayerClient client;
danakj762a2552018-06-12 20:57:286390
6391 scoped_refptr<Layer> root = Layer::Create();
chrishtr01539b802015-11-24 08:11:326392 client.set_bounds(root->bounds());
danakj762a2552018-06-12 20:57:286393 scoped_refptr<Layer> child = Layer::Create();
6394 child->SetIsDrawable(true);
6395 scoped_refptr<Layer> grandchild = Layer::Create();
6396 grandchild->SetIsDrawable(true);
danakj4e95f7632015-06-05 19:46:256397 scoped_refptr<FakePictureLayer> greatgrandchild(
loyso0940d412016-03-14 01:30:316398 FakePictureLayer::Create(&client));
danakjf78fb272016-07-26 19:06:156399
6400 root->SetBounds(gfx::Size(100, 100));
6401 child->SetBounds(gfx::Size(10, 10));
6402 grandchild->SetBounds(gfx::Size(10, 10));
6403 greatgrandchild->SetBounds(gfx::Size(10, 10));
vollick2175fae82015-04-27 21:18:126404
6405 root->AddChild(child);
6406 child->AddChild(grandchild);
6407 grandchild->AddChild(greatgrandchild);
ennea7b43c32015-06-18 20:01:336408 host()->SetRootLayer(root);
khushalsagarb69ba9452017-01-27 22:20:076409 host()->SetElementIdsForTesting();
vollickef2ae922016-06-29 17:54:276410
vollick2175fae82015-04-27 21:18:126411 // Check the non-skipped case.
Xianzhu Wang66e13e02019-09-18 20:39:126412 UpdateMainDrawProperties();
Xianzhu Wangc62ecebf2019-08-31 15:54:136413 EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));
vollick2175fae82015-04-27 21:18:126414
6415 // Now we will reset the visible rect from property trees for the grandchild,
6416 // and we will configure |child| in several ways that should force the subtree
6417 // to be skipped. The visible content rect for |grandchild| should, therefore,
6418 // remain empty.
vollick2175fae82015-04-27 21:18:126419 gfx::Transform singular;
6420 singular.matrix().set(0, 0, 0);
6421
6422 child->SetTransform(singular);
Xianzhu Wang66e13e02019-09-18 20:39:126423 UpdateMainDrawProperties();
Xianzhu Wangc62ecebf2019-08-31 15:54:136424 EXPECT_FALSE(UpdateLayerListContains(grandchild->id()));
danakjf78fb272016-07-26 19:06:156425 child->SetTransform(gfx::Transform());
vollick2175fae82015-04-27 21:18:126426
6427 child->SetHideLayerAndSubtree(true);
Xianzhu Wang66e13e02019-09-18 20:39:126428 UpdateMainDrawProperties();
Xianzhu Wangc62ecebf2019-08-31 15:54:136429 EXPECT_FALSE(UpdateLayerListContains(grandchild->id()));
vollick2175fae82015-04-27 21:18:126430 child->SetHideLayerAndSubtree(false);
6431
ajuma315a4782015-07-24 21:16:346432 gfx::Transform zero_z_scale;
6433 zero_z_scale.Scale3d(1, 1, 0);
6434 child->SetTransform(zero_z_scale);
6435
6436 // Add a transform animation with a start delay. Now, even though |child| has
6437 // a singular transform, the subtree should still get processed.
Yi Gu3904dc22018-02-15 18:35:246438 int keyframe_model_id = 0;
6439 std::unique_ptr<KeyframeModel> keyframe_model = KeyframeModel::Create(
danakj60bc3bc2016-04-09 00:24:486440 std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1.0)),
Yi Gu3904dc22018-02-15 18:35:246441 keyframe_model_id, 1, TargetProperty::TRANSFORM);
6442 keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
6443 keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
Yi Guaa830ff2018-02-22 03:09:116444 AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(),
6445 std::move(keyframe_model));
Xianzhu Wang66e13e02019-09-18 20:39:126446 UpdateMainDrawProperties();
Xianzhu Wangc62ecebf2019-08-31 15:54:136447 EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));
ajuma315a4782015-07-24 21:16:346448
Yi Gu4e1dce32018-07-04 20:52:156449 RemoveKeyframeModelFromElementWithExistingKeyframeEffect(
6450 child->element_id(), timeline(), keyframe_model_id);
danakjf78fb272016-07-26 19:06:156451 child->SetTransform(gfx::Transform());
vollick2175fae82015-04-27 21:18:126452 child->SetOpacity(0.f);
Xianzhu Wang66e13e02019-09-18 20:39:126453 UpdateMainDrawProperties();
Xianzhu Wangc62ecebf2019-08-31 15:54:136454 EXPECT_FALSE(UpdateLayerListContains(grandchild->id()));
vollick2175fae82015-04-27 21:18:126455
6456 // Now, even though child has zero opacity, we will configure |grandchild| and
6457 // |greatgrandchild| in several ways that should force the subtree to be
6458 // processed anyhow.
Yuri Wiitalab9ad27a2017-09-06 19:13:506459 grandchild->RequestCopyOfOutput(
6460 viz::CopyOutputRequest::CreateStubForTesting());
Xianzhu Wang66e13e02019-09-18 20:39:126461 UpdateMainDrawProperties();
Xianzhu Wangc62ecebf2019-08-31 15:54:136462 EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));
ajuma315a4782015-07-24 21:16:346463
6464 // Add an opacity animation with a start delay.
Yi Gu3904dc22018-02-15 18:35:246465 keyframe_model_id = 1;
6466 keyframe_model = KeyframeModel::Create(
danakj60bc3bc2016-04-09 00:24:486467 std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
Yi Gu3904dc22018-02-15 18:35:246468 keyframe_model_id, 1, TargetProperty::OPACITY);
6469 keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
6470 keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
6471 AddKeyframeModelToElementWithExistingKeyframeEffect(
6472 child->element_id(), timeline(), std::move(keyframe_model));
Xianzhu Wang66e13e02019-09-18 20:39:126473 UpdateMainDrawProperties();
Xianzhu Wangc62ecebf2019-08-31 15:54:136474 EXPECT_TRUE(UpdateLayerListContains(grandchild->id()));
vollick2175fae82015-04-27 21:18:126475}
6476
Xianzhu Wang5b429f02019-08-29 20:45:276477// Needs layer tree mode: hide_layer_and_subtree, etc.
Xianzhu Wang66e13e02019-09-18 20:39:126478TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayerImpl) {
Xianzhu Wangc62ecebf2019-08-31 15:54:136479 auto root = Layer::Create();
6480 host()->SetRootLayer(root);
6481 auto parent = Layer::Create();
6482 root->AddChild(parent);
6483 auto child = Layer::Create();
6484 parent->AddChild(child);
6485 auto grandchild = Layer::Create();
6486 child->AddChild(grandchild);
6487 FakeContentLayerClient client;
6488 auto greatgrandchild = PictureLayer::Create(&client);
6489 grandchild->AddChild(greatgrandchild);
vollick2175fae82015-04-27 21:18:126490
danakjf78fb272016-07-26 19:06:156491 root->SetBounds(gfx::Size(100, 100));
Xianzhu Wang1ff8cf382019-08-19 17:33:106492 parent->SetBounds(gfx::Size(100, 100));
danakjf78fb272016-07-26 19:06:156493 child->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc62ecebf2019-08-31 15:54:136494 child->SetIsDrawable(true);
danakjf78fb272016-07-26 19:06:156495 grandchild->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc62ecebf2019-08-31 15:54:136496 grandchild->SetIsDrawable(true);
6497 greatgrandchild->SetIsDrawable(true);
vollick2175fae82015-04-27 21:18:126498
Xianzhu Wangc62ecebf2019-08-31 15:54:136499 host()->SetElementIdsForTesting();
vollickef2ae922016-06-29 17:54:276500
vollick2175fae82015-04-27 21:18:126501 // Check the non-skipped case.
Xianzhu Wangc62ecebf2019-08-31 15:54:136502 CommitAndActivate();
6503 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect());
vollick2175fae82015-04-27 21:18:126504
6505 // Now we will reset the visible rect from property trees for the grandchild,
6506 // and we will configure |child| in several ways that should force the subtree
6507 // to be skipped. The visible content rect for |grandchild| should, therefore,
6508 // remain empty.
Xianzhu Wangc62ecebf2019-08-31 15:54:136509 ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
sunxd71aea3e2016-04-01 23:48:056510
vollick2175fae82015-04-27 21:18:126511 gfx::Transform singular;
6512 singular.matrix().set(0, 0, 0);
sunxd71aea3e2016-04-01 23:48:056513 // This line is used to make the results of skipping and not skipping layers
6514 // different.
6515 singular.matrix().set(0, 1, 1);
6516
6517 gfx::Transform rotate;
6518 rotate.Rotate(90);
6519
6520 gfx::Transform rotate_back_and_translate;
6521 rotate_back_and_translate.RotateAboutYAxis(180);
6522 rotate_back_and_translate.Translate(-10, 0);
vollick2175fae82015-04-27 21:18:126523
Xianzhu Wangc62ecebf2019-08-31 15:54:136524 child->SetTransform(singular);
6525 CommitAndActivate();
6526 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
6527 child->SetTransform(gfx::Transform());
vollick2175fae82015-04-27 21:18:126528
Xianzhu Wangc62ecebf2019-08-31 15:54:136529 child->SetHideLayerAndSubtree(true);
6530 CommitAndActivate();
6531 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
6532 child->SetHideLayerAndSubtree(false);
vollick2175fae82015-04-27 21:18:126533
Xianzhu Wangc62ecebf2019-08-31 15:54:136534 child->SetOpacity(0.f);
6535 CommitAndActivate();
6536 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
6537 child->SetOpacity(1.f);
vollick2175fae82015-04-27 21:18:126538
Xianzhu Wangc62ecebf2019-08-31 15:54:136539 parent->SetTransform(singular);
sunxd71aea3e2016-04-01 23:48:056540 // Force transform tree to have a node for child, so that ancestor's
6541 // invertible transform can be tested.
Xianzhu Wangc62ecebf2019-08-31 15:54:136542 child->SetTransform(rotate);
6543 CommitAndActivate();
6544 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
6545 parent->SetTransform(gfx::Transform());
6546 child->SetTransform(gfx::Transform());
sunxd71aea3e2016-04-01 23:48:056547
Xianzhu Wangc62ecebf2019-08-31 15:54:136548 parent->SetOpacity(0.f);
6549 child->SetOpacity(0.7f);
6550 CommitAndActivate();
6551 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
6552 parent->SetOpacity(1.f);
sunxd71aea3e2016-04-01 23:48:056553
Xianzhu Wangc62ecebf2019-08-31 15:54:136554 child->SetOpacity(0.f);
vollick2175fae82015-04-27 21:18:126555 // Now, even though child has zero opacity, we will configure |grandchild| and
6556 // |greatgrandchild| in several ways that should force the subtree to be
6557 // processed anyhow.
Xianzhu Wangc62ecebf2019-08-31 15:54:136558 grandchild->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:506559 viz::CopyOutputRequest::CreateStubForTesting());
Xianzhu Wangc62ecebf2019-08-31 15:54:136560 CommitAndActivate();
6561 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect());
ajumae6f541b2016-05-31 16:50:506562
Xianzhu Wangc62ecebf2019-08-31 15:54:136563 GetPropertyTrees(root.get())->effect_tree.ClearCopyRequests();
6564 child->SetOpacity(1.f);
sunxd71aea3e2016-04-01 23:48:056565
6566 // A double sided render surface with backface visible should not be skipped
Xianzhu Wangc62ecebf2019-08-31 15:54:136567 ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
6568 child->SetForceRenderSurfaceForTesting(true);
6569 child->SetDoubleSided(true);
6570 child->SetTransform(rotate_back_and_translate);
6571 CommitAndActivate();
6572 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(grandchild)->visible_layer_rect());
6573 child->SetTransform(gfx::Transform());
sunxd71aea3e2016-04-01 23:48:056574
danakj60bc3bc2016-04-09 00:24:486575 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
sunxd71aea3e2016-04-01 23:48:056576 KeyframedTransformAnimationCurve::Create());
6577 TransformOperations start;
6578 start.AppendTranslate(1.f, 2.f, 3.f);
6579 gfx::Transform transform;
6580 transform.Scale3d(1.0, 2.0, 3.0);
6581 TransformOperations operation;
6582 operation.AppendMatrix(transform);
6583 curve->AddKeyframe(
6584 TransformKeyframe::Create(base::TimeDelta(), start, nullptr));
6585 curve->AddKeyframe(TransformKeyframe::Create(
6586 base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
Yi Gu3904dc22018-02-15 18:35:246587 std::unique_ptr<KeyframeModel> transform_animation(
6588 KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
Yi Guaa830ff2018-02-22 03:09:116589 scoped_refptr<SingleKeyframeEffectAnimation> animation(
6590 SingleKeyframeEffectAnimation::Create(1));
Xianzhu Wangc62ecebf2019-08-31 15:54:136591 timeline()->AttachAnimation(animation);
Xianzhu Wang5b429f02019-08-29 20:45:276592 animation->AttachElementForKeyframeEffect(parent->element_id(),
Peter Mayo6b93dab2019-03-13 14:42:386593 animation->keyframe_effect()->id());
Yi Guaa830ff2018-02-22 03:09:116594 animation->AddKeyframeModel(std::move(transform_animation));
Xianzhu Wangc62ecebf2019-08-31 15:54:136595 ImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
6596 parent->SetTransform(singular);
6597 child->SetTransform(singular);
6598 CommitAndActivate();
6599 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(grandchild)->visible_layer_rect());
sunxd71aea3e2016-04-01 23:48:056600}
6601
Peter Mayo6b93dab2019-03-13 14:42:386602// This tests for correctness of an optimization. If a node in the tree
6603// maps all possible spaces to a single point (ie has a singular transform)
6604// we can ignore the size of all its children. We need to make sure that
6605// we don't do this if an animation can replace this transform in the
6606// compositor without recomputing the trees.
Xianzhu Wang66e13e02019-09-18 20:39:126607TEST_F(DrawPropertiesTest, LayerSkippingInSubtreeOfSingularTransform) {
Peter Mayo6b93dab2019-03-13 14:42:386608 // Set up a transform animation
danakj25c52c32016-04-12 21:51:086609 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
jaydasikaf187b06b2016-04-11 23:30:276610 KeyframedTransformAnimationCurve::Create());
6611 TransformOperations start;
6612 start.AppendTranslate(1.f, 2.f, 3.f);
6613 gfx::Transform transform;
6614 transform.Scale3d(1.0, 2.0, 3.0);
6615 TransformOperations operation;
6616 operation.AppendMatrix(transform);
6617 curve->AddKeyframe(
6618 TransformKeyframe::Create(base::TimeDelta(), start, nullptr));
6619 curve->AddKeyframe(TransformKeyframe::Create(
6620 base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
Yi Gu3904dc22018-02-15 18:35:246621 std::unique_ptr<KeyframeModel> transform_animation(
6622 KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
Yi Guaa830ff2018-02-22 03:09:116623 scoped_refptr<SingleKeyframeEffectAnimation> animation(
6624 SingleKeyframeEffectAnimation::Create(1));
Peter Mayo6b93dab2019-03-13 14:42:386625 timeline_impl()->AttachAnimation(animation);
Yi Guaa830ff2018-02-22 03:09:116626 animation->AddKeyframeModel(std::move(transform_animation));
jaydasikaf187b06b2016-04-11 23:30:276627
Peter Mayo6b93dab2019-03-13 14:42:386628 // Set up some layers to have a tree.
Xianzhu Wangd6a62d82019-09-09 22:35:366629 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276630 LayerImpl* child = AddLayer<LayerImpl>();
6631 LayerImpl* grand_child = AddLayer<LayerImpl>();
jaydasikaf187b06b2016-04-11 23:30:276632
Peter Mayo6b93dab2019-03-13 14:42:386633 SetElementIdsForTesting();
6634
6635 // If these are not on the same host we are doomed to fail.
6636 ASSERT_EQ(timeline_impl()->animation_host(),
6637 child->layer_tree_impl()->mutator_host());
6638
6639 // A non-invertible matrix for use later.
6640 gfx::Transform singular;
6641 singular.matrix().set(0, 0, 0);
6642 singular.matrix().set(0, 1, 1);
6643
6644 root->SetBounds(gfx::Size(10, 10));
6645 child->SetBounds(gfx::Size(10, 10));
6646 child->SetDrawsContent(true);
6647 grand_child->SetBounds(gfx::Size(10, 10));
6648 grand_child->SetDrawsContent(true);
6649
6650 // Check that we set the visible sizes as expected in CalculateDrawProperties
6651 grand_child->set_visible_layer_rect(gfx::Rect());
6652 child->set_visible_layer_rect(gfx::Rect());
Xianzhu Wang5b429f02019-08-29 20:45:276653
Xianzhu Wang5b429f02019-08-29 20:45:276654 CopyProperties(root, child);
6655 CreateTransformNode(child);
6656 CopyProperties(child, grand_child);
6657
Xianzhu Wang66e13e02019-09-18 20:39:126658 UpdateActiveTreeDrawProperties();
Peter Mayo6b93dab2019-03-13 14:42:386659 ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect());
6660 ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());
6661
6662 // See if we optimize out irrelevant pieces of work.
Xianzhu Wang5b429f02019-08-29 20:45:276663 SetTransform(child, singular);
Peter Mayo6b93dab2019-03-13 14:42:386664 grand_child->set_visible_layer_rect(gfx::Rect());
6665 child->set_visible_layer_rect(gfx::Rect());
Xianzhu Wang66e13e02019-09-18 20:39:126666 UpdateActiveTreeDrawProperties();
Peter Mayo6b93dab2019-03-13 14:42:386667 EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect());
6668 EXPECT_EQ(gfx::Rect(), child->visible_layer_rect());
6669
6670 // Check that undoing the transform is still valid (memoryless enough)
Xianzhu Wang5b429f02019-08-29 20:45:276671 SetTransform(child, gfx::Transform());
Peter Mayo6b93dab2019-03-13 14:42:386672 grand_child->set_visible_layer_rect(gfx::Rect());
6673 child->set_visible_layer_rect(gfx::Rect());
6674 root->layer_tree_impl()->property_trees()->needs_rebuild = true;
Xianzhu Wang66e13e02019-09-18 20:39:126675 UpdateActiveTreeDrawProperties();
Peter Mayo6b93dab2019-03-13 14:42:386676 ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect());
6677 ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());
6678
6679 // If the transform is singular, but there is an animation on it, we
6680 // should not skip the subtree. Note that the animation has not started or
6681 // ticked, there is also code along that path. This is not its test.
6682 animation->AttachElementForKeyframeEffect(child->element_id(),
6683 animation->keyframe_effect()->id());
Xianzhu Wang5b429f02019-08-29 20:45:276684 SetTransform(child, singular);
Peter Mayo6b93dab2019-03-13 14:42:386685 grand_child->set_visible_layer_rect(gfx::Rect(1, 1));
6686 child->set_visible_layer_rect(gfx::Rect(1, 1));
Xianzhu Wang66e13e02019-09-18 20:39:126687 UpdateActiveTreeDrawProperties();
Peter Mayo6b93dab2019-03-13 14:42:386688 EXPECT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect());
6689 EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect());
jaydasikaf187b06b2016-04-11 23:30:276690}
6691
Peter Mayo6b93dab2019-03-13 14:42:386692// This tests that we skip computing the visible areas for the subtree
6693// rooted at nodes with constant zero opacity.
Xianzhu Wang66e13e02019-09-18 20:39:126694TEST_F(DrawPropertiesTestWithLayerTree, SkippingPendingLayerImpl) {
Xianzhu Wangc62ecebf2019-08-31 15:54:136695 auto root = Layer::Create();
6696 auto child = Layer::Create();
6697 auto grandchild = Layer::Create();
6698 FakeContentLayerClient client;
6699 auto greatgrandchild = PictureLayer::Create(&client);
sunxd71aea3e2016-04-01 23:48:056700
danakjf78fb272016-07-26 19:06:156701 root->SetBounds(gfx::Size(100, 100));
6702 child->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc62ecebf2019-08-31 15:54:136703 child->SetIsDrawable(true);
danakjf78fb272016-07-26 19:06:156704 grandchild->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc62ecebf2019-08-31 15:54:136705 grandchild->SetIsDrawable(true);
6706 greatgrandchild->SetIsDrawable(true);
sunxd71aea3e2016-04-01 23:48:056707
Xianzhu Wangc62ecebf2019-08-31 15:54:136708 child->AddChild(grandchild);
6709 root->AddChild(child);
6710 host()->SetRootLayer(root);
6711 host()->SetElementIdsForTesting();
sunxd71aea3e2016-04-01 23:48:056712
6713 // Check the non-skipped case.
Xianzhu Wangc62ecebf2019-08-31 15:54:136714 root->SetOpacity(1.f);
6715 Commit();
6716 ASSERT_EQ(gfx::Rect(10, 10), PendingImplOf(grandchild)->visible_layer_rect());
sunxd71aea3e2016-04-01 23:48:056717
Peter Mayo6b93dab2019-03-13 14:42:386718 // Check the skipped case.
Xianzhu Wangc62ecebf2019-08-31 15:54:136719 root->SetOpacity(0.f);
6720 PendingImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
6721 Commit();
6722 EXPECT_EQ(gfx::Rect(), PendingImplOf(grandchild)->visible_layer_rect());
Peter Mayo6b93dab2019-03-13 14:42:386723
6724 // Check the animated case is not skipped.
danakj60bc3bc2016-04-09 00:24:486725 std::unique_ptr<KeyframedFloatAnimationCurve> curve(
sunxd71aea3e2016-04-01 23:48:056726 KeyframedFloatAnimationCurve::Create());
loyso1e4e7ee2016-06-03 03:04:496727 std::unique_ptr<TimingFunction> func =
6728 CubicBezierTimingFunction::CreatePreset(
6729 CubicBezierTimingFunction::EaseType::EASE);
sunxd71aea3e2016-04-01 23:48:056730 curve->AddKeyframe(
6731 FloatKeyframe::Create(base::TimeDelta(), 0.9f, std::move(func)));
6732 curve->AddKeyframe(
6733 FloatKeyframe::Create(base::TimeDelta::FromSecondsD(1.0), 0.3f, nullptr));
Yi Gu3904dc22018-02-15 18:35:246734 std::unique_ptr<KeyframeModel> keyframe_model(
6735 KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::OPACITY));
Yi Guaa830ff2018-02-22 03:09:116736 scoped_refptr<SingleKeyframeEffectAnimation> animation(
6737 SingleKeyframeEffectAnimation::Create(1));
Xianzhu Wangc62ecebf2019-08-31 15:54:136738 timeline()->AttachAnimation(animation);
Yi Guaa830ff2018-02-22 03:09:116739 animation->AddKeyframeModel(std::move(keyframe_model));
Xianzhu Wangc62ecebf2019-08-31 15:54:136740 animation->AttachElementForKeyframeEffect(root->element_id(),
Peter Mayo6b93dab2019-03-13 14:42:386741 animation->keyframe_effect()->id());
6742 // Repeat the calculation invocation.
Xianzhu Wangc62ecebf2019-08-31 15:54:136743 PendingImplOf(grandchild)->set_visible_layer_rect(gfx::Rect());
6744 Commit();
6745 EXPECT_EQ(gfx::Rect(10, 10), PendingImplOf(grandchild)->visible_layer_rect());
vollick2175fae82015-04-27 21:18:126746}
6747
Xianzhu Wang5b429f02019-08-29 20:45:276748// Needs layer tree mode: hide_layer_and_subtree.
Xianzhu Wang66e13e02019-09-18 20:39:126749TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayer) {
Xianzhu Wangc62ecebf2019-08-31 15:54:136750 auto root = Layer::Create();
6751 host()->SetRootLayer(root);
6752 auto child = Layer::Create();
6753 root->AddChild(child);
vollick2175fae82015-04-27 21:18:126754
danakjf78fb272016-07-26 19:06:156755 root->SetBounds(gfx::Size(100, 100));
6756 child->SetBounds(gfx::Size(10, 10));
Xianzhu Wangc62ecebf2019-08-31 15:54:136757 child->SetIsDrawable(true);
vollick2175fae82015-04-27 21:18:126758
Xianzhu Wangc62ecebf2019-08-31 15:54:136759 CommitAndActivate();
vollick2175fae82015-04-27 21:18:126760
Xianzhu Wangc62ecebf2019-08-31 15:54:136761 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(child)->visible_layer_rect());
6762 ImplOf(child)->set_visible_layer_rect(gfx::Rect());
6763
6764 child->SetHideLayerAndSubtree(true);
6765 CommitAndActivate();
6766 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
6767 child->SetHideLayerAndSubtree(false);
vollick2175fae82015-04-27 21:18:126768
6769 child->SetBounds(gfx::Size());
Xianzhu Wangc62ecebf2019-08-31 15:54:136770 CommitAndActivate();
6771 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
vollick2175fae82015-04-27 21:18:126772 child->SetBounds(gfx::Size(10, 10));
6773
6774 gfx::Transform rotate;
Xianzhu Wangc62ecebf2019-08-31 15:54:136775 child->SetDoubleSided(false);
vollick2175fae82015-04-27 21:18:126776 rotate.RotateAboutXAxis(180.f);
Xianzhu Wangc62ecebf2019-08-31 15:54:136777 child->SetTransform(rotate);
6778 CommitAndActivate();
6779 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
6780 child->SetDoubleSided(true);
6781 child->SetTransform(gfx::Transform());
vollick2175fae82015-04-27 21:18:126782
Xianzhu Wangc62ecebf2019-08-31 15:54:136783 child->SetOpacity(0.f);
6784 CommitAndActivate();
6785 EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect());
vollick2175fae82015-04-27 21:18:126786}
6787
Xianzhu Wang66e13e02019-09-18 20:39:126788TEST_F(DrawPropertiesTest, TransformOfParentClipNodeAncestorOfTarget) {
jaydasika67d7989e2015-08-06 21:55:346789 // Ensure that when parent clip node's transform is an ancestor of current
6790 // clip node's target, clip is 'projected' from parent space to current
6791 // target space and visible rects are calculated correctly.
Xianzhu Wangd6a62d82019-09-09 22:35:366792 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276793 LayerImpl* clip_layer = AddLayer<LayerImpl>();
6794 LayerImpl* target_layer = AddLayer<LayerImpl>();
6795 LayerImpl* test_layer = AddLayer<LayerImpl>();
jaydasika67d7989e2015-08-06 21:55:346796
jaydasika67d7989e2015-08-06 21:55:346797 gfx::Transform transform;
6798 transform.RotateAboutYAxis(45);
danakjf78fb272016-07-26 19:06:156799
6800 root->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:156801 clip_layer->SetBounds(gfx::Size(30, 30));
jaydasika67d7989e2015-08-06 21:55:346802 clip_layer->SetMasksToBounds(true);
danakjf78fb272016-07-26 19:06:156803 target_layer->SetBounds(gfx::Size(30, 30));
jaydasika67d7989e2015-08-06 21:55:346804 target_layer->SetMasksToBounds(true);
danakjf78fb272016-07-26 19:06:156805 test_layer->SetBounds(gfx::Size(30, 30));
jaydasika67d7989e2015-08-06 21:55:346806 test_layer->SetDrawsContent(true);
6807
Xianzhu Wang5b429f02019-08-29 20:45:276808 CopyProperties(root, clip_layer);
6809 CreateTransformNode(clip_layer).local = transform;
6810 CreateClipNode(clip_layer);
6811 CopyProperties(clip_layer, target_layer);
6812 CreateTransformNode(target_layer).local = transform;
6813 CreateClipNode(target_layer);
6814 CopyProperties(target_layer, test_layer);
6815
Xianzhu Wang66e13e02019-09-18 20:39:126816 UpdateActiveTreeDrawProperties();
jaydasika67d7989e2015-08-06 21:55:346817
weiliangcc97575c2016-03-03 18:34:276818 EXPECT_EQ(gfx::Rect(30, 30), test_layer->visible_layer_rect());
jaydasika67d7989e2015-08-06 21:55:346819}
6820
Xianzhu Wang66e13e02019-09-18 20:39:126821TEST_F(DrawPropertiesTest, RenderSurfaceWithUnclippedDescendantsClipsSubtree) {
jaydasika7d5c1ed2015-08-14 14:27:026822 // Ensure clip rect is calculated correctly when render surface has unclipped
6823 // descendants.
Xianzhu Wangd6a62d82019-09-09 22:35:366824 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276825 LayerImpl* clip_parent = AddLayer<LayerImpl>();
6826 LayerImpl* between_clip_parent_and_child = AddLayer<LayerImpl>();
6827 LayerImpl* render_surface = AddLayer<LayerImpl>();
6828 LayerImpl* test_layer = AddLayer<LayerImpl>();
jaydasika7d5c1ed2015-08-14 14:27:026829
danakjf78fb272016-07-26 19:06:156830 root->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:156831 clip_parent->SetBounds(gfx::Size(30, 30));
Xianzhu Wang5b429f02019-08-29 20:45:276832 between_clip_parent_and_child->SetBounds(gfx::Size(30, 30));
6833 render_surface->SetBounds(gfx::Size(30, 30));
6834 test_layer->SetBounds(gfx::Size(30, 30));
6835 test_layer->SetDrawsContent(true);
6836
Xianzhu Wangc8189212019-08-28 01:32:286837 CopyProperties(root, clip_parent);
6838 CreateTransformNode(clip_parent).local.Translate(2, 2);
6839 CreateClipNode(clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:286840 CopyProperties(clip_parent, between_clip_parent_and_child);
6841 CreateClipNode(between_clip_parent_and_child);
6842 CreateTransformNode(between_clip_parent_and_child).local.Translate(2, 2);
6843 CreateClipNode(between_clip_parent_and_child);
Xianzhu Wangc8189212019-08-28 01:32:286844 CopyProperties(between_clip_parent_and_child, render_surface);
6845 CreateEffectNode(render_surface).render_surface_reason =
6846 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:286847 CopyProperties(render_surface, test_layer);
6848 test_layer->SetClipTreeIndex(clip_parent->clip_tree_index());
jaydasika7d5c1ed2015-08-14 14:27:026849
Xianzhu Wang66e13e02019-09-18 20:39:126850 UpdateActiveTreeDrawProperties();
jaydasika7d5c1ed2015-08-14 14:27:026851
weiliangcbb2e8642016-03-04 00:24:426852 EXPECT_TRUE(test_layer->is_clipped());
weiliangc189c1a12016-04-11 16:16:256853 EXPECT_FALSE(test_layer->render_target()->is_clipped());
weiliangc0b41eaf2016-03-14 21:35:566854 EXPECT_EQ(gfx::Rect(-2, -2, 30, 30), test_layer->clip_rect());
6855 EXPECT_EQ(gfx::Rect(28, 28), test_layer->drawable_content_rect());
jaydasika7d5c1ed2015-08-14 14:27:026856}
6857
Xianzhu Wang66e13e02019-09-18 20:39:126858TEST_F(DrawPropertiesTest,
ajuma01734dd02015-10-07 01:22:086859 RenderSurfaceWithUnclippedDescendantsButDoesntApplyOwnClip) {
6860 // Ensure that the visible layer rect of a descendant of a surface with
6861 // unclipped descendants is computed correctly, when the surface doesn't apply
6862 // a clip.
Xianzhu Wangd6a62d82019-09-09 22:35:366863 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276864 LayerImpl* clip_parent = AddLayer<LayerImpl>();
6865 LayerImpl* render_surface = AddLayer<LayerImpl>();
6866 LayerImpl* clip_child = AddLayer<LayerImpl>();
6867 LayerImpl* child = AddLayer<LayerImpl>();
ajuma01734dd02015-10-07 01:22:086868
danakjf78fb272016-07-26 19:06:156869 root->SetBounds(gfx::Size(30, 10));
6870 clip_parent->SetBounds(gfx::Size(30, 30));
6871 render_surface->SetBounds(gfx::Size(10, 15));
Xianzhu Wang5b429f02019-08-29 20:45:276872 clip_child->SetBounds(gfx::Size(10, 10));
6873 clip_child->SetDrawsContent(true);
6874 child->SetBounds(gfx::Size(40, 40));
6875 child->SetDrawsContent(true);
6876
Xianzhu Wang5b429f02019-08-29 20:45:276877 CopyProperties(root, clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:286878 CopyProperties(clip_parent, render_surface);
6879 CreateEffectNode(render_surface).render_surface_reason =
6880 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:286881 CopyProperties(render_surface, clip_child);
6882 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
Xianzhu Wangc8189212019-08-28 01:32:286883 CopyProperties(clip_child, child);
ajuma01734dd02015-10-07 01:22:086884
Xianzhu Wang66e13e02019-09-18 20:39:126885 UpdateActiveTreeDrawProperties();
jaydasika94bebdd2016-09-16 22:11:186886 EXPECT_EQ(gfx::Rect(30, 10), child->visible_layer_rect());
ajuma01734dd02015-10-07 01:22:086887}
6888
Xianzhu Wang66e13e02019-09-18 20:39:126889TEST_F(DrawPropertiesTest,
jaydasika571dd2cf2015-09-25 20:55:426890 RenderSurfaceClipsSubtreeAndHasUnclippedDescendants) {
Xianzhu Wangd6a62d82019-09-09 22:35:366891 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276892 LayerImpl* clip_parent = AddLayer<LayerImpl>();
6893 LayerImpl* render_surface = AddLayer<LayerImpl>();
6894 LayerImpl* test_layer1 = AddLayer<LayerImpl>();
6895 LayerImpl* clip_child = AddLayer<LayerImpl>();
6896 LayerImpl* test_layer2 = AddLayer<LayerImpl>();
jaydasika571dd2cf2015-09-25 20:55:426897
danakjf78fb272016-07-26 19:06:156898 root->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:156899 clip_parent->SetBounds(gfx::Size(30, 30));
6900 render_surface->SetBounds(gfx::Size(50, 50));
jaydasika571dd2cf2015-09-25 20:55:426901 render_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:276902 test_layer1->SetBounds(gfx::Size(50, 50));
6903 test_layer1->SetDrawsContent(true);
6904 clip_child->SetBounds(gfx::Size(50, 50));
6905 clip_child->SetDrawsContent(true);
6906 test_layer2->SetBounds(gfx::Size(50, 50));
6907 test_layer2->SetDrawsContent(true);
6908
Xianzhu Wang5b429f02019-08-29 20:45:276909 CreateClipNode(root);
6910 CopyProperties(root, clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:286911 CopyProperties(clip_parent, render_surface);
6912 CreateEffectNode(render_surface).render_surface_reason =
6913 RenderSurfaceReason::kTest;
6914 CreateClipNode(render_surface);
Xianzhu Wangc8189212019-08-28 01:32:286915 CopyProperties(render_surface, test_layer1);
Xianzhu Wangc8189212019-08-28 01:32:286916 CopyProperties(test_layer1, clip_child);
6917 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
Xianzhu Wangc8189212019-08-28 01:32:286918 CopyProperties(clip_child, test_layer2);
jaydasika571dd2cf2015-09-25 20:55:426919
Xianzhu Wang66e13e02019-09-18 20:39:126920 UpdateActiveTreeDrawProperties();
weiliangc0e13ba602016-03-12 04:53:566921 EXPECT_EQ(gfx::Rect(30, 30), render_surface->visible_layer_rect());
6922 EXPECT_EQ(gfx::Rect(30, 30), test_layer1->visible_layer_rect());
jaydasika571dd2cf2015-09-25 20:55:426923 EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect());
6924 EXPECT_EQ(gfx::Rect(30, 30), test_layer2->visible_layer_rect());
6925}
6926
Xianzhu Wang66e13e02019-09-18 20:39:126927TEST_F(DrawPropertiesTest, UnclippedClipParent) {
Xianzhu Wangd6a62d82019-09-09 22:35:366928 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276929 LayerImpl* clip_parent = AddLayer<LayerImpl>();
6930 LayerImpl* render_surface = AddLayer<LayerImpl>();
6931 LayerImpl* clip_child = AddLayer<LayerImpl>();
ajumae2b7a5c2015-09-30 21:41:426932
danakjf78fb272016-07-26 19:06:156933 root->SetBounds(gfx::Size(50, 50));
6934 clip_parent->SetBounds(gfx::Size(50, 50));
ajumae2b7a5c2015-09-30 21:41:426935 clip_parent->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:156936 render_surface->SetBounds(gfx::Size(30, 30));
ajumae2b7a5c2015-09-30 21:41:426937 render_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:276938 clip_child->SetBounds(gfx::Size(50, 50));
6939 clip_child->SetDrawsContent(true);
6940
Xianzhu Wang5b429f02019-08-29 20:45:276941 CopyProperties(root, clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:286942 CopyProperties(clip_parent, render_surface);
6943 CreateEffectNode(render_surface).render_surface_reason =
6944 RenderSurfaceReason::kTest;
6945 CreateClipNode(render_surface);
Xianzhu Wangc8189212019-08-28 01:32:286946 CopyProperties(render_surface, clip_child);
6947 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
ajumae2b7a5c2015-09-30 21:41:426948
Xianzhu Wang66e13e02019-09-18 20:39:126949 UpdateActiveTreeDrawProperties();
ajumae2b7a5c2015-09-30 21:41:426950
6951 // The clip child should inherit its clip parent's clipping state, not its
6952 // tree parent's clipping state.
6953 EXPECT_FALSE(clip_parent->is_clipped());
6954 EXPECT_TRUE(render_surface->is_clipped());
6955 EXPECT_FALSE(clip_child->is_clipped());
6956}
6957
Xianzhu Wang66e13e02019-09-18 20:39:126958TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWithMultipleSurfaces) {
jaydasika77a4a072015-10-20 21:47:276959 // Tests the value of render surface content rect when we have multiple types
6960 // of surfaces : unclipped surfaces, surfaces with unclipped surfaces and
6961 // clipped surfaces.
Xianzhu Wangd6a62d82019-09-09 22:35:366962 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:276963 LayerImpl* unclipped_surface = AddLayer<LayerImpl>();
6964 LayerImpl* clip_parent = AddLayer<LayerImpl>();
6965 LayerImpl* clip_layer = AddLayer<LayerImpl>();
6966 LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
6967 LayerImpl* unclipped_desc_surface2 = AddLayer<LayerImpl>();
6968 LayerImpl* clip_child = AddLayer<LayerImpl>();
6969 LayerImpl* clipped_surface = AddLayer<LayerImpl>();
jaydasika77a4a072015-10-20 21:47:276970
danakjf78fb272016-07-26 19:06:156971 root->SetBounds(gfx::Size(80, 80));
Xianzhu Wangc8189212019-08-28 01:32:286972
danakjf78fb272016-07-26 19:06:156973 unclipped_surface->SetBounds(gfx::Size(50, 50));
danakjf78fb272016-07-26 19:06:156974 unclipped_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:276975 clip_parent->SetBounds(gfx::Size(50, 50));
6976 clip_layer->SetBounds(gfx::Size(100, 100));
6977 unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
6978 unclipped_desc_surface->SetDrawsContent(true);
6979 unclipped_desc_surface2->SetBounds(gfx::Size(60, 60));
6980 unclipped_desc_surface2->SetDrawsContent(true);
6981 clip_child->SetBounds(gfx::Size(100, 100));
6982 clipped_surface->SetBounds(gfx::Size(70, 70));
6983 clipped_surface->SetDrawsContent(true);
6984
Xianzhu Wangc8189212019-08-28 01:32:286985 CopyProperties(root, unclipped_surface);
6986 CreateEffectNode(unclipped_surface).render_surface_reason =
6987 RenderSurfaceReason::kTest;
6988 CreateClipNode(unclipped_surface);
Xianzhu Wangc8189212019-08-28 01:32:286989 CopyProperties(unclipped_surface, clip_parent);
6990 CreateClipNode(clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:286991 CopyProperties(clip_parent, clip_layer);
6992 CreateClipNode(clip_layer);
Xianzhu Wangc8189212019-08-28 01:32:286993 CopyProperties(clip_layer, unclipped_desc_surface);
6994 CreateEffectNode(unclipped_desc_surface).render_surface_reason =
6995 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:286996 CopyProperties(unclipped_desc_surface, unclipped_desc_surface2);
6997 CreateEffectNode(unclipped_desc_surface2).render_surface_reason =
6998 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:286999 CopyProperties(unclipped_desc_surface2, clip_child);
7000 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
Xianzhu Wangc8189212019-08-28 01:32:287001 CopyProperties(clip_child, clipped_surface);
7002 CreateEffectNode(clipped_surface).render_surface_reason =
7003 RenderSurfaceReason::kTest;
jaydasika77a4a072015-10-20 21:47:277004
Xianzhu Wang66e13e02019-09-18 20:39:127005 UpdateActiveTreeDrawProperties();
jaydasika77a4a072015-10-20 21:47:277006 EXPECT_EQ(gfx::Rect(50, 50),
chrishtr7e3aaf22017-05-04 15:04:017007 GetRenderSurface(unclipped_surface)->content_rect());
weiliangc0e13ba602016-03-12 04:53:567008 EXPECT_EQ(gfx::Rect(50, 50),
chrishtr7e3aaf22017-05-04 15:04:017009 GetRenderSurface(unclipped_desc_surface)->content_rect());
jaydasika1553a142017-04-05 00:37:097010 EXPECT_EQ(gfx::Rect(60, 60),
chrishtr7e3aaf22017-05-04 15:04:017011 GetRenderSurface(unclipped_desc_surface2)->content_rect());
jaydasika77a4a072015-10-20 21:47:277012 EXPECT_EQ(gfx::Rect(50, 50),
chrishtr7e3aaf22017-05-04 15:04:017013 GetRenderSurface(clipped_surface)->content_rect());
jaydasika77a4a072015-10-20 21:47:277014}
7015
Xianzhu Wang66e13e02019-09-18 20:39:127016TEST_F(DrawPropertiesTest, ClipBetweenClipChildTargetAndClipParentTarget) {
jaydasika77a4a072015-10-20 21:47:277017 // Tests the value of render surface content rect when we have a layer that
7018 // clips between the clip parent's target and clip child's target.
Xianzhu Wangd6a62d82019-09-09 22:35:367019 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277020 LayerImpl* surface = AddLayer<LayerImpl>();
7021 LayerImpl* clip_layer = AddLayer<LayerImpl>();
7022 LayerImpl* clip_parent = AddLayer<LayerImpl>();
7023 LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
7024 LayerImpl* clip_child = AddLayer<LayerImpl>();
jaydasika778cb272016-08-15 19:00:547025
danakjf78fb272016-07-26 19:06:157026 root->SetBounds(gfx::Size(100, 100));
7027 surface->SetBounds(gfx::Size(100, 100));
Xianzhu Wang5b429f02019-08-29 20:45:277028 clip_layer->SetBounds(gfx::Size(20, 20));
7029 clip_parent->SetBounds(gfx::Size(50, 50));
7030 unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
7031 unclipped_desc_surface->SetDrawsContent(true);
7032 clip_child->SetBounds(gfx::Size(100, 100));
7033 clip_child->SetDrawsContent(true);
7034
Xianzhu Wangc8189212019-08-28 01:32:287035 CopyProperties(root, surface);
7036 CreateTransformNode(surface).local.RotateAboutXAxis(10);
7037 CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
7038 CreateClipNode(surface);
Xianzhu Wangc8189212019-08-28 01:32:287039 CopyProperties(surface, clip_layer);
7040 CreateClipNode(clip_layer);
Xianzhu Wangc8189212019-08-28 01:32:287041 CopyProperties(clip_layer, clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:287042 CopyProperties(clip_parent, unclipped_desc_surface);
7043 CreateTransformNode(unclipped_desc_surface).local.Translate(10, 10);
7044 CreateEffectNode(unclipped_desc_surface).render_surface_reason =
7045 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:287046 CopyProperties(unclipped_desc_surface, clip_child);
7047 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
jaydasika77a4a072015-10-20 21:47:277048
Xianzhu Wang66e13e02019-09-18 20:39:127049 UpdateActiveTreeDrawProperties();
jaydasika77a4a072015-10-20 21:47:277050
7051 EXPECT_EQ(gfx::Rect(10, 10),
chrishtr7e3aaf22017-05-04 15:04:017052 GetRenderSurface(unclipped_desc_surface)->content_rect());
jaydasika77a4a072015-10-20 21:47:277053}
7054
Xianzhu Wang66e13e02019-09-18 20:39:127055TEST_F(DrawPropertiesTest, VisibleRectForDescendantOfScaledSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:367056 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277057 LayerImpl* surface = AddLayer<LayerImpl>();
7058 LayerImpl* clip_layer = AddLayer<LayerImpl>();
7059 LayerImpl* clip_parent = AddLayer<LayerImpl>();
7060 LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
7061 LayerImpl* clip_child = AddLayer<LayerImpl>();
danakjf78fb272016-07-26 19:06:157062
7063 root->SetBounds(gfx::Size(100, 100));
danakjf78fb272016-07-26 19:06:157064 surface->SetBounds(gfx::Size(100, 100));
Xianzhu Wang5b429f02019-08-29 20:45:277065 clip_layer->SetBounds(gfx::Size(20, 20));
7066 clip_parent->SetBounds(gfx::Size(50, 50));
7067 unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
7068 unclipped_desc_surface->SetDrawsContent(true);
7069 clip_child->SetBounds(gfx::Size(100, 100));
7070 clip_child->SetDrawsContent(true);
7071
Xianzhu Wangc8189212019-08-28 01:32:287072 CopyProperties(root, surface);
7073 CreateTransformNode(surface).local.Scale(2, 2);
7074 CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest;
7075 CreateClipNode(surface);
Xianzhu Wangc8189212019-08-28 01:32:287076 CopyProperties(surface, clip_layer);
7077 CreateClipNode(clip_layer);
Xianzhu Wangc8189212019-08-28 01:32:287078 CopyProperties(clip_layer, clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:287079 CopyProperties(clip_parent, unclipped_desc_surface);
7080 CreateEffectNode(unclipped_desc_surface).render_surface_reason =
7081 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:287082 CopyProperties(unclipped_desc_surface, clip_child);
7083 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
jaydasika2c8c2872015-10-21 23:28:217084
Xianzhu Wang66e13e02019-09-18 20:39:127085 UpdateActiveTreeDrawProperties();
jaydasika2c8c2872015-10-21 23:28:217086
7087 EXPECT_EQ(gfx::Rect(20, 20), clip_child->visible_layer_rect());
7088}
7089
Xianzhu Wang66e13e02019-09-18 20:39:127090TEST_F(DrawPropertiesTest, LayerWithInputHandlerAndZeroOpacity) {
Xianzhu Wangd6a62d82019-09-09 22:35:367091 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277092 LayerImpl* render_surface = AddLayer<LayerImpl>();
7093 LayerImpl* test_layer = AddLayer<LayerImpl>();
jaydasika60f85862015-10-01 20:36:147094
jaydasika86654512016-01-27 17:05:077095 gfx::Transform translation;
7096 translation.Translate(10, 10);
jaydasika60f85862015-10-01 20:36:147097
danakjf78fb272016-07-26 19:06:157098 root->SetBounds(gfx::Size(30, 30));
7099 render_surface->SetBounds(gfx::Size(30, 30));
jaydasika60f85862015-10-01 20:36:147100 render_surface->SetMasksToBounds(true);
danakjf78fb272016-07-26 19:06:157101 test_layer->SetBounds(gfx::Size(20, 20));
jaydasika60f85862015-10-01 20:36:147102 test_layer->SetDrawsContent(true);
Hayley Ferrd9ee3a72017-06-16 14:16:097103
7104 TouchActionRegion touch_action_region;
7105 touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 20, 20));
7106 test_layer->SetTouchActionRegion(std::move(touch_action_region));
Xianzhu Wang5b429f02019-08-29 20:45:277107
Xianzhu Wang5b429f02019-08-29 20:45:277108 CopyProperties(root, render_surface);
7109 CreateEffectNode(render_surface).render_surface_reason =
7110 RenderSurfaceReason::kTest;
7111 CreateClipNode(render_surface);
7112 CopyProperties(render_surface, test_layer);
7113 CreateTransformNode(test_layer).local = translation;
7114 CreateEffectNode(test_layer).opacity = 0.f;
jaydasika60f85862015-10-01 20:36:147115
Xianzhu Wang66e13e02019-09-18 20:39:127116 UpdateActiveTreeDrawProperties();
weiliangcc3517722016-06-28 22:52:027117 EXPECT_TRANSFORMATION_MATRIX_EQ(translation,
7118 test_layer->ScreenSpaceTransform());
jaydasika60f85862015-10-01 20:36:147119}
7120
Xianzhu Wang66e13e02019-09-18 20:39:127121TEST_F(DrawPropertiesTest, ClipParentDrawsIntoScaledRootSurface) {
Xianzhu Wangd6a62d82019-09-09 22:35:367122 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277123 LayerImpl* clip_layer = AddLayer<LayerImpl>();
7124 LayerImpl* clip_parent = AddLayer<LayerImpl>();
7125 LayerImpl* clip_parent_child = AddLayer<LayerImpl>();
7126 LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>();
7127 LayerImpl* clip_child = AddLayer<LayerImpl>();
jaydasikab874eddc2016-11-02 22:34:287128
7129 root->SetBounds(gfx::Size(100, 100));
7130 clip_layer->SetBounds(gfx::Size(20, 20));
jaydasikab874eddc2016-11-02 22:34:287131 clip_parent->SetBounds(gfx::Size(50, 50));
jaydasika1553a142017-04-05 00:37:097132 clip_parent_child->SetBounds(gfx::Size(20, 20));
jaydasikab874eddc2016-11-02 22:34:287133 unclipped_desc_surface->SetBounds(gfx::Size(100, 100));
7134 unclipped_desc_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:277135 clip_child->SetBounds(gfx::Size(100, 100));
7136 clip_child->SetDrawsContent(true);
7137
Xianzhu Wang5b429f02019-08-29 20:45:277138 CopyProperties(root, clip_layer);
7139 CreateClipNode(clip_layer);
7140 CopyProperties(clip_layer, clip_parent);
7141 CopyProperties(clip_parent, clip_parent_child);
7142 CreateClipNode(clip_parent_child);
Xianzhu Wangc8189212019-08-28 01:32:287143 CopyProperties(clip_parent_child, unclipped_desc_surface);
7144 CreateTransformNode(unclipped_desc_surface).local.Translate(10, 10);
7145 CreateEffectNode(unclipped_desc_surface).render_surface_reason =
7146 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:287147 CopyProperties(unclipped_desc_surface, clip_child);
7148 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
jaydasikab874eddc2016-11-02 22:34:287149
7150 float device_scale_factor = 1.f;
Xianzhu Wang66e13e02019-09-18 20:39:127151 UpdateActiveTreeDrawProperties(device_scale_factor);
jaydasika264a0dd2017-02-24 23:17:277152 EXPECT_EQ(gfx::Rect(-10, -10, 20, 20), clip_child->clip_rect());
7153 EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect());
jaydasikab874eddc2016-11-02 22:34:287154
7155 device_scale_factor = 2.f;
Xianzhu Wang66e13e02019-09-18 20:39:127156 UpdateActiveTreeDrawProperties(device_scale_factor);
jaydasika264a0dd2017-02-24 23:17:277157 EXPECT_EQ(gfx::Rect(-20, -20, 40, 40), clip_child->clip_rect());
7158 EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect());
jaydasikab874eddc2016-11-02 22:34:287159}
7160
Xianzhu Wang66e13e02019-09-18 20:39:127161TEST_F(DrawPropertiesTest, ClipChildVisibleRect) {
Xianzhu Wangd6a62d82019-09-09 22:35:367162 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277163 LayerImpl* clip_parent = AddLayer<LayerImpl>();
7164 LayerImpl* render_surface = AddLayer<LayerImpl>();
7165 LayerImpl* clip_child = AddLayer<LayerImpl>();
jaydasikae4910fa22015-10-09 00:52:097166
danakjf78fb272016-07-26 19:06:157167 root->SetBounds(gfx::Size(30, 30));
7168 clip_parent->SetBounds(gfx::Size(40, 40));
danakjf78fb272016-07-26 19:06:157169 render_surface->SetBounds(gfx::Size(50, 50));
jaydasikae4910fa22015-10-09 00:52:097170 render_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:277171 clip_child->SetBounds(gfx::Size(50, 50));
7172 clip_child->SetDrawsContent(true);
7173
Xianzhu Wang5b429f02019-08-29 20:45:277174 CopyProperties(root, clip_parent);
7175 CreateClipNode(clip_parent);
Xianzhu Wangc8189212019-08-28 01:32:287176 CopyProperties(clip_parent, render_surface);
7177 CreateEffectNode(render_surface).render_surface_reason =
7178 RenderSurfaceReason::kTest;
7179 CreateClipNode(render_surface);
Xianzhu Wangc8189212019-08-28 01:32:287180 CopyProperties(render_surface, clip_child);
7181 clip_child->SetClipTreeIndex(clip_parent->clip_tree_index());
jaydasikae4910fa22015-10-09 00:52:097182
Xianzhu Wang66e13e02019-09-18 20:39:127183 UpdateActiveTreeDrawProperties();
jaydasikab4df4032016-09-13 18:38:497184 EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect());
jaydasikae4910fa22015-10-09 00:52:097185}
7186
Xianzhu Wang66e13e02019-09-18 20:39:127187TEST_F(DrawPropertiesTest, LayerClipRectLargerThanClippingRenderSurfaceRect) {
Xianzhu Wangd6a62d82019-09-09 22:35:367188 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277189 LayerImpl* render_surface = AddLayer<LayerImpl>();
7190 LayerImpl* test_layer = AddLayer<LayerImpl>();
danakjf78fb272016-07-26 19:06:157191
7192 root->SetBounds(gfx::Size(30, 30));
jaydasika8640f9f2015-11-10 01:34:367193 root->SetDrawsContent(true);
danakjf78fb272016-07-26 19:06:157194 render_surface->SetBounds(gfx::Size(50, 50));
jaydasika8640f9f2015-11-10 01:34:367195 render_surface->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:277196
7197 test_layer->SetBounds(gfx::Size(50, 50));
7198 test_layer->SetDrawsContent(true);
7199
Xianzhu Wang5b429f02019-08-29 20:45:277200 CreateClipNode(root);
Xianzhu Wangc8189212019-08-28 01:32:287201 CopyProperties(root, render_surface);
7202 CreateTransformNode(render_surface);
7203 CreateEffectNode(render_surface).render_surface_reason =
7204 RenderSurfaceReason::kTest;
7205 CreateClipNode(render_surface);
Xianzhu Wangc8189212019-08-28 01:32:287206 CopyProperties(render_surface, test_layer);
7207 CreateClipNode(test_layer);
7208
Xianzhu Wang66e13e02019-09-18 20:39:127209 UpdateActiveTreeDrawProperties();
jaydasika571dd2cf2015-09-25 20:55:427210
7211 EXPECT_EQ(gfx::Rect(30, 30), root->clip_rect());
7212 EXPECT_EQ(gfx::Rect(50, 50), render_surface->clip_rect());
7213 EXPECT_EQ(gfx::Rect(50, 50), test_layer->clip_rect());
7214}
7215
Xianzhu Wang5b429f02019-08-29 20:45:277216// Needs layer tree mode: hide_layer_and_subtree.
Xianzhu Wang66e13e02019-09-18 20:39:127217TEST_F(DrawPropertiesTestWithLayerTree, SubtreeIsHiddenTest) {
jaydasikab5504ca2015-12-18 23:41:557218 // Tests that subtree is hidden is updated.
Xianzhu Wangc62ecebf2019-08-31 15:54:137219 auto root = Layer::Create();
7220 host()->SetRootLayer(root);
7221 auto hidden = Layer::Create();
7222 root->AddChild(hidden);
7223 auto test = Layer::Create();
7224 hidden->AddChild(test);
jaydasikab5504ca2015-12-18 23:41:557225
danakjf78fb272016-07-26 19:06:157226 root->SetBounds(gfx::Size(30, 30));
7227 hidden->SetBounds(gfx::Size(30, 30));
Xianzhu Wangc62ecebf2019-08-31 15:54:137228 hidden->SetForceRenderSurfaceForTesting(true);
7229 hidden->SetHideLayerAndSubtree(true);
danakjf78fb272016-07-26 19:06:157230 test->SetBounds(gfx::Size(30, 30));
Xianzhu Wangc62ecebf2019-08-31 15:54:137231 test->SetForceRenderSurfaceForTesting(true);
danakjf78fb272016-07-26 19:06:157232
Xianzhu Wangc62ecebf2019-08-31 15:54:137233 CommitAndActivate();
jaydasikab5504ca2015-12-18 23:41:557234
Xianzhu Wangc62ecebf2019-08-31 15:54:137235 EXPECT_EQ(
7236 0.f,
7237 GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity);
7238
7239 hidden->SetHideLayerAndSubtree(false);
7240 CommitAndActivate();
7241 EXPECT_EQ(
7242 1.f,
7243 GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity);
jaydasikab5504ca2015-12-18 23:41:557244}
7245
Xianzhu Wang66e13e02019-09-18 20:39:127246TEST_F(DrawPropertiesTest, TwoUnclippedRenderSurfaces) {
Xianzhu Wangd6a62d82019-09-09 22:35:367247 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277248 LayerImpl* clip_layer = AddLayer<LayerImpl>();
7249 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
7250 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
7251 LayerImpl* clip_child = AddLayer<LayerImpl>();
jaydasikac0137282015-10-01 15:50:307252
danakjf78fb272016-07-26 19:06:157253 root->SetBounds(gfx::Size(30, 30));
jaydasika1553a142017-04-05 00:37:097254 clip_layer->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:157255 render_surface1->SetBounds(gfx::Size(30, 30));
jaydasikac0137282015-10-01 15:50:307256 render_surface1->SetDrawsContent(true);
Xianzhu Wang5b429f02019-08-29 20:45:277257 render_surface2->SetBounds(gfx::Size(30, 30));
7258 render_surface2->SetDrawsContent(true);
7259 clip_child->SetBounds(gfx::Size(30, 30));
7260 clip_child->SetDrawsContent(true);
7261
Xianzhu Wang5b429f02019-08-29 20:45:277262 CreateClipNode(root);
7263 CopyProperties(root, clip_layer);
7264 CreateClipNode(clip_layer);
Xianzhu Wangc8189212019-08-28 01:32:287265 CopyProperties(clip_layer, render_surface1);
7266 CreateTransformNode(render_surface1).post_translation =
7267 gfx::Vector2dF(10, 10);
7268 CreateEffectNode(render_surface1).render_surface_reason =
7269 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:287270 CopyProperties(render_surface1, render_surface2);
7271 CreateEffectNode(render_surface2).render_surface_reason =
7272 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:287273 CopyProperties(render_surface2, clip_child);
7274 clip_child->SetClipTreeIndex(root->clip_tree_index());
danakjf78fb272016-07-26 19:06:157275
Xianzhu Wang66e13e02019-09-18 20:39:127276 UpdateActiveTreeDrawProperties();
jaydasikac0137282015-10-01 15:50:307277
7278 EXPECT_EQ(gfx::Rect(-10, -10, 30, 30), render_surface2->clip_rect());
7279}
7280
Xianzhu Wang5b429f02019-08-29 20:45:277281// Needs layer tree mode: mask layer.
Xianzhu Wang66e13e02019-09-18 20:39:127282TEST_F(DrawPropertiesTestWithLayerTree, MaskLayerDrawProperties) {
ajumadb6216f2c2016-06-07 21:44:057283 // Tests that a mask layer's draw properties are computed correctly.
Xianzhu Wangc62ecebf2019-08-31 15:54:137284 auto root = Layer::Create();
7285 host()->SetRootLayer(root);
7286 auto child = Layer::Create();
7287 root->AddChild(child);
7288 FakeContentLayerClient client;
7289 auto mask = PictureLayer::Create(&client);
7290 child->SetMaskLayer(mask);
jaydasika224bca02015-12-18 02:37:097291
jaydasika224bca02015-12-18 02:37:097292 gfx::Transform transform;
7293 transform.Translate(10, 10);
7294
danakjf78fb272016-07-26 19:06:157295 root->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:137296 root->SetIsDrawable(true);
7297 child->SetTransform(transform);
danakjf78fb272016-07-26 19:06:157298 child->SetBounds(gfx::Size(30, 30));
Xianzhu Wangdf85eae2019-09-17 18:56:087299 child->SetIsDrawable(true);
7300 child->SetOpacity(0.f);
Xianzhu Wangc62ecebf2019-08-31 15:54:137301 mask->SetBounds(gfx::Size(30, 30));
7302
7303 CommitAndActivate();
jaydasika224bca02015-12-18 02:37:097304
ajumadb6216f2c2016-06-07 21:44:057305 // The render surface created for the mask has no contributing content, so the
ajuma651848a2017-05-01 21:23:457306 // mask doesn't contribute to a drawn render surface. This means it has an
7307 // empty visible rect, but its screen space transform can still be computed
7308 // correctly on-demand.
Xianzhu Wangdf85eae2019-09-17 18:56:087309 EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface());
Xianzhu Wangc62ecebf2019-08-31 15:54:137310 EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface());
7311 EXPECT_EQ(gfx::Rect(), ImplOf(mask)->visible_layer_rect());
7312 EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
7313 ImplOf(mask)->ScreenSpaceTransform());
ajumadb6216f2c2016-06-07 21:44:057314
7315 // Make the child's render surface have contributing content.
Xianzhu Wangdf85eae2019-09-17 18:56:087316 child->SetOpacity(1.f);
Xianzhu Wangc62ecebf2019-08-31 15:54:137317 CommitAndActivate();
7318 EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
7319 EXPECT_EQ(gfx::Rect(30, 30), ImplOf(mask)->visible_layer_rect());
7320 EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
7321 ImplOf(mask)->ScreenSpaceTransform());
ajumadb6216f2c2016-06-07 21:44:057322
jaydasika224bca02015-12-18 02:37:097323 transform.Translate(10, 10);
Xianzhu Wangc62ecebf2019-08-31 15:54:137324 child->SetTransform(transform);
7325 CommitAndActivate();
7326 EXPECT_TRANSFORMATION_MATRIX_EQ(transform,
7327 ImplOf(mask)->ScreenSpaceTransform());
7328 EXPECT_EQ(gfx::Rect(20, 20), ImplOf(mask)->visible_layer_rect());
Xianzhu Wangdf85eae2019-09-17 18:56:087329
7330 // For now SetIsDrawable of masked layer doesn't affect draw properties of
7331 // the mask layer because it doesn't affect property trees.
7332 child->SetIsDrawable(false);
7333 CommitAndActivate();
7334 EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface());
7335
7336 // SetIsDrawable of mask layer itself affects its draw properties.
7337 mask->SetIsDrawable(false);
7338 CommitAndActivate();
7339 EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface());
ajumadb6216f2c2016-06-07 21:44:057340}
7341
Xianzhu Wang66e13e02019-09-18 20:39:127342TEST_F(DrawPropertiesTest, SublayerScaleWithTransformNodeBetweenTwoTargets) {
Xianzhu Wangd6a62d82019-09-09 22:35:367343 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277344 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
7345 LayerImpl* between_targets = AddLayer<LayerImpl>();
7346 LayerImpl* render_surface2 = AddLayer<LayerImpl>();
7347 LayerImpl* test_layer = AddLayer<LayerImpl>();
jaydasikaf62311f2016-04-20 14:38:457348
7349 gfx::Transform scale;
7350 scale.Scale(2.f, 2.f);
danakjf78fb272016-07-26 19:06:157351
7352 root->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:157353 render_surface1->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:157354 between_targets->SetBounds(gfx::Size(30, 30));
7355 render_surface2->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:157356 test_layer->SetBounds(gfx::Size(30, 30));
7357 test_layer->SetDrawsContent(true);
7358
jaydasikab433552b2016-10-26 18:49:447359 // We want layer between the two targets to create a clip node and effect
jaydasikaf62311f2016-04-20 14:38:457360 // node but it shouldn't create a render surface.
7361 between_targets->SetMasksToBounds(true);
Xianzhu Wang5b429f02019-08-29 20:45:277362 CopyProperties(root, render_surface1);
7363 CreateTransformNode(render_surface1).local = scale;
7364 CreateEffectNode(render_surface1).render_surface_reason =
7365 RenderSurfaceReason::kTest;
7366 CopyProperties(render_surface1, between_targets);
7367 CreateEffectNode(between_targets).opacity = 0.5f;
7368 CreateClipNode(between_targets);
7369 CopyProperties(between_targets, render_surface2);
7370 CreateEffectNode(render_surface2).render_surface_reason =
7371 RenderSurfaceReason::kTest;
7372 CopyProperties(render_surface2, test_layer);
jaydasikaf62311f2016-04-20 14:38:457373
Xianzhu Wang66e13e02019-09-18 20:39:127374 UpdateActiveTreeDrawProperties();
jaydasikaf62311f2016-04-20 14:38:457375
Xianzhu Wang5b429f02019-08-29 20:45:277376 EXPECT_EQ(gfx::Vector2dF(2.f, 2.f),
7377 GetEffectNode(render_surface1)->surface_contents_scale);
7378 EXPECT_EQ(gfx::Vector2dF(1.f, 1.f),
7379 GetEffectNode(between_targets)->surface_contents_scale);
7380 EXPECT_EQ(gfx::Vector2dF(2.f, 2.f),
7381 GetEffectNode(render_surface2)->surface_contents_scale);
jaydasikaf62311f2016-04-20 14:38:457382
7383 EXPECT_EQ(gfx::Rect(15, 15), test_layer->visible_layer_rect());
7384}
7385
Xianzhu Wang66e13e02019-09-18 20:39:127386TEST_F(DrawPropertiesTest, NoisyTransform) {
Xianzhu Wangd6a62d82019-09-09 22:35:367387 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277388 LayerImpl* render_surface = AddLayer<LayerImpl>();
7389 LayerImpl* parent = AddLayer<LayerImpl>();
7390 LayerImpl* child = AddLayer<LayerImpl>();
jaydasika3c5633d2016-08-25 00:39:227391
Xianzhu Wangc8189212019-08-28 01:32:287392 root->SetBounds(gfx::Size(30, 30));
Xianzhu Wang5b429f02019-08-29 20:45:277393 parent->SetBounds(gfx::Size(30, 30));
7394 parent->SetDrawsContent(true);
7395 child->SetBounds(gfx::Size(30, 30));
7396 child->SetDrawsContent(true);
jaydasika3c5633d2016-08-25 00:39:227397
7398 // A noisy transform that's invertible.
7399 gfx::Transform transform;
7400 transform.matrix().setDouble(0, 0, 6.12323e-17);
7401 transform.matrix().setDouble(0, 2, 1);
7402 transform.matrix().setDouble(2, 2, 6.12323e-17);
7403 transform.matrix().setDouble(2, 0, -1);
7404
Xianzhu Wangc8189212019-08-28 01:32:287405 CopyProperties(root, render_surface);
7406 CreateTransformNode(render_surface).local = transform;
7407 CreateEffectNode(render_surface).render_surface_reason =
7408 RenderSurfaceReason::kTest;
Xianzhu Wangc8189212019-08-28 01:32:287409 CopyProperties(render_surface, parent);
Xianzhu Wangc8189212019-08-28 01:32:287410 CopyProperties(parent, child);
7411 CreateTransformNode(child).local = transform;
7412
Xianzhu Wang66e13e02019-09-18 20:39:127413 UpdateActiveTreeDrawProperties();
jaydasika3c5633d2016-08-25 00:39:227414
7415 gfx::Transform expected;
7416 expected.matrix().setDouble(0, 0, 3.749395e-33);
7417 expected.matrix().setDouble(0, 2, 6.12323e-17);
7418 expected.matrix().setDouble(2, 0, -1);
7419 expected.matrix().setDouble(2, 2, 6.12323e-17);
Xianzhu Wangc8189212019-08-28 01:32:287420 EXPECT_TRANSFORMATION_MATRIX_EQ(expected, child->ScreenSpaceTransform());
jaydasika3c5633d2016-08-25 00:39:227421}
7422
Xianzhu Wang66e13e02019-09-18 20:39:127423TEST_F(DrawPropertiesTest, LargeTransformTest) {
Xianzhu Wangd6a62d82019-09-09 22:35:367424 LayerImpl* root = root_layer();
Xianzhu Wang5b429f02019-08-29 20:45:277425 LayerImpl* render_surface1 = AddLayer<LayerImpl>();
7426 LayerImpl* child = AddLayer<LayerImpl>();
jaydasika5160e672015-10-15 15:25:147427
sunxd71aea3e2016-04-01 23:48:057428 child->SetDrawsContent(true);
7429 child->SetMasksToBounds(true);
jaydasika5160e672015-10-15 15:25:147430
7431 gfx::Transform large_transform;
7432 large_transform.Scale(99999999999999999999.f, 99999999999999999999.f);
7433 large_transform.Scale(9999999999999999999.f, 9999999999999999999.f);
7434 EXPECT_TRUE(std::isinf(large_transform.matrix().get(0, 0)));
7435 EXPECT_TRUE(std::isinf(large_transform.matrix().get(1, 1)));
7436
danakjf78fb272016-07-26 19:06:157437 root->SetBounds(gfx::Size(30, 30));
7438 render_surface1->SetBounds(gfx::Size(30, 30));
danakjf78fb272016-07-26 19:06:157439
sunxd71aea3e2016-04-01 23:48:057440 // TODO(sunxd): we make child have no render surface, because if the
7441 // child has one, the large transform applied to child will result in NaNs in
7442 // the draw_transform of the render_surface, thus make draw property updates
7443 // skip the child layer. We need further investigation into this to know
7444 // what exactly happens here.
danakjf78fb272016-07-26 19:06:157445 child->SetBounds(gfx::Size(30, 30));
jaydasika5160e672015-10-15 15:25:147446
Xianzhu Wang5b429f02019-08-29 20:45:277447 CopyProperties(root, render_surface1);
7448 CreateEffectNode(render_surface1).render_surface_reason =
7449 RenderSurfaceReason::kTest;
7450 CopyProperties(render_surface1, child);
7451 CreateTransformNode(child).local = large_transform;
7452 CreateClipNode(child);
7453
Xianzhu Wang66e13e02019-09-18 20:39:127454 UpdateActiveTreeDrawProperties();
jaydasika5160e672015-10-15 15:25:147455
jaydasika5160e672015-10-15 15:25:147456 EXPECT_EQ(gfx::RectF(),
chrishtr7e3aaf22017-05-04 15:04:017457 GetRenderSurface(render_surface1)->DrawableContentRect());
sunxd71aea3e2016-04-01 23:48:057458
7459 bool is_inf_or_nan = std::isinf(child->DrawTransform().matrix().get(0, 0)) ||
7460 std::isnan(child->DrawTransform().matrix().get(0, 0));
7461 EXPECT_TRUE(is_inf_or_nan);
7462
7463 is_inf_or_nan = std::isinf(child->DrawTransform().matrix().get(1, 1)) ||
7464 std::isnan(child->DrawTransform().matrix().get(1, 1));
7465 EXPECT_TRUE(is_inf_or_nan);
jaydasika5160e672015-10-15 15:25:147466
ajumab784ef42017-04-28 23:01:527467 // The root layer should be in the RenderSurfaceList.
Xianzhu Wang66e13e02019-09-18 20:39:127468 EXPECT_TRUE(base::Contains(GetRenderSurfaceList(), GetRenderSurface(root)));
jaydasika8d6efe2e2016-05-17 15:37:217469}
7470
Xianzhu Wang5b429f02019-08-29 20:45:277471// In layer tree mode, not using impl-side PropertyTreeBuilder.
Xianzhu Wang66e13e02019-09-18 20:39:127472TEST_F(DrawPropertiesTestWithLayerTree, OpacityAnimationsTrackingTest) {
jaydasika9cb21c772016-05-10 22:37:087473 scoped_refptr<Layer> root = Layer::Create();
danakj762a2552018-06-12 20:57:287474 scoped_refptr<Layer> animated = Layer::Create();
7475 animated->SetIsDrawable(true);
jaydasika9cb21c772016-05-10 22:37:087476 root->AddChild(animated);
jaydasika9cb21c772016-05-10 22:37:087477 host()->SetRootLayer(root);
khushalsagarb69ba9452017-01-27 22:20:077478 host()->SetElementIdsForTesting();
vollickef2ae922016-06-29 17:54:277479
danakjf78fb272016-07-26 19:06:157480 root->SetBounds(gfx::Size(100, 100));
jaydasika9cb21c772016-05-10 22:37:087481 root->SetForceRenderSurfaceForTesting(true);
danakjf78fb272016-07-26 19:06:157482 animated->SetBounds(gfx::Size(20, 20));
jaydasika9cb21c772016-05-10 22:37:087483 animated->SetOpacity(0.f);
7484
Yi Guaa830ff2018-02-22 03:09:117485 scoped_refptr<SingleKeyframeEffectAnimation> animation =
7486 SingleKeyframeEffectAnimation::Create(
7487 AnimationIdProvider::NextAnimationId());
7488 timeline()->AttachAnimation(animation);
vollickef2ae922016-06-29 17:54:277489
Yi Guaa830ff2018-02-22 03:09:117490 animation->AttachElement(animated->element_id());
jaydasika9cb21c772016-05-10 22:37:087491
Yi Gu3904dc22018-02-15 18:35:247492 int keyframe_model_id = 0;
7493 std::unique_ptr<KeyframeModel> keyframe_model = KeyframeModel::Create(
jaydasika9cb21c772016-05-10 22:37:087494 std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
Yi Gu3904dc22018-02-15 18:35:247495 keyframe_model_id, 1, TargetProperty::OPACITY);
7496 keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
7497 keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
7498 KeyframeModel* keyframe_model_ptr = keyframe_model.get();
7499 AddKeyframeModelToElementWithExistingKeyframeEffect(
7500 animated->element_id(), timeline(), std::move(keyframe_model));
jaydasika9cb21c772016-05-10 22:37:087501
Xianzhu Wang66e13e02019-09-18 20:39:127502 UpdateMainDrawProperties();
jaydasika9cb21c772016-05-10 22:37:087503
Xianzhu Wang5b429f02019-08-29 20:45:277504 EffectNode* node = GetEffectNode(animated.get());
trchendba8b1502016-07-08 09:47:017505 EXPECT_FALSE(node->is_currently_animating_opacity);
7506 EXPECT_TRUE(node->has_potential_opacity_animation);
jaydasika9cb21c772016-05-10 22:37:087507
Yi Gu3904dc22018-02-15 18:35:247508 keyframe_model_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0));
Yuri Wiitalad0611762017-07-22 02:33:217509 host()->AnimateLayers(base::TimeTicks::Max());
Xianzhu Wang5b429f02019-08-29 20:45:277510 node = GetEffectNode(animated.get());
trchendba8b1502016-07-08 09:47:017511 EXPECT_TRUE(node->is_currently_animating_opacity);
7512 EXPECT_TRUE(node->has_potential_opacity_animation);
jaydasika9cb21c772016-05-10 22:37:087513
Yi Gufcce1762018-07-10 14:56:497514 animation->AbortKeyframeModelsWithProperty(TargetProperty::OPACITY,
7515 false /*needs_completion*/);
Xianzhu Wang5b429f02019-08-29 20:45:277516 node = GetEffectNode(animated.get());
trchendba8b1502016-07-08 09:47:017517 EXPECT_FALSE(node->is_currently_animating_opacity);
7518 EXPECT_FALSE(node->has_potential_opacity_animation);
jaydasika9cb21c772016-05-10 22:37:087519}
7520
Xianzhu Wang5b429f02019-08-29 20:45:277521// In layer tree mode, not using impl-side PropertyTreeBuilder.
Xianzhu Wang66e13e02019-09-18 20:39:127522TEST_F(DrawPropertiesTestWithLayerTree, TransformAnimationsTrackingTest) {
jaydasika6c3404e92016-05-19 02:40:367523 scoped_refptr<Layer> root = Layer::Create();
danakj762a2552018-06-12 20:57:287524 scoped_refptr<Layer> animated = Layer::Create();
7525 animated->SetIsDrawable(true);
jaydasika6c3404e92016-05-19 02:40:367526 root->AddChild(animated);
jaydasika6c3404e92016-05-19 02:40:367527 host()->SetRootLayer(root);
khushalsagarb69ba9452017-01-27 22:20:077528 host()->SetElementIdsForTesting();
vollickef2ae922016-06-29 17:54:277529
danakjf78fb272016-07-26 19:06:157530 root->SetBounds(gfx::Size(100, 100));
jaydasika6c3404e92016-05-19 02:40:367531 root->SetForceRenderSurfaceForTesting(true);
danakjf78fb272016-07-26 19:06:157532 animated->SetBounds(gfx::Size(20, 20));
jaydasika6c3404e92016-05-19 02:40:367533
Yi Guaa830ff2018-02-22 03:09:117534 scoped_refptr<SingleKeyframeEffectAnimation> animation =
7535 SingleKeyframeEffectAnimation::Create(
7536 AnimationIdProvider::NextAnimationId());
7537 timeline()->AttachAnimation(animation);
7538 animation->AttachElement(animated->element_id());
jaydasika6c3404e92016-05-19 02:40:367539
7540 std::unique_ptr<KeyframedTransformAnimationCurve> curve(
7541 KeyframedTransformAnimationCurve::Create());
7542 TransformOperations start;
7543 start.AppendTranslate(1.f, 2.f, 3.f);
7544 gfx::Transform transform;
7545 transform.Scale3d(1.0, 2.0, 3.0);
7546 TransformOperations operation;
7547 operation.AppendMatrix(transform);
7548 curve->AddKeyframe(
7549 TransformKeyframe::Create(base::TimeDelta(), start, nullptr));
7550 curve->AddKeyframe(TransformKeyframe::Create(
7551 base::TimeDelta::FromSecondsD(1.0), operation, nullptr));
Yi Gu3904dc22018-02-15 18:35:247552 std::unique_ptr<KeyframeModel> keyframe_model(
7553 KeyframeModel::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM));
7554 keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE);
7555 keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000));
7556 KeyframeModel* keyframe_model_ptr = keyframe_model.get();
7557 AddKeyframeModelToElementWithExistingKeyframeEffect(
7558 animated->element_id(), timeline(), std::move(keyframe_model));
jaydasika6c3404e92016-05-19 02:40:367559
Xianzhu Wang66e13e02019-09-18 20:39:127560 UpdateMainDrawProperties();
jaydasika6c3404e92016-05-19 02:40:367561
Xianzhu Wang5b429f02019-08-29 20:45:277562 TransformNode* node = GetTransformNode(animated.get());
trchendba8b1502016-07-08 09:47:017563 EXPECT_FALSE(node->is_currently_animating);
7564 EXPECT_TRUE(node->has_potential_animation);
jaydasika6c3404e92016-05-19 02:40:367565
Yi Gu3904dc22018-02-15 18:35:247566 keyframe_model_ptr->set_time_offset(base::TimeDelta::FromMilliseconds(0));
Yuri Wiitalad0611762017-07-22 02:33:217567 host()->AnimateLayers(base::TimeTicks::Max());
Xianzhu Wang5b429f02019-08-29 20:45:277568 node = GetTransformNode(animated.get());
trchendba8b1502016-07-08 09:47:017569 EXPECT_TRUE(node->is_currently_animating);
7570 EXPECT_TRUE(node->has_potential_animation);
jaydasika6c3404e92016-05-19 02:40:367571
Yi Gufcce1762018-07-10 14:56:497572 animation->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
7573 false /*needs_completion*/);
Xianzhu Wang5b429f02019-08-29 20:45:277574 node = GetTransformNode(animated.get());
trchendba8b1502016-07-08 09:47:017575 EXPECT_FALSE(node->is_currently_animating);
7576 EXPECT_FALSE(node->has_potential_animation);
jaydasika6c3404e92016-05-19 02:40:367577}
7578
Xianzhu Wang5b429f02019-08-29 20:45:277579// Needs layer tree mode: copy request.
Xianzhu Wang66e13e02019-09-18 20:39:127580TEST_F(DrawPropertiesTestWithLayerTree, CopyRequestScalingTest) {
Xianzhu Wangc62ecebf2019-08-31 15:54:137581 auto root = Layer::Create();
7582 host()->SetRootLayer(root);
7583 auto scale_layer = Layer::Create();
7584 root->AddChild(scale_layer);
7585 auto copy_layer = Layer::Create();
7586 scale_layer->AddChild(copy_layer);
7587 auto clip_layer = Layer::Create();
7588 copy_layer->AddChild(clip_layer);
7589 auto test_layer = Layer::Create();
7590 clip_layer->AddChild(test_layer);
wutao834bd202017-07-14 01:12:537591
7592 root->SetBounds(gfx::Size(150, 150));
7593
7594 scale_layer->SetBounds(gfx::Size(30, 30));
7595 gfx::Transform transform;
7596 transform.Scale(5.f, 5.f);
Xianzhu Wangc62ecebf2019-08-31 15:54:137597 scale_layer->SetTransform(transform);
wutao834bd202017-07-14 01:12:537598
7599 // Need to persist the render surface after copy request is cleared.
Xianzhu Wangc62ecebf2019-08-31 15:54:137600 copy_layer->SetForceRenderSurfaceForTesting(true);
7601 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:507602 viz::CopyOutputRequest::CreateStubForTesting());
wutao834bd202017-07-14 01:12:537603
Xianzhu Wangc62ecebf2019-08-31 15:54:137604 clip_layer->SetIsDrawable(true);
wutao834bd202017-07-14 01:12:537605 clip_layer->SetMasksToBounds(true);
7606 clip_layer->SetBounds(gfx::Size(10, 10));
7607
Xianzhu Wangc62ecebf2019-08-31 15:54:137608 test_layer->SetIsDrawable(true);
wutao834bd202017-07-14 01:12:537609 test_layer->SetMasksToBounds(true);
7610 test_layer->SetBounds(gfx::Size(20, 20));
7611
Xianzhu Wangc62ecebf2019-08-31 15:54:137612 CommitAndActivate();
wutao834bd202017-07-14 01:12:537613
7614 // Check surface with copy request draw properties.
Xianzhu Wangc62ecebf2019-08-31 15:54:137615 EXPECT_EQ(gfx::Rect(50, 50),
7616 GetRenderSurfaceImpl(copy_layer)->content_rect());
7617 EXPECT_EQ(gfx::Transform(),
7618 GetRenderSurfaceImpl(copy_layer)->draw_transform());
wutao834bd202017-07-14 01:12:537619 EXPECT_EQ(gfx::RectF(50.0f, 50.0f),
Xianzhu Wangc62ecebf2019-08-31 15:54:137620 GetRenderSurfaceImpl(copy_layer)->DrawableContentRect());
wutao834bd202017-07-14 01:12:537621
7622 // Check test layer draw properties.
Xianzhu Wangc62ecebf2019-08-31 15:54:137623 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(test_layer)->visible_layer_rect());
7624 EXPECT_EQ(transform, ImplOf(test_layer)->DrawTransform());
7625 EXPECT_EQ(gfx::Rect(50, 50), ImplOf(test_layer)->clip_rect());
7626 EXPECT_EQ(gfx::Rect(50, 50), ImplOf(test_layer)->drawable_content_rect());
wutao834bd202017-07-14 01:12:537627
7628 // Clear the copy request and call UpdateSurfaceContentsScale.
Xianzhu Wangc62ecebf2019-08-31 15:54:137629 GetPropertyTrees(root.get())->effect_tree.ClearCopyRequests();
7630 CommitAndActivate();
wutao834bd202017-07-14 01:12:537631}
7632
Xianzhu Wang5b429f02019-08-29 20:45:277633// Needs layer tree mode: hide_layer_and_subtree, etc.
Xianzhu Wang66e13e02019-09-18 20:39:127634TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCacheRenderSurface) {
Xianzhu Wangc62ecebf2019-08-31 15:54:137635 auto root = Layer::Create();
7636 host()->SetRootLayer(root);
wutao36850732017-07-29 20:24:077637 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:137638 root->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077639
Xianzhu Wangc62ecebf2019-08-31 15:54:137640 auto cache_grand_parent_sibling_before = Layer::Create();
7641 root->AddChild(cache_grand_parent_sibling_before);
Xianzhu Wang5b429f02019-08-29 20:45:277642 cache_grand_parent_sibling_before->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:137643 cache_grand_parent_sibling_before->SetIsDrawable(true);
Xianzhu Wang5b429f02019-08-29 20:45:277644
Xianzhu Wangc62ecebf2019-08-31 15:54:137645 auto cache_grand_parent = Layer::Create();
7646 root->AddChild(cache_grand_parent);
wutao36850732017-07-29 20:24:077647 cache_grand_parent->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:137648 cache_grand_parent->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077649
Xianzhu Wangc62ecebf2019-08-31 15:54:137650 auto cache_parent = Layer::Create();
7651 cache_grand_parent->AddChild(cache_parent);
wutao36850732017-07-29 20:24:077652 cache_parent->SetBounds(gfx::Size(30, 30));
Xianzhu Wangc62ecebf2019-08-31 15:54:137653 cache_parent->SetIsDrawable(true);
7654 cache_parent->SetForceRenderSurfaceForTesting(true);
wutao36850732017-07-29 20:24:077655
Xianzhu Wangc62ecebf2019-08-31 15:54:137656 auto cache_render_surface = Layer::Create();
7657 cache_parent->AddChild(cache_render_surface);
wutao36850732017-07-29 20:24:077658 cache_render_surface->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:137659 cache_render_surface->SetIsDrawable(true);
7660 cache_render_surface->SetCacheRenderSurface(true);
wutao36850732017-07-29 20:24:077661
Xianzhu Wangc62ecebf2019-08-31 15:54:137662 auto cache_child = Layer::Create();
7663 cache_render_surface->AddChild(cache_child);
wutao36850732017-07-29 20:24:077664 cache_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:137665 cache_child->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077666
Xianzhu Wangc62ecebf2019-08-31 15:54:137667 auto cache_grand_child = Layer::Create();
7668 cache_child->AddChild(cache_grand_child);
wutao36850732017-07-29 20:24:077669 cache_grand_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:137670 cache_grand_child->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077671
Xianzhu Wangc62ecebf2019-08-31 15:54:137672 auto cache_grand_parent_sibling_after = Layer::Create();
7673 root->AddChild(cache_grand_parent_sibling_after);
wutao36850732017-07-29 20:24:077674 cache_grand_parent_sibling_after->SetBounds(gfx::Size(40, 40));
Xianzhu Wangc62ecebf2019-08-31 15:54:137675 cache_grand_parent_sibling_after->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077676
7677 // Hide the cache_grand_parent and its subtree. But cache a render surface in
7678 // that hidden subtree on cache_layer. Also hide the cache grand child and its
7679 // subtree.
Xianzhu Wangc62ecebf2019-08-31 15:54:137680 cache_grand_parent->SetHideLayerAndSubtree(true);
7681 cache_grand_parent_sibling_before->SetHideLayerAndSubtree(true);
7682 cache_grand_parent_sibling_after->SetHideLayerAndSubtree(true);
7683 cache_grand_child->SetHideLayerAndSubtree(true);
wutao36850732017-07-29 20:24:077684
Xianzhu Wangc62ecebf2019-08-31 15:54:137685 CommitAndActivate();
wutao36850732017-07-29 20:24:077686
7687 // We should have four render surfaces, one for the root, one for the grand
7688 // parent since it has opacity and two drawing descendants, one for the parent
Xianzhu Wang5b429f02019-08-29 20:45:277689 // since it owns a surface, and one for the cache.
Xianzhu Wang66e13e02019-09-18 20:39:127690 ASSERT_EQ(4u, GetRenderSurfaceList().size());
Xianzhu Wang5b429f02019-08-29 20:45:277691 EXPECT_EQ(static_cast<uint64_t>(root->id()),
Xianzhu Wang66e13e02019-09-18 20:39:127692 GetRenderSurfaceList().at(0)->id());
Xianzhu Wang5b429f02019-08-29 20:45:277693 EXPECT_EQ(static_cast<uint64_t>(cache_grand_parent->id()),
Xianzhu Wang66e13e02019-09-18 20:39:127694 GetRenderSurfaceList().at(1)->id());
Xianzhu Wang5b429f02019-08-29 20:45:277695 EXPECT_EQ(static_cast<uint64_t>(cache_parent->id()),
Xianzhu Wang66e13e02019-09-18 20:39:127696 GetRenderSurfaceList().at(2)->id());
Xianzhu Wang5b429f02019-08-29 20:45:277697 EXPECT_EQ(static_cast<uint64_t>(cache_render_surface->id()),
Xianzhu Wang66e13e02019-09-18 20:39:127698 GetRenderSurfaceList().at(3)->id());
wutao36850732017-07-29 20:24:077699
7700 // The root render surface should have 2 contributing layers.
Xianzhu Wangc62ecebf2019-08-31 15:54:137701 EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors());
7702 EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface());
Xianzhu Wang5b429f02019-08-29 20:45:277703 EXPECT_FALSE(
Xianzhu Wangc62ecebf2019-08-31 15:54:137704 ImplOf(cache_grand_parent)->contributes_to_drawn_render_surface());
7705 EXPECT_FALSE(ImplOf(cache_grand_parent_sibling_before)
7706 ->contributes_to_drawn_render_surface());
7707 EXPECT_FALSE(ImplOf(cache_grand_parent_sibling_after)
7708 ->contributes_to_drawn_render_surface());
wutao36850732017-07-29 20:24:077709
Xianzhu Wang5b429f02019-08-29 20:45:277710 // Nothing actually draws into the cache parent, so only the cache will
wutao36850732017-07-29 20:24:077711 // appear in its list, since it needs to be drawn for the cache render
7712 // surface.
Xianzhu Wangc62ecebf2019-08-31 15:54:137713 ASSERT_EQ(1, GetRenderSurfaceImpl(cache_parent)->num_contributors());
7714 EXPECT_FALSE(ImplOf(cache_parent)->contributes_to_drawn_render_surface());
wutao36850732017-07-29 20:24:077715
7716 // The cache layer's render surface should have 2 contributing layers.
Xianzhu Wangc62ecebf2019-08-31 15:54:137717 ASSERT_EQ(2, GetRenderSurfaceImpl(cache_render_surface)->num_contributors());
7718 EXPECT_TRUE(
7719 ImplOf(cache_render_surface)->contributes_to_drawn_render_surface());
7720 EXPECT_TRUE(ImplOf(cache_child)->contributes_to_drawn_render_surface());
7721 EXPECT_FALSE(
7722 ImplOf(cache_grand_child)->contributes_to_drawn_render_surface());
wutao36850732017-07-29 20:24:077723
7724 // cache_grand_parent, cache_parent shouldn't be drawn because they are
Xianzhu Wang5b429f02019-08-29 20:45:277725 // hidden, but the cache and cache_child should be drawn for the cache
wutao36850732017-07-29 20:24:077726 // render surface. cache grand child should not be drawn as its hidden even in
7727 // the cache render surface.
Xianzhu Wangc62ecebf2019-08-31 15:54:137728 EXPECT_FALSE(GetEffectNode(ImplOf(cache_grand_parent))->is_drawn);
7729 EXPECT_FALSE(GetEffectNode(ImplOf(cache_parent))->is_drawn);
7730 EXPECT_TRUE(GetEffectNode(ImplOf(cache_render_surface))->is_drawn);
7731 EXPECT_TRUE(GetEffectNode(ImplOf(cache_child))->is_drawn);
7732 EXPECT_FALSE(GetEffectNode(ImplOf(cache_grand_child))->is_drawn);
wutao36850732017-07-29 20:24:077733
Xianzhu Wang5b429f02019-08-29 20:45:277734 // Though cache is drawn, it shouldn't contribute to drawn surface as
wutao36850732017-07-29 20:24:077735 // its actually hidden.
Xianzhu Wangc62ecebf2019-08-31 15:54:137736 EXPECT_FALSE(GetRenderSurfaceImpl(cache_render_surface)
7737 ->contributes_to_drawn_surface());
wutao36850732017-07-29 20:24:077738}
7739
Xianzhu Wang5b429f02019-08-29 20:45:277740// Needs layer tree mode: copy request.
Xianzhu Wang66e13e02019-09-18 20:39:127741TEST_F(DrawPropertiesTestWithLayerTree,
Xianzhu Wang5b429f02019-08-29 20:45:277742 VisibleRectInNonRootCacheRenderSurface) {
Xianzhu Wangc62ecebf2019-08-31 15:54:137743 auto root = Layer::Create();
7744 host()->SetRootLayer(root);
wutao36850732017-07-29 20:24:077745 root->SetBounds(gfx::Size(50, 50));
Xianzhu Wangc62ecebf2019-08-31 15:54:137746 root->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077747 root->SetMasksToBounds(true);
7748
Xianzhu Wangc62ecebf2019-08-31 15:54:137749 auto cache_render_surface_layer = Layer::Create();
7750 root->AddChild(cache_render_surface_layer);
wutao36850732017-07-29 20:24:077751 cache_render_surface_layer->SetBounds(gfx::Size(120, 120));
Xianzhu Wangc62ecebf2019-08-31 15:54:137752 cache_render_surface_layer->SetIsDrawable(true);
7753 cache_render_surface_layer->SetCacheRenderSurface(true);
wutao36850732017-07-29 20:24:077754
Xianzhu Wangc62ecebf2019-08-31 15:54:137755 auto copy_layer = Layer::Create();
7756 cache_render_surface_layer->AddChild(copy_layer);
wutao36850732017-07-29 20:24:077757 copy_layer->SetBounds(gfx::Size(100, 100));
Xianzhu Wangc62ecebf2019-08-31 15:54:137758 copy_layer->SetIsDrawable(true);
7759 copy_layer->SetForceRenderSurfaceForTesting(true);
wutao36850732017-07-29 20:24:077760
Xianzhu Wangc62ecebf2019-08-31 15:54:137761 auto copy_child = Layer::Create();
7762 copy_layer->AddChild(copy_child);
7763 copy_child->SetPosition(gfx::PointF(40.f, 40.f));
wutao36850732017-07-29 20:24:077764 copy_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:137765 copy_child->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077766
Xianzhu Wangc62ecebf2019-08-31 15:54:137767 auto copy_clip = Layer::Create();
7768 copy_layer->AddChild(copy_clip);
wutao36850732017-07-29 20:24:077769 copy_clip->SetBounds(gfx::Size(55, 55));
7770 copy_clip->SetMasksToBounds(true);
7771
Xianzhu Wangc62ecebf2019-08-31 15:54:137772 auto copy_clipped_child = Layer::Create();
7773 copy_clip->AddChild(copy_clipped_child);
7774 copy_clipped_child->SetPosition(gfx::PointF(40.f, 40.f));
wutao36850732017-07-29 20:24:077775 copy_clipped_child->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:137776 copy_clipped_child->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077777
Xianzhu Wangc62ecebf2019-08-31 15:54:137778 auto cache_surface = Layer::Create();
7779 copy_clip->AddChild(cache_surface);
7780 cache_surface->SetPosition(gfx::PointF(45.f, 45.f));
wutao36850732017-07-29 20:24:077781 cache_surface->SetBounds(gfx::Size(20, 20));
Xianzhu Wangc62ecebf2019-08-31 15:54:137782 cache_surface->SetIsDrawable(true);
wutao36850732017-07-29 20:24:077783
Xianzhu Wangc62ecebf2019-08-31 15:54:137784 CommitAndActivate();
7785
wutao36850732017-07-29 20:24:077786 EXPECT_EQ(gfx::Rect(120, 120),
Xianzhu Wangc62ecebf2019-08-31 15:54:137787 ImplOf(cache_render_surface_layer)->visible_layer_rect());
7788 EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
7789 EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
7790 EXPECT_EQ(gfx::Rect(15, 15),
7791 ImplOf(copy_clipped_child)->visible_layer_rect());
7792 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(cache_surface)->visible_layer_rect());
wutao36850732017-07-29 20:24:077793
7794 // Case 2: When the non root cache render surface layer is clipped.
7795 cache_render_surface_layer->SetBounds(gfx::Size(50, 50));
7796 cache_render_surface_layer->SetMasksToBounds(true);
Xianzhu Wangc62ecebf2019-08-31 15:54:137797 CommitAndActivate();
wutao36850732017-07-29 20:24:077798 EXPECT_EQ(gfx::Rect(50, 50),
Xianzhu Wangc62ecebf2019-08-31 15:54:137799 ImplOf(cache_render_surface_layer)->visible_layer_rect());
7800 EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
7801 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
7802 EXPECT_EQ(gfx::Rect(10, 10),
7803 ImplOf(copy_clipped_child)->visible_layer_rect());
7804 EXPECT_EQ(gfx::Rect(5, 5), ImplOf(cache_surface)->visible_layer_rect());
wutao36850732017-07-29 20:24:077805
7806 // Case 3: When there is device scale factor.
7807 float device_scale_factor = 2.f;
Xianzhu Wangc62ecebf2019-08-31 15:54:137808 CommitAndActivate(device_scale_factor);
wutao36850732017-07-29 20:24:077809 EXPECT_EQ(gfx::Rect(50, 50),
Xianzhu Wangc62ecebf2019-08-31 15:54:137810 ImplOf(cache_render_surface_layer)->visible_layer_rect());
7811 EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect());
7812 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(copy_child)->visible_layer_rect());
7813 EXPECT_EQ(gfx::Rect(10, 10),
7814 ImplOf(copy_clipped_child)->visible_layer_rect());
7815 EXPECT_EQ(gfx::Rect(5, 5), ImplOf(cache_surface)->visible_layer_rect());
wutao36850732017-07-29 20:24:077816
7817 // Case 4: When the non root cache render surface layer is clipped and there
7818 // is a copy request layer beneath it.
Xianzhu Wangc62ecebf2019-08-31 15:54:137819 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:507820 viz::CopyOutputRequest::CreateStubForTesting());
Xianzhu Wangc62ecebf2019-08-31 15:54:137821 ASSERT_TRUE(copy_layer->HasCopyRequest());
7822 CommitAndActivate();
7823 ASSERT_FALSE(copy_layer->HasCopyRequest());
wutao36850732017-07-29 20:24:077824 EXPECT_EQ(gfx::Rect(50, 50),
Xianzhu Wangc62ecebf2019-08-31 15:54:137825 ImplOf(cache_render_surface_layer)->visible_layer_rect());
7826 EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
7827 EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
7828 EXPECT_EQ(gfx::Rect(15, 15),
7829 ImplOf(copy_clipped_child)->visible_layer_rect());
7830 EXPECT_EQ(gfx::Rect(10, 10), ImplOf(cache_surface)->visible_layer_rect());
wutao36850732017-07-29 20:24:077831
7832 // Case 5: When there is another cache render surface layer under the copy
7833 // request layer.
Xianzhu Wangc62ecebf2019-08-31 15:54:137834 cache_surface->SetCacheRenderSurface(true);
7835 copy_layer->RequestCopyOfOutput(
Yuri Wiitalab9ad27a2017-09-06 19:13:507836 viz::CopyOutputRequest::CreateStubForTesting());
Xianzhu Wangc62ecebf2019-08-31 15:54:137837 ASSERT_TRUE(copy_layer->HasCopyRequest());
7838 CommitAndActivate();
7839 ASSERT_FALSE(copy_layer->HasCopyRequest());
wutao36850732017-07-29 20:24:077840 EXPECT_EQ(gfx::Rect(50, 50),
Xianzhu Wangc62ecebf2019-08-31 15:54:137841 ImplOf(cache_render_surface_layer)->visible_layer_rect());
7842 EXPECT_EQ(gfx::Rect(100, 100), ImplOf(copy_layer)->visible_layer_rect());
7843 EXPECT_EQ(gfx::Rect(20, 20), ImplOf(copy_child)->visible_layer_rect());
7844 EXPECT_EQ(gfx::Rect(15, 15),
7845 ImplOf(copy_clipped_child)->visible_layer_rect());
7846 EXPECT_EQ(gfx::Rect(20, 20), ImplOf(cache_surface)->visible_layer_rect());
wutao36850732017-07-29 20:24:077847}
7848
Xianzhu Wang5b429f02019-08-29 20:45:277849// In layer tree mode, not using impl-side PropertyTreeBuilder.
Xianzhu Wang66e13e02019-09-18 20:39:127850TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBounds) {
Malay Keshavf8e2b482019-06-19 21:18:387851 // The custom clip API should have the same effect as if an intermediate
7852 // clip layer has been added to the layer tree. To check this the test creates
7853 // 2 subtree for a root layer. One of the subtree uses the clip API to clip
7854 // its subtree while the other uses an intermediate layer. The resulting clip
7855 // in draw properties are expected to be the same.
7856 // -Root
7857 // - Parent [Clip set to |kClipBounds| using API]
7858 // - Child
7859 // - Clip Layer [Masks to bounds = true] [Layer bounds set to |kClipBounds|]
7860 // - Expected Parent
7861 // - Expected Child
7862 constexpr float kDeviceScale = 1.f;
7863
7864 const gfx::Rect kRootLayerBounds(0, 0, 100, 100);
7865 const gfx::Rect kParentLayerBounds(0, 0, 50, 100);
7866 const gfx::Rect kChildLayerBounds(20, 20, 30, 60);
7867
7868 constexpr gfx::Rect kClipBounds(10, 10, 50, 50);
7869
7870 // The position of |Expected Parent| on screen should be same as |Parent|.
7871 const gfx::Rect kExpectedParentLayerBounds(
7872 gfx::Point(0, 0) - kClipBounds.OffsetFromOrigin(), gfx::Size(50, 100));
7873
7874 scoped_refptr<Layer> root = Layer::Create();
7875 scoped_refptr<Layer> parent = Layer::Create();
7876 scoped_refptr<Layer> child = Layer::Create();
7877
7878 scoped_refptr<Layer> clip_layer = Layer::Create();
7879 scoped_refptr<Layer> expected_parent = Layer::Create();
7880 scoped_refptr<Layer> expected_child = Layer::Create();
7881
7882 root->AddChild(parent);
7883 parent->AddChild(child);
7884
7885 root->AddChild(clip_layer);
7886 clip_layer->AddChild(expected_parent);
7887 expected_parent->AddChild(expected_child);
7888
7889 host()->SetRootLayer(root);
7890
7891 root->SetIsDrawable(true);
7892 parent->SetIsDrawable(true);
7893 child->SetIsDrawable(true);
7894 expected_parent->SetIsDrawable(true);
7895 expected_child->SetIsDrawable(true);
7896
7897 // Set layer positions.
7898 root->SetPosition(gfx::PointF(kRootLayerBounds.origin()));
7899 parent->SetPosition(gfx::PointF(kParentLayerBounds.origin()));
7900 child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
7901
7902 clip_layer->SetPosition(gfx::PointF(kClipBounds.origin()));
7903 expected_parent->SetPosition(
7904 gfx::PointF(kExpectedParentLayerBounds.origin()));
7905 expected_child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
7906
7907 root->SetBounds(kRootLayerBounds.size());
7908 parent->SetBounds(kParentLayerBounds.size());
7909 child->SetBounds(kChildLayerBounds.size());
7910
7911 clip_layer->SetBounds(kClipBounds.size());
7912 expected_parent->SetBounds(kExpectedParentLayerBounds.size());
7913 expected_child->SetBounds(kChildLayerBounds.size());
7914
7915 parent->SetClipRect(kClipBounds);
7916 clip_layer->SetMasksToBounds(true);
7917
Xianzhu Wang66e13e02019-09-18 20:39:127918 UpdateMainDrawProperties(kDeviceScale);
Malay Keshavf8e2b482019-06-19 21:18:387919
Xianzhu Wang5b429f02019-08-29 20:45:277920 EXPECT_EQ(GetClipNode(parent.get())->clip, gfx::RectF(kClipBounds));
Malay Keshavf8e2b482019-06-19 21:18:387921 EXPECT_TRUE(!parent->clip_rect().IsEmpty());
7922
Xianzhu Wang5b429f02019-08-29 20:45:277923 EXPECT_EQ(GetClipNode(child.get())->clip, gfx::RectF(kClipBounds));
Malay Keshavf8e2b482019-06-19 21:18:387924
Xianzhu Wang66e13e02019-09-18 20:39:127925 CommitAndActivate(kDeviceScale);
Malay Keshavf8e2b482019-06-19 21:18:387926 LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
7927
7928 // Get the layer impl for each Layer.
Malay Keshavf8e2b482019-06-19 21:18:387929 LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id());
7930 LayerImpl* child_impl = layer_tree_impl->LayerById(child->id());
7931 LayerImpl* expected_parent_impl =
7932 layer_tree_impl->LayerById(expected_parent->id());
7933 LayerImpl* expected_child_impl =
7934 layer_tree_impl->LayerById(expected_child->id());
7935
Xianzhu Wang66e13e02019-09-18 20:39:127936 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
Malay Keshavf8e2b482019-06-19 21:18:387937
7938 EXPECT_TRUE(parent_impl->is_clipped());
7939 EXPECT_TRUE(child_impl->is_clipped());
7940 ASSERT_TRUE(expected_parent_impl->is_clipped());
7941 ASSERT_TRUE(expected_child_impl->is_clipped());
7942
7943 EXPECT_EQ(parent_impl->clip_rect(), expected_parent_impl->clip_rect());
7944 EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect());
7945}
7946
Xianzhu Wang5b429f02019-08-29 20:45:277947// In layer tree mode, not using impl-side PropertyTreeBuilder.
Xianzhu Wang66e13e02019-09-18 20:39:127948TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBoundsWithMaskToBounds) {
Malay Keshavf8e2b482019-06-19 21:18:387949 // The custom clip API should have the same effect as if an intermediate
7950 // clip layer has been added to the layer tree. To check this the test creates
7951 // 2 subtree for a root layer. One of the subtree uses the clip API to clip
7952 // its subtree while the other uses an intermediate layer. The resulting clip
7953 // in draw properties are expected to be the same. In this test, the subtree
7954 // roots also have their masks to bounds property set.
7955 // -Root
7956 // - Parent [Clip set to |kClipBounds| using API]
7957 // - Child
7958 // - Clip Layer [Masks to bounds = true] [Layer bounds set to |kClipBounds|]
7959 // - Expected Parent [Masks to bounds = true]
7960 // - Expected Child
7961 constexpr float kDeviceScale = 1.f;
7962
7963 const gfx::Rect kRootLayerBounds(0, 0, 100, 100);
7964 const gfx::Rect kParentLayerBounds(0, 0, 50, 100);
7965 const gfx::Rect kChildLayerBounds(20, 20, 30, 60);
7966
7967 constexpr gfx::Rect kClipBounds(10, 10, 50, 50);
7968
7969 // The position of |Expected Parent| on screen should be same as |Parent|.
7970 const gfx::Rect kExpectedParentLayerBounds(
7971 gfx::Point(0, 0) - kClipBounds.OffsetFromOrigin(), gfx::Size(50, 100));
7972
7973 scoped_refptr<Layer> root = Layer::Create();
7974 scoped_refptr<Layer> parent = Layer::Create();
7975 scoped_refptr<Layer> child = Layer::Create();
7976
7977 scoped_refptr<Layer> clip_layer = Layer::Create();
7978 scoped_refptr<Layer> expected_parent = Layer::Create();
7979 scoped_refptr<Layer> expected_child = Layer::Create();
7980
7981 root->AddChild(parent);
7982 parent->AddChild(child);
7983
7984 root->AddChild(clip_layer);
7985 clip_layer->AddChild(expected_parent);
7986 expected_parent->AddChild(expected_child);
7987
7988 host()->SetRootLayer(root);
7989
7990 root->SetIsDrawable(true);
7991 parent->SetIsDrawable(true);
7992 child->SetIsDrawable(true);
7993 expected_parent->SetIsDrawable(true);
7994 expected_child->SetIsDrawable(true);
7995
7996 // Set layer positions.
7997 root->SetPosition(gfx::PointF(kRootLayerBounds.origin()));
7998 parent->SetPosition(gfx::PointF(kParentLayerBounds.origin()));
7999 child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
8000
8001 clip_layer->SetPosition(gfx::PointF(kClipBounds.origin()));
8002 expected_parent->SetPosition(
8003 gfx::PointF(kExpectedParentLayerBounds.origin()));
8004 expected_child->SetPosition(gfx::PointF(kChildLayerBounds.origin()));
8005
8006 root->SetBounds(kRootLayerBounds.size());
8007 parent->SetBounds(kParentLayerBounds.size());
8008 child->SetBounds(kChildLayerBounds.size());
8009
8010 clip_layer->SetBounds(kClipBounds.size());
8011 expected_parent->SetBounds(kExpectedParentLayerBounds.size());
8012 expected_child->SetBounds(kChildLayerBounds.size());
8013
8014 parent->SetClipRect(kClipBounds);
8015 parent->SetMasksToBounds(true);
8016
8017 clip_layer->SetMasksToBounds(true);
8018 expected_parent->SetMasksToBounds(true);
8019
Xianzhu Wang66e13e02019-09-18 20:39:128020 UpdateMainDrawProperties(kDeviceScale);
Malay Keshavf8e2b482019-06-19 21:18:388021
Malay Keshavf8e2b482019-06-19 21:18:388022 const gfx::RectF expected_clip_bounds = gfx::IntersectRects(
8023 gfx::RectF(kClipBounds), gfx::RectF(kParentLayerBounds));
Xianzhu Wang5b429f02019-08-29 20:45:278024 EXPECT_EQ(GetClipNode(parent.get())->clip, expected_clip_bounds);
Malay Keshavf8e2b482019-06-19 21:18:388025 EXPECT_TRUE(!parent->clip_rect().IsEmpty());
8026
Xianzhu Wang5b429f02019-08-29 20:45:278027 EXPECT_EQ(GetClipNode(child.get())->clip, expected_clip_bounds);
Malay Keshavf8e2b482019-06-19 21:18:388028
Xianzhu Wang66e13e02019-09-18 20:39:128029 CommitAndActivate(kDeviceScale);
Malay Keshavf8e2b482019-06-19 21:18:388030 LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree();
8031
8032 // Get the layer impl for each Layer.
Malay Keshavf8e2b482019-06-19 21:18:388033 LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id());
8034 LayerImpl* child_impl = layer_tree_impl->LayerById(child->id());
8035 LayerImpl* expected_parent_impl =
8036 layer_tree_impl->LayerById(expected_parent->id());
8037 LayerImpl* expected_child_impl =
8038 layer_tree_impl->LayerById(expected_child->id());
8039
Xianzhu Wang66e13e02019-09-18 20:39:128040 EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor());
Malay Keshavf8e2b482019-06-19 21:18:388041
8042 EXPECT_TRUE(parent_impl->is_clipped());
8043 EXPECT_TRUE(child_impl->is_clipped());
8044 ASSERT_TRUE(expected_parent_impl->is_clipped());
8045 ASSERT_TRUE(expected_child_impl->is_clipped());
8046
8047 EXPECT_EQ(parent_impl->clip_rect(), expected_parent_impl->clip_rect());
8048 EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect());
8049}
8050
Malay Keshav4a580f52019-10-01 20:27:448051// In layer tree mode, not using impl-side PropertyTreeBuilder.
8052TEST_F(DrawPropertiesTestWithLayerTree, RoundedCornerOnRenderSurface) {
8053 // -Root
8054 // - Parent 1
8055 // - [Render Surface] Child 1 with rounded corner
8056 // - [Render Surface] Parent 2 with rounded corner
8057 // - [Render Surface] Child 2
8058 // - Parent 3 with rounded corner
8059 // - [Render Surface] Child 3
8060
8061 scoped_refptr<Layer> root = Layer::Create();
8062 host()->SetRootLayer(root);
8063 root->SetBounds(gfx::Size(250, 250));
8064 root->SetIsDrawable(true);
8065
8066 scoped_refptr<Layer> parent_1 = Layer::Create();
8067 root->AddChild(parent_1);
8068 parent_1->SetBounds(gfx::Size(80, 80));
8069 parent_1->SetPosition(gfx::PointF(0, 0));
8070 parent_1->SetIsDrawable(true);
8071
8072 scoped_refptr<Layer> parent_2 = Layer::Create();
8073 root->AddChild(parent_2);
8074 parent_2->SetBounds(gfx::Size(80, 80));
8075 parent_1->SetPosition(gfx::PointF(80, 80));
8076 parent_2->SetIsDrawable(true);
8077 parent_2->SetForceRenderSurfaceForTesting(true);
8078 parent_2->SetRoundedCorner(gfx::RoundedCornersF(10.f));
8079 parent_2->SetIsFastRoundedCorner(true);
8080
8081 scoped_refptr<Layer> parent_3 = Layer::Create();
8082 root->AddChild(parent_3);
8083 parent_3->SetBounds(gfx::Size(80, 80));
8084 parent_1->SetPosition(gfx::PointF(160, 160));
8085 parent_3->SetIsDrawable(true);
8086 parent_3->SetRoundedCorner(gfx::RoundedCornersF(10.f));
8087 parent_3->SetIsFastRoundedCorner(true);
8088
8089 scoped_refptr<Layer> child_1 = Layer::Create();
8090 parent_1->AddChild(child_1);
8091 child_1->SetBounds(gfx::Size(80, 80));
8092 child_1->SetIsDrawable(true);
8093 child_1->SetForceRenderSurfaceForTesting(true);
8094 child_1->SetRoundedCorner(gfx::RoundedCornersF(10.f));
8095 child_1->SetIsFastRoundedCorner(true);
8096
8097 scoped_refptr<Layer> child_2 = Layer::Create();
8098 parent_2->AddChild(child_2);
8099 child_2->SetBounds(gfx::Size(80, 80));
8100 child_2->SetIsDrawable(true);
8101 child_2->SetForceRenderSurfaceForTesting(true);
8102
8103 scoped_refptr<Layer> child_3 = Layer::Create();
8104 parent_3->AddChild(child_3);
8105 child_3->SetBounds(gfx::Size(80, 80));
8106 child_3->SetIsDrawable(true);
8107 child_3->SetForceRenderSurfaceForTesting(true);
8108
8109 UpdateMainDrawProperties();
8110 CommitAndActivate();
8111
8112 EXPECT_FALSE(
8113 GetRenderSurfaceImpl(child_1)->rounded_corner_bounds().IsEmpty());
8114 EXPECT_FALSE(
8115 GetRenderSurfaceImpl(child_2)->rounded_corner_bounds().IsEmpty());
8116 EXPECT_FALSE(
8117 GetRenderSurfaceImpl(child_3)->rounded_corner_bounds().IsEmpty());
8118}
8119
[email protected]ba565742012-11-10 09:29:488120} // namespace
8121} // namespace cc