blob: d97c7e846af26ce7d0c29117fe56469294f3bcb7 [file] [log] [blame]
[email protected]caa1aafd2012-01-12 21:56:061// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]ad7258912011-08-29 20:33:532// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
dcheng79c14492015-12-18 05:07:265#include "ui/compositor/layer.h"
6
avi87b8b582015-12-24 21:35:257#include <stddef.h>
8
danakj25c52c32016-04-12 21:51:089#include <memory>
dcheng79c14492015-12-18 05:07:2610#include <utility>
Edwin Joe863d45302019-03-28 19:57:0411#include <vector>
dcheng79c14492015-12-18 05:07:2612
[email protected]f79729062013-04-03 20:01:5013#include "base/bind.h"
Xiyuan Xiad2bcb9352020-01-10 23:02:5914#include "base/callback.h"
[email protected]00b86982011-09-01 00:02:0915#include "base/compiler_specific.h"
[email protected]57999812013-02-24 05:40:5216#include "base/files/file_path.h"
thestig22dfc4012014-09-05 08:29:4417#include "base/files/file_util.h"
[email protected]36c391d2014-01-22 18:44:5018#include "base/json/json_reader.h"
avi87b8b582015-12-24 21:35:2519#include "base/macros.h"
[email protected]6f83e4f2011-11-15 21:25:3320#include "base/path_service.h"
Gabriel Charette078e3662017-08-28 22:59:0421#include "base/run_loop.h"
[email protected]f3652ff92013-06-11 13:54:3122#include "base/strings/string_util.h"
23#include "base/strings/stringprintf.h"
lof84a7578772016-07-19 20:39:3524#include "base/strings/utf_string_conversions.h"
Xiyuan Xiad2bcb9352020-01-10 23:02:5925#include "base/test/bind_test_util.h"
Gabriel Charettec7108742019-08-23 03:31:4026#include "base/test/task_environment.h"
jonross180dc482018-10-23 21:22:0927#include "base/time/time.h"
ssid334fb87a2015-01-27 20:12:0728#include "base/trace_event/trace_event.h"
Guido Urdaneta121a6e22017-11-17 11:01:0829#include "build/build_config.h"
Yi Gub0422c42020-01-13 17:00:3630#include "cc/animation/animation.h"
Francois Doray9b3b01282017-09-20 12:31:4631#include "cc/animation/animation_events.h"
32#include "cc/animation/animation_host.h"
Yi Gu3904dc22018-02-15 18:35:2433#include "cc/animation/keyframe_effect.h"
[email protected]cc3cfaa2013-03-18 09:05:5234#include "cc/layers/layer.h"
Mohsen Izadi1bcbf252019-06-27 01:26:2935#include "cc/layers/mirror_layer.h"
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:4036#include "cc/test/pixel_comparator.h"
[email protected]1b901a32012-12-07 08:52:0337#include "cc/test/pixel_test_utils.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"
danakj4957a222017-11-21 17:23:1040#include "components/viz/common/resources/transferable_resource.h"
Jennifer Apacibleea38ede2018-03-15 02:41:5541#include "components/viz/common/surfaces/parent_local_surface_id_allocator.h"
Fady Samuel644df1d2017-07-13 01:13:0242#include "components/viz/common/surfaces/surface_id.h"
Francois Doray4f515ad2017-09-15 16:19:3443#include "testing/gmock/include/gmock/gmock.h"
[email protected]ad7258912011-08-29 20:33:5344#include "testing/gtest/include/gtest/gtest.h"
danakj6f2861b2016-08-17 02:10:1745#include "third_party/khronos/GLES2/gl2.h"
[email protected]116302fc2012-05-05 21:45:4146#include "ui/compositor/compositor_observer.h"
[email protected]e09c592ff2014-07-17 06:55:0747#include "ui/compositor/dip_util.h"
bruthig33b1edab2016-03-02 02:22:3548#include "ui/compositor/layer_animation_element.h"
49#include "ui/compositor/layer_animation_observer.h"
[email protected]116302fc2012-05-05 21:45:4150#include "ui/compositor/layer_animation_sequence.h"
[email protected]f2891462013-03-11 23:26:5151#include "ui/compositor/layer_animator.h"
danakj85d970e2015-04-04 00:15:2452#include "ui/compositor/paint_context.h"
danakjc7323222015-04-07 21:09:3853#include "ui/compositor/paint_recorder.h"
jonross31048b62015-05-20 02:09:2554#include "ui/compositor/scoped_animation_duration_scale_mode.h"
55#include "ui/compositor/scoped_layer_animation_settings.h"
[email protected]b58081d2014-01-24 10:13:5156#include "ui/compositor/test/draw_waiter_for_test.h"
Francois Doray9b3b01282017-09-20 12:31:4657#include "ui/compositor/test/layer_animator_test_controller.h"
[email protected]116302fc2012-05-05 21:45:4158#include "ui/compositor/test/test_compositor_host.h"
Mohsen Izadib3710182019-04-30 04:57:3559#include "ui/compositor/test/test_context_factories.h"
[email protected]2f19761c2013-05-22 13:04:3560#include "ui/compositor/test/test_layers.h"
Francois Doray8e962612017-11-10 20:51:2161#include "ui/gfx/animation/tween.h"
[email protected]94a0d2582012-03-09 00:30:5962#include "ui/gfx/canvas.h"
[email protected]6f83e4f2011-11-15 21:25:3363#include "ui/gfx/codec/png_codec.h"
lof84a7578772016-07-19 20:39:3564#include "ui/gfx/font_list.h"
Francois Doray8e962612017-11-10 20:51:2165#include "ui/gfx/interpolated_transform.h"
[email protected]caa1aafd2012-01-12 21:56:0666#include "ui/gfx/skia_util.h"
[email protected]ad7258912011-08-29 20:33:5367
[email protected]ca435682013-03-29 04:09:4768using cc::MatchesPNGFile;
lof84a7578772016-07-19 20:39:3569using cc::WritePNGFile;
[email protected]1b901a32012-12-07 08:52:0370
[email protected]ad7258912011-08-29 20:33:5371namespace ui {
72
73namespace {
74
[email protected]e4e8afef2011-10-05 13:58:3375// There are three test classes in here that configure the Compositor and
76// Layer's slightly differently:
[email protected]72f08de2011-12-09 16:19:0377// - LayerWithNullDelegateTest uses NullLayerDelegate as the LayerDelegate. This
78// is typically the base class you want to use.
79// - LayerWithDelegateTest uses LayerDelegate on the delegates.
[email protected]5610d512011-10-04 21:32:5780// - LayerWithRealCompositorTest when a real compositor is required for testing.
[email protected]e4e8afef2011-10-05 13:58:3381// - Slow because they bring up a window and run the real compositor. This
82// is typically not what you want.
[email protected]332749032011-10-22 00:32:4683
84class ColoredLayer : public Layer, public LayerDelegate {
85 public:
[email protected]7ab3f272011-11-16 00:51:5686 explicit ColoredLayer(SkColor color)
[email protected]595b52a2012-03-23 16:17:2487 : Layer(LAYER_TEXTURED),
[email protected]332749032011-10-22 00:32:4688 color_(color) {
89 set_delegate(this);
90 }
91
dchengbc07fa02014-10-29 20:07:2492 ~ColoredLayer() override {}
[email protected]332749032011-10-22 00:32:4693
94 // Overridden from LayerDelegate:
danakj85d970e2015-04-04 00:15:2495 void OnPaintLayer(const ui::PaintContext& context) override {
weiliangca032f93b2015-07-13 22:39:4796 ui::PaintRecorder recorder(context, size());
danakjc7323222015-04-07 21:09:3897 recorder.canvas()->DrawColor(color_);
danakj85d970e2015-04-04 00:15:2498 }
[email protected]332749032011-10-22 00:32:4699
Scott Violet06aff2b42017-09-08 00:26:32100 void OnDeviceScaleFactorChanged(float old_device_scale_factor,
101 float new_device_scale_factor) override {}
[email protected]d3f5bbc12012-05-17 00:09:04102
[email protected]332749032011-10-22 00:32:46103 private:
104 SkColor color_;
105};
106
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40107// Param specifies whether to use SkiaRenderer or not
108class LayerWithRealCompositorTest : public testing::TestWithParam<bool> {
[email protected]993d6b322011-09-27 19:14:38109 public:
jonross1ec7d992018-08-31 03:55:54110 LayerWithRealCompositorTest()
Gabriel Charettedfa36042019-08-19 17:30:11111 : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {
Etienne Bergeronab7a66b2019-04-15 19:27:03112 gfx::FontList::SetDefaultFontDescription("Segoe UI, 15px");
[email protected]fcb98b72011-11-18 04:29:18113 }
dchengbc07fa02014-10-29 20:07:24114 ~LayerWithRealCompositorTest() override {}
[email protected]993d6b322011-09-27 19:14:38115
116 // Overridden from testing::Test:
dchengbc07fa02014-10-29 20:07:24117 void SetUp() override {
Peter Kastingee6749472018-11-20 05:13:25118 ASSERT_TRUE(base::PathService::Get(base::DIR_SOURCE_ROOT, &test_data_dir_));
119 test_data_dir_ = test_data_dir_.Append(FILE_PATH_LITERAL("ui"))
120 .Append(FILE_PATH_LITERAL("gfx"))
121 .Append(FILE_PATH_LITERAL("test"))
122 .Append(FILE_PATH_LITERAL("data"))
123 .Append(FILE_PATH_LITERAL("compositor"));
124 ASSERT_TRUE(base::PathExists(test_data_dir_));
125
Mohsen Izadib3710182019-04-30 04:57:35126 const bool enable_pixel_output = true;
127 context_factories_ =
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40128 std::make_unique<TestContextFactories>(enable_pixel_output, GetParam());
[email protected]d56d3bb2013-08-12 20:58:01129
[email protected]993d6b322011-09-27 19:14:38130 const gfx::Rect host_bounds(10, 10, 500, 500);
fsamuela0bcfe12016-12-14 06:21:49131 compositor_host_.reset(TestCompositorHost::Create(
Sean Gilhulydc0b9fd2020-02-25 23:47:14132 host_bounds, context_factories_->GetContextFactory()));
[email protected]4eafa9692014-02-21 22:36:17133 compositor_host_->Show();
[email protected]993d6b322011-09-27 19:14:38134 }
135
dchengbc07fa02014-10-29 20:07:24136 void TearDown() override {
lof84adf2ce862015-06-02 22:23:32137 ResetCompositor();
Mohsen Izadib3710182019-04-30 04:57:35138 context_factories_.reset();
[email protected]993d6b322011-09-27 19:14:38139 }
140
[email protected]4eafa9692014-02-21 22:36:17141 Compositor* GetCompositor() { return compositor_host_->GetCompositor(); }
[email protected]993d6b322011-09-27 19:14:38142
lof84adf2ce862015-06-02 22:23:32143 void ResetCompositor() {
144 compositor_host_.reset();
145 }
146
Mohsen Izadi62a338d2019-07-30 19:49:47147 std::unique_ptr<Layer> CreateLayer(LayerType type) {
148 return std::make_unique<Layer>(type);
[email protected]993d6b322011-09-27 19:14:38149 }
150
Mohsen Izadi62a338d2019-07-30 19:49:47151 std::unique_ptr<Layer> CreateColorLayer(SkColor color,
152 const gfx::Rect& bounds) {
153 auto layer = std::make_unique<ColoredLayer>(color);
[email protected]993d6b322011-09-27 19:14:38154 layer->SetBounds(bounds);
[email protected]993d6b322011-09-27 19:14:38155 return layer;
156 }
157
Mohsen Izadi62a338d2019-07-30 19:49:47158 std::unique_ptr<Layer> CreateNoTextureLayer(const gfx::Rect& bounds) {
159 std::unique_ptr<Layer> layer = CreateLayer(LAYER_NOT_DRAWN);
[email protected]993d6b322011-09-27 19:14:38160 layer->SetBounds(bounds);
161 return layer;
162 }
163
[email protected]993d6b322011-09-27 19:14:38164 void DrawTree(Layer* root) {
165 GetCompositor()->SetRootLayer(root);
[email protected]f79729062013-04-03 20:01:50166 GetCompositor()->ScheduleDraw();
starazb14cc10cc2017-04-13 18:06:39167 WaitForSwap();
[email protected]993d6b322011-09-27 19:14:38168 }
169
weiliangccb9e0df2014-09-22 14:55:21170 void ReadPixels(SkBitmap* bitmap) {
171 ReadPixels(bitmap, gfx::Rect(GetCompositor()->size()));
[email protected]5fd58222014-01-30 23:16:01172 }
173
weiliangccb9e0df2014-09-22 14:55:21174 void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) {
[email protected]5fd58222014-01-30 23:16:01175 scoped_refptr<ReadbackHolder> holder(new ReadbackHolder);
Fady Samueldfecb7d2017-07-26 11:41:04176 std::unique_ptr<viz::CopyOutputRequest> request =
Yuri Wiitalab9ad27a2017-09-06 19:13:50177 std::make_unique<viz::CopyOutputRequest>(
178 viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP,
Yuri Wiitalab2511762017-07-19 00:17:53179 base::BindOnce(&ReadbackHolder::OutputRequestCallback, holder));
[email protected]5fd58222014-01-30 23:16:01180 request->set_area(source_rect);
181
dcheng79c14492015-12-18 05:07:26182 GetCompositor()->root_layer()->RequestCopyOfOutput(std::move(request));
[email protected]5fd58222014-01-30 23:16:01183
[email protected]2decdd782014-08-13 22:36:06184 // Wait for copy response. This needs to wait as the compositor could
185 // be in the middle of a draw right now, and the commit with the
186 // copy output request may not be done on the first draw.
187 for (int i = 0; i < 2; i++) {
weiliangc5efa0a12015-01-29 19:56:46188 GetCompositor()->ScheduleFullRedraw();
[email protected]5fd58222014-01-30 23:16:01189 WaitForDraw();
190 }
191
weiliangccb9e0df2014-09-22 14:55:21192 // Waits for the callback to finish run and return result.
193 holder->WaitForReadback();
[email protected]5fd58222014-01-30 23:16:01194
weiliangccb9e0df2014-09-22 14:55:21195 *bitmap = holder->result();
[email protected]d86e97e2011-11-21 15:06:26196 }
197
weiliangc5efa0a12015-01-29 19:56:46198 void WaitForDraw() {
199 ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor());
200 }
201
starazb14cc10cc2017-04-13 18:06:39202 void WaitForSwap() {
203 ui::DrawWaiterForTest::WaitForCompositingEnded(GetCompositor());
204 }
205
[email protected]36e5ff12013-06-11 12:19:29206 void WaitForCommit() {
207 ui::DrawWaiterForTest::WaitForCommit(GetCompositor());
208 }
209
[email protected]993d6b322011-09-27 19:14:38210 // Invalidates the entire contents of the layer.
211 void SchedulePaintForLayer(Layer* layer) {
212 layer->SchedulePaint(
213 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
214 }
215
Peter Kastingee6749472018-11-20 05:13:25216 const base::FilePath& test_data_dir() const { return test_data_dir_; }
[email protected]fcb98b72011-11-18 04:29:18217
[email protected]993d6b322011-09-27 19:14:38218 private:
[email protected]5fd58222014-01-30 23:16:01219 class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> {
220 public:
Mohsen Izadi62a338d2019-07-30 19:49:47221 ReadbackHolder() : run_loop_(std::make_unique<base::RunLoop>()) {}
[email protected]5fd58222014-01-30 23:16:01222
Fady Samueldfecb7d2017-07-26 11:41:04223 void OutputRequestCallback(std::unique_ptr<viz::CopyOutputResult> result) {
Yuri Wiitalab9ad27a2017-09-06 19:13:50224 if (result->IsEmpty())
225 result_.reset();
226 else
227 result_ = std::make_unique<SkBitmap>(result->AsSkBitmap());
weiliangccb9e0df2014-09-22 14:55:21228 run_loop_->Quit();
[email protected]5fd58222014-01-30 23:16:01229 }
weiliangccb9e0df2014-09-22 14:55:21230
231 void WaitForReadback() { run_loop_->Run(); }
232
[email protected]5fd58222014-01-30 23:16:01233 const SkBitmap& result() const { return *result_; }
234
235 private:
236 friend class base::RefCountedThreadSafe<ReadbackHolder>;
237
238 virtual ~ReadbackHolder() {}
239
danakj25c52c32016-04-12 21:51:08240 std::unique_ptr<SkBitmap> result_;
241 std::unique_ptr<base::RunLoop> run_loop_;
[email protected]5fd58222014-01-30 23:16:01242 };
243
Gabriel Charettedfa36042019-08-19 17:30:11244 base::test::TaskEnvironment task_environment_;
Mohsen Izadib3710182019-04-30 04:57:35245 std::unique_ptr<TestContextFactories> context_factories_;
danakj25c52c32016-04-12 21:51:08246 std::unique_ptr<TestCompositorHost> compositor_host_;
[email protected]993d6b322011-09-27 19:14:38247
[email protected]fcb98b72011-11-18 04:29:18248 // The root directory for test files.
Peter Kastingee6749472018-11-20 05:13:25249 base::FilePath test_data_dir_;
[email protected]fcb98b72011-11-18 04:29:18250
[email protected]4916d622011-09-28 23:45:38251 DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest);
[email protected]993d6b322011-09-27 19:14:38252};
253
254// LayerDelegate that paints colors to the layer.
[email protected]00b86982011-09-01 00:02:09255class TestLayerDelegate : public LayerDelegate {
[email protected]28cd2bb2011-09-19 21:04:19256 public:
thestigd5fcf982015-05-11 18:41:38257 TestLayerDelegate() { reset(); }
dchengbc07fa02014-10-29 20:07:24258 ~TestLayerDelegate() override {}
[email protected]00b86982011-09-01 00:02:09259
260 void AddColor(SkColor color) {
261 colors_.push_back(color);
262 }
263
[email protected]00b86982011-09-01 00:02:09264 int color_index() const { return color_index_; }
265
[email protected]d3f5bbc12012-05-17 00:09:04266 float device_scale_factor() const {
267 return device_scale_factor_;
268 }
269
weiliangca032f93b2015-07-13 22:39:47270 void set_layer_bounds(const gfx::Rect& layer_bounds) {
271 layer_bounds_ = layer_bounds;
272 }
273
[email protected]00b86982011-09-01 00:02:09274 // Overridden from LayerDelegate:
danakj85d970e2015-04-04 00:15:24275 void OnPaintLayer(const ui::PaintContext& context) override {
weiliangca032f93b2015-07-13 22:39:47276 ui::PaintRecorder recorder(context, layer_bounds_.size());
danakjc7323222015-04-07 21:09:38277 recorder.canvas()->DrawColor(colors_[color_index_]);
[email protected]7b013fc2011-09-22 23:12:34278 color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size());
[email protected]00b86982011-09-01 00:02:09279 }
280
Scott Violet06aff2b42017-09-08 00:26:32281 void OnDeviceScaleFactorChanged(float old_device_scale_factor,
282 float new_device_scale_factor) override {
283 device_scale_factor_ = new_device_scale_factor;
[email protected]d3f5bbc12012-05-17 00:09:04284 }
285
Francois Doray8e962612017-11-10 20:51:21286 MOCK_METHOD2(OnLayerBoundsChanged,
287 void(const gfx::Rect&, PropertyChangeReason));
Scott Violetac1a8082018-03-19 05:14:34288 MOCK_METHOD2(OnLayerTransformed,
289 void(const gfx::Transform&, PropertyChangeReason));
Francois Doray8e962612017-11-10 20:51:21290 MOCK_METHOD1(OnLayerOpacityChanged, void(PropertyChangeReason));
Francois Doraya3a0b7f42018-08-15 15:44:32291 MOCK_METHOD0(OnLayerAlphaShapeChanged, void());
Francois Doray4f515ad2017-09-15 16:19:34292
[email protected]07908eb2012-05-09 00:15:30293 void reset() {
294 color_index_ = 0;
[email protected]d3f5bbc12012-05-17 00:09:04295 device_scale_factor_ = 0.0f;
[email protected]07908eb2012-05-09 00:15:30296 }
297
[email protected]28cd2bb2011-09-19 21:04:19298 private:
[email protected]00b86982011-09-01 00:02:09299 std::vector<SkColor> colors_;
300 int color_index_;
[email protected]d3f5bbc12012-05-17 00:09:04301 float device_scale_factor_;
weiliangca032f93b2015-07-13 22:39:47302 gfx::Rect layer_bounds_;
[email protected]00b86982011-09-01 00:02:09303
304 DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate);
305};
306
[email protected]993d6b322011-09-27 19:14:38307// LayerDelegate that verifies that a layer was asked to update its canvas.
[email protected]28cd2bb2011-09-19 21:04:19308class DrawTreeLayerDelegate : public LayerDelegate {
[email protected]3aa43942011-09-13 20:59:53309 public:
Sean Gilhulydc0b9fd2020-02-25 23:47:14310 explicit DrawTreeLayerDelegate(const gfx::Rect& layer_bounds)
weiliangca032f93b2015-07-13 22:39:47311 : painted_(false), layer_bounds_(layer_bounds) {}
Sean Gilhulydc0b9fd2020-02-25 23:47:14312 ~DrawTreeLayerDelegate() override = default;
[email protected]3aa43942011-09-13 20:59:53313
[email protected]28cd2bb2011-09-19 21:04:19314 void Reset() {
315 painted_ = false;
[email protected]3aa43942011-09-13 20:59:53316 }
317
[email protected]28cd2bb2011-09-19 21:04:19318 bool painted() const { return painted_; }
319
[email protected]993d6b322011-09-27 19:14:38320 private:
[email protected]28cd2bb2011-09-19 21:04:19321 // Overridden from LayerDelegate:
danakj85d970e2015-04-04 00:15:24322 void OnPaintLayer(const ui::PaintContext& context) override {
[email protected]28cd2bb2011-09-19 21:04:19323 painted_ = true;
weiliangca032f93b2015-07-13 22:39:47324 ui::PaintRecorder recorder(context, layer_bounds_.size());
danakjc7323222015-04-07 21:09:38325 recorder.canvas()->DrawColor(SK_ColorWHITE);
[email protected]3aa43942011-09-13 20:59:53326 }
Scott Violet06aff2b42017-09-08 00:26:32327 void OnDeviceScaleFactorChanged(float old_device_scale_factor,
328 float new_device_scale_factor) override {}
[email protected]3aa43942011-09-13 20:59:53329
[email protected]28cd2bb2011-09-19 21:04:19330 bool painted_;
weiliangca032f93b2015-07-13 22:39:47331 const gfx::Rect layer_bounds_;
[email protected]3aa43942011-09-13 20:59:53332
[email protected]28cd2bb2011-09-19 21:04:19333 DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate);
[email protected]3aa43942011-09-13 20:59:53334};
335
[email protected]993d6b322011-09-27 19:14:38336// The simplest possible layer delegate. Does nothing.
337class NullLayerDelegate : public LayerDelegate {
338 public:
339 NullLayerDelegate() {}
dchengbc07fa02014-10-29 20:07:24340 ~NullLayerDelegate() override {}
[email protected]993d6b322011-09-27 19:14:38341
wutao61373a392017-09-26 18:45:35342 gfx::Rect invalidation() const { return invalidation_; }
343
[email protected]993d6b322011-09-27 19:14:38344 private:
wutao61373a392017-09-26 18:45:35345 gfx::Rect invalidation_;
346
[email protected]993d6b322011-09-27 19:14:38347 // Overridden from LayerDelegate:
wutao61373a392017-09-26 18:45:35348 void OnPaintLayer(const ui::PaintContext& context) override {
349 invalidation_ = context.InvalidationForTesting();
350 }
Scott Violet06aff2b42017-09-08 00:26:32351 void OnDeviceScaleFactorChanged(float old_device_scale_factor,
352 float new_device_scale_factor) override {}
[email protected]993d6b322011-09-27 19:14:38353
354 DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate);
355};
356
[email protected]05fab8d2011-11-16 02:15:33357// Remembers if it has been notified.
358class TestCompositorObserver : public CompositorObserver {
359 public:
danakj6c872fc02016-10-22 04:29:49360 TestCompositorObserver() = default;
[email protected]05fab8d2011-11-16 02:15:33361
[email protected]36e5ff12013-06-11 12:19:29362 bool committed() const { return committed_; }
starazb14cc10cc2017-04-13 18:06:39363 bool notified() const { return started_ && ended_; }
[email protected]05fab8d2011-11-16 02:15:33364
[email protected]a8f677c2012-03-23 01:36:06365 void Reset() {
[email protected]36e5ff12013-06-11 12:19:29366 committed_ = false;
[email protected]a8f677c2012-03-23 01:36:06367 started_ = false;
starazb14cc10cc2017-04-13 18:06:39368 ended_ = false;
[email protected]05fab8d2011-11-16 02:15:33369 }
370
[email protected]a8f677c2012-03-23 01:36:06371 private:
dchengbc07fa02014-10-29 20:07:24372 void OnCompositingDidCommit(Compositor* compositor) override {
[email protected]36e5ff12013-06-11 12:19:29373 committed_ = true;
[email protected]2700daddd2012-07-13 19:35:37374 }
375
dchengbc07fa02014-10-29 20:07:24376 void OnCompositingStarted(Compositor* compositor,
377 base::TimeTicks start_time) override {
[email protected]a8f677c2012-03-23 01:36:06378 started_ = true;
379 }
380
starazb14cc10cc2017-04-13 18:06:39381 void OnCompositingEnded(Compositor* compositor) override { ended_ = true; }
382
danakj6c872fc02016-10-22 04:29:49383 bool committed_ = false;
384 bool started_ = false;
starazb14cc10cc2017-04-13 18:06:39385 bool ended_ = false;
[email protected]05fab8d2011-11-16 02:15:33386
387 DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver);
388};
389
lof84adf2ce862015-06-02 22:23:32390class TestCompositorAnimationObserver : public CompositorAnimationObserver {
391 public:
392 explicit TestCompositorAnimationObserver(ui::Compositor* compositor)
393 : compositor_(compositor),
394 animation_step_count_(0),
395 shutdown_(false) {
396 DCHECK(compositor_);
397 compositor_->AddAnimationObserver(this);
398 }
399
400 ~TestCompositorAnimationObserver() override {
401 if (compositor_)
402 compositor_->RemoveAnimationObserver(this);
403 }
404
405 size_t animation_step_count() const { return animation_step_count_; }
406 bool shutdown() const { return shutdown_; }
407
408 private:
409 void OnAnimationStep(base::TimeTicks timestamp) override {
410 ++animation_step_count_;
411 }
412
413 void OnCompositingShuttingDown(Compositor* compositor) override {
414 DCHECK_EQ(compositor_, compositor);
415 compositor_->RemoveAnimationObserver(this);
416 compositor_ = nullptr;
417 shutdown_ = true;
418 }
419
420 ui::Compositor* compositor_;
421 size_t animation_step_count_;
422 bool shutdown_;
423
424 DISALLOW_COPY_AND_ASSIGN(TestCompositorAnimationObserver);
425};
426
Xiyuan Xiad2bcb9352020-01-10 23:02:59427// An animation observer that invokes a callback when the animation ends.
428class TestCallbackAnimationObserver : public ImplicitAnimationObserver {
429 public:
430 TestCallbackAnimationObserver() = default;
431
432 void SetCallback(base::OnceClosure callback) {
433 callback_ = std::move(callback);
434 }
435
436 // ui::ImplicitAnimationObserver overrides:
437 void OnImplicitAnimationsCompleted() override {}
438 void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override {
439 if (callback_)
440 std::move(callback_).Run();
441 }
442
443 private:
444 base::OnceClosure callback_;
445};
446
[email protected]caa1aafd2012-01-12 21:56:06447} // namespace
[email protected]ad7258912011-08-29 20:33:53448
Ilia Samsonove2d8abe2019-11-20 22:25:24449INSTANTIATE_TEST_SUITE_P(All, LayerWithRealCompositorTest, ::testing::Bool());
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40450
451TEST_P(LayerWithRealCompositorTest, Draw) {
Mohsen Izadi62a338d2019-07-30 19:49:47452 std::unique_ptr<Layer> layer =
453 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 50, 50));
[email protected]ad7258912011-08-29 20:33:53454 DrawTree(layer.get());
455}
456
457// Create this hierarchy:
458// L1 - red
459// +-- L2 - blue
460// | +-- L3 - yellow
461// +-- L4 - magenta
462//
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40463TEST_P(LayerWithRealCompositorTest, Hierarchy) {
Mohsen Izadi62a338d2019-07-30 19:49:47464 std::unique_ptr<Layer> l1 =
465 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
466 std::unique_ptr<Layer> l2 =
467 CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 350, 350));
468 std::unique_ptr<Layer> l3 =
469 CreateColorLayer(SK_ColorYELLOW, gfx::Rect(5, 5, 25, 25));
470 std::unique_ptr<Layer> l4 =
471 CreateColorLayer(SK_ColorMAGENTA, gfx::Rect(300, 300, 100, 100));
[email protected]ad7258912011-08-29 20:33:53472
473 l1->Add(l2.get());
474 l1->Add(l4.get());
475 l2->Add(l3.get());
476
477 DrawTree(l1.get());
478}
479
[email protected]c3fac4d2013-10-17 22:10:05480class LayerWithDelegateTest : public testing::Test {
[email protected]4916d622011-09-28 23:45:38481 public:
jonross1ec7d992018-08-31 03:55:54482 LayerWithDelegateTest()
Gabriel Charettedfa36042019-08-19 17:30:11483 : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
dchengbc07fa02014-10-29 20:07:24484 ~LayerWithDelegateTest() override {}
[email protected]4916d622011-09-28 23:45:38485
486 // Overridden from testing::Test:
dchengbc07fa02014-10-29 20:07:24487 void SetUp() override {
Mohsen Izadib3710182019-04-30 04:57:35488 const bool enable_pixel_output = false;
489 context_factories_ =
490 std::make_unique<TestContextFactories>(enable_pixel_output);
[email protected]d57eca12014-02-21 02:39:22491
492 const gfx::Rect host_bounds(1000, 1000);
fsamuela0bcfe12016-12-14 06:21:49493 compositor_host_.reset(TestCompositorHost::Create(
Sean Gilhulydc0b9fd2020-02-25 23:47:14494 host_bounds, context_factories_->GetContextFactory()));
[email protected]d57eca12014-02-21 02:39:22495 compositor_host_->Show();
[email protected]4916d622011-09-28 23:45:38496 }
497
dchengbc07fa02014-10-29 20:07:24498 void TearDown() override {
[email protected]d57eca12014-02-21 02:39:22499 compositor_host_.reset();
Mohsen Izadib3710182019-04-30 04:57:35500 context_factories_.reset();
[email protected]4916d622011-09-28 23:45:38501 }
502
[email protected]d57eca12014-02-21 02:39:22503 Compositor* compositor() { return compositor_host_->GetCompositor(); }
[email protected]4916d622011-09-28 23:45:38504
Mohsen Izadi62a338d2019-07-30 19:49:47505 virtual std::unique_ptr<Layer> CreateLayer(LayerType type) {
506 return std::make_unique<Layer>(type);
[email protected]4916d622011-09-28 23:45:38507 }
508
Mohsen Izadi62a338d2019-07-30 19:49:47509 std::unique_ptr<Layer> CreateColorLayer(SkColor color,
510 const gfx::Rect& bounds) {
511 auto layer = std::make_unique<ColoredLayer>(color);
[email protected]4916d622011-09-28 23:45:38512 layer->SetBounds(bounds);
[email protected]4916d622011-09-28 23:45:38513 return layer;
514 }
515
Mohsen Izadi62a338d2019-07-30 19:49:47516 virtual std::unique_ptr<Layer> CreateNoTextureLayer(const gfx::Rect& bounds) {
517 std::unique_ptr<Layer> layer = CreateLayer(LAYER_NOT_DRAWN);
[email protected]4916d622011-09-28 23:45:38518 layer->SetBounds(bounds);
519 return layer;
520 }
521
[email protected]4916d622011-09-28 23:45:38522 void DrawTree(Layer* root) {
523 compositor()->SetRootLayer(root);
[email protected]44ed4bd2013-04-06 00:11:27524 Draw();
[email protected]4916d622011-09-28 23:45:38525 }
526
527 // Invalidates the entire contents of the layer.
528 void SchedulePaintForLayer(Layer* layer) {
529 layer->SchedulePaint(
530 gfx::Rect(0, 0, layer->bounds().width(), layer->bounds().height()));
531 }
532
533 // Invokes DrawTree on the compositor.
534 void Draw() {
[email protected]44ed4bd2013-04-06 00:11:27535 compositor()->ScheduleDraw();
536 WaitForDraw();
537 }
538
weiliangc5efa0a12015-01-29 19:56:46539 void WaitForDraw() {
540 DrawWaiterForTest::WaitForCompositingStarted(compositor());
541 }
[email protected]4916d622011-09-28 23:45:38542
[email protected]36e5ff12013-06-11 12:19:29543 void WaitForCommit() {
544 DrawWaiterForTest::WaitForCommit(compositor());
545 }
546
[email protected]4916d622011-09-28 23:45:38547 private:
Gabriel Charettedfa36042019-08-19 17:30:11548 base::test::TaskEnvironment task_environment_;
Mohsen Izadib3710182019-04-30 04:57:35549 std::unique_ptr<TestContextFactories> context_factories_;
danakj25c52c32016-04-12 21:51:08550 std::unique_ptr<TestCompositorHost> compositor_host_;
[email protected]4916d622011-09-28 23:45:38551
[email protected]5610d512011-10-04 21:32:57552 DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest);
[email protected]4916d622011-09-28 23:45:38553};
554
dcastagnaef83bc32016-03-24 22:32:45555void ReturnMailbox(bool* run, const gpu::SyncToken& sync_token, bool is_lost) {
556 *run = true;
557}
558
559TEST(LayerStandaloneTest, ReleaseMailboxOnDestruction) {
Mohsen Izadi62a338d2019-07-30 19:49:47560 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
dcastagnaef83bc32016-03-24 22:32:45561 bool callback_run = false;
Saman Sami51c0a3e2019-05-02 13:43:38562
563 constexpr gfx::Size size(64, 64);
danakj4957a222017-11-21 17:23:10564 auto resource = viz::TransferableResource::MakeGL(
Saman Sami51c0a3e2019-05-02 13:43:38565 gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
566 size, false /* is_overlay_candidate */);
tzik387bee3f2018-03-30 21:06:48567 layer->SetTransferableResource(
568 resource,
569 viz::SingleReleaseCallback::Create(
570 base::BindOnce(ReturnMailbox, &callback_run)),
571 gfx::Size(10, 10));
dcastagnaef83bc32016-03-24 22:32:45572 EXPECT_FALSE(callback_run);
573 layer.reset();
574 EXPECT_TRUE(callback_run);
575}
576
[email protected]ad7258912011-08-29 20:33:53577// L1
578// +-- L2
[email protected]5610d512011-10-04 21:32:57579TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) {
Mohsen Izadi62a338d2019-07-30 19:49:47580 std::unique_ptr<Layer> l1 =
581 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
582 std::unique_ptr<Layer> l2 =
583 CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 350, 350));
[email protected]ad7258912011-08-29 20:33:53584 l1->Add(l2.get());
585 DrawTree(l1.get());
586
Ella Ge7540c842017-10-19 03:27:27587 gfx::PointF point1_in_l2_coords(5, 5);
[email protected]ad7258912011-08-29 20:33:53588 Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords);
Ella Ge7540c842017-10-19 03:27:27589 gfx::PointF point1_in_l1_coords(15, 15);
[email protected]ad7258912011-08-29 20:33:53590 EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords);
591
Ella Ge7540c842017-10-19 03:27:27592 gfx::PointF point2_in_l1_coords(5, 5);
[email protected]ad7258912011-08-29 20:33:53593 Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords);
Ella Ge7540c842017-10-19 03:27:27594 gfx::PointF point2_in_l2_coords(-5, -5);
[email protected]ad7258912011-08-29 20:33:53595 EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords);
596}
597
598// L1
599// +-- L2
600// +-- L3
[email protected]5610d512011-10-04 21:32:57601TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) {
Mohsen Izadi62a338d2019-07-30 19:49:47602 std::unique_ptr<Layer> l1 =
603 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
604 std::unique_ptr<Layer> l2 =
605 CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 350, 350));
606 std::unique_ptr<Layer> l3 =
607 CreateColorLayer(SK_ColorYELLOW, gfx::Rect(10, 10, 100, 100));
[email protected]ad7258912011-08-29 20:33:53608 l1->Add(l2.get());
609 l2->Add(l3.get());
610 DrawTree(l1.get());
611
Ella Ge7540c842017-10-19 03:27:27612 gfx::PointF point1_in_l3_coords(5, 5);
[email protected]ad7258912011-08-29 20:33:53613 Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords);
Ella Ge7540c842017-10-19 03:27:27614 gfx::PointF point1_in_l1_coords(25, 25);
[email protected]ad7258912011-08-29 20:33:53615 EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords);
616
Ella Ge7540c842017-10-19 03:27:27617 gfx::PointF point2_in_l1_coords(5, 5);
[email protected]ad7258912011-08-29 20:33:53618 Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords);
Ella Ge7540c842017-10-19 03:27:27619 gfx::PointF point2_in_l3_coords(-15, -15);
[email protected]ad7258912011-08-29 20:33:53620 EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords);
621}
622
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40623TEST_P(LayerWithRealCompositorTest, Delegate) {
weiliangcd048acf2015-03-10 19:00:07624 // This test makes sure that whenever paint happens at a layer, its layer
625 // delegate gets the paint, which in this test update its color and
626 // |color_index|.
Mohsen Izadi62a338d2019-07-30 19:49:47627 std::unique_ptr<Layer> l1 =
628 CreateColorLayer(SK_ColorBLACK, gfx::Rect(20, 20, 400, 400));
[email protected]332749032011-10-22 00:32:46629 GetCompositor()->SetRootLayer(l1.get());
[email protected]260c3212013-04-11 22:25:38630 WaitForDraw();
[email protected]332749032011-10-22 00:32:46631
632 TestLayerDelegate delegate;
[email protected]00b86982011-09-01 00:02:09633 l1->set_delegate(&delegate);
weiliangca032f93b2015-07-13 22:39:47634 delegate.set_layer_bounds(l1->bounds());
[email protected]00b86982011-09-01 00:02:09635 delegate.AddColor(SK_ColorWHITE);
636 delegate.AddColor(SK_ColorYELLOW);
637 delegate.AddColor(SK_ColorGREEN);
638
[email protected]00b86982011-09-01 00:02:09639 l1->SchedulePaint(gfx::Rect(0, 0, 400, 400));
[email protected]260c3212013-04-11 22:25:38640 WaitForDraw();
weiliangcd048acf2015-03-10 19:00:07641 // Test that paint happened at layer delegate.
642 EXPECT_EQ(1, delegate.color_index());
[email protected]00b86982011-09-01 00:02:09643
644 l1->SchedulePaint(gfx::Rect(10, 10, 200, 200));
[email protected]260c3212013-04-11 22:25:38645 WaitForDraw();
weiliangcd048acf2015-03-10 19:00:07646 // Test that paint happened at layer delegate.
647 EXPECT_EQ(2, delegate.color_index());
[email protected]00b86982011-09-01 00:02:09648
649 l1->SchedulePaint(gfx::Rect(5, 5, 50, 50));
[email protected]260c3212013-04-11 22:25:38650 WaitForDraw();
weiliangcd048acf2015-03-10 19:00:07651 // Test that paint happened at layer delegate.
652 EXPECT_EQ(0, delegate.color_index());
[email protected]00b86982011-09-01 00:02:09653}
654
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40655TEST_P(LayerWithRealCompositorTest, DrawTree) {
Mohsen Izadi62a338d2019-07-30 19:49:47656 std::unique_ptr<Layer> l1 =
657 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
658 std::unique_ptr<Layer> l2 =
659 CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 350, 350));
660 std::unique_ptr<Layer> l3 =
661 CreateColorLayer(SK_ColorYELLOW, gfx::Rect(10, 10, 100, 100));
[email protected]3aa43942011-09-13 20:59:53662 l1->Add(l2.get());
663 l2->Add(l3.get());
664
[email protected]332749032011-10-22 00:32:46665 GetCompositor()->SetRootLayer(l1.get());
[email protected]260c3212013-04-11 22:25:38666 WaitForDraw();
[email protected]332749032011-10-22 00:32:46667
weiliangca032f93b2015-07-13 22:39:47668 DrawTreeLayerDelegate d1(l1->bounds());
[email protected]3aa43942011-09-13 20:59:53669 l1->set_delegate(&d1);
weiliangca032f93b2015-07-13 22:39:47670 DrawTreeLayerDelegate d2(l2->bounds());
[email protected]3aa43942011-09-13 20:59:53671 l2->set_delegate(&d2);
weiliangca032f93b2015-07-13 22:39:47672 DrawTreeLayerDelegate d3(l3->bounds());
[email protected]3aa43942011-09-13 20:59:53673 l3->set_delegate(&d3);
674
[email protected]3aa43942011-09-13 20:59:53675 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
[email protected]260c3212013-04-11 22:25:38676 WaitForDraw();
[email protected]3aa43942011-09-13 20:59:53677 EXPECT_FALSE(d1.painted());
678 EXPECT_TRUE(d2.painted());
679 EXPECT_FALSE(d3.painted());
680}
681
varkha662bc742016-07-13 07:32:27682// Tests that scheduling paint on a layer with a mask updates the mask.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40683TEST_P(LayerWithRealCompositorTest, SchedulePaintUpdatesMask) {
Mohsen Izadi62a338d2019-07-30 19:49:47684 std::unique_ptr<Layer> layer =
685 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
686 std::unique_ptr<Layer> mask_layer = CreateLayer(ui::LAYER_TEXTURED);
varkha662bc742016-07-13 07:32:27687 mask_layer->SetBounds(gfx::Rect(layer->GetTargetBounds().size()));
688 layer->SetMaskLayer(mask_layer.get());
689
690 GetCompositor()->SetRootLayer(layer.get());
691 WaitForDraw();
692
693 DrawTreeLayerDelegate d1(layer->bounds());
694 layer->set_delegate(&d1);
695 DrawTreeLayerDelegate d2(mask_layer->bounds());
696 mask_layer->set_delegate(&d2);
697
698 layer->SchedulePaint(gfx::Rect(5, 5, 5, 5));
699 WaitForDraw();
700 EXPECT_TRUE(d1.painted());
701 EXPECT_TRUE(d2.painted());
702}
703
[email protected]28cd2bb2011-09-19 21:04:19704// Tests no-texture Layers.
705// Create this hierarchy:
706// L1 - red
707// +-- L2 - NO TEXTURE
708// | +-- L3 - yellow
709// +-- L4 - magenta
710//
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:40711TEST_P(LayerWithRealCompositorTest, HierarchyNoTexture) {
Mohsen Izadi62a338d2019-07-30 19:49:47712 std::unique_ptr<Layer> l1 =
713 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
714 std::unique_ptr<Layer> l2 = CreateNoTextureLayer(gfx::Rect(10, 10, 350, 350));
715 std::unique_ptr<Layer> l3 =
716 CreateColorLayer(SK_ColorYELLOW, gfx::Rect(5, 5, 25, 25));
717 std::unique_ptr<Layer> l4 =
718 CreateColorLayer(SK_ColorMAGENTA, gfx::Rect(300, 300, 100, 100));
[email protected]28cd2bb2011-09-19 21:04:19719
720 l1->Add(l2.get());
721 l1->Add(l4.get());
722 l2->Add(l3.get());
723
[email protected]332749032011-10-22 00:32:46724 GetCompositor()->SetRootLayer(l1.get());
[email protected]260c3212013-04-11 22:25:38725 WaitForDraw();
[email protected]332749032011-10-22 00:32:46726
weiliangca032f93b2015-07-13 22:39:47727 DrawTreeLayerDelegate d2(l2->bounds());
[email protected]28cd2bb2011-09-19 21:04:19728 l2->set_delegate(&d2);
weiliangca032f93b2015-07-13 22:39:47729 DrawTreeLayerDelegate d3(l3->bounds());
[email protected]28cd2bb2011-09-19 21:04:19730 l3->set_delegate(&d3);
731
[email protected]28cd2bb2011-09-19 21:04:19732 l2->SchedulePaint(gfx::Rect(5, 5, 5, 5));
733 l3->SchedulePaint(gfx::Rect(5, 5, 5, 5));
[email protected]260c3212013-04-11 22:25:38734 WaitForDraw();
[email protected]28cd2bb2011-09-19 21:04:19735
736 // |d2| should not have received a paint notification since it has no texture.
737 EXPECT_FALSE(d2.painted());
738 // |d3| should have received a paint notification.
739 EXPECT_TRUE(d3.painted());
740}
741
Jun Mukai7a20ff02019-08-02 00:46:06742TEST_F(LayerWithDelegateTest, Cloning) {
Mohsen Izadi62a338d2019-07-30 19:49:47743 std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR);
domlaskowski4b33bfe2016-10-27 00:34:22744
745 gfx::Transform transform;
746 transform.Scale(2, 1);
747 transform.Translate(10, 5);
748
749 layer->SetTransform(transform);
750 layer->SetColor(SK_ColorRED);
751 layer->SetLayerInverted(true);
wutao52217d12017-08-18 02:40:31752 layer->AddCacheRenderSurfaceRequest();
wutao1d35eeb72017-10-12 23:01:24753 layer->AddTrilinearFilteringRequest();
Malay Keshav2e04a95b2019-03-14 19:11:21754 layer->SetRoundedCornerRadius({1, 2, 4, 5});
755 layer->SetIsFastRoundedCorner(true);
domlaskowski4b33bfe2016-10-27 00:34:22756
757 auto clone = layer->Clone();
758
759 // Cloning preserves layer state.
760 EXPECT_EQ(transform, clone->GetTargetTransform());
761 EXPECT_EQ(SK_ColorRED, clone->background_color());
762 EXPECT_EQ(SK_ColorRED, clone->GetTargetColor());
763 EXPECT_TRUE(clone->layer_inverted());
wutao36850732017-07-29 20:24:07764 // Cloning should not preserve cache_render_surface flag.
765 EXPECT_NE(layer->cc_layer_for_testing()->cache_render_surface(),
766 clone->cc_layer_for_testing()->cache_render_surface());
wutao1d35eeb72017-10-12 23:01:24767 // Cloning should not preserve trilinear_filtering flag.
768 EXPECT_NE(layer->cc_layer_for_testing()->trilinear_filtering(),
769 clone->cc_layer_for_testing()->trilinear_filtering());
Malay Keshav2e04a95b2019-03-14 19:11:21770 EXPECT_EQ(layer->rounded_corner_radii(), clone->rounded_corner_radii());
771 EXPECT_EQ(layer->is_fast_rounded_corner(), clone->is_fast_rounded_corner());
domlaskowski4b33bfe2016-10-27 00:34:22772
773 layer->SetTransform(gfx::Transform());
774 layer->SetColor(SK_ColorGREEN);
775 layer->SetLayerInverted(false);
Malay Keshav2e04a95b2019-03-14 19:11:21776 layer->SetIsFastRoundedCorner(false);
777 layer->SetRoundedCornerRadius({3, 6, 9, 12});
domlaskowski4b33bfe2016-10-27 00:34:22778
779 // The clone is an independent copy, so state changes do not propagate.
780 EXPECT_EQ(transform, clone->GetTargetTransform());
781 EXPECT_EQ(SK_ColorRED, clone->background_color());
782 EXPECT_EQ(SK_ColorRED, clone->GetTargetColor());
783 EXPECT_TRUE(clone->layer_inverted());
Malay Keshav2e04a95b2019-03-14 19:11:21784 EXPECT_FALSE(layer->is_fast_rounded_corner());
785 EXPECT_TRUE(clone->is_fast_rounded_corner());
786 EXPECT_NE(layer->rounded_corner_radii(), clone->rounded_corner_radii());
domlaskowski4b33bfe2016-10-27 00:34:22787
788 constexpr SkColor kTransparent = SK_ColorTRANSPARENT;
789 layer->SetColor(kTransparent);
790 layer->SetFillsBoundsOpaquely(false);
791 // Color and opaqueness targets should be preserved during cloning, even after
792 // switching away from solid color content.
793 layer->SwitchCCLayerForTest();
794
795 clone = layer->Clone();
796
797 // The clone is a copy of the latest state.
798 EXPECT_TRUE(clone->GetTargetTransform().IsIdentity());
799 EXPECT_EQ(kTransparent, clone->background_color());
800 EXPECT_EQ(kTransparent, clone->GetTargetColor());
801 EXPECT_FALSE(clone->layer_inverted());
802 EXPECT_FALSE(clone->fills_bounds_opaquely());
803
sadrul458e50e2017-03-15 17:44:31804 // A solid color layer with transparent color can be marked as opaque. The
805 // clone should retain this state.
Mohsen Izadi62a338d2019-07-30 19:49:47806 layer = CreateLayer(LAYER_SOLID_COLOR);
sadrul458e50e2017-03-15 17:44:31807 layer->SetColor(kTransparent);
808 layer->SetFillsBoundsOpaquely(true);
809
810 clone = layer->Clone();
811 EXPECT_TRUE(clone->GetTargetTransform().IsIdentity());
812 EXPECT_EQ(kTransparent, clone->background_color());
813 EXPECT_EQ(kTransparent, clone->GetTargetColor());
814 EXPECT_FALSE(clone->layer_inverted());
815 EXPECT_TRUE(clone->fills_bounds_opaquely());
816
Mohsen Izadi62a338d2019-07-30 19:49:47817 layer = CreateLayer(LAYER_SOLID_COLOR);
domlaskowski4b33bfe2016-10-27 00:34:22818 layer->SetVisible(true);
819 layer->SetOpacity(1.0f);
820 layer->SetColor(SK_ColorRED);
821
822 ScopedLayerAnimationSettings settings(layer->GetAnimator());
823 layer->SetVisible(false);
824 layer->SetOpacity(0.0f);
825 layer->SetColor(SK_ColorGREEN);
826
827 EXPECT_TRUE(layer->visible());
828 EXPECT_EQ(1.0f, layer->opacity());
829 EXPECT_EQ(SK_ColorRED, layer->background_color());
830
831 clone = layer->Clone();
832
833 // Cloning copies animation targets.
834 EXPECT_FALSE(clone->visible());
835 EXPECT_EQ(0.0f, clone->opacity());
836 EXPECT_EQ(SK_ColorGREEN, clone->background_color());
837}
838
839TEST_F(LayerWithDelegateTest, Mirroring) {
Mohsen Izadi62a338d2019-07-30 19:49:47840 std::unique_ptr<Layer> root = CreateNoTextureLayer(gfx::Rect(0, 0, 100, 100));
841 std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED);
domlaskowski4b33bfe2016-10-27 00:34:22842
843 const gfx::Rect bounds(0, 0, 50, 50);
844 child->SetBounds(bounds);
845 child->SetVisible(true);
846
847 DrawTreeLayerDelegate delegate(child->bounds());
848 child->set_delegate(&delegate);
849
Ahmed Fakhry881c92932019-05-22 17:47:23850 const auto mirror1 = child->Mirror();
domlaskowski4b33bfe2016-10-27 00:34:22851
852 // Bounds and visibility are preserved.
Ahmed Fakhry881c92932019-05-22 17:47:23853 EXPECT_EQ(bounds, mirror1->bounds());
854 EXPECT_TRUE(mirror1->visible());
domlaskowski4b33bfe2016-10-27 00:34:22855
856 root->Add(child.get());
Ahmed Fakhry881c92932019-05-22 17:47:23857 root->Add(mirror1.get());
domlaskowski4b33bfe2016-10-27 00:34:22858
859 DrawTree(root.get());
860 EXPECT_TRUE(delegate.painted());
861 delegate.Reset();
862
863 // Both layers should be clean.
864 EXPECT_TRUE(child->damaged_region_for_testing().IsEmpty());
Ahmed Fakhry881c92932019-05-22 17:47:23865 EXPECT_TRUE(mirror1->damaged_region_for_testing().IsEmpty());
domlaskowski4b33bfe2016-10-27 00:34:22866
867 const gfx::Rect damaged_rect(10, 10, 20, 20);
868 EXPECT_TRUE(child->SchedulePaint(damaged_rect));
869 EXPECT_EQ(damaged_rect, child->damaged_region_for_testing().bounds());
870
871 DrawTree(root.get());
872 EXPECT_TRUE(delegate.painted());
873 delegate.Reset();
874
875 // Damage should be propagated to the mirror.
Ahmed Fakhry881c92932019-05-22 17:47:23876 EXPECT_EQ(damaged_rect, mirror1->damaged_region_for_testing().bounds());
domlaskowski4b33bfe2016-10-27 00:34:22877 EXPECT_TRUE(child->damaged_region_for_testing().IsEmpty());
878
879 DrawTree(root.get());
880 EXPECT_TRUE(delegate.painted());
881
882 // Mirror should be clean.
Ahmed Fakhry881c92932019-05-22 17:47:23883 EXPECT_TRUE(mirror1->damaged_region_for_testing().IsEmpty());
884
885 const auto mirror2 = child->Mirror();
886 root->Add(mirror2.get());
domlaskowski4b33bfe2016-10-27 00:34:22887
888 // Bounds are not synchronized by default.
889 const gfx::Rect new_bounds(10, 10, 10, 10);
890 child->SetBounds(new_bounds);
Ahmed Fakhry881c92932019-05-22 17:47:23891 EXPECT_EQ(bounds, mirror1->bounds());
892 EXPECT_EQ(bounds, mirror2->bounds());
domlaskowski4b33bfe2016-10-27 00:34:22893 child->SetBounds(bounds);
894
Ahmed Fakhry881c92932019-05-22 17:47:23895 // Bounds should be synchronized only for the mirror layer that requested it.
896 mirror1->set_sync_bounds_with_source(true);
domlaskowski4b33bfe2016-10-27 00:34:22897 child->SetBounds(new_bounds);
Ahmed Fakhry881c92932019-05-22 17:47:23898 EXPECT_EQ(new_bounds, mirror1->bounds());
899 EXPECT_EQ(bounds, mirror2->bounds());
Malay Keshav2e04a95b2019-03-14 19:11:21900
901 // Check for rounded corner mirror behavior
Ahmed Fakhry881c92932019-05-22 17:47:23902 EXPECT_TRUE(mirror1->rounded_corner_radii().IsEmpty());
903 EXPECT_FALSE(mirror1->is_fast_rounded_corner());
Dana Fried45b87ecc2019-05-13 17:36:25904 constexpr gfx::RoundedCornersF kCornerRadii(2, 3, 4, 5);
905 child->SetRoundedCornerRadius(kCornerRadii);
Malay Keshav2e04a95b2019-03-14 19:11:21906 child->SetIsFastRoundedCorner(true);
Ahmed Fakhry881c92932019-05-22 17:47:23907 EXPECT_EQ(kCornerRadii, mirror1->rounded_corner_radii());
908 EXPECT_TRUE(mirror1->is_fast_rounded_corner());
domlaskowski4b33bfe2016-10-27 00:34:22909}
910
Jennifer Apacibleea38ede2018-03-15 02:41:55911// Tests for SurfaceLayer cloning and mirroring. This tests certain properties
912// are preserved.
913TEST_F(LayerWithDelegateTest, SurfaceLayerCloneAndMirror) {
914 const viz::FrameSinkId arbitrary_frame_sink(1, 1);
915 viz::ParentLocalSurfaceIdAllocator allocator;
Mohsen Izadi62a338d2019-07-30 19:49:47916 std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR);
Jennifer Apacibleea38ede2018-03-15 02:41:55917
Jonathan Ross89807fc2018-10-30 17:41:21918 allocator.GenerateId();
jonross58cab432018-11-29 02:30:30919 viz::LocalSurfaceId local_surface_id =
920 allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
Jennifer Apacibleea38ede2018-03-15 02:41:55921 viz::SurfaceId surface_id_one(arbitrary_frame_sink, local_surface_id);
Saman Sami98c524052018-10-26 17:34:57922 layer->SetShowSurface(surface_id_one, gfx::Size(10, 10), SK_ColorWHITE,
923 cc::DeadlinePolicy::UseDefaultDeadline(), false);
Jennifer Apacibleea38ede2018-03-15 02:41:55924 EXPECT_FALSE(layer->StretchContentToFillBounds());
925
926 auto clone = layer->Clone();
927 EXPECT_FALSE(clone->StretchContentToFillBounds());
928 auto mirror = layer->Mirror();
sunxd26e9bae2018-03-22 19:32:33929 EXPECT_FALSE(mirror->StretchContentToFillBounds());
Jennifer Apacibleea38ede2018-03-15 02:41:55930
Jonathan Ross89807fc2018-10-30 17:41:21931 allocator.GenerateId();
jonross58cab432018-11-29 02:30:30932 local_surface_id =
933 allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id();
Jennifer Apacibleea38ede2018-03-15 02:41:55934 viz::SurfaceId surface_id_two(arbitrary_frame_sink, local_surface_id);
Saman Sami98c524052018-10-26 17:34:57935 layer->SetShowSurface(surface_id_two, gfx::Size(10, 10), SK_ColorWHITE,
936 cc::DeadlinePolicy::UseDefaultDeadline(), true);
Jennifer Apacibleea38ede2018-03-15 02:41:55937 EXPECT_TRUE(layer->StretchContentToFillBounds());
938
939 clone = layer->Clone();
940 EXPECT_TRUE(clone->StretchContentToFillBounds());
941 mirror = layer->Mirror();
sunxd26e9bae2018-03-22 19:32:33942 EXPECT_TRUE(mirror->StretchContentToFillBounds());
Jennifer Apacibleea38ede2018-03-15 02:41:55943}
944
[email protected]5610d512011-10-04 21:32:57945class LayerWithNullDelegateTest : public LayerWithDelegateTest {
946 public:
947 LayerWithNullDelegateTest() {}
dchengbc07fa02014-10-29 20:07:24948 ~LayerWithNullDelegateTest() override {}
[email protected]5610d512011-10-04 21:32:57949
dchengbc07fa02014-10-29 20:07:24950 void SetUp() override {
[email protected]5610d512011-10-04 21:32:57951 LayerWithDelegateTest::SetUp();
Mohsen Izadi62a338d2019-07-30 19:49:47952 default_layer_delegate_ = std::make_unique<NullLayerDelegate>();
[email protected]5610d512011-10-04 21:32:57953 }
954
Mohsen Izadi62a338d2019-07-30 19:49:47955 std::unique_ptr<Layer> CreateLayer(LayerType type) override {
956 auto layer = std::make_unique<Layer>(type);
[email protected]5610d512011-10-04 21:32:57957 layer->set_delegate(default_layer_delegate_.get());
958 return layer;
959 }
960
Mohsen Izadi62a338d2019-07-30 19:49:47961 std::unique_ptr<Layer> CreateTextureRootLayer(const gfx::Rect& bounds) {
962 std::unique_ptr<Layer> layer = CreateTextureLayer(bounds);
963 compositor()->SetRootLayer(layer.get());
[email protected]5610d512011-10-04 21:32:57964 return layer;
965 }
966
Mohsen Izadi62a338d2019-07-30 19:49:47967 std::unique_ptr<Layer> CreateTextureLayer(const gfx::Rect& bounds) {
968 std::unique_ptr<Layer> layer = CreateLayer(LAYER_TEXTURED);
[email protected]5610d512011-10-04 21:32:57969 layer->SetBounds(bounds);
970 return layer;
971 }
972
Mohsen Izadi62a338d2019-07-30 19:49:47973 std::unique_ptr<Layer> CreateNoTextureLayer(
974 const gfx::Rect& bounds) override {
975 std::unique_ptr<Layer> layer = CreateLayer(LAYER_NOT_DRAWN);
[email protected]5610d512011-10-04 21:32:57976 layer->SetBounds(bounds);
977 return layer;
978 }
979
wutao61373a392017-09-26 18:45:35980 gfx::Rect LastInvalidation() const {
981 return default_layer_delegate_->invalidation();
982 }
983
[email protected]5610d512011-10-04 21:32:57984 private:
danakj25c52c32016-04-12 21:51:08985 std::unique_ptr<NullLayerDelegate> default_layer_delegate_;
[email protected]5610d512011-10-04 21:32:57986
987 DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest);
988};
989
Jun Mukai7a20ff02019-08-02 00:46:06990TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) {
Mohsen Izadi62a338d2019-07-30 19:49:47991 std::unique_ptr<Layer> l1 = CreateLayer(LAYER_SOLID_COLOR);
[email protected]3b4b2f02013-06-24 23:15:27992 l1->SetFillsBoundsOpaquely(true);
[email protected]3b4b2f02013-06-24 23:15:27993 l1->SetVisible(false);
danakj2ec13e92015-02-24 23:52:04994 l1->SetBounds(gfx::Rect(4, 5));
[email protected]3b4b2f02013-06-24 23:15:27995
Dana Fried45b87ecc2019-05-13 17:36:25996 constexpr gfx::RoundedCornersF kCornerRadii(1, 2, 3, 4);
Malay Keshav2e04a95b2019-03-14 19:11:21997 l1->SetRoundedCornerRadius(kCornerRadii);
998 l1->SetIsFastRoundedCorner(true);
999
loysoac008462015-05-27 01:05:501000 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
1001 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
1002 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
loysoac008462015-05-27 01:05:501003 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1004 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
Malay Keshav2e04a95b2019-03-14 19:11:211005 EXPECT_TRUE(l1->cc_layer_for_testing()->HasRoundedCorner());
1006 EXPECT_EQ(l1->cc_layer_for_testing()->corner_radii(), kCornerRadii);
1007 EXPECT_TRUE(l1->cc_layer_for_testing()->is_fast_rounded_corner());
[email protected]3b4b2f02013-06-24 23:15:271008
loysoac008462015-05-27 01:05:501009 cc::Layer* before_layer = l1->cc_layer_for_testing();
[email protected]3b4b2f02013-06-24 23:15:271010
[email protected]4508b152014-04-09 22:14:171011 bool callback1_run = false;
Saman Sami51c0a3e2019-05-02 13:43:381012 constexpr gfx::Size size(64, 64);
danakj4957a222017-11-21 17:23:101013 auto resource = viz::TransferableResource::MakeGL(
Saman Sami51c0a3e2019-05-02 13:43:381014 gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
1015 size, false /* is_overlay_candidate */);
danakj4957a222017-11-21 17:23:101016 l1->SetTransferableResource(resource,
tzik387bee3f2018-03-30 21:06:481017 viz::SingleReleaseCallback::Create(base::BindOnce(
1018 ReturnMailbox, &callback1_run)),
danakj4957a222017-11-21 17:23:101019 gfx::Size(10, 10));
[email protected]3b4b2f02013-06-24 23:15:271020
loysoac008462015-05-27 01:05:501021 EXPECT_NE(before_layer, l1->cc_layer_for_testing());
[email protected]3b4b2f02013-06-24 23:15:271022
loysoac008462015-05-27 01:05:501023 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
1024 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
1025 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
loysoac008462015-05-27 01:05:501026 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1027 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
Malay Keshav2e04a95b2019-03-14 19:11:211028 EXPECT_TRUE(l1->cc_layer_for_testing()->HasRoundedCorner());
1029 EXPECT_EQ(l1->cc_layer_for_testing()->corner_radii(), kCornerRadii);
1030 EXPECT_TRUE(l1->cc_layer_for_testing()->is_fast_rounded_corner());
[email protected]4508b152014-04-09 22:14:171031 EXPECT_FALSE(callback1_run);
1032
1033 bool callback2_run = false;
danakj4957a222017-11-21 17:23:101034 resource = viz::TransferableResource::MakeGL(
Saman Sami51c0a3e2019-05-02 13:43:381035 gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
1036 size, false /* is_overlay_candidate */);
danakj4957a222017-11-21 17:23:101037 l1->SetTransferableResource(resource,
tzik387bee3f2018-03-30 21:06:481038 viz::SingleReleaseCallback::Create(base::BindOnce(
1039 ReturnMailbox, &callback2_run)),
danakj4957a222017-11-21 17:23:101040 gfx::Size(10, 10));
[email protected]4508b152014-04-09 22:14:171041 EXPECT_TRUE(callback1_run);
1042 EXPECT_FALSE(callback2_run);
1043
danakj2ec13e92015-02-24 23:52:041044 // Show solid color instead.
jbaumanf472c6872014-10-13 20:06:431045 l1->SetShowSolidColorContent();
loysoac008462015-05-27 01:05:501046 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
1047 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
1048 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
loysoac008462015-05-27 01:05:501049 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1050 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
Malay Keshav2e04a95b2019-03-14 19:11:211051 EXPECT_TRUE(l1->cc_layer_for_testing()->HasRoundedCorner());
1052 EXPECT_EQ(l1->cc_layer_for_testing()->corner_radii(), kCornerRadii);
1053 EXPECT_TRUE(l1->cc_layer_for_testing()->is_fast_rounded_corner());
[email protected]4508b152014-04-09 22:14:171054 EXPECT_TRUE(callback2_run);
danakj2ec13e92015-02-24 23:52:041055
loysoac008462015-05-27 01:05:501056 before_layer = l1->cc_layer_for_testing();
danakj2ec13e92015-02-24 23:52:041057
1058 // Back to a texture, without changing the bounds of the layer or the texture.
1059 bool callback3_run = false;
danakj4957a222017-11-21 17:23:101060 resource = viz::TransferableResource::MakeGL(
Saman Sami51c0a3e2019-05-02 13:43:381061 gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
1062 size, false /* is_overlay_candidate */);
danakj4957a222017-11-21 17:23:101063 l1->SetTransferableResource(resource,
tzik387bee3f2018-03-30 21:06:481064 viz::SingleReleaseCallback::Create(base::BindOnce(
1065 ReturnMailbox, &callback3_run)),
danakj4957a222017-11-21 17:23:101066 gfx::Size(10, 10));
danakj2ec13e92015-02-24 23:52:041067
loysoac008462015-05-27 01:05:501068 EXPECT_NE(before_layer, l1->cc_layer_for_testing());
danakj2ec13e92015-02-24 23:52:041069
loysoac008462015-05-27 01:05:501070 EXPECT_EQ(gfx::Point3F(), l1->cc_layer_for_testing()->transform_origin());
1071 EXPECT_TRUE(l1->cc_layer_for_testing()->DrawsContent());
1072 EXPECT_TRUE(l1->cc_layer_for_testing()->contents_opaque());
loysoac008462015-05-27 01:05:501073 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1074 EXPECT_EQ(gfx::Size(4, 5), l1->cc_layer_for_testing()->bounds());
Malay Keshav2e04a95b2019-03-14 19:11:211075 EXPECT_TRUE(l1->cc_layer_for_testing()->HasRoundedCorner());
1076 EXPECT_EQ(l1->cc_layer_for_testing()->corner_radii(), kCornerRadii);
1077 EXPECT_TRUE(l1->cc_layer_for_testing()->is_fast_rounded_corner());
danakj2ec13e92015-02-24 23:52:041078 EXPECT_FALSE(callback3_run);
1079
1080 // Release the on |l1| mailbox to clean up the test.
1081 l1->SetShowSolidColorContent();
[email protected]3b4b2f02013-06-24 23:15:271082}
1083
erg4ad81c082017-05-15 22:30:001084// Various visible/drawn assertions.
[email protected]e4e8afef2011-10-05 13:58:331085TEST_F(LayerWithNullDelegateTest, Visibility) {
Mohsen Izadi62a338d2019-07-30 19:49:471086 auto l1 = std::make_unique<Layer>(LAYER_TEXTURED);
1087 auto l2 = std::make_unique<Layer>(LAYER_TEXTURED);
1088 auto l3 = std::make_unique<Layer>(LAYER_TEXTURED);
[email protected]e4e8afef2011-10-05 13:58:331089 l1->Add(l2.get());
1090 l2->Add(l3.get());
1091
1092 NullLayerDelegate delegate;
1093 l1->set_delegate(&delegate);
1094 l2->set_delegate(&delegate);
1095 l3->set_delegate(&delegate);
1096
1097 // Layers should initially be drawn.
1098 EXPECT_TRUE(l1->IsDrawn());
1099 EXPECT_TRUE(l2->IsDrawn());
1100 EXPECT_TRUE(l3->IsDrawn());
loysoac008462015-05-27 01:05:501101 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1102 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1103 EXPECT_FALSE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
[email protected]e4e8afef2011-10-05 13:58:331104
1105 compositor()->SetRootLayer(l1.get());
1106
1107 Draw();
1108
1109 l1->SetVisible(false);
1110 EXPECT_FALSE(l1->IsDrawn());
1111 EXPECT_FALSE(l2->IsDrawn());
1112 EXPECT_FALSE(l3->IsDrawn());
loysoac008462015-05-27 01:05:501113 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1114 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1115 EXPECT_FALSE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
[email protected]e4e8afef2011-10-05 13:58:331116
1117 l3->SetVisible(false);
1118 EXPECT_FALSE(l1->IsDrawn());
1119 EXPECT_FALSE(l2->IsDrawn());
1120 EXPECT_FALSE(l3->IsDrawn());
loysoac008462015-05-27 01:05:501121 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1122 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1123 EXPECT_TRUE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
[email protected]e4e8afef2011-10-05 13:58:331124
1125 l1->SetVisible(true);
1126 EXPECT_TRUE(l1->IsDrawn());
1127 EXPECT_TRUE(l2->IsDrawn());
1128 EXPECT_FALSE(l3->IsDrawn());
loysoac008462015-05-27 01:05:501129 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1130 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1131 EXPECT_TRUE(l3->cc_layer_for_testing()->hide_layer_and_subtree());
[email protected]e4e8afef2011-10-05 13:58:331132}
1133
Malay Keshavdf4c12cd2019-02-07 04:19:581134// Various visible/drawn assertions.
1135TEST_F(LayerWithNullDelegateTest, MirroringVisibility) {
Mohsen Izadi62a338d2019-07-30 19:49:471136 auto l1 = std::make_unique<Layer>(LAYER_TEXTURED);
1137 auto l2 = std::make_unique<Layer>(LAYER_TEXTURED);
Malay Keshavdf4c12cd2019-02-07 04:19:581138 std::unique_ptr<Layer> l2_mirror = l2->Mirror();
1139 l1->Add(l2.get());
1140 l1->Add(l2_mirror.get());
1141
1142 NullLayerDelegate delegate;
1143 l1->set_delegate(&delegate);
1144 l2->set_delegate(&delegate);
1145 l2_mirror->set_delegate(&delegate);
1146
1147 // Layers should initially be drawn.
1148 EXPECT_TRUE(l1->IsDrawn());
1149 EXPECT_TRUE(l2->IsDrawn());
1150 EXPECT_TRUE(l2_mirror->IsDrawn());
1151 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1152 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1153 EXPECT_FALSE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
1154
1155 compositor()->SetRootLayer(l1.get());
1156
1157 Draw();
1158
1159 // Hiding the root layer should hide that specific layer and its subtree.
1160 l1->SetVisible(false);
1161
1162 // Since the entire subtree is hidden, no layer should be drawn.
1163 EXPECT_FALSE(l1->IsDrawn());
1164 EXPECT_FALSE(l2->IsDrawn());
1165 EXPECT_FALSE(l2_mirror->IsDrawn());
1166
1167 // The visibitily property for the subtree is rooted at |l1|.
1168 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1169 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1170 EXPECT_FALSE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
1171
1172 // Hiding |l2| should also set the visibility on its mirror layer. In this
1173 // case the visibility of |l2| will be mirrored by |l2_mirror|.
1174 l2->SetVisible(false);
1175
1176 // None of the layers are drawn since the visibility is false at every node.
1177 EXPECT_FALSE(l1->IsDrawn());
1178 EXPECT_FALSE(l2->IsDrawn());
1179 EXPECT_FALSE(l2_mirror->IsDrawn());
1180
1181 // Visibility property is set on every node and hence their subtree is also
1182 // hidden.
1183 EXPECT_TRUE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1184 EXPECT_TRUE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1185 EXPECT_TRUE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
1186
1187 // Setting visibility on the root layer should make that layer visible and its
1188 // subtree ready for visibility.
1189 l1->SetVisible(true);
1190 EXPECT_TRUE(l1->IsDrawn());
1191 EXPECT_FALSE(l2->IsDrawn());
1192 EXPECT_FALSE(l2_mirror->IsDrawn());
1193 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1194 EXPECT_TRUE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1195 EXPECT_TRUE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
1196
1197 // Setting visibility on the mirrored layer should not effect its source
1198 // layer.
1199 l2_mirror->SetVisible(true);
1200 EXPECT_TRUE(l1->IsDrawn());
1201 EXPECT_FALSE(l2->IsDrawn());
1202 EXPECT_TRUE(l2_mirror->IsDrawn());
1203 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1204 EXPECT_TRUE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1205 EXPECT_FALSE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
1206
1207 // Setting visibility on the source layer should keep the mirror layer in
1208 // sync and not cause any invalid state.
1209 l2->SetVisible(true);
1210 EXPECT_TRUE(l1->IsDrawn());
1211 EXPECT_TRUE(l2->IsDrawn());
1212 EXPECT_TRUE(l2_mirror->IsDrawn());
1213 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1214 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1215 EXPECT_FALSE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
1216
1217 // Setting visibility on the mirrored layer should not effect its source
1218 // layer.
1219 l2_mirror->SetVisible(false);
1220 EXPECT_TRUE(l1->IsDrawn());
1221 EXPECT_TRUE(l2->IsDrawn());
1222 EXPECT_FALSE(l2_mirror->IsDrawn());
1223 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1224 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1225 EXPECT_TRUE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
1226
1227 // Setting source layer's visibility to true should update the mirror layer
1228 // even if the source layer did not change in the process.
1229 l2->SetVisible(true);
1230 EXPECT_TRUE(l1->IsDrawn());
1231 EXPECT_TRUE(l2->IsDrawn());
1232 EXPECT_TRUE(l2_mirror->IsDrawn());
1233 EXPECT_FALSE(l1->cc_layer_for_testing()->hide_layer_and_subtree());
1234 EXPECT_FALSE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1235 EXPECT_FALSE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
Ahmed Fakhrye27143322019-07-09 23:40:251236
1237 // Disable visibility sync on the mirrored layer. Changes in |l2|'s visibility
1238 // shouldn't affect the visibility of |l2_mirror|.
1239 l2_mirror->set_sync_visibility_with_source(false);
1240 l2->SetVisible(false);
1241 EXPECT_FALSE(l2->IsDrawn());
1242 EXPECT_TRUE(l2->cc_layer_for_testing()->hide_layer_and_subtree());
1243 EXPECT_TRUE(l2_mirror->IsDrawn());
1244 EXPECT_FALSE(l2_mirror->cc_layer_for_testing()->hide_layer_and_subtree());
Malay Keshavdf4c12cd2019-02-07 04:19:581245}
1246
Malay Keshavb78848742019-03-05 03:33:041247TEST_F(LayerWithDelegateTest, RoundedCorner) {
1248 gfx::Rect layer_bounds(10, 20, 100, 100);
Dana Fried45b87ecc2019-05-13 17:36:251249 constexpr gfx::RoundedCornersF kRadii(5, 10, 15, 20);
Mohsen Izadi62a338d2019-07-30 19:49:471250 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
Malay Keshavb78848742019-03-05 03:33:041251
1252 NullLayerDelegate delegate;
1253 layer->set_delegate(&delegate);
1254 layer->SetVisible(true);
1255 layer->SetBounds(layer_bounds);
1256 layer->SetMasksToBounds(true);
1257
1258 compositor()->SetRootLayer(layer.get());
1259 Draw();
1260
Dana Fried45b87ecc2019-05-13 17:36:251261 EXPECT_TRUE(layer->rounded_corner_radii().IsEmpty());
Malay Keshavb78848742019-03-05 03:33:041262
1263 // Setting a rounded corner radius should set an rrect with bounds same as the
1264 // layer.
Dana Fried45b87ecc2019-05-13 17:36:251265 layer->SetRoundedCornerRadius(kRadii);
1266 EXPECT_EQ(kRadii, layer->rounded_corner_radii());
Malay Keshavb78848742019-03-05 03:33:041267}
1268
[email protected]ebc335f2011-11-23 00:43:511269// Checks that stacking-related methods behave as advertised.
1270TEST_F(LayerWithNullDelegateTest, Stacking) {
Mohsen Izadi62a338d2019-07-30 19:49:471271 auto root = std::make_unique<Layer>(LAYER_NOT_DRAWN);
1272 auto l1 = std::make_unique<Layer>(LAYER_TEXTURED);
1273 auto l2 = std::make_unique<Layer>(LAYER_TEXTURED);
1274 auto l3 = std::make_unique<Layer>(LAYER_TEXTURED);
yjliu0b2876212019-12-19 03:36:201275 l1->SetName("1");
1276 l2->SetName("2");
1277 l3->SetName("3");
[email protected]ebc335f2011-11-23 00:43:511278 root->Add(l3.get());
1279 root->Add(l2.get());
1280 root->Add(l1.get());
1281
1282 // Layers' children are stored in bottom-to-top order.
[email protected]2f19761c2013-05-22 13:04:351283 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]ebc335f2011-11-23 00:43:511284
1285 root->StackAtTop(l3.get());
[email protected]2f19761c2013-05-22 13:04:351286 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
[email protected]ebc335f2011-11-23 00:43:511287
1288 root->StackAtTop(l1.get());
[email protected]2f19761c2013-05-22 13:04:351289 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]ebc335f2011-11-23 00:43:511290
1291 root->StackAtTop(l1.get());
[email protected]2f19761c2013-05-22 13:04:351292 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]ebc335f2011-11-23 00:43:511293
1294 root->StackAbove(l2.get(), l3.get());
[email protected]2f19761c2013-05-22 13:04:351295 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]ebc335f2011-11-23 00:43:511296
1297 root->StackAbove(l1.get(), l3.get());
[email protected]2f19761c2013-05-22 13:04:351298 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
[email protected]ebc335f2011-11-23 00:43:511299
1300 root->StackAbove(l2.get(), l1.get());
[email protected]2f19761c2013-05-22 13:04:351301 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041302
1303 root->StackAtBottom(l2.get());
[email protected]2f19761c2013-05-22 13:04:351304 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041305
1306 root->StackAtBottom(l3.get());
[email protected]2f19761c2013-05-22 13:04:351307 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041308
1309 root->StackAtBottom(l3.get());
[email protected]2f19761c2013-05-22 13:04:351310 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041311
1312 root->StackBelow(l2.get(), l3.get());
[email protected]2f19761c2013-05-22 13:04:351313 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041314
1315 root->StackBelow(l1.get(), l3.get());
[email protected]2f19761c2013-05-22 13:04:351316 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041317
1318 root->StackBelow(l3.get(), l2.get());
[email protected]2f19761c2013-05-22 13:04:351319 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041320
1321 root->StackBelow(l3.get(), l2.get());
[email protected]2f19761c2013-05-22 13:04:351322 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
[email protected]44c6f8d2011-12-27 23:49:041323
1324 root->StackBelow(l3.get(), l1.get());
[email protected]2f19761c2013-05-22 13:04:351325 EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get()));
Edwin Joe863d45302019-03-28 19:57:041326
1327 std::vector<Layer*> child_bottom_stack;
1328 child_bottom_stack.emplace_back(l1.get());
1329 root->StackChildrenAtBottom(child_bottom_stack);
1330 EXPECT_EQ("1 2 3", test::ChildLayerNamesAsString(*root.get()));
1331
1332 child_bottom_stack.clear();
1333 child_bottom_stack.emplace_back(l3.get());
1334 child_bottom_stack.emplace_back(l2.get());
1335 root->StackChildrenAtBottom(child_bottom_stack);
1336 EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get()));
1337
1338 child_bottom_stack.clear();
1339 child_bottom_stack.emplace_back(l2.get());
1340 child_bottom_stack.emplace_back(l1.get());
1341 root->StackChildrenAtBottom(child_bottom_stack);
1342 EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get()));
1343
1344 child_bottom_stack.clear();
1345 child_bottom_stack.emplace_back(l3.get());
1346 child_bottom_stack.emplace_back(l1.get());
1347 child_bottom_stack.emplace_back(l2.get());
1348 root->StackChildrenAtBottom(child_bottom_stack);
1349 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
1350
1351 child_bottom_stack.clear();
1352 root->StackChildrenAtBottom(child_bottom_stack);
1353 EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get()));
[email protected]ebc335f2011-11-23 00:43:511354}
1355
[email protected]a50ff372011-11-03 16:06:281356// Verifies SetBounds triggers the appropriate painting/drawing.
1357TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) {
Mohsen Izadi62a338d2019-07-30 19:49:471358 std::unique_ptr<Layer> l1 = CreateTextureLayer(gfx::Rect(0, 0, 200, 200));
[email protected]a50ff372011-11-03 16:06:281359 compositor()->SetRootLayer(l1.get());
1360
1361 Draw();
[email protected]3f1f5e6a2011-11-11 15:09:021362
[email protected]a50ff372011-11-03 16:06:281363 l1->SetBounds(gfx::Rect(5, 5, 200, 200));
[email protected]3f1f5e6a2011-11-11 15:09:021364
1365 // The CompositorDelegate (us) should have been told to draw for a move.
[email protected]260c3212013-04-11 22:25:381366 WaitForDraw();
[email protected]a50ff372011-11-03 16:06:281367
[email protected]a50ff372011-11-03 16:06:281368 l1->SetBounds(gfx::Rect(5, 5, 100, 100));
[email protected]3f1f5e6a2011-11-11 15:09:021369
1370 // The CompositorDelegate (us) should have been told to draw for a resize.
[email protected]260c3212013-04-11 22:25:381371 WaitForDraw();
[email protected]a50ff372011-11-03 16:06:281372}
1373
jbaumanac619ac2016-06-02 22:22:031374// Checks that the damage rect for a TextureLayer is empty after a commit.
1375TEST_F(LayerWithNullDelegateTest, EmptyDamagedRect) {
kylecharcf88963a82017-04-26 21:08:571376 base::RunLoop run_loop;
tzik387bee3f2018-03-30 21:06:481377 viz::ReleaseCallback callback = base::BindOnce(
1378 [](base::RunLoop* run_loop, const gpu::SyncToken& sync_token,
1379 bool is_lost) { run_loop->Quit(); },
1380 base::Unretained(&run_loop));
kylecharcf88963a82017-04-26 21:08:571381
Mohsen Izadi62a338d2019-07-30 19:49:471382 std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR);
Saman Sami51c0a3e2019-05-02 13:43:381383 constexpr gfx::Size size(64, 64);
danakj4957a222017-11-21 17:23:101384 auto resource = viz::TransferableResource::MakeGL(
Saman Sami51c0a3e2019-05-02 13:43:381385 gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
1386 size, false /* is_overlay_candidate */);
danakj4957a222017-11-21 17:23:101387 root->SetTransferableResource(
1388 resource, viz::SingleReleaseCallback::Create(std::move(callback)),
tzik736175f2017-11-15 13:39:241389 gfx::Size(10, 10));
jbaumanac619ac2016-06-02 22:22:031390 compositor()->SetRootLayer(root.get());
1391
1392 root->SetBounds(gfx::Rect(0, 0, 10, 10));
1393 root->SetVisible(true);
1394 WaitForCommit();
1395
1396 gfx::Rect damaged_rect(0, 0, 5, 5);
1397 root->SchedulePaint(damaged_rect);
1398 EXPECT_EQ(damaged_rect, root->damaged_region_for_testing().bounds());
1399 WaitForCommit();
1400 EXPECT_TRUE(root->damaged_region_for_testing().IsEmpty());
1401
kylecharcf88963a82017-04-26 21:08:571402 // The texture mailbox has a reference from an in-flight texture layer.
1403 // We clear the texture mailbox from the root layer and draw a new frame
1404 // to ensure that the texture mailbox is released.
1405 root->SetShowSolidColorContent();
1406 Draw();
1407
1408 // Wait for texture mailbox release to avoid DCHECKs.
1409 run_loop.Run();
jbaumanac619ac2016-06-02 22:22:031410}
1411
wutao61373a392017-09-26 18:45:351412// Tests that in deferred paint request, the layer damage will be accumulated.
1413TEST_F(LayerWithNullDelegateTest, UpdateDamageInDeferredPaint) {
1414 gfx::Rect bound(gfx::Rect(500, 500));
Mohsen Izadi62a338d2019-07-30 19:49:471415 std::unique_ptr<Layer> root = CreateTextureRootLayer(bound);
wutao61373a392017-09-26 18:45:351416 EXPECT_EQ(bound, root->damaged_region_for_testing());
1417 WaitForCommit();
1418 EXPECT_EQ(gfx::Rect(), root->damaged_region_for_testing());
1419 EXPECT_EQ(bound, LastInvalidation());
1420
1421 // Deferring paint.
1422 root->AddDeferredPaintRequest();
1423
1424 // During deferring paint request, invalid_rect will not be set to
1425 // cc_layer_->inputs_->update_rect, and the paint_region is empty.
1426 gfx::Rect bound1(gfx::Rect(100, 100));
1427 root->SchedulePaint(bound1);
1428 EXPECT_EQ(bound1, root->damaged_region_for_testing());
1429 root->SendDamagedRects();
1430 EXPECT_EQ(gfx::Rect(), root->cc_layer_for_testing()->update_rect());
1431 root->PaintContentsToDisplayList(
1432 cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
1433 EXPECT_EQ(gfx::Rect(), LastInvalidation());
1434
1435 // During deferring paint request, a new invalid_rect will be accumulated.
1436 gfx::Rect bound2(gfx::Rect(100, 200, 100, 100));
1437 gfx::Rect bound_union(bound1);
1438 bound_union.Union(bound2);
1439 root->SchedulePaint(bound2);
1440 EXPECT_EQ(bound_union, root->damaged_region_for_testing().bounds());
1441 root->SendDamagedRects();
1442 EXPECT_EQ(gfx::Rect(), root->cc_layer_for_testing()->update_rect());
1443 root->PaintContentsToDisplayList(
1444 cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
1445 EXPECT_EQ(gfx::Rect(), LastInvalidation());
1446
1447 // Remove deferring paint request.
1448 root->RemoveDeferredPaintRequest();
1449
1450 // The invalidation region should be accumulated invalid_rect during deferred
1451 // paint, i.e. union of bound1 and bound2.
1452 root->SendDamagedRects();
1453 EXPECT_EQ(bound_union, root->cc_layer_for_testing()->update_rect());
1454 root->PaintContentsToDisplayList(
1455 cc::ContentLayerClient::PAINTING_BEHAVIOR_NORMAL);
1456 EXPECT_EQ(bound_union, LastInvalidation());
1457}
1458
Collin Bakerced131a22019-02-02 01:14:441459// Tests that Layer::SendDamagedRects() always recurses into its mask layer, if
1460// present, even if it shouldn't send its damaged regions itself.
1461TEST_F(LayerWithNullDelegateTest, AlwaysSendsMaskDamagedRects) {
1462 gfx::Rect bound(gfx::Rect(2, 2));
Mohsen Izadi62a338d2019-07-30 19:49:471463 std::unique_ptr<Layer> mask = CreateTextureLayer(bound);
1464 std::unique_ptr<Layer> root = CreateTextureRootLayer(bound);
Collin Bakerced131a22019-02-02 01:14:441465 root->SetMaskLayer(mask.get());
1466
1467 WaitForCommit();
1468 EXPECT_EQ(root->damaged_region_for_testing().bounds(), gfx::Rect());
1469 EXPECT_EQ(mask->damaged_region_for_testing().bounds(), gfx::Rect());
1470
1471 const gfx::Rect invalid_rect(gfx::Size(1, 1));
1472 mask->SchedulePaint(invalid_rect);
1473 EXPECT_EQ(mask->damaged_region_for_testing().bounds(), invalid_rect);
1474 root->SendDamagedRects();
1475 EXPECT_EQ(mask->damaged_region_for_testing().bounds(), gfx::Rect());
1476}
1477
Mohsen Izadi7be854302019-07-04 23:11:551478// Verifies that when a layer is reflecting other layers, mirror counts of
1479// reflected layers are updated properly.
1480TEST_F(LayerWithNullDelegateTest, SetShowReflectedLayerSubtree) {
Mohsen Izadi62a338d2019-07-30 19:49:471481 std::unique_ptr<Layer> reflected_layer_1 = CreateLayer(LAYER_SOLID_COLOR);
Mohsen Izadi7be854302019-07-04 23:11:551482 auto* reflected_layer_1_cc = reflected_layer_1->cc_layer_for_testing();
Mohsen Izadi1bcbf252019-06-27 01:26:291483
Mohsen Izadi62a338d2019-07-30 19:49:471484 std::unique_ptr<Layer> reflected_layer_2 = CreateLayer(LAYER_SOLID_COLOR);
Mohsen Izadi7be854302019-07-04 23:11:551485 auto* reflected_layer_2_cc = reflected_layer_2->cc_layer_for_testing();
Mohsen Izadi1bcbf252019-06-27 01:26:291486
Mohsen Izadi62a338d2019-07-30 19:49:471487 std::unique_ptr<Layer> reflecting_layer = CreateLayer(LAYER_SOLID_COLOR);
Mohsen Izadi1bcbf252019-06-27 01:26:291488
1489 // Originally, mirror counts should be zero.
Mohsen Izadi7be854302019-07-04 23:11:551490 auto* reflecting_layer_cc = reflecting_layer->mirror_layer_for_testing();
1491 EXPECT_EQ(nullptr, reflecting_layer_cc);
1492 EXPECT_EQ(0, reflected_layer_1_cc->mirror_count());
1493 EXPECT_EQ(0, reflected_layer_2_cc->mirror_count());
Mohsen Izadi1bcbf252019-06-27 01:26:291494
1495 // Mirror the first layer. Its mirror count should be increased.
Mohsen Izadi7be854302019-07-04 23:11:551496 reflecting_layer->SetShowReflectedLayerSubtree(reflected_layer_1.get());
1497 reflecting_layer_cc = reflecting_layer->mirror_layer_for_testing();
1498 ASSERT_NE(nullptr, reflecting_layer_cc);
1499 EXPECT_EQ(reflecting_layer->cc_layer_for_testing(), reflecting_layer_cc);
1500 EXPECT_EQ(reflected_layer_1_cc, reflecting_layer_cc->mirrored_layer());
1501 EXPECT_EQ(1, reflected_layer_1_cc->mirror_count());
1502 EXPECT_EQ(0, reflected_layer_2_cc->mirror_count());
Mohsen Izadi1bcbf252019-06-27 01:26:291503
1504 // Mirror the second layer. Its mirror count should be increased, but mirror
1505 // count for the first mirrored layer should be set back to zero.
Mohsen Izadi7be854302019-07-04 23:11:551506 reflecting_layer->SetShowReflectedLayerSubtree(reflected_layer_2.get());
1507 reflecting_layer_cc = reflecting_layer->mirror_layer_for_testing();
1508 ASSERT_NE(nullptr, reflecting_layer_cc);
1509 EXPECT_EQ(reflecting_layer->cc_layer_for_testing(), reflecting_layer_cc);
1510 EXPECT_EQ(reflected_layer_2_cc, reflecting_layer_cc->mirrored_layer());
1511 EXPECT_EQ(0, reflected_layer_1_cc->mirror_count());
1512 EXPECT_EQ(1, reflected_layer_2_cc->mirror_count());
Mohsen Izadi1bcbf252019-06-27 01:26:291513
1514 // Un-mirror the layer. All mirror counts should be set to zero.
Mohsen Izadi7be854302019-07-04 23:11:551515 reflecting_layer->SetShowSolidColorContent();
1516 reflecting_layer_cc = reflecting_layer->mirror_layer_for_testing();
1517 EXPECT_EQ(nullptr, reflecting_layer_cc);
1518 EXPECT_EQ(0, reflected_layer_1_cc->mirror_count());
1519 EXPECT_EQ(0, reflected_layer_2_cc->mirror_count());
Mohsen Izadi1bcbf252019-06-27 01:26:291520}
1521
Mohsen Izadi7be854302019-07-04 23:11:551522// Verifies that when a layer is reflecting another layer, its size matches the
1523// size of the reflected layer.
1524TEST_F(LayerWithNullDelegateTest, SetShowReflectedLayerSubtreeBounds) {
1525 const gfx::Rect reflected_bounds(0, 0, 50, 50);
1526 const gfx::Rect reflecting_bounds(0, 50, 10, 10);
Mohsen Izadi1bcbf252019-06-27 01:26:291527
Mohsen Izadi62a338d2019-07-30 19:49:471528 std::unique_ptr<Layer> reflected_layer = CreateLayer(LAYER_SOLID_COLOR);
Mohsen Izadi7be854302019-07-04 23:11:551529 reflected_layer->SetBounds(reflected_bounds);
Mohsen Izadi1bcbf252019-06-27 01:26:291530
Mohsen Izadi62a338d2019-07-30 19:49:471531 std::unique_ptr<Layer> reflecting_layer = CreateLayer(LAYER_SOLID_COLOR);
Mohsen Izadi7be854302019-07-04 23:11:551532 reflecting_layer->SetBounds(reflecting_bounds);
Mohsen Izadi1bcbf252019-06-27 01:26:291533
Mohsen Izadi7be854302019-07-04 23:11:551534 EXPECT_EQ(reflecting_bounds, reflecting_layer->bounds());
Mohsen Izadi1bcbf252019-06-27 01:26:291535
Mohsen Izadi7be854302019-07-04 23:11:551536 reflecting_layer->SetShowReflectedLayerSubtree(reflected_layer.get());
1537 EXPECT_EQ(reflecting_bounds.origin(), reflecting_layer->bounds().origin());
1538 EXPECT_EQ(reflected_bounds.size(), reflecting_layer->bounds().size());
Mohsen Izadi49108e12019-07-05 02:06:271539
1540 const gfx::Rect new_reflected_bounds(10, 10, 30, 30);
1541 reflected_layer->SetBounds(new_reflected_bounds);
1542 EXPECT_EQ(reflecting_bounds.origin(), reflecting_layer->bounds().origin());
1543 EXPECT_EQ(new_reflected_bounds.size(), reflecting_layer->bounds().size());
Xiyuan Xia6ff562d2019-08-27 15:54:331544
1545 // No crashes on reflected layer bounds change after the reflecting layer is
1546 // released.
1547 reflecting_layer = nullptr;
1548 reflected_layer->SetBounds(reflected_bounds);
1549 EXPECT_EQ(reflected_bounds, reflected_layer->bounds());
Mohsen Izadi1bcbf252019-06-27 01:26:291550}
1551
garykaceba92942014-09-05 04:26:071552void ExpectRgba(int x, int y, SkColor expected_color, SkColor actual_color) {
1553 EXPECT_EQ(expected_color, actual_color)
1554 << "Pixel error at x=" << x << " y=" << y << "; "
1555 << "actual RGBA=("
1556 << SkColorGetR(actual_color) << ","
1557 << SkColorGetG(actual_color) << ","
1558 << SkColorGetB(actual_color) << ","
1559 << SkColorGetA(actual_color) << "); "
1560 << "expected RGBA=("
1561 << SkColorGetR(expected_color) << ","
1562 << SkColorGetG(expected_color) << ","
1563 << SkColorGetB(expected_color) << ","
1564 << SkColorGetA(expected_color) << ")";
1565}
1566
[email protected]afed40642011-11-03 04:50:011567// Checks that pixels are actually drawn to the screen with a read back.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401568TEST_P(LayerWithRealCompositorTest, DrawPixels) {
[email protected]d56d3bb2013-08-12 20:58:011569 gfx::Size viewport_size = GetCompositor()->size();
1570
1571 // The window should be some non-trivial size but may not be exactly
1572 // 500x500 on all platforms/bots.
1573 EXPECT_GE(viewport_size.width(), 200);
1574 EXPECT_GE(viewport_size.height(), 200);
1575
1576 int blue_height = 10;
1577
Mohsen Izadi62a338d2019-07-30 19:49:471578 std::unique_ptr<Layer> layer =
1579 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size));
1580 std::unique_ptr<Layer> layer2 = CreateColorLayer(
1581 SK_ColorBLUE, gfx::Rect(0, 0, viewport_size.width(), blue_height));
[email protected]d86e97e2011-11-21 15:06:261582
1583 layer->Add(layer2.get());
1584
[email protected]afed40642011-11-03 04:50:011585 DrawTree(layer.get());
1586
1587 SkBitmap bitmap;
weiliangccb9e0df2014-09-22 14:55:211588 ReadPixels(&bitmap, gfx::Rect(viewport_size));
[email protected]e34d72512011-11-10 18:05:241589 ASSERT_FALSE(bitmap.empty());
[email protected]afed40642011-11-03 04:50:011590
[email protected]d56d3bb2013-08-12 20:58:011591 for (int x = 0; x < viewport_size.width(); x++) {
1592 for (int y = 0; y < viewport_size.height(); y++) {
1593 SkColor actual_color = bitmap.getColor(x, y);
1594 SkColor expected_color = y < blue_height ? SK_ColorBLUE : SK_ColorRED;
garykaceba92942014-09-05 04:26:071595 ExpectRgba(x, y, expected_color, actual_color);
1596 }
1597 }
1598}
1599
1600// Checks that drawing a layer with transparent pixels is blended correctly
1601// with the lower layer.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401602TEST_P(LayerWithRealCompositorTest, DrawAlphaBlendedPixels) {
garykaceba92942014-09-05 04:26:071603 gfx::Size viewport_size = GetCompositor()->size();
1604
1605 int test_size = 200;
1606 EXPECT_GE(viewport_size.width(), test_size);
1607 EXPECT_GE(viewport_size.height(), test_size);
1608
1609 // Blue with a wee bit of transparency.
Cary Clark9a8b8082018-04-23 18:29:211610 SkColor blue_with_alpha = SkColorSetARGB(40, 10, 20, 200);
1611 SkColor blend_color = SkColorSetARGB(255, 216, 3, 32);
garykaceba92942014-09-05 04:26:071612
Mohsen Izadi62a338d2019-07-30 19:49:471613 std::unique_ptr<Layer> background_layer =
1614 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size));
1615 std::unique_ptr<Layer> foreground_layer =
1616 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size));
garykaceba92942014-09-05 04:26:071617
1618 // This must be set to false for layers with alpha to be blended correctly.
1619 foreground_layer->SetFillsBoundsOpaquely(false);
1620
1621 background_layer->Add(foreground_layer.get());
1622 DrawTree(background_layer.get());
1623
1624 SkBitmap bitmap;
weiliangccb9e0df2014-09-22 14:55:211625 ReadPixels(&bitmap, gfx::Rect(viewport_size));
garykaceba92942014-09-05 04:26:071626 ASSERT_FALSE(bitmap.empty());
1627
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401628 SkBitmap original_bitmap;
1629 original_bitmap.allocPixels(bitmap.info());
1630 original_bitmap.eraseColor(blend_color);
1631
1632 cc::FuzzyPixelOffByOneComparator comparator(false);
1633 EXPECT_TRUE(comparator.Compare(bitmap, original_bitmap));
garykaceba92942014-09-05 04:26:071634}
1635
1636// Checks that using the AlphaShape filter applied to a layer with
1637// transparency, alpha-blends properly with the layer below.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401638TEST_P(LayerWithRealCompositorTest, DrawAlphaThresholdFilterPixels) {
garykaceba92942014-09-05 04:26:071639 gfx::Size viewport_size = GetCompositor()->size();
1640
1641 int test_size = 200;
1642 EXPECT_GE(viewport_size.width(), test_size);
1643 EXPECT_GE(viewport_size.height(), test_size);
1644
1645 int blue_height = 10;
Cary Clark9a8b8082018-04-23 18:29:211646 SkColor blue_with_alpha = SkColorSetARGB(40, 0, 0, 255);
1647 SkColor blend_color = SkColorSetARGB(255, 215, 0, 40);
garykaceba92942014-09-05 04:26:071648
Mohsen Izadi62a338d2019-07-30 19:49:471649 std::unique_ptr<Layer> background_layer =
1650 CreateColorLayer(SK_ColorRED, gfx::Rect(viewport_size));
1651 std::unique_ptr<Layer> foreground_layer =
1652 CreateColorLayer(blue_with_alpha, gfx::Rect(viewport_size));
garykaceba92942014-09-05 04:26:071653
1654 // Add a shape to restrict the visible part of the layer.
Jeremy Romanb4600572017-10-17 01:31:501655 auto shape = std::make_unique<Layer::ShapeRects>();
Valery Arkhangorodskya5d3bb32017-08-18 15:13:471656 shape->emplace_back(0, 0, viewport_size.width(), blue_height);
1657 foreground_layer->SetAlphaShape(std::move(shape));
garykaceba92942014-09-05 04:26:071658
1659 foreground_layer->SetFillsBoundsOpaquely(false);
1660
1661 background_layer->Add(foreground_layer.get());
1662 DrawTree(background_layer.get());
1663
1664 SkBitmap bitmap;
weiliangccb9e0df2014-09-22 14:55:211665 ReadPixels(&bitmap, gfx::Rect(viewport_size));
garykaceba92942014-09-05 04:26:071666 ASSERT_FALSE(bitmap.empty());
1667
garykaceba92942014-09-05 04:26:071668 for (int x = 0; x < test_size; x++) {
1669 for (int y = 0; y < test_size; y++) {
1670 SkColor actual_color = bitmap.getColor(x, y);
1671 ExpectRgba(x, y, actual_color,
1672 y < blue_height ? blend_color : SK_ColorRED);
[email protected]d56d3bb2013-08-12 20:58:011673 }
1674 }
[email protected]afed40642011-11-03 04:50:011675}
1676
[email protected]7ab3f272011-11-16 00:51:561677// Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401678TEST_P(LayerWithRealCompositorTest, SetRootLayer) {
[email protected]7ab3f272011-11-16 00:51:561679 Compositor* compositor = GetCompositor();
Mohsen Izadi62a338d2019-07-30 19:49:471680 std::unique_ptr<Layer> l1 =
1681 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
1682 std::unique_ptr<Layer> l2 =
1683 CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 350, 350));
[email protected]7ab3f272011-11-16 00:51:561684
[email protected]12233c362011-11-21 16:09:251685 EXPECT_EQ(NULL, l1->GetCompositor());
1686 EXPECT_EQ(NULL, l2->GetCompositor());
[email protected]7ab3f272011-11-16 00:51:561687
[email protected]12233c362011-11-21 16:09:251688 compositor->SetRootLayer(l1.get());
1689 EXPECT_EQ(compositor, l1->GetCompositor());
[email protected]7ab3f272011-11-16 00:51:561690
[email protected]12233c362011-11-21 16:09:251691 l1->Add(l2.get());
1692 EXPECT_EQ(compositor, l2->GetCompositor());
[email protected]7ab3f272011-11-16 00:51:561693
[email protected]12233c362011-11-21 16:09:251694 l1->Remove(l2.get());
1695 EXPECT_EQ(NULL, l2->GetCompositor());
[email protected]7ab3f272011-11-16 00:51:561696
[email protected]12233c362011-11-21 16:09:251697 l1->Add(l2.get());
1698 EXPECT_EQ(compositor, l2->GetCompositor());
[email protected]7ab3f272011-11-16 00:51:561699
1700 compositor->SetRootLayer(NULL);
[email protected]12233c362011-11-21 16:09:251701 EXPECT_EQ(NULL, l1->GetCompositor());
1702 EXPECT_EQ(NULL, l2->GetCompositor());
[email protected]7ab3f272011-11-16 00:51:561703}
1704
[email protected]05fab8d2011-11-16 02:15:331705// Checks that compositor observers are notified when:
1706// - DrawTree is called,
1707// - After ScheduleDraw is called, or
1708// - Whenever SetBounds, SetOpacity or SetTransform are called.
1709// TODO(vollick): could be reorganized into compositor_unittest.cc
Guido Urdaneta121a6e22017-11-17 11:01:081710// Flaky on Windows. See https://crbug.com/784563.
Jesse Doherty591df2822018-04-19 14:27:421711// Flaky on Linux tsan. See https://crbug.com/834026.
1712#if defined(OS_WIN) || defined(OS_LINUX)
Guido Urdaneta121a6e22017-11-17 11:01:081713#define MAYBE_CompositorObservers DISABLED_CompositorObservers
1714#else
1715#define MAYBE_CompositorObservers CompositorObservers
1716#endif
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401717TEST_P(LayerWithRealCompositorTest, MAYBE_CompositorObservers) {
Mohsen Izadi62a338d2019-07-30 19:49:471718 std::unique_ptr<Layer> l1 =
1719 CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 400, 400));
1720 std::unique_ptr<Layer> l2 =
1721 CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 350, 350));
[email protected]05fab8d2011-11-16 02:15:331722 l1->Add(l2.get());
1723 TestCompositorObserver observer;
1724 GetCompositor()->AddObserver(&observer);
1725
1726 // Explicitly called DrawTree should cause the observers to be notified.
1727 // NOTE: this call to DrawTree sets l1 to be the compositor's root layer.
1728 DrawTree(l1.get());
starazb14cc10cc2017-04-13 18:06:391729 EXPECT_TRUE(observer.notified());
[email protected]05fab8d2011-11-16 02:15:331730
[email protected]36e5ff12013-06-11 12:19:291731 // ScheduleDraw without any visible change should cause a commit.
[email protected]05fab8d2011-11-16 02:15:331732 observer.Reset();
1733 l1->ScheduleDraw();
[email protected]36e5ff12013-06-11 12:19:291734 WaitForCommit();
1735 EXPECT_TRUE(observer.committed());
[email protected]05fab8d2011-11-16 02:15:331736
1737 // Moving, but not resizing, a layer should alert the observers.
1738 observer.Reset();
1739 l2->SetBounds(gfx::Rect(0, 0, 350, 350));
starazb14cc10cc2017-04-13 18:06:391740 WaitForSwap();
1741 EXPECT_TRUE(observer.notified());
[email protected]05fab8d2011-11-16 02:15:331742
1743 // So should resizing a layer.
1744 observer.Reset();
1745 l2->SetBounds(gfx::Rect(0, 0, 400, 400));
starazb14cc10cc2017-04-13 18:06:391746 WaitForSwap();
1747 EXPECT_TRUE(observer.notified());
[email protected]05fab8d2011-11-16 02:15:331748
1749 // Opacity changes should alert the observers.
1750 observer.Reset();
1751 l2->SetOpacity(0.5f);
starazb14cc10cc2017-04-13 18:06:391752 WaitForSwap();
1753 EXPECT_TRUE(observer.notified());
[email protected]05fab8d2011-11-16 02:15:331754
1755 // So should setting the opacity back.
1756 observer.Reset();
1757 l2->SetOpacity(1.0f);
starazb14cc10cc2017-04-13 18:06:391758 WaitForSwap();
1759 EXPECT_TRUE(observer.notified());
[email protected]05fab8d2011-11-16 02:15:331760
1761 // Setting the transform of a layer should alert the observers.
1762 observer.Reset();
[email protected]0f0453e2012-10-14 18:15:351763 gfx::Transform transform;
[email protected]f7c321eb2012-11-26 20:13:081764 transform.Translate(200.0, 200.0);
1765 transform.Rotate(90.0);
1766 transform.Translate(-200.0, -200.0);
[email protected]05fab8d2011-11-16 02:15:331767 l2->SetTransform(transform);
starazb14cc10cc2017-04-13 18:06:391768 WaitForSwap();
1769 EXPECT_TRUE(observer.notified());
[email protected]05fab8d2011-11-16 02:15:331770
1771 GetCompositor()->RemoveObserver(&observer);
1772
1773 // Opacity changes should no longer alert the removed observer.
1774 observer.Reset();
1775 l2->SetOpacity(0.5f);
starazb14cc10cc2017-04-13 18:06:391776 WaitForSwap();
[email protected]f79729062013-04-03 20:01:501777
starazb14cc10cc2017-04-13 18:06:391778 EXPECT_FALSE(observer.notified());
[email protected]05fab8d2011-11-16 02:15:331779}
1780
[email protected]fcb98b72011-11-18 04:29:181781// Checks that modifying the hierarchy correctly affects final composite.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401782TEST_P(LayerWithRealCompositorTest, ModifyHierarchy) {
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:121783 viz::ParentLocalSurfaceIdAllocator allocator;
1784 allocator.GenerateId();
1785 GetCompositor()->SetScaleAndSize(
1786 1.0f, gfx::Size(50, 50), allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]fcb98b72011-11-18 04:29:181787
1788 // l0
1789 // +-l11
1790 // | +-l21
1791 // +-l12
Mohsen Izadi62a338d2019-07-30 19:49:471792 std::unique_ptr<Layer> l0 =
1793 CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 50, 50));
1794 std::unique_ptr<Layer> l11 =
1795 CreateColorLayer(SK_ColorGREEN, gfx::Rect(0, 0, 25, 25));
1796 std::unique_ptr<Layer> l21 =
1797 CreateColorLayer(SK_ColorMAGENTA, gfx::Rect(0, 0, 15, 15));
1798 std::unique_ptr<Layer> l12 =
1799 CreateColorLayer(SK_ColorBLUE, gfx::Rect(10, 10, 25, 25));
[email protected]fcb98b72011-11-18 04:29:181800
Peter Kastingee6749472018-11-20 05:13:251801 base::FilePath ref_img1 = test_data_dir().AppendASCII("ModifyHierarchy1.png");
1802 base::FilePath ref_img2 = test_data_dir().AppendASCII("ModifyHierarchy2.png");
[email protected]fcb98b72011-11-18 04:29:181803 SkBitmap bitmap;
1804
1805 l0->Add(l11.get());
1806 l11->Add(l21.get());
1807 l0->Add(l12.get());
1808 DrawTree(l0.get());
weiliangccb9e0df2014-09-22 14:55:211809 ReadPixels(&bitmap);
[email protected]fcb98b72011-11-18 04:29:181810 ASSERT_FALSE(bitmap.empty());
1811 // WritePNGFile(bitmap, ref_img1);
[email protected]ca435682013-03-29 04:09:471812 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
[email protected]fcb98b72011-11-18 04:29:181813
[email protected]5e4e61f2011-11-22 16:55:241814 l0->StackAtTop(l11.get());
[email protected]fcb98b72011-11-18 04:29:181815 DrawTree(l0.get());
weiliangccb9e0df2014-09-22 14:55:211816 ReadPixels(&bitmap);
[email protected]fcb98b72011-11-18 04:29:181817 ASSERT_FALSE(bitmap.empty());
1818 // WritePNGFile(bitmap, ref_img2);
[email protected]ca435682013-03-29 04:09:471819 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
[email protected]fcb98b72011-11-18 04:29:181820
[email protected]36e5ff12013-06-11 12:19:291821 // should restore to original configuration
1822 l0->StackAbove(l12.get(), l11.get());
[email protected]fcb98b72011-11-18 04:29:181823 DrawTree(l0.get());
weiliangccb9e0df2014-09-22 14:55:211824 ReadPixels(&bitmap);
[email protected]fcb98b72011-11-18 04:29:181825 ASSERT_FALSE(bitmap.empty());
[email protected]36e5ff12013-06-11 12:19:291826 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
[email protected]fcb98b72011-11-18 04:29:181827
[email protected]36e5ff12013-06-11 12:19:291828 // l11 back to front
1829 l0->StackAtTop(l11.get());
[email protected]fcb98b72011-11-18 04:29:181830 DrawTree(l0.get());
weiliangccb9e0df2014-09-22 14:55:211831 ReadPixels(&bitmap);
[email protected]fcb98b72011-11-18 04:29:181832 ASSERT_FALSE(bitmap.empty());
[email protected]ca435682013-03-29 04:09:471833 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
[email protected]fcb98b72011-11-18 04:29:181834
1835 // should restore to original configuration
[email protected]5e4e61f2011-11-22 16:55:241836 l0->StackAbove(l12.get(), l11.get());
[email protected]fcb98b72011-11-18 04:29:181837 DrawTree(l0.get());
weiliangccb9e0df2014-09-22 14:55:211838 ReadPixels(&bitmap);
[email protected]fcb98b72011-11-18 04:29:181839 ASSERT_FALSE(bitmap.empty());
[email protected]ca435682013-03-29 04:09:471840 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true)));
[email protected]36e5ff12013-06-11 12:19:291841
1842 // l11 back to front
1843 l0->StackAbove(l11.get(), l12.get());
1844 DrawTree(l0.get());
weiliangccb9e0df2014-09-22 14:55:211845 ReadPixels(&bitmap);
[email protected]36e5ff12013-06-11 12:19:291846 ASSERT_FALSE(bitmap.empty());
1847 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true)));
[email protected]fcb98b72011-11-18 04:29:181848}
1849
Mason Freed7302ffc2018-12-20 22:35:181850// Checks that basic background blur is working.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401851TEST_P(LayerWithRealCompositorTest, BackgroundBlur) {
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:121852 viz::ParentLocalSurfaceIdAllocator allocator;
1853 allocator.GenerateId();
1854 GetCompositor()->SetScaleAndSize(
1855 1.0f, gfx::Size(200, 200),
1856 allocator.GetCurrentLocalSurfaceIdAllocation());
Mason Freed7302ffc2018-12-20 22:35:181857 // l0
1858 // +-l1
1859 // +-l2
Mohsen Izadi62a338d2019-07-30 19:49:471860 std::unique_ptr<Layer> l0 =
1861 CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 200, 200));
1862 std::unique_ptr<Layer> l1 =
1863 CreateColorLayer(SK_ColorGREEN, gfx::Rect(100, 100, 100, 100));
Mason Freed7302ffc2018-12-20 22:35:181864 SkColor blue_with_alpha = SkColorSetARGB(40, 10, 20, 200);
Mohsen Izadi62a338d2019-07-30 19:49:471865 std::unique_ptr<Layer> l2 =
1866 CreateColorLayer(blue_with_alpha, gfx::Rect(50, 50, 100, 100));
Mason Freed7302ffc2018-12-20 22:35:181867 l2->SetFillsBoundsOpaquely(false);
1868 l2->SetBackgroundBlur(15);
1869
1870 base::FilePath ref_img1 = test_data_dir().AppendASCII("BackgroundBlur1.png");
1871 base::FilePath ref_img2 = test_data_dir().AppendASCII("BackgroundBlur2.png");
1872 SkBitmap bitmap;
1873
Mason Freed16f5c5ac2019-06-13 18:00:011874 // 25% of image can have up to a difference of 3.
1875 cc::FuzzyPixelComparator fuzzy_comparator(true, 25.f, 0.0f, 3.f, 3, 0);
1876
Mason Freed7302ffc2018-12-20 22:35:181877 l0->Add(l1.get());
1878 l0->Add(l2.get());
1879 DrawTree(l0.get());
1880 ReadPixels(&bitmap);
1881 ASSERT_FALSE(bitmap.empty());
1882 // WritePNGFile(bitmap, ref_img1, false);
Mason Freed16f5c5ac2019-06-13 18:00:011883 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, fuzzy_comparator));
Mason Freed7302ffc2018-12-20 22:35:181884
1885 l0->StackAtTop(l1.get());
1886 DrawTree(l0.get());
1887 ReadPixels(&bitmap);
1888 ASSERT_FALSE(bitmap.empty());
1889 // WritePNGFile(bitmap, ref_img2, false);
Mason Freed16f5c5ac2019-06-13 18:00:011890 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, fuzzy_comparator));
Mason Freed7302ffc2018-12-20 22:35:181891}
1892
1893// Checks that background blur bounds rect gets properly updated when device
1894// scale changes.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401895TEST_P(LayerWithRealCompositorTest, BackgroundBlurChangeDeviceScale) {
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:121896 viz::ParentLocalSurfaceIdAllocator allocator;
1897 allocator.GenerateId();
1898 GetCompositor()->SetScaleAndSize(
1899 1.0f, gfx::Size(200, 200),
1900 allocator.GetCurrentLocalSurfaceIdAllocation());
Mason Freed7302ffc2018-12-20 22:35:181901 // l0
1902 // +-l1
1903 // +-l2
Mohsen Izadi62a338d2019-07-30 19:49:471904 std::unique_ptr<Layer> l0 =
1905 CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 200, 200));
1906 std::unique_ptr<Layer> l1 =
1907 CreateColorLayer(SK_ColorGREEN, gfx::Rect(100, 100, 100, 100));
Mason Freed7302ffc2018-12-20 22:35:181908 SkColor blue_with_alpha = SkColorSetARGB(40, 10, 20, 200);
Mohsen Izadi62a338d2019-07-30 19:49:471909 std::unique_ptr<Layer> l2 =
1910 CreateColorLayer(blue_with_alpha, gfx::Rect(50, 50, 100, 100));
Mason Freed7302ffc2018-12-20 22:35:181911 l2->SetFillsBoundsOpaquely(false);
1912 l2->SetBackgroundBlur(15);
1913
1914 base::FilePath ref_img1 = test_data_dir().AppendASCII("BackgroundBlur1.png");
1915 base::FilePath ref_img2 =
1916 test_data_dir().AppendASCII("BackgroundBlur1_zoom.png");
1917 SkBitmap bitmap;
1918
Mason Freed16f5c5ac2019-06-13 18:00:011919 // 25% of image can have up to a difference of 3.
1920 cc::FuzzyPixelComparator fuzzy_comparator(true, 25.f, 0.0f, 3.f, 3, 0);
1921
Mason Freed7302ffc2018-12-20 22:35:181922 l0->Add(l1.get());
1923 l0->Add(l2.get());
1924 DrawTree(l0.get());
1925 ReadPixels(&bitmap);
1926 ASSERT_FALSE(bitmap.empty());
1927 // See LayerWithRealCompositorTest.BackgroundBlur test to rewrite this
1928 // baseline.
Mason Freed16f5c5ac2019-06-13 18:00:011929 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, fuzzy_comparator));
Mason Freed7302ffc2018-12-20 22:35:181930
jonross9746a212019-01-18 19:08:411931 allocator.GenerateId();
Mason Freed7302ffc2018-12-20 22:35:181932 // Now change the scale, and make sure the bounds are still correct.
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:121933 GetCompositor()->SetScaleAndSize(
1934 2.0f, gfx::Size(200, 200),
1935 allocator.GetCurrentLocalSurfaceIdAllocation());
Mason Freed7302ffc2018-12-20 22:35:181936 DrawTree(l0.get());
1937 ReadPixels(&bitmap);
1938 ASSERT_FALSE(bitmap.empty());
1939 // WritePNGFile(bitmap, ref_img2, false);
Mason Freed16f5c5ac2019-06-13 18:00:011940 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, fuzzy_comparator));
Mason Freed7302ffc2018-12-20 22:35:181941}
1942
[email protected]fcb98b72011-11-18 04:29:181943// Opacity is rendered correctly.
1944// Checks that modifying the hierarchy correctly affects final composite.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:401945TEST_P(LayerWithRealCompositorTest, Opacity) {
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:121946 viz::ParentLocalSurfaceIdAllocator allocator;
1947 allocator.GenerateId();
1948 GetCompositor()->SetScaleAndSize(
1949 1.0f, gfx::Size(50, 50), allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]fcb98b72011-11-18 04:29:181950
1951 // l0
1952 // +-l11
Mohsen Izadi62a338d2019-07-30 19:49:471953 std::unique_ptr<Layer> l0 =
1954 CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 50, 50));
1955 std::unique_ptr<Layer> l11 =
1956 CreateColorLayer(SK_ColorGREEN, gfx::Rect(0, 0, 25, 25));
[email protected]fcb98b72011-11-18 04:29:181957
Peter Kastingee6749472018-11-20 05:13:251958 base::FilePath ref_img = test_data_dir().AppendASCII("Opacity.png");
[email protected]fcb98b72011-11-18 04:29:181959
1960 l11->SetOpacity(0.75);
1961 l0->Add(l11.get());
1962 DrawTree(l0.get());
1963 SkBitmap bitmap;
weiliangccb9e0df2014-09-22 14:55:211964 ReadPixels(&bitmap);
[email protected]fcb98b72011-11-18 04:29:181965 ASSERT_FALSE(bitmap.empty());
1966 // WritePNGFile(bitmap, ref_img);
[email protected]ca435682013-03-29 04:09:471967 EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true)));
[email protected]fcb98b72011-11-18 04:29:181968}
1969
[email protected]caa1aafd2012-01-12 21:56:061970namespace {
1971
1972class SchedulePaintLayerDelegate : public LayerDelegate {
1973 public:
1974 SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {}
1975
dchengbc07fa02014-10-29 20:07:241976 ~SchedulePaintLayerDelegate() override {}
[email protected]caa1aafd2012-01-12 21:56:061977
1978 void set_layer(Layer* layer) {
1979 layer_ = layer;
1980 layer_->set_delegate(this);
1981 }
1982
1983 void SetSchedulePaintRect(const gfx::Rect& rect) {
1984 schedule_paint_rect_ = rect;
1985 }
1986
1987 int GetPaintCountAndClear() {
1988 int value = paint_count_;
1989 paint_count_ = 0;
1990 return value;
1991 }
1992
danakjc7323222015-04-07 21:09:381993 const gfx::Rect& last_clip_rect() const { return last_clip_rect_; }
[email protected]caa1aafd2012-01-12 21:56:061994
1995 private:
1996 // Overridden from LayerDelegate:
danakj85d970e2015-04-04 00:15:241997 void OnPaintLayer(const ui::PaintContext& context) override {
[email protected]caa1aafd2012-01-12 21:56:061998 paint_count_++;
1999 if (!schedule_paint_rect_.IsEmpty()) {
2000 layer_->SchedulePaint(schedule_paint_rect_);
2001 schedule_paint_rect_ = gfx::Rect();
2002 }
danakjc7323222015-04-07 21:09:382003 last_clip_rect_ = context.InvalidationForTesting();
[email protected]caa1aafd2012-01-12 21:56:062004 }
2005
Scott Violet06aff2b42017-09-08 00:26:322006 void OnDeviceScaleFactorChanged(float old_device_scale_factor,
2007 float new_device_scale_factor) override {}
[email protected]d3f5bbc12012-05-17 00:09:042008
[email protected]caa1aafd2012-01-12 21:56:062009 int paint_count_;
2010 Layer* layer_;
2011 gfx::Rect schedule_paint_rect_;
danakjc7323222015-04-07 21:09:382012 gfx::Rect last_clip_rect_;
[email protected]caa1aafd2012-01-12 21:56:062013
2014 DISALLOW_COPY_AND_ASSIGN(SchedulePaintLayerDelegate);
2015};
2016
2017} // namespace
2018
2019// Verifies that if SchedulePaint is invoked during painting the layer is still
2020// marked dirty.
2021TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) {
Mohsen Izadi62a338d2019-07-30 19:49:472022 std::unique_ptr<Layer> root =
2023 CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 500, 500));
[email protected]caa1aafd2012-01-12 21:56:062024 SchedulePaintLayerDelegate child_delegate;
Mohsen Izadi62a338d2019-07-30 19:49:472025 std::unique_ptr<Layer> child =
2026 CreateColorLayer(SK_ColorBLUE, gfx::Rect(0, 0, 200, 200));
[email protected]caa1aafd2012-01-12 21:56:062027 child_delegate.set_layer(child.get());
2028
2029 root->Add(child.get());
2030
2031 SchedulePaintForLayer(root.get());
2032 DrawTree(root.get());
[email protected]caa1aafd2012-01-12 21:56:062033 child->SchedulePaint(gfx::Rect(0, 0, 20, 20));
[email protected]36e5ff12013-06-11 12:19:292034 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
[email protected]44ed4bd2013-04-06 00:11:272035
[email protected]caa1aafd2012-01-12 21:56:062036 // Set a rect so that when OnPaintLayer() is invoked SchedulePaint is invoked
2037 // again.
2038 child_delegate.SetSchedulePaintRect(gfx::Rect(10, 10, 30, 30));
[email protected]36e5ff12013-06-11 12:19:292039 WaitForCommit();
[email protected]caa1aafd2012-01-12 21:56:062040 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
[email protected]44ed4bd2013-04-06 00:11:272041
[email protected]caa1aafd2012-01-12 21:56:062042 // Because SchedulePaint() was invoked from OnPaintLayer() |child| should
2043 // still need to be painted.
[email protected]36e5ff12013-06-11 12:19:292044 WaitForCommit();
[email protected]caa1aafd2012-01-12 21:56:062045 EXPECT_EQ(1, child_delegate.GetPaintCountAndClear());
2046 EXPECT_TRUE(child_delegate.last_clip_rect().Contains(
2047 gfx::Rect(10, 10, 30, 30)));
2048}
2049
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402050TEST_P(LayerWithRealCompositorTest, ScaleUpDown) {
Mohsen Izadi62a338d2019-07-30 19:49:472051 std::unique_ptr<Layer> root =
2052 CreateColorLayer(SK_ColorWHITE, gfx::Rect(10, 20, 200, 220));
[email protected]cd9a61c72012-05-08 19:16:592053 TestLayerDelegate root_delegate;
2054 root_delegate.AddColor(SK_ColorWHITE);
2055 root->set_delegate(&root_delegate);
weiliangca032f93b2015-07-13 22:39:472056 root_delegate.set_layer_bounds(root->bounds());
[email protected]cd9a61c72012-05-08 19:16:592057
Mohsen Izadi62a338d2019-07-30 19:49:472058 std::unique_ptr<Layer> l1 =
2059 CreateColorLayer(SK_ColorWHITE, gfx::Rect(10, 20, 140, 180));
[email protected]cd9a61c72012-05-08 19:16:592060 TestLayerDelegate l1_delegate;
2061 l1_delegate.AddColor(SK_ColorWHITE);
2062 l1->set_delegate(&l1_delegate);
weiliangca032f93b2015-07-13 22:39:472063 l1_delegate.set_layer_bounds(l1->bounds());
[email protected]cd9a61c72012-05-08 19:16:592064
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122065 viz::ParentLocalSurfaceIdAllocator allocator;
2066 allocator.GenerateId();
2067 GetCompositor()->SetScaleAndSize(
2068 1.0f, gfx::Size(500, 500),
2069 allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]cd9a61c72012-05-08 19:16:592070 GetCompositor()->SetRootLayer(root.get());
2071 root->Add(l1.get());
[email protected]260c3212013-04-11 22:25:382072 WaitForDraw();
[email protected]cd9a61c72012-05-08 19:16:592073
2074 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
2075 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
loysoac008462015-05-27 01:05:502076 gfx::Size cc_bounds_size = root->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322077 EXPECT_EQ("200x220", cc_bounds_size.ToString());
loysoac008462015-05-27 01:05:502078 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322079 EXPECT_EQ("140x180", cc_bounds_size.ToString());
[email protected]d3f5bbc12012-05-17 00:09:042080 // No scale change, so no scale notification.
2081 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
2082 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
[email protected]cd9a61c72012-05-08 19:16:592083
[email protected]cd9a61c72012-05-08 19:16:592084 // Scale up to 2.0. Changing scale doesn't change the bounds in DIP.
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122085 allocator.GenerateId();
2086 GetCompositor()->SetScaleAndSize(
2087 2.0f, gfx::Size(500, 500),
2088 allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]cd9a61c72012-05-08 19:16:592089 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
2090 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
[email protected]caa21662014-05-14 10:02:322091 // CC layer should still match the UI layer bounds.
loysoac008462015-05-27 01:05:502092 cc_bounds_size = root->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322093 EXPECT_EQ("200x220", cc_bounds_size.ToString());
loysoac008462015-05-27 01:05:502094 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322095 EXPECT_EQ("140x180", cc_bounds_size.ToString());
weiliangcd048acf2015-03-10 19:00:072096 // New scale factor must have been notified. Make sure painting happens at
2097 // right scale.
[email protected]d3f5bbc12012-05-17 00:09:042098 EXPECT_EQ(2.0f, root_delegate.device_scale_factor());
2099 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
[email protected]cd9a61c72012-05-08 19:16:592100
[email protected]cd9a61c72012-05-08 19:16:592101 // Scale down back to 1.0f.
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122102 allocator.GenerateId();
2103 GetCompositor()->SetScaleAndSize(
2104 1.0f, gfx::Size(500, 500),
2105 allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]cd9a61c72012-05-08 19:16:592106 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
2107 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
[email protected]caa21662014-05-14 10:02:322108 // CC layer should still match the UI layer bounds.
loysoac008462015-05-27 01:05:502109 cc_bounds_size = root->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322110 EXPECT_EQ("200x220", cc_bounds_size.ToString());
loysoac008462015-05-27 01:05:502111 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322112 EXPECT_EQ("140x180", cc_bounds_size.ToString());
weiliangcd048acf2015-03-10 19:00:072113 // New scale factor must have been notified. Make sure painting happens at
2114 // right scale.
[email protected]d3f5bbc12012-05-17 00:09:042115 EXPECT_EQ(1.0f, root_delegate.device_scale_factor());
2116 EXPECT_EQ(1.0f, l1_delegate.device_scale_factor());
[email protected]cd9a61c72012-05-08 19:16:592117
[email protected]07908eb2012-05-09 00:15:302118 root_delegate.reset();
2119 l1_delegate.reset();
[email protected]d3f5bbc12012-05-17 00:09:042120 // Just changing the size shouldn't notify the scale change nor
2121 // trigger repaint.
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122122 allocator.GenerateId();
2123 GetCompositor()->SetScaleAndSize(
2124 1.0f, gfx::Size(1000, 1000),
2125 allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]d3f5bbc12012-05-17 00:09:042126 // No scale change, so no scale notification.
2127 EXPECT_EQ(0.0f, root_delegate.device_scale_factor());
2128 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
[email protected]cd9a61c72012-05-08 19:16:592129}
2130
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402131TEST_P(LayerWithRealCompositorTest, ScaleReparent) {
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122132 viz::ParentLocalSurfaceIdAllocator allocator;
2133 allocator.GenerateId();
Mohsen Izadi62a338d2019-07-30 19:49:472134 std::unique_ptr<Layer> root =
2135 CreateColorLayer(SK_ColorWHITE, gfx::Rect(10, 20, 200, 220));
2136 std::unique_ptr<Layer> l1 =
2137 CreateColorLayer(SK_ColorWHITE, gfx::Rect(10, 20, 140, 180));
[email protected]cd9a61c72012-05-08 19:16:592138 TestLayerDelegate l1_delegate;
2139 l1_delegate.AddColor(SK_ColorWHITE);
2140 l1->set_delegate(&l1_delegate);
weiliangca032f93b2015-07-13 22:39:472141 l1_delegate.set_layer_bounds(l1->bounds());
[email protected]cd9a61c72012-05-08 19:16:592142
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122143 GetCompositor()->SetScaleAndSize(
2144 1.0f, gfx::Size(500, 500),
2145 allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]cd9a61c72012-05-08 19:16:592146 GetCompositor()->SetRootLayer(root.get());
[email protected]cd9a61c72012-05-08 19:16:592147
2148 root->Add(l1.get());
2149 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
loysoac008462015-05-27 01:05:502150 gfx::Size cc_bounds_size = l1->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322151 EXPECT_EQ("140x180", cc_bounds_size.ToString());
[email protected]d3f5bbc12012-05-17 00:09:042152 EXPECT_EQ(0.0f, l1_delegate.device_scale_factor());
[email protected]cd9a61c72012-05-08 19:16:592153
[email protected]cd9a61c72012-05-08 19:16:592154 // Remove l1 from root and change the scale.
2155 root->Remove(l1.get());
2156 EXPECT_EQ(NULL, l1->parent());
2157 EXPECT_EQ(NULL, l1->GetCompositor());
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122158 allocator.GenerateId();
2159 GetCompositor()->SetScaleAndSize(
2160 2.0f, gfx::Size(500, 500),
2161 allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]cd9a61c72012-05-08 19:16:592162 // Sanity check on root and l1.
2163 EXPECT_EQ("10,20 200x220", root->bounds().ToString());
loysoac008462015-05-27 01:05:502164 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322165 EXPECT_EQ("140x180", cc_bounds_size.ToString());
[email protected]cd9a61c72012-05-08 19:16:592166
2167 root->Add(l1.get());
2168 EXPECT_EQ("10,20 140x180", l1->bounds().ToString());
loysoac008462015-05-27 01:05:502169 cc_bounds_size = l1->cc_layer_for_testing()->bounds();
[email protected]caa21662014-05-14 10:02:322170 EXPECT_EQ("140x180", cc_bounds_size.ToString());
[email protected]d3f5bbc12012-05-17 00:09:042171 EXPECT_EQ(2.0f, l1_delegate.device_scale_factor());
[email protected]cd9a61c72012-05-08 19:16:592172}
2173
[email protected]28c219382012-05-11 09:05:312174// Verifies that when changing bounds on a layer that is invisible, and then
2175// made visible, the right thing happens:
2176// - if just a move, then no painting should happen.
2177// - if a resize, the layer should be repainted.
2178TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) {
Mohsen Izadi62a338d2019-07-30 19:49:472179 std::unique_ptr<Layer> root =
2180 CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000));
[email protected]28c219382012-05-11 09:05:312181
Mohsen Izadi62a338d2019-07-30 19:49:472182 std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED);
[email protected]28c219382012-05-11 09:05:312183 child->SetBounds(gfx::Rect(0, 0, 500, 500));
weiliangca032f93b2015-07-13 22:39:472184 DrawTreeLayerDelegate delegate(child->bounds());
[email protected]28c219382012-05-11 09:05:312185 child->set_delegate(&delegate);
2186 root->Add(child.get());
2187
2188 // Paint once for initial damage.
2189 child->SetVisible(true);
2190 DrawTree(root.get());
2191
2192 // Reset into invisible state.
2193 child->SetVisible(false);
2194 DrawTree(root.get());
[email protected]28c219382012-05-11 09:05:312195 delegate.Reset();
2196
2197 // Move layer.
2198 child->SetBounds(gfx::Rect(200, 200, 500, 500));
2199 child->SetVisible(true);
[email protected]28c219382012-05-11 09:05:312200 DrawTree(root.get());
2201 EXPECT_FALSE(delegate.painted());
2202
2203 // Reset into invisible state.
2204 child->SetVisible(false);
2205 DrawTree(root.get());
[email protected]28c219382012-05-11 09:05:312206 delegate.Reset();
2207
2208 // Resize layer.
2209 child->SetBounds(gfx::Rect(200, 200, 400, 400));
2210 child->SetVisible(true);
[email protected]28c219382012-05-11 09:05:312211 DrawTree(root.get());
2212 EXPECT_TRUE(delegate.painted());
2213}
2214
[email protected]785b0af2013-10-02 18:08:412215TEST_F(LayerWithDelegateTest, ExternalContent) {
Mohsen Izadi62a338d2019-07-30 19:49:472216 std::unique_ptr<Layer> root =
2217 CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000));
2218 std::unique_ptr<Layer> child = CreateLayer(LAYER_SOLID_COLOR);
[email protected]785b0af2013-10-02 18:08:412219
2220 child->SetBounds(gfx::Rect(0, 0, 10, 10));
2221 child->SetVisible(true);
2222 root->Add(child.get());
2223
jbaumanf472c6872014-10-13 20:06:432224 // The layer is already showing solid color content, so the cc layer won't
2225 // change.
loysoac008462015-05-27 01:05:502226 scoped_refptr<cc::Layer> before = child->cc_layer_for_testing();
Fady Samuelb46e0ef2018-01-30 04:48:412227
jbaumanf472c6872014-10-13 20:06:432228 child->SetShowSolidColorContent();
loysoac008462015-05-27 01:05:502229 EXPECT_TRUE(child->cc_layer_for_testing());
2230 EXPECT_EQ(before.get(), child->cc_layer_for_testing());
[email protected]785b0af2013-10-02 18:08:412231
jbauman957acd52016-02-05 23:13:312232 // Showing surface content changes the underlying cc layer.
Fady Samuel6ca67282018-06-21 23:00:412233 viz::FrameSinkId frame_sink_id(1u, 1u);
2234 viz::ParentLocalSurfaceIdAllocator allocator;
loysoac008462015-05-27 01:05:502235 before = child->cc_layer_for_testing();
Jonathan Ross89807fc2018-10-30 17:41:212236 allocator.GenerateId();
2237 child->SetShowSurface(
jonross58cab432018-11-29 02:30:302238 viz::SurfaceId(
2239 frame_sink_id,
2240 allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id()),
Jonathan Ross89807fc2018-10-30 17:41:212241 gfx::Size(10, 10), SK_ColorWHITE,
2242 cc::DeadlinePolicy::UseDefaultDeadline(), false);
Fady Samuelb46e0ef2018-01-30 04:48:412243 scoped_refptr<cc::Layer> after = child->cc_layer_for_testing();
2244 const auto* surface = static_cast<cc::SurfaceLayer*>(after.get());
2245 EXPECT_TRUE(after.get());
2246 EXPECT_NE(before.get(), after.get());
2247 EXPECT_EQ(base::nullopt, surface->deadline_in_frames());
2248
Jonathan Ross89807fc2018-10-30 17:41:212249 allocator.GenerateId();
2250 child->SetShowSurface(
jonross58cab432018-11-29 02:30:302251 viz::SurfaceId(
2252 frame_sink_id,
2253 allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id()),
Jonathan Ross89807fc2018-10-30 17:41:212254 gfx::Size(10, 10), SK_ColorWHITE,
2255 cc::DeadlinePolicy::UseSpecifiedDeadline(4u), false);
Fady Samuelb46e0ef2018-01-30 04:48:412256 EXPECT_EQ(4u, surface->deadline_in_frames());
[email protected]785b0af2013-10-02 18:08:412257}
2258
domlaskowski4b33bfe2016-10-27 00:34:222259TEST_F(LayerWithDelegateTest, ExternalContentMirroring) {
Mohsen Izadi62a338d2019-07-30 19:49:472260 std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR);
domlaskowski4b33bfe2016-10-27 00:34:222261
Fady Samueld5c26182017-07-12 02:43:332262 viz::SurfaceId surface_id(
2263 viz::FrameSinkId(0, 1),
2264 viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
Saman Sami98c524052018-10-26 17:34:572265 layer->SetShowSurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE,
2266 cc::DeadlinePolicy::UseDefaultDeadline(), false);
domlaskowski4b33bfe2016-10-27 00:34:222267
2268 const auto mirror = layer->Mirror();
2269 auto* const cc_layer = mirror->cc_layer_for_testing();
2270 const auto* surface = static_cast<cc::SurfaceLayer*>(cc_layer);
2271
2272 // Mirroring preserves surface state.
Saman Sami98c524052018-10-26 17:34:572273 EXPECT_EQ(surface_id, surface->surface_id());
domlaskowski4b33bfe2016-10-27 00:34:222274
staraz7d7f6eb2016-11-11 00:19:172275 surface_id =
Fady Samueld5c26182017-07-12 02:43:332276 viz::SurfaceId(viz::FrameSinkId(1, 2),
2277 viz::LocalSurfaceId(3, base::UnguessableToken::Create()));
Saman Sami98c524052018-10-26 17:34:572278 layer->SetShowSurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE,
2279 cc::DeadlinePolicy::UseDefaultDeadline(), false);
domlaskowski4b33bfe2016-10-27 00:34:222280
fsamuel3f0eb022017-02-28 19:52:162281 // The mirror should continue to use the same cc_layer.
2282 EXPECT_EQ(cc_layer, mirror->cc_layer_for_testing());
Saman Sami98c524052018-10-26 17:34:572283 layer->SetShowSurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE,
2284 cc::DeadlinePolicy::UseDefaultDeadline(), false);
domlaskowski4b33bfe2016-10-27 00:34:222285
2286 // Surface updates propagate to the mirror.
Saman Sami98c524052018-10-26 17:34:572287 EXPECT_EQ(surface_id, surface->surface_id());
samans47fb8912016-12-14 22:24:462288}
2289
Malay Keshav87c42c02019-01-15 08:37:472290TEST_F(LayerWithDelegateTest, TransferableResourceMirroring) {
Mohsen Izadi62a338d2019-07-30 19:49:472291 std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR);
Malay Keshav87c42c02019-01-15 08:37:472292
Saman Sami51c0a3e2019-05-02 13:43:382293 constexpr gfx::Size size(64, 64);
Malay Keshav87c42c02019-01-15 08:37:472294 auto resource = viz::TransferableResource::MakeGL(
Saman Sami51c0a3e2019-05-02 13:43:382295 gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
2296 size, false /* is_overlay_candidate */);
Malay Keshav87c42c02019-01-15 08:37:472297 bool release_callback_run = false;
2298
2299 layer->SetTransferableResource(
2300 resource,
2301 viz::SingleReleaseCallback::Create(
2302 base::BindOnce(ReturnMailbox, &release_callback_run)),
2303 gfx::Size(10, 10));
2304 EXPECT_FALSE(release_callback_run);
2305 EXPECT_TRUE(layer->has_external_content());
2306
2307 auto mirror = layer->Mirror();
2308 EXPECT_TRUE(mirror->has_external_content());
2309
2310 // Clearing the resource on a mirror layer should not release the source layer
2311 // resource.
2312 mirror.reset();
2313 EXPECT_FALSE(release_callback_run);
2314
2315 mirror = layer->Mirror();
2316 EXPECT_TRUE(mirror->has_external_content());
2317
2318 // Clearing the transferable resource on the source layer should clear it from
2319 // the mirror layer as well.
2320 layer->SetShowSolidColorContent();
2321 EXPECT_TRUE(release_callback_run);
2322 EXPECT_FALSE(layer->has_external_content());
2323 EXPECT_FALSE(mirror->has_external_content());
2324
2325 resource = viz::TransferableResource::MakeGL(
Saman Sami51c0a3e2019-05-02 13:43:382326 gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(),
2327 size, false /* is_overlay_candidate */);
Malay Keshav87c42c02019-01-15 08:37:472328 release_callback_run = false;
2329
2330 // Setting a transferable resource on the source layer should set it on the
2331 // mirror layers as well.
2332 layer->SetTransferableResource(
2333 resource,
2334 viz::SingleReleaseCallback::Create(
2335 base::BindOnce(ReturnMailbox, &release_callback_run)),
2336 gfx::Size(10, 10));
2337 EXPECT_FALSE(release_callback_run);
2338 EXPECT_TRUE(layer->has_external_content());
2339 EXPECT_TRUE(mirror->has_external_content());
2340
2341 layer.reset();
2342}
2343
kirr783d44112014-10-06 17:17:122344// Verifies that layer filters still attached after changing implementation
2345// layer.
2346TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) {
Mohsen Izadi62a338d2019-07-30 19:49:472347 std::unique_ptr<Layer> layer = CreateLayer(LAYER_TEXTURED);
kirr783d44112014-10-06 17:17:122348 layer->SetBounds(gfx::Rect(0, 0, 10, 10));
loysoac008462015-05-27 01:05:502349 EXPECT_TRUE(layer->cc_layer_for_testing());
2350 EXPECT_EQ(0u, layer->cc_layer_for_testing()->filters().size());
kirr783d44112014-10-06 17:17:122351
2352 layer->SetLayerGrayscale(0.5f);
2353 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
loysoac008462015-05-27 01:05:502354 EXPECT_EQ(1u, layer->cc_layer_for_testing()->filters().size());
kirr783d44112014-10-06 17:17:122355
jbauman957acd52016-02-05 23:13:312356 // Showing surface content changes the underlying cc layer.
loysoac008462015-05-27 01:05:502357 scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing();
Saman Sami98c524052018-10-26 17:34:572358 layer->SetShowSurface(viz::SurfaceId(), gfx::Size(10, 10), SK_ColorWHITE,
2359 cc::DeadlinePolicy::UseDefaultDeadline(), false);
kirr783d44112014-10-06 17:17:122360 EXPECT_EQ(layer->layer_grayscale(), 0.5f);
loysoac008462015-05-27 01:05:502361 EXPECT_TRUE(layer->cc_layer_for_testing());
2362 EXPECT_NE(before.get(), layer->cc_layer_for_testing());
2363 EXPECT_EQ(1u, layer->cc_layer_for_testing()->filters().size());
kirr783d44112014-10-06 17:17:122364}
2365
[email protected]f2891462013-03-11 23:26:512366// Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402367TEST_P(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) {
Mohsen Izadi62a338d2019-07-30 19:49:472368 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2369 std::unique_ptr<Layer> l1 = CreateLayer(LAYER_TEXTURED);
2370 std::unique_ptr<Layer> l2 = CreateLayer(LAYER_TEXTURED);
[email protected]f2891462013-03-11 23:26:512371
2372 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
2373 l2->SetAnimator(LayerAnimator::CreateImplicitAnimator());
2374
Yi Guaa830ff2018-02-22 03:09:112375 auto* animation1 = l1->GetAnimator()->GetAnimationForTesting();
2376 auto* animation2 = l2->GetAnimator()->GetAnimationForTesting();
loysodb006882016-09-14 00:31:512377
Yi Guaa830ff2018-02-22 03:09:112378 EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512379
2380 // Trigger a threaded animation.
2381 l1->SetOpacity(0.5f);
2382
Yi Guaa830ff2018-02-22 03:09:112383 EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512384
2385 // Ensure we can remove a pending threaded animation.
2386 l1->GetAnimator()->StopAnimating();
2387
Yi Guaa830ff2018-02-22 03:09:112388 EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512389
2390 // Trigger another threaded animation.
2391 l1->SetOpacity(0.2f);
2392
Yi Guaa830ff2018-02-22 03:09:112393 EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512394
2395 root->Add(l1.get());
2396 GetCompositor()->SetRootLayer(root.get());
2397
loysodb006882016-09-14 00:31:512398 // Now l1 is part of a tree.
Yi Guaa830ff2018-02-22 03:09:112399 EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512400
[email protected]f2891462013-03-11 23:26:512401 l1->SetOpacity(0.1f);
loysodb006882016-09-14 00:31:512402 // IMMEDIATELY_SET_NEW_TARGET is a default preemption strategy for conflicting
2403 // animations.
Yi Guaa830ff2018-02-22 03:09:112404 EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512405
loysodb006882016-09-14 00:31:512406 // Adding a layer to an existing tree.
[email protected]f2891462013-03-11 23:26:512407 l2->SetOpacity(0.5f);
Yi Guaa830ff2018-02-22 03:09:112408 EXPECT_TRUE(animation2->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512409
2410 l1->Add(l2.get());
Yi Guaa830ff2018-02-22 03:09:112411 EXPECT_TRUE(animation2->keyframe_effect()->has_any_keyframe_model());
[email protected]f2891462013-03-11 23:26:512412}
2413
[email protected]ffd1ccb2013-03-15 07:48:242414// Tests that in-progress threaded animations complete when a Layer's
2415// cc::Layer changes.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402416TEST_P(LayerWithRealCompositorTest, SwitchCCLayerAnimations) {
Mohsen Izadi62a338d2019-07-30 19:49:472417 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2418 std::unique_ptr<Layer> l1 = CreateLayer(LAYER_TEXTURED);
[email protected]ffd1ccb2013-03-15 07:48:242419 GetCompositor()->SetRootLayer(root.get());
2420 root->Add(l1.get());
2421
2422 l1->SetAnimator(LayerAnimator::CreateImplicitAnimator());
2423
2424 EXPECT_FLOAT_EQ(l1->opacity(), 1.0f);
2425
2426 // Trigger a threaded animation.
2427 l1->SetOpacity(0.5f);
2428
2429 // Change l1's cc::Layer.
2430 l1->SwitchCCLayerForTest();
2431
2432 // Ensure that the opacity animation completed.
2433 EXPECT_FLOAT_EQ(l1->opacity(), 0.5f);
2434}
2435
jonross31048b62015-05-20 02:09:252436// Tests that when a LAYER_SOLID_COLOR has its CC layer switched, that
2437// opaqueness and color set while not animating, are maintained.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402438TEST_P(LayerWithRealCompositorTest, SwitchCCLayerSolidColorNotAnimating) {
jonross31048b62015-05-20 02:09:252439 SkColor transparent = SK_ColorTRANSPARENT;
Mohsen Izadi62a338d2019-07-30 19:49:472440 std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR);
jonross31048b62015-05-20 02:09:252441 GetCompositor()->SetRootLayer(root.get());
2442 root->SetFillsBoundsOpaquely(false);
2443 root->SetColor(transparent);
2444
2445 EXPECT_FALSE(root->fills_bounds_opaquely());
2446 EXPECT_FALSE(
2447 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
2448 EXPECT_EQ(transparent, root->background_color());
2449 EXPECT_EQ(transparent, root->GetTargetColor());
2450
2451 // Changing the underlying layer should not affect targets.
2452 root->SwitchCCLayerForTest();
2453
2454 EXPECT_FALSE(root->fills_bounds_opaquely());
2455 EXPECT_FALSE(
2456 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
2457 EXPECT_EQ(transparent, root->background_color());
2458 EXPECT_EQ(transparent, root->GetTargetColor());
2459}
2460
2461// Tests that when a LAYER_SOLID_COLOR has its CC layer switched during an
2462// animation of its opaquness and color, that both the current values, and the
2463// targets are maintained.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402464TEST_P(LayerWithRealCompositorTest, SwitchCCLayerSolidColorWhileAnimating) {
jonross31048b62015-05-20 02:09:252465 SkColor transparent = SK_ColorTRANSPARENT;
Mohsen Izadi62a338d2019-07-30 19:49:472466 std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR);
jonross31048b62015-05-20 02:09:252467 GetCompositor()->SetRootLayer(root.get());
2468 root->SetColor(SK_ColorBLACK);
2469
2470 EXPECT_TRUE(root->fills_bounds_opaquely());
2471 EXPECT_EQ(SK_ColorBLACK, root->GetTargetColor());
2472
Mohsen Izadi62a338d2019-07-30 19:49:472473 auto long_duration_animation =
2474 std::make_unique<ui::ScopedAnimationDurationScaleMode>(
2475 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
jonross31048b62015-05-20 02:09:252476 {
2477 ui::ScopedLayerAnimationSettings animation(root->GetAnimator());
2478 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
2479 root->SetFillsBoundsOpaquely(false);
2480 root->SetColor(transparent);
2481 }
2482
2483 EXPECT_TRUE(root->fills_bounds_opaquely());
2484 EXPECT_TRUE(
2485 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
2486 EXPECT_EQ(SK_ColorBLACK, root->background_color());
2487 EXPECT_EQ(transparent, root->GetTargetColor());
2488
2489 // Changing the underlying layer should not affect targets.
2490 root->SwitchCCLayerForTest();
2491
2492 EXPECT_TRUE(root->fills_bounds_opaquely());
2493 EXPECT_TRUE(
2494 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
2495 EXPECT_EQ(SK_ColorBLACK, root->background_color());
2496 EXPECT_EQ(transparent, root->GetTargetColor());
2497
2498 // End all animations.
2499 root->GetAnimator()->StopAnimating();
2500 EXPECT_FALSE(root->fills_bounds_opaquely());
2501 EXPECT_FALSE(
2502 root->GetAnimator()->IsAnimatingProperty(LayerAnimationElement::COLOR));
2503 EXPECT_EQ(transparent, root->background_color());
2504 EXPECT_EQ(transparent, root->GetTargetColor());
2505}
2506
wutao36850732017-07-29 20:24:072507// Tests that when a layer with cache_render_surface flag has its CC layer
2508// switched, that the cache_render_surface flag is maintained.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402509TEST_P(LayerWithRealCompositorTest, SwitchCCLayerCacheRenderSurface) {
Mohsen Izadi62a338d2019-07-30 19:49:472510 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2511 std::unique_ptr<Layer> l1 = CreateLayer(LAYER_TEXTURED);
wutao36850732017-07-29 20:24:072512 GetCompositor()->SetRootLayer(root.get());
2513 root->Add(l1.get());
2514
wutao52217d12017-08-18 02:40:312515 l1->AddCacheRenderSurfaceRequest();
wutao36850732017-07-29 20:24:072516
2517 // Change l1's cc::Layer.
2518 l1->SwitchCCLayerForTest();
2519
2520 // Ensure that the cache_render_surface flag is maintained.
2521 EXPECT_TRUE(l1->cc_layer_for_testing()->cache_render_surface());
2522}
2523
wutao1d35eeb72017-10-12 23:01:242524// Tests that when a layer with trilinear_filtering flag has its CC layer
2525// switched, that the trilinear_filtering flag is maintained.
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402526TEST_P(LayerWithRealCompositorTest, SwitchCCLayerTrilinearFiltering) {
Mohsen Izadi62a338d2019-07-30 19:49:472527 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2528 std::unique_ptr<Layer> l1 = CreateLayer(LAYER_TEXTURED);
wutao1d35eeb72017-10-12 23:01:242529 GetCompositor()->SetRootLayer(root.get());
2530 root->Add(l1.get());
2531
2532 l1->AddTrilinearFilteringRequest();
2533
2534 // Change l1's cc::Layer.
2535 l1->SwitchCCLayerForTest();
2536
2537 // Ensure that the trilinear_filtering flag is maintained.
2538 EXPECT_TRUE(l1->cc_layer_for_testing()->trilinear_filtering());
2539}
2540
Mohsen Izadib22195c72019-07-30 02:21:152541// Tests that when a layer with masks_to_bounds flag has its CC layer switched,
2542// that the masks_to_bounds flag is maintained.
2543TEST_P(LayerWithRealCompositorTest, SwitchCCLayerMasksToBounds) {
2544 std::unique_ptr<Layer> root(CreateLayer(LAYER_TEXTURED));
2545 std::unique_ptr<Layer> l1(CreateLayer(LAYER_TEXTURED));
2546 GetCompositor()->SetRootLayer(root.get());
2547 root->Add(l1.get());
2548
2549 l1->SetMasksToBounds(true);
2550 EXPECT_TRUE(l1->cc_layer_for_testing()->masks_to_bounds());
2551
2552 // Change l1's cc::Layer.
2553 l1->SwitchCCLayerForTest();
2554
2555 // Ensure that the trilinear_filtering flag is maintained.
2556 EXPECT_TRUE(l1->cc_layer_for_testing()->masks_to_bounds());
2557}
2558
Malay Keshav65840f0e2019-08-20 00:38:502559// Triggerring a OnDeviceScaleFactorChanged while a layer is undergoing
Xiyuan Xiad2bcb9352020-01-10 23:02:592560// transform animation, may cause a crash. This is because an animation observer
2561// may mutate the tree, e.g. deleting a layer, changing ancestor z-order etc,
2562// which breaks the tree traversal and might lead to a use-after-free seg fault.
2563TEST_P(LayerWithRealCompositorTest, TreeMutationDuringScaleFactorChange) {
2564 TestCallbackAnimationObserver animation_observer;
Malay Keshav65840f0e2019-08-20 00:38:502565
2566 std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR);
Malay Keshav65840f0e2019-08-20 00:38:502567 GetCompositor()->SetRootLayer(root.get());
Xiyuan Xiad2bcb9352020-01-10 23:02:592568
2569 // Tests scenarios that |layer_to_delete| is deleted when animation ends.
2570
2571 std::unique_ptr<Layer> layer_to_delete = CreateLayer(LAYER_SOLID_COLOR);
2572 animation_observer.SetCallback(
2573 base::BindLambdaForTesting([&]() { layer_to_delete.reset(); }));
2574
2575 root->Add(layer_to_delete.get());
Malay Keshav65840f0e2019-08-20 00:38:502576
2577 EXPECT_EQ(gfx::Transform(), layer_to_delete->GetTargetTransform());
2578
2579 gfx::Transform transform;
2580 transform.Scale(2, 1);
2581 transform.Translate(10, 5);
2582
2583 auto long_duration_animation =
2584 std::make_unique<ui::ScopedAnimationDurationScaleMode>(
2585 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
2586 {
2587 ui::ScopedLayerAnimationSettings animation(layer_to_delete->GetAnimator());
2588 animation.AddObserver(&animation_observer);
2589 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
2590 layer_to_delete->SetTransform(transform);
2591 }
2592
2593 // This call should not crash.
2594 root->OnDeviceScaleFactorChanged(2.f);
Xiyuan Xiad2bcb9352020-01-10 23:02:592595 // |layer_to_delete| should be gone.
2596 EXPECT_FALSE(layer_to_delete);
Malay Keshav65840f0e2019-08-20 00:38:502597
Xiyuan Xiad2bcb9352020-01-10 23:02:592598 layer_to_delete = CreateLayer(LAYER_SOLID_COLOR);
2599 animation_observer.SetCallback(
2600 base::BindLambdaForTesting([&]() { layer_to_delete.reset(); }));
Malay Keshav65840f0e2019-08-20 00:38:502601
2602 std::unique_ptr<Layer> child = CreateLayer(LAYER_SOLID_COLOR);
2603
Xiyuan Xiad2bcb9352020-01-10 23:02:592604 root->Add(layer_to_delete.get());
Malay Keshav65840f0e2019-08-20 00:38:502605 layer_to_delete->Add(child.get());
2606
2607 long_duration_animation =
2608 std::make_unique<ui::ScopedAnimationDurationScaleMode>(
2609 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
2610 {
2611 ui::ScopedLayerAnimationSettings animation(layer_to_delete->GetAnimator());
2612 animation.AddObserver(&animation_observer);
2613 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
2614 layer_to_delete->SetTransform(transform);
2615 }
2616
2617 // This call should not crash.
2618 root->OnDeviceScaleFactorChanged(1.5f);
Xiyuan Xiad2bcb9352020-01-10 23:02:592619 // |layer_to_delete| should be gone.
2620 EXPECT_FALSE(layer_to_delete);
Malay Keshav65840f0e2019-08-20 00:38:502621
Xiyuan Xiad2bcb9352020-01-10 23:02:592622 layer_to_delete = CreateLayer(LAYER_SOLID_COLOR);
2623 animation_observer.SetCallback(
2624 base::BindLambdaForTesting([&]() { layer_to_delete.reset(); }));
Malay Keshav65840f0e2019-08-20 00:38:502625
2626 std::unique_ptr<Layer> child2 = CreateLayer(LAYER_SOLID_COLOR);
2627
Xiyuan Xiad2bcb9352020-01-10 23:02:592628 root->Add(layer_to_delete.get());
Malay Keshav65840f0e2019-08-20 00:38:502629 layer_to_delete->Add(child.get());
2630 layer_to_delete->Add(child2.get());
2631
2632 long_duration_animation =
2633 std::make_unique<ui::ScopedAnimationDurationScaleMode>(
2634 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
2635 {
2636 ui::ScopedLayerAnimationSettings animation(child->GetAnimator());
2637 animation.AddObserver(&animation_observer);
2638 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
2639 child->SetTransform(transform);
2640 }
2641
2642 // This call should not crash.
2643 root->OnDeviceScaleFactorChanged(2.f);
Xiyuan Xiad2bcb9352020-01-10 23:02:592644 // |layer_to_delete| should be gone.
2645 EXPECT_FALSE(layer_to_delete);
2646
2647 // Tests scenarios that the tree is changed when animation ends.
2648
2649 root->Add(child.get());
2650 root->Add(child2.get());
2651
2652 animation_observer.SetCallback(base::BindLambdaForTesting(
2653 [&]() { root->StackChildrenAtBottom({child2.get()}); }));
2654
2655 long_duration_animation =
2656 std::make_unique<ui::ScopedAnimationDurationScaleMode>(
2657 ui::ScopedAnimationDurationScaleMode::SLOW_DURATION);
2658 {
2659 ui::ScopedLayerAnimationSettings animation(child->GetAnimator());
2660 animation.AddObserver(&animation_observer);
2661 animation.SetTransitionDuration(base::TimeDelta::FromMilliseconds(1000));
2662 child->SetTransform(transform);
2663 }
2664
2665 // This call should not crash.
2666 root->OnDeviceScaleFactorChanged(1.5f);
Malay Keshav65840f0e2019-08-20 00:38:502667}
2668
[email protected]9034a282014-06-05 03:11:472669// Tests that the animators in the layer tree is added to the
2670// animator-collection when the root-layer is set to the compositor.
2671TEST_F(LayerWithDelegateTest, RootLayerAnimatorsInCompositor) {
Mohsen Izadi62a338d2019-07-30 19:49:472672 std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR);
2673 std::unique_ptr<Layer> child =
2674 CreateColorLayer(SK_ColorRED, gfx::Rect(10, 10));
[email protected]9034a282014-06-05 03:11:472675 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
2676 child->SetOpacity(0.5f);
2677 root->Add(child.get());
2678
2679 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
2680 compositor()->SetRootLayer(root.get());
2681 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
2682}
2683
2684// Tests that adding/removing a layer adds/removes the animator from its entire
2685// subtree from the compositor's animator-collection.
2686TEST_F(LayerWithDelegateTest, AddRemoveLayerUpdatesAnimatorsFromSubtree) {
Mohsen Izadi62a338d2019-07-30 19:49:472687 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2688 std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED);
2689 std::unique_ptr<Layer> grandchild =
2690 CreateColorLayer(SK_ColorRED, gfx::Rect(10, 10));
[email protected]9034a282014-06-05 03:11:472691 root->Add(child.get());
2692 child->Add(grandchild.get());
2693 compositor()->SetRootLayer(root.get());
2694
2695 grandchild->SetAnimator(LayerAnimator::CreateImplicitAnimator());
2696 grandchild->SetOpacity(0.5f);
2697 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
2698
2699 root->Remove(child.get());
2700 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
2701
2702 root->Add(child.get());
2703 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
2704}
2705
2706TEST_F(LayerWithDelegateTest, DestroyingLayerRemovesTheAnimatorFromCollection) {
Mohsen Izadi62a338d2019-07-30 19:49:472707 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2708 std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED);
[email protected]9034a282014-06-05 03:11:472709 root->Add(child.get());
2710 compositor()->SetRootLayer(root.get());
2711
2712 child->SetAnimator(LayerAnimator::CreateImplicitAnimator());
2713 child->SetOpacity(0.5f);
2714 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
2715
2716 child.reset();
2717 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
2718}
2719
bruthig33b1edab2016-03-02 02:22:352720// A LayerAnimationObserver that removes a child layer from a parent when an
2721// animation completes.
2722class LayerRemovingLayerAnimationObserver : public LayerAnimationObserver {
2723 public:
2724 LayerRemovingLayerAnimationObserver(Layer* root, Layer* child)
2725 : root_(root), child_(child) {}
2726
2727 // LayerAnimationObserver:
2728 void OnLayerAnimationEnded(LayerAnimationSequence* sequence) override {
2729 root_->Remove(child_);
2730 }
2731
2732 void OnLayerAnimationAborted(LayerAnimationSequence* sequence) override {
2733 root_->Remove(child_);
2734 }
2735
2736 void OnLayerAnimationScheduled(LayerAnimationSequence* sequence) override {}
2737
2738 private:
2739 Layer* root_;
2740 Layer* child_;
2741
2742 DISALLOW_COPY_AND_ASSIGN(LayerRemovingLayerAnimationObserver);
2743};
2744
2745// Verifies that empty LayerAnimators are not left behind when removing child
2746// Layers that own an empty LayerAnimator. See http://crbug.com/552037.
2747TEST_F(LayerWithDelegateTest, NonAnimatingAnimatorsAreRemovedFromCollection) {
Mohsen Izadi62a338d2019-07-30 19:49:472748 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2749 std::unique_ptr<Layer> parent = CreateLayer(LAYER_TEXTURED);
2750 std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED);
bruthig33b1edab2016-03-02 02:22:352751 root->Add(parent.get());
2752 parent->Add(child.get());
2753 compositor()->SetRootLayer(root.get());
2754
2755 child->SetAnimator(LayerAnimator::CreateDefaultAnimator());
2756
2757 LayerRemovingLayerAnimationObserver observer(root.get(), parent.get());
2758 child->GetAnimator()->AddObserver(&observer);
2759
ratsunnybd5087e2016-12-17 05:19:252760 std::unique_ptr<LayerAnimationElement> element =
bruthig33b1edab2016-03-02 02:22:352761 ui::LayerAnimationElement::CreateOpacityElement(
2762 0.5f, base::TimeDelta::FromSeconds(1));
ratsunnybd5087e2016-12-17 05:19:252763 LayerAnimationSequence* sequence =
2764 new LayerAnimationSequence(std::move(element));
bruthig33b1edab2016-03-02 02:22:352765
2766 child->GetAnimator()->StartAnimation(sequence);
2767 EXPECT_TRUE(compositor()->layer_animator_collection()->HasActiveAnimators());
2768
2769 child->GetAnimator()->StopAnimating();
2770 EXPECT_FALSE(root->Contains(parent.get()));
2771 EXPECT_FALSE(compositor()->layer_animator_collection()->HasActiveAnimators());
2772}
2773
[email protected]e09c592ff2014-07-17 06:55:072774namespace {
2775
Roger Johannesson41dd59f2018-01-25 19:05:062776std::string Vector2dFTo100thPrecisionString(const gfx::Vector2dF& vector) {
[email protected]e09c592ff2014-07-17 06:55:072777 return base::StringPrintf("%.2f %0.2f", vector.x(), vector.y());
2778}
2779
2780} // namespace
2781
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:402782TEST_P(LayerWithRealCompositorTest, SnapLayerToPixels) {
Mohsen Izadi62a338d2019-07-30 19:49:472783 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
2784 std::unique_ptr<Layer> c1 = CreateLayer(LAYER_TEXTURED);
2785 std::unique_ptr<Layer> c11 = CreateLayer(LAYER_TEXTURED);
[email protected]e09c592ff2014-07-17 06:55:072786
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122787 viz::ParentLocalSurfaceIdAllocator allocator;
2788 allocator.GenerateId();
2789 GetCompositor()->SetScaleAndSize(
2790 1.25f, gfx::Size(100, 100),
2791 allocator.GetCurrentLocalSurfaceIdAllocation());
[email protected]e09c592ff2014-07-17 06:55:072792 GetCompositor()->SetRootLayer(root.get());
2793 root->Add(c1.get());
2794 c1->Add(c11.get());
2795
2796 root->SetBounds(gfx::Rect(0, 0, 100, 100));
2797 c1->SetBounds(gfx::Rect(1, 1, 10, 10));
2798 c11->SetBounds(gfx::Rect(1, 1, 10, 10));
Malay Keshavebd73ca2019-06-27 22:17:272799 // 1 at 1.25 scale = 1.25 : (-0.25) / 1.25 = -0.20
2800 EXPECT_EQ("-0.20 -0.20",
2801 Vector2dFTo100thPrecisionString(c11->GetSubpixelOffset()));
[email protected]e09c592ff2014-07-17 06:55:072802
Sadrul Habib Chowdhurya3806cc62018-12-21 06:39:122803 allocator.GenerateId();
2804 GetCompositor()->SetScaleAndSize(
2805 1.5f, gfx::Size(100, 100),
2806 allocator.GetCurrentLocalSurfaceIdAllocation());
Malay Keshavebd73ca2019-06-27 22:17:272807 // 1 at 1.5 scale = 1.5 : (round(1.5) - 1.5) / 1.5 = 0.33
2808 EXPECT_EQ("0.33 0.33",
2809 Vector2dFTo100thPrecisionString(c11->GetSubpixelOffset()));
[email protected]e09c592ff2014-07-17 06:55:072810
2811 c11->SetBounds(gfx::Rect(2, 2, 10, 10));
Malay Keshavebd73ca2019-06-27 22:17:272812 // 2 at 1.5 scale = 3 : (round(3) - 3) / 1.5 = 0
2813 EXPECT_EQ("0.00 0.00",
2814 Vector2dFTo100thPrecisionString(c11->GetSubpixelOffset()));
[email protected]e09c592ff2014-07-17 06:55:072815}
2816
Francois Doray8e962612017-11-10 20:51:212817// Verify that LayerDelegate::OnLayerBoundsChanged() is called when the bounds
2818// are set without an animation.
2819TEST(LayerDelegateTest, OnLayerBoundsChanged) {
2820 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
2821 testing::StrictMock<TestLayerDelegate> delegate;
2822 layer->set_delegate(&delegate);
2823 const gfx::Rect initial_bounds = layer->bounds();
2824 constexpr gfx::Rect kTargetBounds(1, 2, 3, 4);
2825 EXPECT_CALL(delegate,
2826 OnLayerBoundsChanged(initial_bounds,
2827 PropertyChangeReason::NOT_FROM_ANIMATION))
2828 .WillOnce(testing::Invoke([&](const gfx::Rect&, PropertyChangeReason) {
2829 // Verify that |layer->bounds()| returns the correct value when the
2830 // delegate is notified.
2831 EXPECT_EQ(layer->bounds(), kTargetBounds);
2832 }));
2833 layer->SetBounds(kTargetBounds);
2834}
2835
2836// Verify that LayerDelegate::OnLayerBoundsChanged() is called at every step of
2837// a bounds animation.
2838TEST(LayerDelegateTest, OnLayerBoundsChangedAnimation) {
2839 ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
2840 ScopedAnimationDurationScaleMode::NORMAL_DURATION);
2841 LayerAnimatorTestController test_controller(
2842 LayerAnimator::CreateImplicitAnimator());
2843 LayerAnimator* const animator = test_controller.animator();
2844
2845 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
2846 testing::StrictMock<TestLayerDelegate> delegate;
2847 layer->set_delegate(&delegate);
2848 layer->SetAnimator(animator);
2849
2850 const gfx::Rect initial_bounds = layer->bounds();
2851 constexpr gfx::Rect kTargetBounds(10, 20, 30, 40);
2852 const gfx::Rect step_bounds =
2853 gfx::Tween::RectValueBetween(0.5, initial_bounds, kTargetBounds);
2854
2855 // Start the animation.
2856 std::unique_ptr<LayerAnimationElement> element =
2857 LayerAnimationElement::CreateBoundsElement(
2858 kTargetBounds, base::TimeDelta::FromSeconds(1));
2859 ASSERT_FALSE(element->IsThreaded(layer.get()));
2860 LayerAnimationElement* element_raw = element.get();
2861 animator->StartAnimation(new LayerAnimationSequence(std::move(element)));
2862 testing::Mock::VerifyAndClear(&delegate);
2863
2864 // Progress the animation.
2865 EXPECT_CALL(delegate,
2866 OnLayerBoundsChanged(initial_bounds,
2867 PropertyChangeReason::FROM_ANIMATION))
2868 .WillOnce(testing::Invoke([&](const gfx::Rect&, PropertyChangeReason) {
2869 // Verify that |layer->bounds()| returns the correct value when the
2870 // delegate is notified.
2871 EXPECT_EQ(layer->bounds(), step_bounds);
2872 EXPECT_TRUE(
2873 animator->IsAnimatingProperty(LayerAnimationElement::BOUNDS));
2874 }));
2875 test_controller.Step(element_raw->duration() / 2);
2876 testing::Mock::VerifyAndClear(&delegate);
2877
2878 // End the animation.
2879 EXPECT_CALL(delegate, OnLayerBoundsChanged(
2880 step_bounds, PropertyChangeReason::FROM_ANIMATION))
2881 .WillOnce(testing::Invoke([&](const gfx::Rect&, PropertyChangeReason) {
2882 // Verify that |layer->bounds()| returns the correct value when the
2883 // delegate is notified.
2884 EXPECT_EQ(layer->bounds(), kTargetBounds);
2885 EXPECT_FALSE(
2886 animator->IsAnimatingProperty(LayerAnimationElement::BOUNDS));
2887 }));
2888 test_controller.Step(element_raw->duration() / 2);
2889 testing::Mock::VerifyAndClear(&delegate);
2890}
2891
2892// Verify that LayerDelegate::OnLayerTransformed() is called when the transform
2893// is set without an animation.
Francois Dorayfaa13f8c2017-10-25 15:45:052894TEST(LayerDelegateTest, OnLayerTransformed) {
2895 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
2896 testing::StrictMock<TestLayerDelegate> delegate;
2897 layer->set_delegate(&delegate);
Scott Violetac1a8082018-03-19 05:14:342898 gfx::Transform target_transform1;
2899 target_transform1.Skew(10.0f, 5.0f);
2900 {
2901 EXPECT_CALL(delegate,
2902 OnLayerTransformed(gfx::Transform(),
2903 PropertyChangeReason::NOT_FROM_ANIMATION))
2904 .WillOnce(testing::Invoke(
2905 [&](const gfx::Transform& old_transform, PropertyChangeReason) {
2906 // Verify that |layer->transform()| returns the correct value when
2907 // the delegate is notified.
2908 EXPECT_EQ(target_transform1, layer->transform());
2909 }));
2910 layer->SetTransform(target_transform1);
2911 }
2912 gfx::Transform target_transform2;
2913 target_transform2.Skew(10.0f, 5.0f);
Francois Doray8e962612017-11-10 20:51:212914 EXPECT_CALL(delegate,
Scott Violetac1a8082018-03-19 05:14:342915 OnLayerTransformed(target_transform1,
2916 PropertyChangeReason::NOT_FROM_ANIMATION))
2917 .WillOnce(testing::Invoke(
2918 [&](const gfx::Transform& old_transform, PropertyChangeReason) {
2919 // Verify that |layer->transform()| returns the correct value when
2920 // the delegate is notified.
2921 EXPECT_EQ(target_transform2, layer->transform());
2922 }));
2923 layer->SetTransform(target_transform2);
Francois Dorayfaa13f8c2017-10-25 15:45:052924}
2925
Francois Doray8e962612017-11-10 20:51:212926// Verify that LayerDelegate::OnLayerTransformed() is called at every step of a
2927// non-threaded transform transition.
2928TEST(LayerDelegateTest, OnLayerTransformedNonThreadedAnimation) {
2929 ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
2930 ScopedAnimationDurationScaleMode::NORMAL_DURATION);
2931 LayerAnimatorTestController test_controller(
2932 LayerAnimator::CreateImplicitAnimator());
2933 LayerAnimator* const animator = test_controller.animator();
2934
Francois Dorayfaa13f8c2017-10-25 15:45:052935 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
2936 testing::StrictMock<TestLayerDelegate> delegate;
2937 layer->set_delegate(&delegate);
Francois Doray8e962612017-11-10 20:51:212938 layer->SetAnimator(animator);
2939
2940 auto interpolated_transform = std::make_unique<InterpolatedRotation>(10, 45);
2941 const gfx::Transform initial_transform =
2942 interpolated_transform->Interpolate(0.0);
2943 const gfx::Transform step_transform =
2944 interpolated_transform->Interpolate(0.5);
2945 const gfx::Transform target_transform =
2946 interpolated_transform->Interpolate(1.0);
2947
2948 // Start the animation.
2949 std::unique_ptr<LayerAnimationElement> element =
2950 LayerAnimationElement::CreateInterpolatedTransformElement(
2951 std::move(interpolated_transform), base::TimeDelta::FromSeconds(1));
2952 // The LayerAnimationElement returned by CreateInterpolatedTransformElement()
2953 // is non-threaded.
2954 ASSERT_FALSE(element->IsThreaded(layer.get()));
2955 LayerAnimationElement* element_raw = element.get();
2956 EXPECT_CALL(delegate,
Scott Violetac1a8082018-03-19 05:14:342957 OnLayerTransformed(gfx::Transform(),
2958 PropertyChangeReason::FROM_ANIMATION))
2959 .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform,
2960 PropertyChangeReason) {
Francois Doray8e962612017-11-10 20:51:212961 // Verify that |layer->transform()| returns the correct value when the
2962 // delegate is notified.
2963 EXPECT_EQ(layer->transform(), initial_transform);
2964 EXPECT_TRUE(
2965 animator->IsAnimatingProperty(LayerAnimationElement::TRANSFORM));
2966 }));
2967 animator->StartAnimation(new LayerAnimationSequence(std::move(element)));
2968 testing::Mock::VerifyAndClear(&delegate);
2969
2970 // Progress the animation.
2971 EXPECT_CALL(delegate,
Scott Violetac1a8082018-03-19 05:14:342972 OnLayerTransformed(initial_transform,
2973 PropertyChangeReason::FROM_ANIMATION))
2974 .WillOnce(testing::Invoke(
2975 [&](const gfx::Transform& old_transform, PropertyChangeReason) {
2976 // Verify that |layer->transform()| returns the correct value when
2977 // the delegate is notified.
2978 EXPECT_EQ(layer->transform(), step_transform);
2979 }));
Francois Doray8e962612017-11-10 20:51:212980 test_controller.Step(element_raw->duration() / 2);
2981 testing::Mock::VerifyAndClear(&delegate);
2982
2983 // End the animation.
Scott Violetac1a8082018-03-19 05:14:342984 EXPECT_CALL(
2985 delegate,
2986 OnLayerTransformed(step_transform, PropertyChangeReason::FROM_ANIMATION))
2987 .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform,
2988 PropertyChangeReason) {
Francois Doray8e962612017-11-10 20:51:212989 // Verify that |layer->transform()| returns the correct value when the
2990 // delegate is notified.
2991 EXPECT_EQ(layer->transform(), target_transform);
2992 EXPECT_FALSE(
2993 animator->IsAnimatingProperty(LayerAnimationElement::TRANSFORM));
2994 }));
2995 test_controller.Step(element_raw->duration() / 2);
2996 testing::Mock::VerifyAndClear(&delegate);
Francois Dorayfaa13f8c2017-10-25 15:45:052997}
2998
Francois Doray8e962612017-11-10 20:51:212999// Verify that LayerDelegate::OnLayerTransformed() is called at the beginning
3000// and at the end of a threaded transform transition.
3001TEST(LayerDelegateTest, OnLayerTransformedThreadedAnimation) {
Francois Dorayfaa13f8c2017-10-25 15:45:053002 ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
3003 ScopedAnimationDurationScaleMode::NORMAL_DURATION);
3004 LayerAnimatorTestController test_controller(
3005 LayerAnimator::CreateImplicitAnimator());
3006 LayerAnimator* const animator = test_controller.animator();
3007
3008 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
3009 testing::StrictMock<TestLayerDelegate> delegate;
Francois Dorayfaa13f8c2017-10-25 15:45:053010 layer->set_delegate(&delegate);
3011 layer->SetAnimator(animator);
Francois Dorayfaa13f8c2017-10-25 15:45:053012
3013 // Start the animation.
Francois Doray8e962612017-11-10 20:51:213014 gfx::Transform initial_transform = layer->transform();
Francois Dorayfaa13f8c2017-10-25 15:45:053015 gfx::Transform target_transform;
3016 target_transform.Skew(10.0f, 5.0f);
Francois Doray4b50f622017-11-06 23:18:033017 std::unique_ptr<LayerAnimationElement> element =
3018 LayerAnimationElement::CreateTransformElement(
3019 target_transform, base::TimeDelta::FromSeconds(1));
Francois Doray8e962612017-11-10 20:51:213020 ASSERT_TRUE(element->IsThreaded(layer.get()));
Francois Doray4b50f622017-11-06 23:18:033021 LayerAnimationElement* element_raw = element.get();
Francois Doray8e962612017-11-10 20:51:213022 EXPECT_CALL(delegate,
Scott Violetac1a8082018-03-19 05:14:343023 OnLayerTransformed(gfx::Transform(),
3024 PropertyChangeReason::FROM_ANIMATION))
3025 .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform,
3026 PropertyChangeReason) {
Francois Doray8e962612017-11-10 20:51:213027 // Verify that |layer->transform()| returns the correct value when the
3028 // delegate is notified.
3029 EXPECT_EQ(layer->transform(), initial_transform);
3030 EXPECT_TRUE(
3031 animator->IsAnimatingProperty(LayerAnimationElement::TRANSFORM));
3032 }));
Francois Doray4b50f622017-11-06 23:18:033033 animator->StartAnimation(new LayerAnimationSequence(std::move(element)));
Francois Doray8e962612017-11-10 20:51:213034 testing::Mock::VerifyAndClear(&delegate);
Francois Doray4b50f622017-11-06 23:18:033035 test_controller.StartThreadedAnimationsIfNeeded();
Francois Dorayfaa13f8c2017-10-25 15:45:053036
3037 // End the animation.
Francois Doray8e962612017-11-10 20:51:213038 EXPECT_CALL(delegate,
Scott Violetac1a8082018-03-19 05:14:343039 OnLayerTransformed(initial_transform,
3040 PropertyChangeReason::FROM_ANIMATION))
3041 .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform,
3042 PropertyChangeReason) {
Francois Doray8e962612017-11-10 20:51:213043 // Verify that |layer->transform()| returns the correct value when the
3044 // delegate is notified.
Francois Dorayfaa13f8c2017-10-25 15:45:053045 EXPECT_EQ(layer->transform(), target_transform);
Francois Doray8e962612017-11-10 20:51:213046 EXPECT_FALSE(
3047 animator->IsAnimatingProperty(LayerAnimationElement::TRANSFORM));
Francois Dorayfaa13f8c2017-10-25 15:45:053048 }));
Francois Doray4b50f622017-11-06 23:18:033049 test_controller.Step(
3050 element_raw->duration() +
3051 (element_raw->effective_start_time() - animator->last_step_time()));
Francois Dorayfaa13f8c2017-10-25 15:45:053052 testing::Mock::VerifyAndClear(&delegate);
Francois Dorayfaa13f8c2017-10-25 15:45:053053}
3054
Francois Doray8e962612017-11-10 20:51:213055// Verify that LayerDelegate::OnLayerOpacityChanged() is called when the opacity
3056// is set without an animation.
Francois Doray4f515ad2017-09-15 16:19:343057TEST(LayerDelegateTest, OnLayerOpacityChanged) {
3058 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
3059 testing::StrictMock<TestLayerDelegate> delegate;
3060 layer->set_delegate(&delegate);
Francois Doray8e962612017-11-10 20:51:213061 constexpr float kTargetOpacity = 0.5f;
3062 EXPECT_CALL(delegate,
3063 OnLayerOpacityChanged(PropertyChangeReason::NOT_FROM_ANIMATION))
3064 .WillOnce(testing::Invoke([&](PropertyChangeReason) {
3065 // Verify that |layer->opacity()| returns the correct value when the
3066 // delegate is notified.
3067 EXPECT_EQ(layer->opacity(), kTargetOpacity);
3068 }));
3069 layer->SetOpacity(kTargetOpacity);
Francois Doray4f515ad2017-09-15 16:19:343070}
3071
Francois Doray8e962612017-11-10 20:51:213072// Verify that LayerDelegate::OnLayerOpacityChanged() is called at the beginning
3073// and at the end of a threaded opacity animation.
Francois Doray9b3b01282017-09-20 12:31:463074TEST(LayerDelegateTest, OnLayerOpacityChangedAnimation) {
Francois Doray9b3b01282017-09-20 12:31:463075 ScopedAnimationDurationScaleMode scoped_animation_duration_scale_mode(
3076 ScopedAnimationDurationScaleMode::NORMAL_DURATION);
3077 LayerAnimatorTestController test_controller(
3078 LayerAnimator::CreateImplicitAnimator());
3079 LayerAnimator* const animator = test_controller.animator();
3080
3081 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
3082 testing::StrictMock<TestLayerDelegate> delegate;
Francois Doray9b3b01282017-09-20 12:31:463083 layer->set_delegate(&delegate);
3084 layer->SetAnimator(animator);
Francois Doray9b3b01282017-09-20 12:31:463085
3086 // Start the animation.
Francois Doray8e962612017-11-10 20:51:213087 const float initial_opacity = layer->opacity();
Francois Doray4b50f622017-11-06 23:18:033088 const float kTargetOpacity = 0.5f;
3089 std::unique_ptr<LayerAnimationElement> element =
3090 LayerAnimationElement::CreateOpacityElement(
3091 kTargetOpacity, base::TimeDelta::FromSeconds(1));
Francois Doray8e962612017-11-10 20:51:213092 ASSERT_TRUE(element->IsThreaded(layer.get()));
Francois Doray4b50f622017-11-06 23:18:033093 LayerAnimationElement* element_raw = element.get();
Francois Doray8e962612017-11-10 20:51:213094 EXPECT_CALL(delegate,
3095 OnLayerOpacityChanged(PropertyChangeReason::FROM_ANIMATION))
3096 .WillOnce(testing::Invoke([&](PropertyChangeReason) {
3097 // Verify that |layer->opacity()| returns the correct value when the
3098 // delegate is notified.
3099 EXPECT_EQ(layer->opacity(), initial_opacity);
3100 EXPECT_TRUE(
3101 animator->IsAnimatingProperty(LayerAnimationElement::OPACITY));
3102 }));
Francois Doray4b50f622017-11-06 23:18:033103 animator->StartAnimation(new LayerAnimationSequence(std::move(element)));
Francois Doray8e962612017-11-10 20:51:213104 testing::Mock::VerifyAndClear(&delegate);
Francois Doray4b50f622017-11-06 23:18:033105 test_controller.StartThreadedAnimationsIfNeeded();
Francois Doray9b3b01282017-09-20 12:31:463106
Francois Doray4b50f622017-11-06 23:18:033107 // End the animation.
Francois Doray8e962612017-11-10 20:51:213108 EXPECT_CALL(delegate,
3109 OnLayerOpacityChanged(PropertyChangeReason::FROM_ANIMATION))
3110 .WillOnce(testing::Invoke([&](PropertyChangeReason) {
3111 // Verify that |layer->opacity()| returns the correct value when the
3112 // delegate is notified.
3113 EXPECT_EQ(layer->opacity(), kTargetOpacity);
3114 EXPECT_FALSE(
3115 animator->IsAnimatingProperty(LayerAnimationElement::OPACITY));
3116 }));
Francois Doray4b50f622017-11-06 23:18:033117 test_controller.Step(
3118 element_raw->duration() +
3119 (element_raw->effective_start_time() - animator->last_step_time()));
Francois Doray9b3b01282017-09-20 12:31:463120 testing::Mock::VerifyAndClear(&delegate);
Francois Doray9b3b01282017-09-20 12:31:463121}
3122
Francois Doraya3a0b7f42018-08-15 15:44:323123// Verify that LayerDelegate::OnLayerAlphaShapeChanged() is called when the
3124// alpha shape of a layer is set.
3125TEST(LayerDelegateTest, OnLayerAlphaShapeChanged) {
3126 auto layer = std::make_unique<Layer>(LAYER_TEXTURED);
3127 testing::StrictMock<TestLayerDelegate> delegate;
3128 layer->set_delegate(&delegate);
3129
3130 // Set an alpha shape for the layer. Expect the delegate to be notified.
3131 auto shape = std::make_unique<Layer::ShapeRects>();
3132 shape->emplace_back(0, 0, 10, 20);
3133 EXPECT_CALL(delegate, OnLayerAlphaShapeChanged());
3134 layer->SetAlphaShape(std::move(shape));
3135 testing::Mock::VerifyAndClear(&delegate);
3136
3137 // Clear the alpha shape for the layer. Expect the delegate to be notified.
3138 EXPECT_CALL(delegate, OnLayerAlphaShapeChanged());
3139 layer->SetAlphaShape(nullptr);
3140 testing::Mock::VerifyAndClear(&delegate);
3141}
3142
Vasiliy Telezhnikov152f6c3c2019-07-26 16:55:403143TEST_P(LayerWithRealCompositorTest, CompositorAnimationObserverTest) {
Mohsen Izadi62a338d2019-07-30 19:49:473144 std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED);
lof84adf2ce862015-06-02 22:23:323145
3146 root->SetAnimator(LayerAnimator::CreateImplicitAnimator());
3147
3148 TestCompositorAnimationObserver animation_observer(GetCompositor());
3149 EXPECT_EQ(0u, animation_observer.animation_step_count());
3150
3151 root->SetOpacity(0.5f);
starazce75f932017-03-29 16:12:273152 WaitForDraw();
lof84adf2ce862015-06-02 22:23:323153 EXPECT_EQ(1u, animation_observer.animation_step_count());
3154
dmazzoniead142a2015-06-22 18:01:013155 EXPECT_FALSE(animation_observer.shutdown());
lof84adf2ce862015-06-02 22:23:323156 ResetCompositor();
dmazzoniead142a2015-06-22 18:01:013157 EXPECT_TRUE(animation_observer.shutdown());
lof84adf2ce862015-06-02 22:23:323158}
3159
[email protected]cff176a2012-06-29 21:11:003160} // namespace ui