1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "ui/compositor/layer_owner.h"
7 #include "base/test/null_task_runner.h"
8 #include "testing/gtest/include/gtest/gtest.h"
9 #include "ui/compositor/compositor.h"
10 #include "ui/compositor/layer.h"
11 #include "ui/compositor/layer_animation_observer.h"
12 #include "ui/compositor/layer_animator.h"
13 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
14 #include "ui/compositor/scoped_layer_animation_settings.h"
15 #include "ui/compositor/test/context_factories_for_test.h"
16 #include "ui/gfx/native_widget_types.h"
21 // An animation observer that confirms upon animation completion, that the
22 // compositor is not null.
23 class TestLayerAnimationObserver
: public ImplicitAnimationObserver
{
25 TestLayerAnimationObserver(Layer
* layer
) : layer_(layer
) {}
26 ~TestLayerAnimationObserver() override
{}
28 // ImplicitAnimationObserver:
29 void OnImplicitAnimationsCompleted() override
{
30 EXPECT_NE(nullptr, layer_
->GetCompositor());
36 DISALLOW_COPY_AND_ASSIGN(TestLayerAnimationObserver
);
39 // Test fixture for LayerOwner tests that require a ui::Compositor.
40 class LayerOwnerTestWithCompositor
: public testing::Test
{
42 LayerOwnerTestWithCompositor();
43 ~LayerOwnerTestWithCompositor() override
;
45 void SetUp() override
;
46 void TearDown() override
;
49 ui::Compositor
* compositor() { return compositor_
.get(); }
52 scoped_ptr
<ui::Compositor
> compositor_
;
54 DISALLOW_COPY_AND_ASSIGN(LayerOwnerTestWithCompositor
);
57 LayerOwnerTestWithCompositor::LayerOwnerTestWithCompositor() {
60 LayerOwnerTestWithCompositor::~LayerOwnerTestWithCompositor() {
63 void LayerOwnerTestWithCompositor::SetUp() {
64 scoped_refptr
<base::SingleThreadTaskRunner
> task_runner
=
65 new base::NullTaskRunner();
67 ui::ContextFactory
* context_factory
=
68 ui::InitializeContextFactoryForTests(false);
70 compositor_
.reset(new ui::Compositor(gfx::kNullAcceleratedWidget
,
71 context_factory
, task_runner
));
74 void LayerOwnerTestWithCompositor::TearDown() {
76 ui::TerminateContextFactoryForTests();
81 TEST(LayerOwnerTest
, RecreateLayerHonorsAnimationTargets
) {
83 Layer
* layer
= new Layer(LAYER_SOLID_COLOR
);
84 layer
->SetVisible(true);
85 layer
->SetOpacity(1.0f
);
86 layer
->SetColor(SK_ColorRED
);
88 owner
.SetLayer(layer
);
90 ScopedLayerAnimationSettings
settings(layer
->GetAnimator());
91 layer
->SetVisible(false);
92 layer
->SetOpacity(0.0f
);
93 layer
->SetColor(SK_ColorGREEN
);
94 EXPECT_TRUE(layer
->visible());
95 EXPECT_EQ(1.0f
, layer
->opacity());
96 EXPECT_EQ(SK_ColorRED
, layer
->background_color());
98 scoped_ptr
<Layer
> old_layer(owner
.RecreateLayer());
99 EXPECT_FALSE(owner
.layer()->visible());
100 EXPECT_EQ(0.0f
, owner
.layer()->opacity());
101 EXPECT_EQ(SK_ColorGREEN
, owner
.layer()->background_color());
104 // Tests that when a LAYER_SOLID_COLOR which is not backed by a SolidColorLayer
105 // that opaqueness and color targets are maintained when the
106 // LayerOwner::RecreateLayers is called.
107 TEST(LayerOwnerTest
, RecreateLayerSolidColorWithChangedCCLayerHonorsTargets
) {
108 SkColor transparent
= SK_ColorTRANSPARENT
;
110 Layer
* layer
= new Layer(LAYER_SOLID_COLOR
);
111 owner
.SetLayer(layer
);
112 layer
->SetFillsBoundsOpaquely(false);
113 layer
->SetColor(transparent
);
114 // Changing the backing layer takes LAYER_SOLID_COLOR off of the normal layer
115 // flow, need to ensure that set values are maintained.
116 layer
->SwitchCCLayerForTest();
118 EXPECT_FALSE(layer
->fills_bounds_opaquely());
119 EXPECT_EQ(transparent
, layer
->background_color());
120 EXPECT_EQ(transparent
, layer
->GetTargetColor());
122 scoped_ptr
<Layer
> old_layer(owner
.RecreateLayer());
123 EXPECT_FALSE(owner
.layer()->fills_bounds_opaquely());
124 EXPECT_EQ(transparent
, owner
.layer()->background_color());
125 EXPECT_EQ(transparent
, owner
.layer()->GetTargetColor());
128 TEST(LayerOwnerTest
, RecreateRootLayerWithNullCompositor
) {
130 Layer
* layer
= new Layer
;
131 owner
.SetLayer(layer
);
133 scoped_ptr
<Layer
> layer_copy
= owner
.RecreateLayer();
135 EXPECT_EQ(nullptr, owner
.layer()->GetCompositor());
136 EXPECT_EQ(nullptr, layer_copy
->GetCompositor());
139 TEST_F(LayerOwnerTestWithCompositor
, RecreateRootLayerWithCompositor
) {
141 Layer
* layer
= new Layer
;
142 owner
.SetLayer(layer
);
144 compositor()->SetRootLayer(layer
);
146 scoped_ptr
<Layer
> layer_copy
= owner
.RecreateLayer();
148 EXPECT_EQ(compositor(), owner
.layer()->GetCompositor());
149 EXPECT_EQ(owner
.layer(), compositor()->root_layer());
150 EXPECT_EQ(nullptr, layer_copy
->GetCompositor());
153 // Tests that recreating the root layer, while one of its children is animating,
154 // properly updates the compositor. So that compositor is not null for observers
155 // of animations being cancelled.
156 TEST_F(LayerOwnerTestWithCompositor
, RecreateRootLayerDuringAnimation
) {
158 Layer
* layer
= new Layer
;
159 owner
.SetLayer(layer
);
160 compositor()->SetRootLayer(layer
);
162 scoped_ptr
<Layer
> child(new Layer
);
163 child
->SetBounds(gfx::Rect(0, 0, 100, 100));
164 layer
->Add(child
.get());
166 // This observer checks that the compositor of |child| is not null upon
167 // animation completion.
168 scoped_ptr
<TestLayerAnimationObserver
> observer(
169 new TestLayerAnimationObserver(child
.get()));
170 scoped_ptr
<ui::ScopedAnimationDurationScaleMode
> long_duration_animation(
171 new ui::ScopedAnimationDurationScaleMode(
172 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION
));
174 ui::ScopedLayerAnimationSettings
animation(child
->GetAnimator());
175 animation
.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
176 animation
.AddObserver(observer
.get());
177 gfx::Transform transform
;
178 transform
.Scale(0.5f
, 0.5f
);
179 child
->SetTransform(transform
);
182 scoped_ptr
<Layer
> layer_copy
= owner
.RecreateLayer();
185 // Tests that recreating a non-root layer, while one of its children is
186 // animating, properly updates the compositor. So that compositor is not null
187 // for observers of animations being cancelled.
188 TEST_F(LayerOwnerTestWithCompositor
, RecreateNonRootLayerDuringAnimation
) {
189 scoped_ptr
<Layer
> root_layer(new Layer
);
190 compositor()->SetRootLayer(root_layer
.get());
193 Layer
* layer
= new Layer
;
194 owner
.SetLayer(layer
);
195 root_layer
->Add(layer
);
197 scoped_ptr
<Layer
> child(new Layer
);
198 child
->SetBounds(gfx::Rect(0, 0, 100, 100));
199 layer
->Add(child
.get());
201 // This observer checks that the compositor of |child| is not null upon
202 // animation completion.
203 scoped_ptr
<TestLayerAnimationObserver
> observer(
204 new TestLayerAnimationObserver(child
.get()));
205 scoped_ptr
<ui::ScopedAnimationDurationScaleMode
> long_duration_animation(
206 new ui::ScopedAnimationDurationScaleMode(
207 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION
));
209 ui::ScopedLayerAnimationSettings
animation(child
->GetAnimator());
210 animation
.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
211 animation
.AddObserver(observer
.get());
212 gfx::Transform transform
;
213 transform
.Scale(0.5f
, 0.5f
);
214 child
->SetTransform(transform
);
217 scoped_ptr
<Layer
> layer_copy
= owner
.RecreateLayer();