[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
dcheng | 79c1449 | 2015-12-18 05:07:26 | [diff] [blame] | 5 | #include "ui/compositor/layer.h" |
| 6 | |
avi | 87b8b58 | 2015-12-24 21:35:25 | [diff] [blame] | 7 | #include <stddef.h> |
| 8 | |
danakj | 25c52c3 | 2016-04-12 21:51:08 | [diff] [blame] | 9 | #include <memory> |
dcheng | 79c1449 | 2015-12-18 05:07:26 | [diff] [blame] | 10 | #include <utility> |
Edwin Joe | 863d4530 | 2019-03-28 19:57:04 | [diff] [blame] | 11 | #include <vector> |
dcheng | 79c1449 | 2015-12-18 05:07:26 | [diff] [blame] | 12 | |
[email protected] | f7972906 | 2013-04-03 20:01:50 | [diff] [blame] | 13 | #include "base/bind.h" |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 14 | #include "base/callback.h" |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 15 | #include "base/compiler_specific.h" |
[email protected] | 5799981 | 2013-02-24 05:40:52 | [diff] [blame] | 16 | #include "base/files/file_path.h" |
thestig | 22dfc401 | 2014-09-05 08:29:44 | [diff] [blame] | 17 | #include "base/files/file_util.h" |
[email protected] | 36c391d | 2014-01-22 18:44:50 | [diff] [blame] | 18 | #include "base/json/json_reader.h" |
avi | 87b8b58 | 2015-12-24 21:35:25 | [diff] [blame] | 19 | #include "base/macros.h" |
[email protected] | 6f83e4f | 2011-11-15 21:25:33 | [diff] [blame] | 20 | #include "base/path_service.h" |
Gabriel Charette | 078e366 | 2017-08-28 22:59:04 | [diff] [blame] | 21 | #include "base/run_loop.h" |
[email protected] | f3652ff9 | 2013-06-11 13:54:31 | [diff] [blame] | 22 | #include "base/strings/string_util.h" |
| 23 | #include "base/strings/stringprintf.h" |
lof84 | a757877 | 2016-07-19 20:39:35 | [diff] [blame] | 24 | #include "base/strings/utf_string_conversions.h" |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 25 | #include "base/test/bind_test_util.h" |
Gabriel Charette | c710874 | 2019-08-23 03:31:40 | [diff] [blame] | 26 | #include "base/test/task_environment.h" |
jonross | 180dc48 | 2018-10-23 21:22:09 | [diff] [blame] | 27 | #include "base/time/time.h" |
ssid | 334fb87a | 2015-01-27 20:12:07 | [diff] [blame] | 28 | #include "base/trace_event/trace_event.h" |
Guido Urdaneta | 121a6e2 | 2017-11-17 11:01:08 | [diff] [blame] | 29 | #include "build/build_config.h" |
Yi Gu | b0422c4 | 2020-01-13 17:00:36 | [diff] [blame] | 30 | #include "cc/animation/animation.h" |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 31 | #include "cc/animation/animation_events.h" |
| 32 | #include "cc/animation/animation_host.h" |
Yi Gu | 3904dc2 | 2018-02-15 18:35:24 | [diff] [blame] | 33 | #include "cc/animation/keyframe_effect.h" |
[email protected] | cc3cfaa | 2013-03-18 09:05:52 | [diff] [blame] | 34 | #include "cc/layers/layer.h" |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 35 | #include "cc/layers/mirror_layer.h" |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 36 | #include "cc/test/pixel_comparator.h" |
[email protected] | 1b901a3 | 2012-12-07 08:52:03 | [diff] [blame] | 37 | #include "cc/test/pixel_test_utils.h" |
danakj | f20f450 | 2017-09-26 17:13:31 | [diff] [blame] | 38 | #include "components/viz/common/frame_sinks/copy_output_request.h" |
| 39 | #include "components/viz/common/frame_sinks/copy_output_result.h" |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 40 | #include "components/viz/common/resources/transferable_resource.h" |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 41 | #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" |
Fady Samuel | 644df1d | 2017-07-13 01:13:02 | [diff] [blame] | 42 | #include "components/viz/common/surfaces/surface_id.h" |
Francois Doray | 4f515ad | 2017-09-15 16:19:34 | [diff] [blame] | 43 | #include "testing/gmock/include/gmock/gmock.h" |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 44 | #include "testing/gtest/include/gtest/gtest.h" |
danakj | 6f2861b | 2016-08-17 02:10:17 | [diff] [blame] | 45 | #include "third_party/khronos/GLES2/gl2.h" |
[email protected] | 116302fc | 2012-05-05 21:45:41 | [diff] [blame] | 46 | #include "ui/compositor/compositor_observer.h" |
[email protected] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 47 | #include "ui/compositor/dip_util.h" |
bruthig | 33b1edab | 2016-03-02 02:22:35 | [diff] [blame] | 48 | #include "ui/compositor/layer_animation_element.h" |
| 49 | #include "ui/compositor/layer_animation_observer.h" |
[email protected] | 116302fc | 2012-05-05 21:45:41 | [diff] [blame] | 50 | #include "ui/compositor/layer_animation_sequence.h" |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 51 | #include "ui/compositor/layer_animator.h" |
danakj | 85d970e | 2015-04-04 00:15:24 | [diff] [blame] | 52 | #include "ui/compositor/paint_context.h" |
danakj | c732322 | 2015-04-07 21:09:38 | [diff] [blame] | 53 | #include "ui/compositor/paint_recorder.h" |
jonross | 31048b6 | 2015-05-20 02:09:25 | [diff] [blame] | 54 | #include "ui/compositor/scoped_animation_duration_scale_mode.h" |
| 55 | #include "ui/compositor/scoped_layer_animation_settings.h" |
[email protected] | b58081d | 2014-01-24 10:13:51 | [diff] [blame] | 56 | #include "ui/compositor/test/draw_waiter_for_test.h" |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 57 | #include "ui/compositor/test/layer_animator_test_controller.h" |
[email protected] | 116302fc | 2012-05-05 21:45:41 | [diff] [blame] | 58 | #include "ui/compositor/test/test_compositor_host.h" |
Mohsen Izadi | b371018 | 2019-04-30 04:57:35 | [diff] [blame] | 59 | #include "ui/compositor/test/test_context_factories.h" |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 60 | #include "ui/compositor/test/test_layers.h" |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 61 | #include "ui/gfx/animation/tween.h" |
[email protected] | 94a0d258 | 2012-03-09 00:30:59 | [diff] [blame] | 62 | #include "ui/gfx/canvas.h" |
[email protected] | 6f83e4f | 2011-11-15 21:25:33 | [diff] [blame] | 63 | #include "ui/gfx/codec/png_codec.h" |
lof84 | a757877 | 2016-07-19 20:39:35 | [diff] [blame] | 64 | #include "ui/gfx/font_list.h" |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 65 | #include "ui/gfx/interpolated_transform.h" |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 66 | #include "ui/gfx/skia_util.h" |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 67 | |
[email protected] | ca43568 | 2013-03-29 04:09:47 | [diff] [blame] | 68 | using cc::MatchesPNGFile; |
lof84 | a757877 | 2016-07-19 20:39:35 | [diff] [blame] | 69 | using cc::WritePNGFile; |
[email protected] | 1b901a3 | 2012-12-07 08:52:03 | [diff] [blame] | 70 | |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 71 | namespace ui { |
| 72 | |
| 73 | namespace { |
| 74 | |
[email protected] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 75 | // There are three test classes in here that configure the Compositor and |
| 76 | // Layer's slightly differently: |
[email protected] | 72f08de | 2011-12-09 16:19:03 | [diff] [blame] | 77 | // - 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] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 80 | // - LayerWithRealCompositorTest when a real compositor is required for testing. |
[email protected] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 81 | // - Slow because they bring up a window and run the real compositor. This |
| 82 | // is typically not what you want. |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 83 | |
| 84 | class ColoredLayer : public Layer, public LayerDelegate { |
| 85 | public: |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 86 | explicit ColoredLayer(SkColor color) |
[email protected] | 595b52a | 2012-03-23 16:17:24 | [diff] [blame] | 87 | : Layer(LAYER_TEXTURED), |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 88 | color_(color) { |
| 89 | set_delegate(this); |
| 90 | } |
| 91 | |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 92 | ~ColoredLayer() override {} |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 93 | |
| 94 | // Overridden from LayerDelegate: |
danakj | 85d970e | 2015-04-04 00:15:24 | [diff] [blame] | 95 | void OnPaintLayer(const ui::PaintContext& context) override { |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 96 | ui::PaintRecorder recorder(context, size()); |
danakj | c732322 | 2015-04-07 21:09:38 | [diff] [blame] | 97 | recorder.canvas()->DrawColor(color_); |
danakj | 85d970e | 2015-04-04 00:15:24 | [diff] [blame] | 98 | } |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 99 | |
Scott Violet | 06aff2b4 | 2017-09-08 00:26:32 | [diff] [blame] | 100 | void OnDeviceScaleFactorChanged(float old_device_scale_factor, |
| 101 | float new_device_scale_factor) override {} |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 102 | |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 103 | private: |
| 104 | SkColor color_; |
| 105 | }; |
| 106 | |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 107 | // Param specifies whether to use SkiaRenderer or not |
| 108 | class LayerWithRealCompositorTest : public testing::TestWithParam<bool> { |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 109 | public: |
jonross | 1ec7d99 | 2018-08-31 03:55:54 | [diff] [blame] | 110 | LayerWithRealCompositorTest() |
Gabriel Charette | dfa3604 | 2019-08-19 17:30:11 | [diff] [blame] | 111 | : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) { |
Etienne Bergeron | ab7a66b | 2019-04-15 19:27:03 | [diff] [blame] | 112 | gfx::FontList::SetDefaultFontDescription("Segoe UI, 15px"); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 113 | } |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 114 | ~LayerWithRealCompositorTest() override {} |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 115 | |
| 116 | // Overridden from testing::Test: |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 117 | void SetUp() override { |
Peter Kasting | ee674947 | 2018-11-20 05:13:25 | [diff] [blame] | 118 | 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 Izadi | b371018 | 2019-04-30 04:57:35 | [diff] [blame] | 126 | const bool enable_pixel_output = true; |
| 127 | context_factories_ = |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 128 | std::make_unique<TestContextFactories>(enable_pixel_output, GetParam()); |
[email protected] | d56d3bb | 2013-08-12 20:58:01 | [diff] [blame] | 129 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 130 | const gfx::Rect host_bounds(10, 10, 500, 500); |
fsamuel | a0bcfe1 | 2016-12-14 06:21:49 | [diff] [blame] | 131 | compositor_host_.reset(TestCompositorHost::Create( |
Sean Gilhuly | dc0b9fd | 2020-02-25 23:47:14 | [diff] [blame] | 132 | host_bounds, context_factories_->GetContextFactory())); |
[email protected] | 4eafa969 | 2014-02-21 22:36:17 | [diff] [blame] | 133 | compositor_host_->Show(); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 134 | } |
| 135 | |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 136 | void TearDown() override { |
lof84 | adf2ce86 | 2015-06-02 22:23:32 | [diff] [blame] | 137 | ResetCompositor(); |
Mohsen Izadi | b371018 | 2019-04-30 04:57:35 | [diff] [blame] | 138 | context_factories_.reset(); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 139 | } |
| 140 | |
[email protected] | 4eafa969 | 2014-02-21 22:36:17 | [diff] [blame] | 141 | Compositor* GetCompositor() { return compositor_host_->GetCompositor(); } |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 142 | |
lof84 | adf2ce86 | 2015-06-02 22:23:32 | [diff] [blame] | 143 | void ResetCompositor() { |
| 144 | compositor_host_.reset(); |
| 145 | } |
| 146 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 147 | std::unique_ptr<Layer> CreateLayer(LayerType type) { |
| 148 | return std::make_unique<Layer>(type); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 149 | } |
| 150 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 151 | std::unique_ptr<Layer> CreateColorLayer(SkColor color, |
| 152 | const gfx::Rect& bounds) { |
| 153 | auto layer = std::make_unique<ColoredLayer>(color); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 154 | layer->SetBounds(bounds); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 155 | return layer; |
| 156 | } |
| 157 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 158 | std::unique_ptr<Layer> CreateNoTextureLayer(const gfx::Rect& bounds) { |
| 159 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_NOT_DRAWN); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 160 | layer->SetBounds(bounds); |
| 161 | return layer; |
| 162 | } |
| 163 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 164 | void DrawTree(Layer* root) { |
| 165 | GetCompositor()->SetRootLayer(root); |
[email protected] | f7972906 | 2013-04-03 20:01:50 | [diff] [blame] | 166 | GetCompositor()->ScheduleDraw(); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 167 | WaitForSwap(); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 168 | } |
| 169 | |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 170 | void ReadPixels(SkBitmap* bitmap) { |
| 171 | ReadPixels(bitmap, gfx::Rect(GetCompositor()->size())); |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 172 | } |
| 173 | |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 174 | void ReadPixels(SkBitmap* bitmap, gfx::Rect source_rect) { |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 175 | scoped_refptr<ReadbackHolder> holder(new ReadbackHolder); |
Fady Samuel | dfecb7d | 2017-07-26 11:41:04 | [diff] [blame] | 176 | std::unique_ptr<viz::CopyOutputRequest> request = |
Yuri Wiitala | b9ad27a | 2017-09-06 19:13:50 | [diff] [blame] | 177 | std::make_unique<viz::CopyOutputRequest>( |
| 178 | viz::CopyOutputRequest::ResultFormat::RGBA_BITMAP, |
Yuri Wiitala | b251176 | 2017-07-19 00:17:53 | [diff] [blame] | 179 | base::BindOnce(&ReadbackHolder::OutputRequestCallback, holder)); |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 180 | request->set_area(source_rect); |
| 181 | |
dcheng | 79c1449 | 2015-12-18 05:07:26 | [diff] [blame] | 182 | GetCompositor()->root_layer()->RequestCopyOfOutput(std::move(request)); |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 183 | |
[email protected] | 2decdd78 | 2014-08-13 22:36:06 | [diff] [blame] | 184 | // 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++) { |
weiliangc | 5efa0a1 | 2015-01-29 19:56:46 | [diff] [blame] | 188 | GetCompositor()->ScheduleFullRedraw(); |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 189 | WaitForDraw(); |
| 190 | } |
| 191 | |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 192 | // Waits for the callback to finish run and return result. |
| 193 | holder->WaitForReadback(); |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 194 | |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 195 | *bitmap = holder->result(); |
[email protected] | d86e97e | 2011-11-21 15:06:26 | [diff] [blame] | 196 | } |
| 197 | |
weiliangc | 5efa0a1 | 2015-01-29 19:56:46 | [diff] [blame] | 198 | void WaitForDraw() { |
| 199 | ui::DrawWaiterForTest::WaitForCompositingStarted(GetCompositor()); |
| 200 | } |
| 201 | |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 202 | void WaitForSwap() { |
| 203 | ui::DrawWaiterForTest::WaitForCompositingEnded(GetCompositor()); |
| 204 | } |
| 205 | |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 206 | void WaitForCommit() { |
| 207 | ui::DrawWaiterForTest::WaitForCommit(GetCompositor()); |
| 208 | } |
| 209 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 210 | // 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 Kasting | ee674947 | 2018-11-20 05:13:25 | [diff] [blame] | 216 | const base::FilePath& test_data_dir() const { return test_data_dir_; } |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 217 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 218 | private: |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 219 | class ReadbackHolder : public base::RefCountedThreadSafe<ReadbackHolder> { |
| 220 | public: |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 221 | ReadbackHolder() : run_loop_(std::make_unique<base::RunLoop>()) {} |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 222 | |
Fady Samuel | dfecb7d | 2017-07-26 11:41:04 | [diff] [blame] | 223 | void OutputRequestCallback(std::unique_ptr<viz::CopyOutputResult> result) { |
Yuri Wiitala | b9ad27a | 2017-09-06 19:13:50 | [diff] [blame] | 224 | if (result->IsEmpty()) |
| 225 | result_.reset(); |
| 226 | else |
| 227 | result_ = std::make_unique<SkBitmap>(result->AsSkBitmap()); |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 228 | run_loop_->Quit(); |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 229 | } |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 230 | |
| 231 | void WaitForReadback() { run_loop_->Run(); } |
| 232 | |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 233 | const SkBitmap& result() const { return *result_; } |
| 234 | |
| 235 | private: |
| 236 | friend class base::RefCountedThreadSafe<ReadbackHolder>; |
| 237 | |
| 238 | virtual ~ReadbackHolder() {} |
| 239 | |
danakj | 25c52c3 | 2016-04-12 21:51:08 | [diff] [blame] | 240 | std::unique_ptr<SkBitmap> result_; |
| 241 | std::unique_ptr<base::RunLoop> run_loop_; |
[email protected] | 5fd5822 | 2014-01-30 23:16:01 | [diff] [blame] | 242 | }; |
| 243 | |
Gabriel Charette | dfa3604 | 2019-08-19 17:30:11 | [diff] [blame] | 244 | base::test::TaskEnvironment task_environment_; |
Mohsen Izadi | b371018 | 2019-04-30 04:57:35 | [diff] [blame] | 245 | std::unique_ptr<TestContextFactories> context_factories_; |
danakj | 25c52c3 | 2016-04-12 21:51:08 | [diff] [blame] | 246 | std::unique_ptr<TestCompositorHost> compositor_host_; |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 247 | |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 248 | // The root directory for test files. |
Peter Kasting | ee674947 | 2018-11-20 05:13:25 | [diff] [blame] | 249 | base::FilePath test_data_dir_; |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 250 | |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 251 | DISALLOW_COPY_AND_ASSIGN(LayerWithRealCompositorTest); |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 252 | }; |
| 253 | |
| 254 | // LayerDelegate that paints colors to the layer. |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 255 | class TestLayerDelegate : public LayerDelegate { |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 256 | public: |
thestig | d5fcf98 | 2015-05-11 18:41:38 | [diff] [blame] | 257 | TestLayerDelegate() { reset(); } |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 258 | ~TestLayerDelegate() override {} |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 259 | |
| 260 | void AddColor(SkColor color) { |
| 261 | colors_.push_back(color); |
| 262 | } |
| 263 | |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 264 | int color_index() const { return color_index_; } |
| 265 | |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 266 | float device_scale_factor() const { |
| 267 | return device_scale_factor_; |
| 268 | } |
| 269 | |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 270 | void set_layer_bounds(const gfx::Rect& layer_bounds) { |
| 271 | layer_bounds_ = layer_bounds; |
| 272 | } |
| 273 | |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 274 | // Overridden from LayerDelegate: |
danakj | 85d970e | 2015-04-04 00:15:24 | [diff] [blame] | 275 | void OnPaintLayer(const ui::PaintContext& context) override { |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 276 | ui::PaintRecorder recorder(context, layer_bounds_.size()); |
danakj | c732322 | 2015-04-07 21:09:38 | [diff] [blame] | 277 | recorder.canvas()->DrawColor(colors_[color_index_]); |
[email protected] | 7b013fc | 2011-09-22 23:12:34 | [diff] [blame] | 278 | color_index_ = (color_index_ + 1) % static_cast<int>(colors_.size()); |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 279 | } |
| 280 | |
Scott Violet | 06aff2b4 | 2017-09-08 00:26:32 | [diff] [blame] | 281 | void OnDeviceScaleFactorChanged(float old_device_scale_factor, |
| 282 | float new_device_scale_factor) override { |
| 283 | device_scale_factor_ = new_device_scale_factor; |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 284 | } |
| 285 | |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 286 | MOCK_METHOD2(OnLayerBoundsChanged, |
| 287 | void(const gfx::Rect&, PropertyChangeReason)); |
Scott Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 288 | MOCK_METHOD2(OnLayerTransformed, |
| 289 | void(const gfx::Transform&, PropertyChangeReason)); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 290 | MOCK_METHOD1(OnLayerOpacityChanged, void(PropertyChangeReason)); |
Francois Doray | a3a0b7f4 | 2018-08-15 15:44:32 | [diff] [blame] | 291 | MOCK_METHOD0(OnLayerAlphaShapeChanged, void()); |
Francois Doray | 4f515ad | 2017-09-15 16:19:34 | [diff] [blame] | 292 | |
[email protected] | 07908eb | 2012-05-09 00:15:30 | [diff] [blame] | 293 | void reset() { |
| 294 | color_index_ = 0; |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 295 | device_scale_factor_ = 0.0f; |
[email protected] | 07908eb | 2012-05-09 00:15:30 | [diff] [blame] | 296 | } |
| 297 | |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 298 | private: |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 299 | std::vector<SkColor> colors_; |
| 300 | int color_index_; |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 301 | float device_scale_factor_; |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 302 | gfx::Rect layer_bounds_; |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 303 | |
| 304 | DISALLOW_COPY_AND_ASSIGN(TestLayerDelegate); |
| 305 | }; |
| 306 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 307 | // LayerDelegate that verifies that a layer was asked to update its canvas. |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 308 | class DrawTreeLayerDelegate : public LayerDelegate { |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 309 | public: |
Sean Gilhuly | dc0b9fd | 2020-02-25 23:47:14 | [diff] [blame] | 310 | explicit DrawTreeLayerDelegate(const gfx::Rect& layer_bounds) |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 311 | : painted_(false), layer_bounds_(layer_bounds) {} |
Sean Gilhuly | dc0b9fd | 2020-02-25 23:47:14 | [diff] [blame] | 312 | ~DrawTreeLayerDelegate() override = default; |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 313 | |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 314 | void Reset() { |
| 315 | painted_ = false; |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 316 | } |
| 317 | |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 318 | bool painted() const { return painted_; } |
| 319 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 320 | private: |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 321 | // Overridden from LayerDelegate: |
danakj | 85d970e | 2015-04-04 00:15:24 | [diff] [blame] | 322 | void OnPaintLayer(const ui::PaintContext& context) override { |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 323 | painted_ = true; |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 324 | ui::PaintRecorder recorder(context, layer_bounds_.size()); |
danakj | c732322 | 2015-04-07 21:09:38 | [diff] [blame] | 325 | recorder.canvas()->DrawColor(SK_ColorWHITE); |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 326 | } |
Scott Violet | 06aff2b4 | 2017-09-08 00:26:32 | [diff] [blame] | 327 | void OnDeviceScaleFactorChanged(float old_device_scale_factor, |
| 328 | float new_device_scale_factor) override {} |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 329 | |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 330 | bool painted_; |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 331 | const gfx::Rect layer_bounds_; |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 332 | |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 333 | DISALLOW_COPY_AND_ASSIGN(DrawTreeLayerDelegate); |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 334 | }; |
| 335 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 336 | // The simplest possible layer delegate. Does nothing. |
| 337 | class NullLayerDelegate : public LayerDelegate { |
| 338 | public: |
| 339 | NullLayerDelegate() {} |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 340 | ~NullLayerDelegate() override {} |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 341 | |
wutao | 61373a39 | 2017-09-26 18:45:35 | [diff] [blame] | 342 | gfx::Rect invalidation() const { return invalidation_; } |
| 343 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 344 | private: |
wutao | 61373a39 | 2017-09-26 18:45:35 | [diff] [blame] | 345 | gfx::Rect invalidation_; |
| 346 | |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 347 | // Overridden from LayerDelegate: |
wutao | 61373a39 | 2017-09-26 18:45:35 | [diff] [blame] | 348 | void OnPaintLayer(const ui::PaintContext& context) override { |
| 349 | invalidation_ = context.InvalidationForTesting(); |
| 350 | } |
Scott Violet | 06aff2b4 | 2017-09-08 00:26:32 | [diff] [blame] | 351 | void OnDeviceScaleFactorChanged(float old_device_scale_factor, |
| 352 | float new_device_scale_factor) override {} |
[email protected] | 993d6b32 | 2011-09-27 19:14:38 | [diff] [blame] | 353 | |
| 354 | DISALLOW_COPY_AND_ASSIGN(NullLayerDelegate); |
| 355 | }; |
| 356 | |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 357 | // Remembers if it has been notified. |
| 358 | class TestCompositorObserver : public CompositorObserver { |
| 359 | public: |
danakj | 6c872fc0 | 2016-10-22 04:29:49 | [diff] [blame] | 360 | TestCompositorObserver() = default; |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 361 | |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 362 | bool committed() const { return committed_; } |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 363 | bool notified() const { return started_ && ended_; } |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 364 | |
[email protected] | a8f677c | 2012-03-23 01:36:06 | [diff] [blame] | 365 | void Reset() { |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 366 | committed_ = false; |
[email protected] | a8f677c | 2012-03-23 01:36:06 | [diff] [blame] | 367 | started_ = false; |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 368 | ended_ = false; |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 369 | } |
| 370 | |
[email protected] | a8f677c | 2012-03-23 01:36:06 | [diff] [blame] | 371 | private: |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 372 | void OnCompositingDidCommit(Compositor* compositor) override { |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 373 | committed_ = true; |
[email protected] | 2700daddd | 2012-07-13 19:35:37 | [diff] [blame] | 374 | } |
| 375 | |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 376 | void OnCompositingStarted(Compositor* compositor, |
| 377 | base::TimeTicks start_time) override { |
[email protected] | a8f677c | 2012-03-23 01:36:06 | [diff] [blame] | 378 | started_ = true; |
| 379 | } |
| 380 | |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 381 | void OnCompositingEnded(Compositor* compositor) override { ended_ = true; } |
| 382 | |
danakj | 6c872fc0 | 2016-10-22 04:29:49 | [diff] [blame] | 383 | bool committed_ = false; |
| 384 | bool started_ = false; |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 385 | bool ended_ = false; |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 386 | |
| 387 | DISALLOW_COPY_AND_ASSIGN(TestCompositorObserver); |
| 388 | }; |
| 389 | |
lof84 | adf2ce86 | 2015-06-02 22:23:32 | [diff] [blame] | 390 | class 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 Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 427 | // An animation observer that invokes a callback when the animation ends. |
| 428 | class 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] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 447 | } // namespace |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 448 | |
Ilia Samsonov | e2d8abe | 2019-11-20 22:25:24 | [diff] [blame] | 449 | INSTANTIATE_TEST_SUITE_P(All, LayerWithRealCompositorTest, ::testing::Bool()); |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 450 | |
| 451 | TEST_P(LayerWithRealCompositorTest, Draw) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 452 | std::unique_ptr<Layer> layer = |
| 453 | CreateColorLayer(SK_ColorRED, gfx::Rect(20, 20, 50, 50)); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 454 | DrawTree(layer.get()); |
| 455 | } |
| 456 | |
| 457 | // Create this hierarchy: |
| 458 | // L1 - red |
| 459 | // +-- L2 - blue |
| 460 | // | +-- L3 - yellow |
| 461 | // +-- L4 - magenta |
| 462 | // |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 463 | TEST_P(LayerWithRealCompositorTest, Hierarchy) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 464 | 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] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 472 | |
| 473 | l1->Add(l2.get()); |
| 474 | l1->Add(l4.get()); |
| 475 | l2->Add(l3.get()); |
| 476 | |
| 477 | DrawTree(l1.get()); |
| 478 | } |
| 479 | |
[email protected] | c3fac4d | 2013-10-17 22:10:05 | [diff] [blame] | 480 | class LayerWithDelegateTest : public testing::Test { |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 481 | public: |
jonross | 1ec7d99 | 2018-08-31 03:55:54 | [diff] [blame] | 482 | LayerWithDelegateTest() |
Gabriel Charette | dfa3604 | 2019-08-19 17:30:11 | [diff] [blame] | 483 | : task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {} |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 484 | ~LayerWithDelegateTest() override {} |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 485 | |
| 486 | // Overridden from testing::Test: |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 487 | void SetUp() override { |
Mohsen Izadi | b371018 | 2019-04-30 04:57:35 | [diff] [blame] | 488 | const bool enable_pixel_output = false; |
| 489 | context_factories_ = |
| 490 | std::make_unique<TestContextFactories>(enable_pixel_output); |
[email protected] | d57eca1 | 2014-02-21 02:39:22 | [diff] [blame] | 491 | |
| 492 | const gfx::Rect host_bounds(1000, 1000); |
fsamuel | a0bcfe1 | 2016-12-14 06:21:49 | [diff] [blame] | 493 | compositor_host_.reset(TestCompositorHost::Create( |
Sean Gilhuly | dc0b9fd | 2020-02-25 23:47:14 | [diff] [blame] | 494 | host_bounds, context_factories_->GetContextFactory())); |
[email protected] | d57eca1 | 2014-02-21 02:39:22 | [diff] [blame] | 495 | compositor_host_->Show(); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 496 | } |
| 497 | |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 498 | void TearDown() override { |
[email protected] | d57eca1 | 2014-02-21 02:39:22 | [diff] [blame] | 499 | compositor_host_.reset(); |
Mohsen Izadi | b371018 | 2019-04-30 04:57:35 | [diff] [blame] | 500 | context_factories_.reset(); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 501 | } |
| 502 | |
[email protected] | d57eca1 | 2014-02-21 02:39:22 | [diff] [blame] | 503 | Compositor* compositor() { return compositor_host_->GetCompositor(); } |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 504 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 505 | virtual std::unique_ptr<Layer> CreateLayer(LayerType type) { |
| 506 | return std::make_unique<Layer>(type); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 507 | } |
| 508 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 509 | std::unique_ptr<Layer> CreateColorLayer(SkColor color, |
| 510 | const gfx::Rect& bounds) { |
| 511 | auto layer = std::make_unique<ColoredLayer>(color); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 512 | layer->SetBounds(bounds); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 513 | return layer; |
| 514 | } |
| 515 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 516 | virtual std::unique_ptr<Layer> CreateNoTextureLayer(const gfx::Rect& bounds) { |
| 517 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_NOT_DRAWN); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 518 | layer->SetBounds(bounds); |
| 519 | return layer; |
| 520 | } |
| 521 | |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 522 | void DrawTree(Layer* root) { |
| 523 | compositor()->SetRootLayer(root); |
[email protected] | 44ed4bd | 2013-04-06 00:11:27 | [diff] [blame] | 524 | Draw(); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 525 | } |
| 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] | 44ed4bd | 2013-04-06 00:11:27 | [diff] [blame] | 535 | compositor()->ScheduleDraw(); |
| 536 | WaitForDraw(); |
| 537 | } |
| 538 | |
weiliangc | 5efa0a1 | 2015-01-29 19:56:46 | [diff] [blame] | 539 | void WaitForDraw() { |
| 540 | DrawWaiterForTest::WaitForCompositingStarted(compositor()); |
| 541 | } |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 542 | |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 543 | void WaitForCommit() { |
| 544 | DrawWaiterForTest::WaitForCommit(compositor()); |
| 545 | } |
| 546 | |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 547 | private: |
Gabriel Charette | dfa3604 | 2019-08-19 17:30:11 | [diff] [blame] | 548 | base::test::TaskEnvironment task_environment_; |
Mohsen Izadi | b371018 | 2019-04-30 04:57:35 | [diff] [blame] | 549 | std::unique_ptr<TestContextFactories> context_factories_; |
danakj | 25c52c3 | 2016-04-12 21:51:08 | [diff] [blame] | 550 | std::unique_ptr<TestCompositorHost> compositor_host_; |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 551 | |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 552 | DISALLOW_COPY_AND_ASSIGN(LayerWithDelegateTest); |
[email protected] | 4916d62 | 2011-09-28 23:45:38 | [diff] [blame] | 553 | }; |
| 554 | |
dcastagna | ef83bc3 | 2016-03-24 22:32:45 | [diff] [blame] | 555 | void ReturnMailbox(bool* run, const gpu::SyncToken& sync_token, bool is_lost) { |
| 556 | *run = true; |
| 557 | } |
| 558 | |
| 559 | TEST(LayerStandaloneTest, ReleaseMailboxOnDestruction) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 560 | auto layer = std::make_unique<Layer>(LAYER_TEXTURED); |
dcastagna | ef83bc3 | 2016-03-24 22:32:45 | [diff] [blame] | 561 | bool callback_run = false; |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 562 | |
| 563 | constexpr gfx::Size size(64, 64); |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 564 | auto resource = viz::TransferableResource::MakeGL( |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 565 | gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(), |
| 566 | size, false /* is_overlay_candidate */); |
tzik | 387bee3f | 2018-03-30 21:06:48 | [diff] [blame] | 567 | layer->SetTransferableResource( |
| 568 | resource, |
| 569 | viz::SingleReleaseCallback::Create( |
| 570 | base::BindOnce(ReturnMailbox, &callback_run)), |
| 571 | gfx::Size(10, 10)); |
dcastagna | ef83bc3 | 2016-03-24 22:32:45 | [diff] [blame] | 572 | EXPECT_FALSE(callback_run); |
| 573 | layer.reset(); |
| 574 | EXPECT_TRUE(callback_run); |
| 575 | } |
| 576 | |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 577 | // L1 |
| 578 | // +-- L2 |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 579 | TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Simple) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 580 | 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] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 584 | l1->Add(l2.get()); |
| 585 | DrawTree(l1.get()); |
| 586 | |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 587 | gfx::PointF point1_in_l2_coords(5, 5); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 588 | Layer::ConvertPointToLayer(l2.get(), l1.get(), &point1_in_l2_coords); |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 589 | gfx::PointF point1_in_l1_coords(15, 15); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 590 | EXPECT_EQ(point1_in_l1_coords, point1_in_l2_coords); |
| 591 | |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 592 | gfx::PointF point2_in_l1_coords(5, 5); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 593 | Layer::ConvertPointToLayer(l1.get(), l2.get(), &point2_in_l1_coords); |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 594 | gfx::PointF point2_in_l2_coords(-5, -5); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 595 | EXPECT_EQ(point2_in_l2_coords, point2_in_l1_coords); |
| 596 | } |
| 597 | |
| 598 | // L1 |
| 599 | // +-- L2 |
| 600 | // +-- L3 |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 601 | TEST_F(LayerWithDelegateTest, ConvertPointToLayer_Medium) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 602 | 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] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 608 | l1->Add(l2.get()); |
| 609 | l2->Add(l3.get()); |
| 610 | DrawTree(l1.get()); |
| 611 | |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 612 | gfx::PointF point1_in_l3_coords(5, 5); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 613 | Layer::ConvertPointToLayer(l3.get(), l1.get(), &point1_in_l3_coords); |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 614 | gfx::PointF point1_in_l1_coords(25, 25); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 615 | EXPECT_EQ(point1_in_l1_coords, point1_in_l3_coords); |
| 616 | |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 617 | gfx::PointF point2_in_l1_coords(5, 5); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 618 | Layer::ConvertPointToLayer(l1.get(), l3.get(), &point2_in_l1_coords); |
Ella Ge | 7540c84 | 2017-10-19 03:27:27 | [diff] [blame] | 619 | gfx::PointF point2_in_l3_coords(-15, -15); |
[email protected] | ad725891 | 2011-08-29 20:33:53 | [diff] [blame] | 620 | EXPECT_EQ(point2_in_l3_coords, point2_in_l1_coords); |
| 621 | } |
| 622 | |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 623 | TEST_P(LayerWithRealCompositorTest, Delegate) { |
weiliangc | d048acf | 2015-03-10 19:00:07 | [diff] [blame] | 624 | // 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 Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 627 | std::unique_ptr<Layer> l1 = |
| 628 | CreateColorLayer(SK_ColorBLACK, gfx::Rect(20, 20, 400, 400)); |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 629 | GetCompositor()->SetRootLayer(l1.get()); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 630 | WaitForDraw(); |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 631 | |
| 632 | TestLayerDelegate delegate; |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 633 | l1->set_delegate(&delegate); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 634 | delegate.set_layer_bounds(l1->bounds()); |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 635 | delegate.AddColor(SK_ColorWHITE); |
| 636 | delegate.AddColor(SK_ColorYELLOW); |
| 637 | delegate.AddColor(SK_ColorGREEN); |
| 638 | |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 639 | l1->SchedulePaint(gfx::Rect(0, 0, 400, 400)); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 640 | WaitForDraw(); |
weiliangc | d048acf | 2015-03-10 19:00:07 | [diff] [blame] | 641 | // Test that paint happened at layer delegate. |
| 642 | EXPECT_EQ(1, delegate.color_index()); |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 643 | |
| 644 | l1->SchedulePaint(gfx::Rect(10, 10, 200, 200)); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 645 | WaitForDraw(); |
weiliangc | d048acf | 2015-03-10 19:00:07 | [diff] [blame] | 646 | // Test that paint happened at layer delegate. |
| 647 | EXPECT_EQ(2, delegate.color_index()); |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 648 | |
| 649 | l1->SchedulePaint(gfx::Rect(5, 5, 50, 50)); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 650 | WaitForDraw(); |
weiliangc | d048acf | 2015-03-10 19:00:07 | [diff] [blame] | 651 | // Test that paint happened at layer delegate. |
| 652 | EXPECT_EQ(0, delegate.color_index()); |
[email protected] | 00b8698 | 2011-09-01 00:02:09 | [diff] [blame] | 653 | } |
| 654 | |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 655 | TEST_P(LayerWithRealCompositorTest, DrawTree) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 656 | 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] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 662 | l1->Add(l2.get()); |
| 663 | l2->Add(l3.get()); |
| 664 | |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 665 | GetCompositor()->SetRootLayer(l1.get()); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 666 | WaitForDraw(); |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 667 | |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 668 | DrawTreeLayerDelegate d1(l1->bounds()); |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 669 | l1->set_delegate(&d1); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 670 | DrawTreeLayerDelegate d2(l2->bounds()); |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 671 | l2->set_delegate(&d2); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 672 | DrawTreeLayerDelegate d3(l3->bounds()); |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 673 | l3->set_delegate(&d3); |
| 674 | |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 675 | l2->SchedulePaint(gfx::Rect(5, 5, 5, 5)); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 676 | WaitForDraw(); |
[email protected] | 3aa4394 | 2011-09-13 20:59:53 | [diff] [blame] | 677 | EXPECT_FALSE(d1.painted()); |
| 678 | EXPECT_TRUE(d2.painted()); |
| 679 | EXPECT_FALSE(d3.painted()); |
| 680 | } |
| 681 | |
varkha | 662bc74 | 2016-07-13 07:32:27 | [diff] [blame] | 682 | // Tests that scheduling paint on a layer with a mask updates the mask. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 683 | TEST_P(LayerWithRealCompositorTest, SchedulePaintUpdatesMask) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 684 | 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); |
varkha | 662bc74 | 2016-07-13 07:32:27 | [diff] [blame] | 687 | 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] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 704 | // Tests no-texture Layers. |
| 705 | // Create this hierarchy: |
| 706 | // L1 - red |
| 707 | // +-- L2 - NO TEXTURE |
| 708 | // | +-- L3 - yellow |
| 709 | // +-- L4 - magenta |
| 710 | // |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 711 | TEST_P(LayerWithRealCompositorTest, HierarchyNoTexture) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 712 | 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] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 719 | |
| 720 | l1->Add(l2.get()); |
| 721 | l1->Add(l4.get()); |
| 722 | l2->Add(l3.get()); |
| 723 | |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 724 | GetCompositor()->SetRootLayer(l1.get()); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 725 | WaitForDraw(); |
[email protected] | 33274903 | 2011-10-22 00:32:46 | [diff] [blame] | 726 | |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 727 | DrawTreeLayerDelegate d2(l2->bounds()); |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 728 | l2->set_delegate(&d2); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 729 | DrawTreeLayerDelegate d3(l3->bounds()); |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 730 | l3->set_delegate(&d3); |
| 731 | |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 732 | l2->SchedulePaint(gfx::Rect(5, 5, 5, 5)); |
| 733 | l3->SchedulePaint(gfx::Rect(5, 5, 5, 5)); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 734 | WaitForDraw(); |
[email protected] | 28cd2bb | 2011-09-19 21:04:19 | [diff] [blame] | 735 | |
| 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 Mukai | 7a20ff0 | 2019-08-02 00:46:06 | [diff] [blame] | 742 | TEST_F(LayerWithDelegateTest, Cloning) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 743 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 744 | |
| 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); |
wutao | 52217d1 | 2017-08-18 02:40:31 | [diff] [blame] | 752 | layer->AddCacheRenderSurfaceRequest(); |
wutao | 1d35eeb7 | 2017-10-12 23:01:24 | [diff] [blame] | 753 | layer->AddTrilinearFilteringRequest(); |
Malay Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 754 | layer->SetRoundedCornerRadius({1, 2, 4, 5}); |
| 755 | layer->SetIsFastRoundedCorner(true); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 756 | |
| 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()); |
wutao | 3685073 | 2017-07-29 20:24:07 | [diff] [blame] | 764 | // 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()); |
wutao | 1d35eeb7 | 2017-10-12 23:01:24 | [diff] [blame] | 767 | // 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 Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 770 | EXPECT_EQ(layer->rounded_corner_radii(), clone->rounded_corner_radii()); |
| 771 | EXPECT_EQ(layer->is_fast_rounded_corner(), clone->is_fast_rounded_corner()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 772 | |
| 773 | layer->SetTransform(gfx::Transform()); |
| 774 | layer->SetColor(SK_ColorGREEN); |
| 775 | layer->SetLayerInverted(false); |
Malay Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 776 | layer->SetIsFastRoundedCorner(false); |
| 777 | layer->SetRoundedCornerRadius({3, 6, 9, 12}); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 778 | |
| 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 Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 784 | 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()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 787 | |
| 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 | |
sadrul | 458e50e | 2017-03-15 17:44:31 | [diff] [blame] | 804 | // A solid color layer with transparent color can be marked as opaque. The |
| 805 | // clone should retain this state. |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 806 | layer = CreateLayer(LAYER_SOLID_COLOR); |
sadrul | 458e50e | 2017-03-15 17:44:31 | [diff] [blame] | 807 | 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 Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 817 | layer = CreateLayer(LAYER_SOLID_COLOR); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 818 | 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 | |
| 839 | TEST_F(LayerWithDelegateTest, Mirroring) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 840 | std::unique_ptr<Layer> root = CreateNoTextureLayer(gfx::Rect(0, 0, 100, 100)); |
| 841 | std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 842 | |
| 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 Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 850 | const auto mirror1 = child->Mirror(); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 851 | |
| 852 | // Bounds and visibility are preserved. |
Ahmed Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 853 | EXPECT_EQ(bounds, mirror1->bounds()); |
| 854 | EXPECT_TRUE(mirror1->visible()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 855 | |
| 856 | root->Add(child.get()); |
Ahmed Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 857 | root->Add(mirror1.get()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 858 | |
| 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 Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 865 | EXPECT_TRUE(mirror1->damaged_region_for_testing().IsEmpty()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 866 | |
| 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 Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 876 | EXPECT_EQ(damaged_rect, mirror1->damaged_region_for_testing().bounds()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 877 | 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 Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 883 | EXPECT_TRUE(mirror1->damaged_region_for_testing().IsEmpty()); |
| 884 | |
| 885 | const auto mirror2 = child->Mirror(); |
| 886 | root->Add(mirror2.get()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 887 | |
| 888 | // Bounds are not synchronized by default. |
| 889 | const gfx::Rect new_bounds(10, 10, 10, 10); |
| 890 | child->SetBounds(new_bounds); |
Ahmed Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 891 | EXPECT_EQ(bounds, mirror1->bounds()); |
| 892 | EXPECT_EQ(bounds, mirror2->bounds()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 893 | child->SetBounds(bounds); |
| 894 | |
Ahmed Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 895 | // Bounds should be synchronized only for the mirror layer that requested it. |
| 896 | mirror1->set_sync_bounds_with_source(true); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 897 | child->SetBounds(new_bounds); |
Ahmed Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 898 | EXPECT_EQ(new_bounds, mirror1->bounds()); |
| 899 | EXPECT_EQ(bounds, mirror2->bounds()); |
Malay Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 900 | |
| 901 | // Check for rounded corner mirror behavior |
Ahmed Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 902 | EXPECT_TRUE(mirror1->rounded_corner_radii().IsEmpty()); |
| 903 | EXPECT_FALSE(mirror1->is_fast_rounded_corner()); |
Dana Fried | 45b87ecc | 2019-05-13 17:36:25 | [diff] [blame] | 904 | constexpr gfx::RoundedCornersF kCornerRadii(2, 3, 4, 5); |
| 905 | child->SetRoundedCornerRadius(kCornerRadii); |
Malay Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 906 | child->SetIsFastRoundedCorner(true); |
Ahmed Fakhry | 881c9293 | 2019-05-22 17:47:23 | [diff] [blame] | 907 | EXPECT_EQ(kCornerRadii, mirror1->rounded_corner_radii()); |
| 908 | EXPECT_TRUE(mirror1->is_fast_rounded_corner()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 909 | } |
| 910 | |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 911 | // Tests for SurfaceLayer cloning and mirroring. This tests certain properties |
| 912 | // are preserved. |
| 913 | TEST_F(LayerWithDelegateTest, SurfaceLayerCloneAndMirror) { |
| 914 | const viz::FrameSinkId arbitrary_frame_sink(1, 1); |
| 915 | viz::ParentLocalSurfaceIdAllocator allocator; |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 916 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR); |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 917 | |
Jonathan Ross | 89807fc | 2018-10-30 17:41:21 | [diff] [blame] | 918 | allocator.GenerateId(); |
jonross | 58cab43 | 2018-11-29 02:30:30 | [diff] [blame] | 919 | viz::LocalSurfaceId local_surface_id = |
| 920 | allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id(); |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 921 | viz::SurfaceId surface_id_one(arbitrary_frame_sink, local_surface_id); |
Saman Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 922 | layer->SetShowSurface(surface_id_one, gfx::Size(10, 10), SK_ColorWHITE, |
| 923 | cc::DeadlinePolicy::UseDefaultDeadline(), false); |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 924 | EXPECT_FALSE(layer->StretchContentToFillBounds()); |
| 925 | |
| 926 | auto clone = layer->Clone(); |
| 927 | EXPECT_FALSE(clone->StretchContentToFillBounds()); |
| 928 | auto mirror = layer->Mirror(); |
sunxd | 26e9bae | 2018-03-22 19:32:33 | [diff] [blame] | 929 | EXPECT_FALSE(mirror->StretchContentToFillBounds()); |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 930 | |
Jonathan Ross | 89807fc | 2018-10-30 17:41:21 | [diff] [blame] | 931 | allocator.GenerateId(); |
jonross | 58cab43 | 2018-11-29 02:30:30 | [diff] [blame] | 932 | local_surface_id = |
| 933 | allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id(); |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 934 | viz::SurfaceId surface_id_two(arbitrary_frame_sink, local_surface_id); |
Saman Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 935 | layer->SetShowSurface(surface_id_two, gfx::Size(10, 10), SK_ColorWHITE, |
| 936 | cc::DeadlinePolicy::UseDefaultDeadline(), true); |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 937 | EXPECT_TRUE(layer->StretchContentToFillBounds()); |
| 938 | |
| 939 | clone = layer->Clone(); |
| 940 | EXPECT_TRUE(clone->StretchContentToFillBounds()); |
| 941 | mirror = layer->Mirror(); |
sunxd | 26e9bae | 2018-03-22 19:32:33 | [diff] [blame] | 942 | EXPECT_TRUE(mirror->StretchContentToFillBounds()); |
Jennifer Apacible | ea38ede | 2018-03-15 02:41:55 | [diff] [blame] | 943 | } |
| 944 | |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 945 | class LayerWithNullDelegateTest : public LayerWithDelegateTest { |
| 946 | public: |
| 947 | LayerWithNullDelegateTest() {} |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 948 | ~LayerWithNullDelegateTest() override {} |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 949 | |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 950 | void SetUp() override { |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 951 | LayerWithDelegateTest::SetUp(); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 952 | default_layer_delegate_ = std::make_unique<NullLayerDelegate>(); |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 953 | } |
| 954 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 955 | std::unique_ptr<Layer> CreateLayer(LayerType type) override { |
| 956 | auto layer = std::make_unique<Layer>(type); |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 957 | layer->set_delegate(default_layer_delegate_.get()); |
| 958 | return layer; |
| 959 | } |
| 960 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 961 | std::unique_ptr<Layer> CreateTextureRootLayer(const gfx::Rect& bounds) { |
| 962 | std::unique_ptr<Layer> layer = CreateTextureLayer(bounds); |
| 963 | compositor()->SetRootLayer(layer.get()); |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 964 | return layer; |
| 965 | } |
| 966 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 967 | std::unique_ptr<Layer> CreateTextureLayer(const gfx::Rect& bounds) { |
| 968 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_TEXTURED); |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 969 | layer->SetBounds(bounds); |
| 970 | return layer; |
| 971 | } |
| 972 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 973 | std::unique_ptr<Layer> CreateNoTextureLayer( |
| 974 | const gfx::Rect& bounds) override { |
| 975 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_NOT_DRAWN); |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 976 | layer->SetBounds(bounds); |
| 977 | return layer; |
| 978 | } |
| 979 | |
wutao | 61373a39 | 2017-09-26 18:45:35 | [diff] [blame] | 980 | gfx::Rect LastInvalidation() const { |
| 981 | return default_layer_delegate_->invalidation(); |
| 982 | } |
| 983 | |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 984 | private: |
danakj | 25c52c3 | 2016-04-12 21:51:08 | [diff] [blame] | 985 | std::unique_ptr<NullLayerDelegate> default_layer_delegate_; |
[email protected] | 5610d51 | 2011-10-04 21:32:57 | [diff] [blame] | 986 | |
| 987 | DISALLOW_COPY_AND_ASSIGN(LayerWithNullDelegateTest); |
| 988 | }; |
| 989 | |
Jun Mukai | 7a20ff0 | 2019-08-02 00:46:06 | [diff] [blame] | 990 | TEST_F(LayerWithNullDelegateTest, SwitchLayerPreservesCCLayerState) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 991 | std::unique_ptr<Layer> l1 = CreateLayer(LAYER_SOLID_COLOR); |
[email protected] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 992 | l1->SetFillsBoundsOpaquely(true); |
[email protected] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 993 | l1->SetVisible(false); |
danakj | 2ec13e9 | 2015-02-24 23:52:04 | [diff] [blame] | 994 | l1->SetBounds(gfx::Rect(4, 5)); |
[email protected] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 995 | |
Dana Fried | 45b87ecc | 2019-05-13 17:36:25 | [diff] [blame] | 996 | constexpr gfx::RoundedCornersF kCornerRadii(1, 2, 3, 4); |
Malay Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 997 | l1->SetRoundedCornerRadius(kCornerRadii); |
| 998 | l1->SetIsFastRoundedCorner(true); |
| 999 | |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1000 | 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()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1003 | 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 Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 1005 | 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] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 1008 | |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1009 | cc::Layer* before_layer = l1->cc_layer_for_testing(); |
[email protected] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 1010 | |
[email protected] | 4508b15 | 2014-04-09 22:14:17 | [diff] [blame] | 1011 | bool callback1_run = false; |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 1012 | constexpr gfx::Size size(64, 64); |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1013 | auto resource = viz::TransferableResource::MakeGL( |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 1014 | gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(), |
| 1015 | size, false /* is_overlay_candidate */); |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1016 | l1->SetTransferableResource(resource, |
tzik | 387bee3f | 2018-03-30 21:06:48 | [diff] [blame] | 1017 | viz::SingleReleaseCallback::Create(base::BindOnce( |
| 1018 | ReturnMailbox, &callback1_run)), |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1019 | gfx::Size(10, 10)); |
[email protected] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 1020 | |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1021 | EXPECT_NE(before_layer, l1->cc_layer_for_testing()); |
[email protected] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 1022 | |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1023 | 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()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1026 | 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 Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 1028 | 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] | 4508b15 | 2014-04-09 22:14:17 | [diff] [blame] | 1031 | EXPECT_FALSE(callback1_run); |
| 1032 | |
| 1033 | bool callback2_run = false; |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1034 | resource = viz::TransferableResource::MakeGL( |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 1035 | gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(), |
| 1036 | size, false /* is_overlay_candidate */); |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1037 | l1->SetTransferableResource(resource, |
tzik | 387bee3f | 2018-03-30 21:06:48 | [diff] [blame] | 1038 | viz::SingleReleaseCallback::Create(base::BindOnce( |
| 1039 | ReturnMailbox, &callback2_run)), |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1040 | gfx::Size(10, 10)); |
[email protected] | 4508b15 | 2014-04-09 22:14:17 | [diff] [blame] | 1041 | EXPECT_TRUE(callback1_run); |
| 1042 | EXPECT_FALSE(callback2_run); |
| 1043 | |
danakj | 2ec13e9 | 2015-02-24 23:52:04 | [diff] [blame] | 1044 | // Show solid color instead. |
jbauman | f472c687 | 2014-10-13 20:06:43 | [diff] [blame] | 1045 | l1->SetShowSolidColorContent(); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1046 | 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()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1049 | 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 Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 1051 | 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] | 4508b15 | 2014-04-09 22:14:17 | [diff] [blame] | 1054 | EXPECT_TRUE(callback2_run); |
danakj | 2ec13e9 | 2015-02-24 23:52:04 | [diff] [blame] | 1055 | |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1056 | before_layer = l1->cc_layer_for_testing(); |
danakj | 2ec13e9 | 2015-02-24 23:52:04 | [diff] [blame] | 1057 | |
| 1058 | // Back to a texture, without changing the bounds of the layer or the texture. |
| 1059 | bool callback3_run = false; |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1060 | resource = viz::TransferableResource::MakeGL( |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 1061 | gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(), |
| 1062 | size, false /* is_overlay_candidate */); |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1063 | l1->SetTransferableResource(resource, |
tzik | 387bee3f | 2018-03-30 21:06:48 | [diff] [blame] | 1064 | viz::SingleReleaseCallback::Create(base::BindOnce( |
| 1065 | ReturnMailbox, &callback3_run)), |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1066 | gfx::Size(10, 10)); |
danakj | 2ec13e9 | 2015-02-24 23:52:04 | [diff] [blame] | 1067 | |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1068 | EXPECT_NE(before_layer, l1->cc_layer_for_testing()); |
danakj | 2ec13e9 | 2015-02-24 23:52:04 | [diff] [blame] | 1069 | |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1070 | 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()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1073 | 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 Keshav | 2e04a95b | 2019-03-14 19:11:21 | [diff] [blame] | 1075 | 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()); |
danakj | 2ec13e9 | 2015-02-24 23:52:04 | [diff] [blame] | 1078 | EXPECT_FALSE(callback3_run); |
| 1079 | |
| 1080 | // Release the on |l1| mailbox to clean up the test. |
| 1081 | l1->SetShowSolidColorContent(); |
[email protected] | 3b4b2f0 | 2013-06-24 23:15:27 | [diff] [blame] | 1082 | } |
| 1083 | |
erg | 4ad81c08 | 2017-05-15 22:30:00 | [diff] [blame] | 1084 | // Various visible/drawn assertions. |
[email protected] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 1085 | TEST_F(LayerWithNullDelegateTest, Visibility) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1086 | 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] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 1089 | 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()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1101 | 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] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 1104 | |
| 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()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1113 | 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] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 1116 | |
| 1117 | l3->SetVisible(false); |
| 1118 | EXPECT_FALSE(l1->IsDrawn()); |
| 1119 | EXPECT_FALSE(l2->IsDrawn()); |
| 1120 | EXPECT_FALSE(l3->IsDrawn()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1121 | 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] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 1124 | |
| 1125 | l1->SetVisible(true); |
| 1126 | EXPECT_TRUE(l1->IsDrawn()); |
| 1127 | EXPECT_TRUE(l2->IsDrawn()); |
| 1128 | EXPECT_FALSE(l3->IsDrawn()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 1129 | 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] | e4e8afef | 2011-10-05 13:58:33 | [diff] [blame] | 1132 | } |
| 1133 | |
Malay Keshav | df4c12cd | 2019-02-07 04:19:58 | [diff] [blame] | 1134 | // Various visible/drawn assertions. |
| 1135 | TEST_F(LayerWithNullDelegateTest, MirroringVisibility) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1136 | auto l1 = std::make_unique<Layer>(LAYER_TEXTURED); |
| 1137 | auto l2 = std::make_unique<Layer>(LAYER_TEXTURED); |
Malay Keshav | df4c12cd | 2019-02-07 04:19:58 | [diff] [blame] | 1138 | 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 Fakhry | e2714332 | 2019-07-09 23:40:25 | [diff] [blame] | 1236 | |
| 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 Keshav | df4c12cd | 2019-02-07 04:19:58 | [diff] [blame] | 1245 | } |
| 1246 | |
Malay Keshav | b7884874 | 2019-03-05 03:33:04 | [diff] [blame] | 1247 | TEST_F(LayerWithDelegateTest, RoundedCorner) { |
| 1248 | gfx::Rect layer_bounds(10, 20, 100, 100); |
Dana Fried | 45b87ecc | 2019-05-13 17:36:25 | [diff] [blame] | 1249 | constexpr gfx::RoundedCornersF kRadii(5, 10, 15, 20); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1250 | auto layer = std::make_unique<Layer>(LAYER_TEXTURED); |
Malay Keshav | b7884874 | 2019-03-05 03:33:04 | [diff] [blame] | 1251 | |
| 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 Fried | 45b87ecc | 2019-05-13 17:36:25 | [diff] [blame] | 1261 | EXPECT_TRUE(layer->rounded_corner_radii().IsEmpty()); |
Malay Keshav | b7884874 | 2019-03-05 03:33:04 | [diff] [blame] | 1262 | |
| 1263 | // Setting a rounded corner radius should set an rrect with bounds same as the |
| 1264 | // layer. |
Dana Fried | 45b87ecc | 2019-05-13 17:36:25 | [diff] [blame] | 1265 | layer->SetRoundedCornerRadius(kRadii); |
| 1266 | EXPECT_EQ(kRadii, layer->rounded_corner_radii()); |
Malay Keshav | b7884874 | 2019-03-05 03:33:04 | [diff] [blame] | 1267 | } |
| 1268 | |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1269 | // Checks that stacking-related methods behave as advertised. |
| 1270 | TEST_F(LayerWithNullDelegateTest, Stacking) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1271 | 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); |
yjliu | 0b287621 | 2019-12-19 03:36:20 | [diff] [blame] | 1275 | l1->SetName("1"); |
| 1276 | l2->SetName("2"); |
| 1277 | l3->SetName("3"); |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1278 | 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] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1283 | EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1284 | |
| 1285 | root->StackAtTop(l3.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1286 | EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1287 | |
| 1288 | root->StackAtTop(l1.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1289 | EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1290 | |
| 1291 | root->StackAtTop(l1.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1292 | EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1293 | |
| 1294 | root->StackAbove(l2.get(), l3.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1295 | EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1296 | |
| 1297 | root->StackAbove(l1.get(), l3.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1298 | EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1299 | |
| 1300 | root->StackAbove(l2.get(), l1.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1301 | EXPECT_EQ("3 1 2", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1302 | |
| 1303 | root->StackAtBottom(l2.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1304 | EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1305 | |
| 1306 | root->StackAtBottom(l3.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1307 | EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1308 | |
| 1309 | root->StackAtBottom(l3.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1310 | EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1311 | |
| 1312 | root->StackBelow(l2.get(), l3.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1313 | EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1314 | |
| 1315 | root->StackBelow(l1.get(), l3.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1316 | EXPECT_EQ("2 1 3", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1317 | |
| 1318 | root->StackBelow(l3.get(), l2.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1319 | EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1320 | |
| 1321 | root->StackBelow(l3.get(), l2.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1322 | EXPECT_EQ("3 2 1", test::ChildLayerNamesAsString(*root.get())); |
[email protected] | 44c6f8d | 2011-12-27 23:49:04 | [diff] [blame] | 1323 | |
| 1324 | root->StackBelow(l3.get(), l1.get()); |
[email protected] | 2f19761c | 2013-05-22 13:04:35 | [diff] [blame] | 1325 | EXPECT_EQ("2 3 1", test::ChildLayerNamesAsString(*root.get())); |
Edwin Joe | 863d4530 | 2019-03-28 19:57:04 | [diff] [blame] | 1326 | |
| 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] | ebc335f | 2011-11-23 00:43:51 | [diff] [blame] | 1354 | } |
| 1355 | |
[email protected] | a50ff37 | 2011-11-03 16:06:28 | [diff] [blame] | 1356 | // Verifies SetBounds triggers the appropriate painting/drawing. |
| 1357 | TEST_F(LayerWithNullDelegateTest, SetBoundsSchedulesPaint) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1358 | std::unique_ptr<Layer> l1 = CreateTextureLayer(gfx::Rect(0, 0, 200, 200)); |
[email protected] | a50ff37 | 2011-11-03 16:06:28 | [diff] [blame] | 1359 | compositor()->SetRootLayer(l1.get()); |
| 1360 | |
| 1361 | Draw(); |
[email protected] | 3f1f5e6a | 2011-11-11 15:09:02 | [diff] [blame] | 1362 | |
[email protected] | a50ff37 | 2011-11-03 16:06:28 | [diff] [blame] | 1363 | l1->SetBounds(gfx::Rect(5, 5, 200, 200)); |
[email protected] | 3f1f5e6a | 2011-11-11 15:09:02 | [diff] [blame] | 1364 | |
| 1365 | // The CompositorDelegate (us) should have been told to draw for a move. |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 1366 | WaitForDraw(); |
[email protected] | a50ff37 | 2011-11-03 16:06:28 | [diff] [blame] | 1367 | |
[email protected] | a50ff37 | 2011-11-03 16:06:28 | [diff] [blame] | 1368 | l1->SetBounds(gfx::Rect(5, 5, 100, 100)); |
[email protected] | 3f1f5e6a | 2011-11-11 15:09:02 | [diff] [blame] | 1369 | |
| 1370 | // The CompositorDelegate (us) should have been told to draw for a resize. |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 1371 | WaitForDraw(); |
[email protected] | a50ff37 | 2011-11-03 16:06:28 | [diff] [blame] | 1372 | } |
| 1373 | |
jbauman | ac619ac | 2016-06-02 22:22:03 | [diff] [blame] | 1374 | // Checks that the damage rect for a TextureLayer is empty after a commit. |
| 1375 | TEST_F(LayerWithNullDelegateTest, EmptyDamagedRect) { |
kylechar | cf88963a8 | 2017-04-26 21:08:57 | [diff] [blame] | 1376 | base::RunLoop run_loop; |
tzik | 387bee3f | 2018-03-30 21:06:48 | [diff] [blame] | 1377 | 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)); |
kylechar | cf88963a8 | 2017-04-26 21:08:57 | [diff] [blame] | 1381 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1382 | std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR); |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 1383 | constexpr gfx::Size size(64, 64); |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1384 | auto resource = viz::TransferableResource::MakeGL( |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 1385 | gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(), |
| 1386 | size, false /* is_overlay_candidate */); |
danakj | 4957a22 | 2017-11-21 17:23:10 | [diff] [blame] | 1387 | root->SetTransferableResource( |
| 1388 | resource, viz::SingleReleaseCallback::Create(std::move(callback)), |
tzik | 736175f | 2017-11-15 13:39:24 | [diff] [blame] | 1389 | gfx::Size(10, 10)); |
jbauman | ac619ac | 2016-06-02 22:22:03 | [diff] [blame] | 1390 | 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 | |
kylechar | cf88963a8 | 2017-04-26 21:08:57 | [diff] [blame] | 1402 | // 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(); |
jbauman | ac619ac | 2016-06-02 22:22:03 | [diff] [blame] | 1410 | } |
| 1411 | |
wutao | 61373a39 | 2017-09-26 18:45:35 | [diff] [blame] | 1412 | // Tests that in deferred paint request, the layer damage will be accumulated. |
| 1413 | TEST_F(LayerWithNullDelegateTest, UpdateDamageInDeferredPaint) { |
| 1414 | gfx::Rect bound(gfx::Rect(500, 500)); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1415 | std::unique_ptr<Layer> root = CreateTextureRootLayer(bound); |
wutao | 61373a39 | 2017-09-26 18:45:35 | [diff] [blame] | 1416 | 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 Baker | ced131a2 | 2019-02-02 01:14:44 | [diff] [blame] | 1459 | // Tests that Layer::SendDamagedRects() always recurses into its mask layer, if |
| 1460 | // present, even if it shouldn't send its damaged regions itself. |
| 1461 | TEST_F(LayerWithNullDelegateTest, AlwaysSendsMaskDamagedRects) { |
| 1462 | gfx::Rect bound(gfx::Rect(2, 2)); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1463 | std::unique_ptr<Layer> mask = CreateTextureLayer(bound); |
| 1464 | std::unique_ptr<Layer> root = CreateTextureRootLayer(bound); |
Collin Baker | ced131a2 | 2019-02-02 01:14:44 | [diff] [blame] | 1465 | 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 Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1478 | // Verifies that when a layer is reflecting other layers, mirror counts of |
| 1479 | // reflected layers are updated properly. |
| 1480 | TEST_F(LayerWithNullDelegateTest, SetShowReflectedLayerSubtree) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1481 | std::unique_ptr<Layer> reflected_layer_1 = CreateLayer(LAYER_SOLID_COLOR); |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1482 | auto* reflected_layer_1_cc = reflected_layer_1->cc_layer_for_testing(); |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1483 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1484 | std::unique_ptr<Layer> reflected_layer_2 = CreateLayer(LAYER_SOLID_COLOR); |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1485 | auto* reflected_layer_2_cc = reflected_layer_2->cc_layer_for_testing(); |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1486 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1487 | std::unique_ptr<Layer> reflecting_layer = CreateLayer(LAYER_SOLID_COLOR); |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1488 | |
| 1489 | // Originally, mirror counts should be zero. |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1490 | 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 Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1494 | |
| 1495 | // Mirror the first layer. Its mirror count should be increased. |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1496 | 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 Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1503 | |
| 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 Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1506 | 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 Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1513 | |
| 1514 | // Un-mirror the layer. All mirror counts should be set to zero. |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1515 | 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 Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1520 | } |
| 1521 | |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1522 | // Verifies that when a layer is reflecting another layer, its size matches the |
| 1523 | // size of the reflected layer. |
| 1524 | TEST_F(LayerWithNullDelegateTest, SetShowReflectedLayerSubtreeBounds) { |
| 1525 | const gfx::Rect reflected_bounds(0, 0, 50, 50); |
| 1526 | const gfx::Rect reflecting_bounds(0, 50, 10, 10); |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1527 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1528 | std::unique_ptr<Layer> reflected_layer = CreateLayer(LAYER_SOLID_COLOR); |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1529 | reflected_layer->SetBounds(reflected_bounds); |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1530 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1531 | std::unique_ptr<Layer> reflecting_layer = CreateLayer(LAYER_SOLID_COLOR); |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1532 | reflecting_layer->SetBounds(reflecting_bounds); |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1533 | |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1534 | EXPECT_EQ(reflecting_bounds, reflecting_layer->bounds()); |
Mohsen Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1535 | |
Mohsen Izadi | 7be85430 | 2019-07-04 23:11:55 | [diff] [blame] | 1536 | 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 Izadi | 49108e1 | 2019-07-05 02:06:27 | [diff] [blame] | 1539 | |
| 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 Xia | 6ff562d | 2019-08-27 15:54:33 | [diff] [blame] | 1544 | |
| 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 Izadi | 1bcbf25 | 2019-06-27 01:26:29 | [diff] [blame] | 1550 | } |
| 1551 | |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1552 | void 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] | afed4064 | 2011-11-03 04:50:01 | [diff] [blame] | 1567 | // Checks that pixels are actually drawn to the screen with a read back. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1568 | TEST_P(LayerWithRealCompositorTest, DrawPixels) { |
[email protected] | d56d3bb | 2013-08-12 20:58:01 | [diff] [blame] | 1569 | 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 Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1578 | 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] | d86e97e | 2011-11-21 15:06:26 | [diff] [blame] | 1582 | |
| 1583 | layer->Add(layer2.get()); |
| 1584 | |
[email protected] | afed4064 | 2011-11-03 04:50:01 | [diff] [blame] | 1585 | DrawTree(layer.get()); |
| 1586 | |
| 1587 | SkBitmap bitmap; |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1588 | ReadPixels(&bitmap, gfx::Rect(viewport_size)); |
[email protected] | e34d7251 | 2011-11-10 18:05:24 | [diff] [blame] | 1589 | ASSERT_FALSE(bitmap.empty()); |
[email protected] | afed4064 | 2011-11-03 04:50:01 | [diff] [blame] | 1590 | |
[email protected] | d56d3bb | 2013-08-12 20:58:01 | [diff] [blame] | 1591 | 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; |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1595 | 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 Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1602 | TEST_P(LayerWithRealCompositorTest, DrawAlphaBlendedPixels) { |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1603 | 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 Clark | 9a8b808 | 2018-04-23 18:29:21 | [diff] [blame] | 1610 | SkColor blue_with_alpha = SkColorSetARGB(40, 10, 20, 200); |
| 1611 | SkColor blend_color = SkColorSetARGB(255, 216, 3, 32); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1612 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1613 | 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)); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1617 | |
| 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; |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1625 | ReadPixels(&bitmap, gfx::Rect(viewport_size)); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1626 | ASSERT_FALSE(bitmap.empty()); |
| 1627 | |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1628 | 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)); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1634 | } |
| 1635 | |
| 1636 | // Checks that using the AlphaShape filter applied to a layer with |
| 1637 | // transparency, alpha-blends properly with the layer below. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1638 | TEST_P(LayerWithRealCompositorTest, DrawAlphaThresholdFilterPixels) { |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1639 | 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 Clark | 9a8b808 | 2018-04-23 18:29:21 | [diff] [blame] | 1646 | SkColor blue_with_alpha = SkColorSetARGB(40, 0, 0, 255); |
| 1647 | SkColor blend_color = SkColorSetARGB(255, 215, 0, 40); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1648 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1649 | 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)); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1653 | |
| 1654 | // Add a shape to restrict the visible part of the layer. |
Jeremy Roman | b460057 | 2017-10-17 01:31:50 | [diff] [blame] | 1655 | auto shape = std::make_unique<Layer::ShapeRects>(); |
Valery Arkhangorodsky | a5d3bb3 | 2017-08-18 15:13:47 | [diff] [blame] | 1656 | shape->emplace_back(0, 0, viewport_size.width(), blue_height); |
| 1657 | foreground_layer->SetAlphaShape(std::move(shape)); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1658 | |
| 1659 | foreground_layer->SetFillsBoundsOpaquely(false); |
| 1660 | |
| 1661 | background_layer->Add(foreground_layer.get()); |
| 1662 | DrawTree(background_layer.get()); |
| 1663 | |
| 1664 | SkBitmap bitmap; |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1665 | ReadPixels(&bitmap, gfx::Rect(viewport_size)); |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1666 | ASSERT_FALSE(bitmap.empty()); |
| 1667 | |
garykac | eba9294 | 2014-09-05 04:26:07 | [diff] [blame] | 1668 | 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] | d56d3bb | 2013-08-12 20:58:01 | [diff] [blame] | 1673 | } |
| 1674 | } |
[email protected] | afed4064 | 2011-11-03 04:50:01 | [diff] [blame] | 1675 | } |
| 1676 | |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1677 | // Checks the logic around Compositor::SetRootLayer and Layer::SetCompositor. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1678 | TEST_P(LayerWithRealCompositorTest, SetRootLayer) { |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1679 | Compositor* compositor = GetCompositor(); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1680 | 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] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1684 | |
[email protected] | 12233c36 | 2011-11-21 16:09:25 | [diff] [blame] | 1685 | EXPECT_EQ(NULL, l1->GetCompositor()); |
| 1686 | EXPECT_EQ(NULL, l2->GetCompositor()); |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1687 | |
[email protected] | 12233c36 | 2011-11-21 16:09:25 | [diff] [blame] | 1688 | compositor->SetRootLayer(l1.get()); |
| 1689 | EXPECT_EQ(compositor, l1->GetCompositor()); |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1690 | |
[email protected] | 12233c36 | 2011-11-21 16:09:25 | [diff] [blame] | 1691 | l1->Add(l2.get()); |
| 1692 | EXPECT_EQ(compositor, l2->GetCompositor()); |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1693 | |
[email protected] | 12233c36 | 2011-11-21 16:09:25 | [diff] [blame] | 1694 | l1->Remove(l2.get()); |
| 1695 | EXPECT_EQ(NULL, l2->GetCompositor()); |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1696 | |
[email protected] | 12233c36 | 2011-11-21 16:09:25 | [diff] [blame] | 1697 | l1->Add(l2.get()); |
| 1698 | EXPECT_EQ(compositor, l2->GetCompositor()); |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1699 | |
| 1700 | compositor->SetRootLayer(NULL); |
[email protected] | 12233c36 | 2011-11-21 16:09:25 | [diff] [blame] | 1701 | EXPECT_EQ(NULL, l1->GetCompositor()); |
| 1702 | EXPECT_EQ(NULL, l2->GetCompositor()); |
[email protected] | 7ab3f27 | 2011-11-16 00:51:56 | [diff] [blame] | 1703 | } |
| 1704 | |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1705 | // 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 Urdaneta | 121a6e2 | 2017-11-17 11:01:08 | [diff] [blame] | 1710 | // Flaky on Windows. See https://crbug.com/784563. |
Jesse Doherty | 591df282 | 2018-04-19 14:27:42 | [diff] [blame] | 1711 | // Flaky on Linux tsan. See https://crbug.com/834026. |
| 1712 | #if defined(OS_WIN) || defined(OS_LINUX) |
Guido Urdaneta | 121a6e2 | 2017-11-17 11:01:08 | [diff] [blame] | 1713 | #define MAYBE_CompositorObservers DISABLED_CompositorObservers |
| 1714 | #else |
| 1715 | #define MAYBE_CompositorObservers CompositorObservers |
| 1716 | #endif |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1717 | TEST_P(LayerWithRealCompositorTest, MAYBE_CompositorObservers) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1718 | 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] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1722 | 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()); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1729 | EXPECT_TRUE(observer.notified()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1730 | |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 1731 | // ScheduleDraw without any visible change should cause a commit. |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1732 | observer.Reset(); |
| 1733 | l1->ScheduleDraw(); |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 1734 | WaitForCommit(); |
| 1735 | EXPECT_TRUE(observer.committed()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1736 | |
| 1737 | // Moving, but not resizing, a layer should alert the observers. |
| 1738 | observer.Reset(); |
| 1739 | l2->SetBounds(gfx::Rect(0, 0, 350, 350)); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1740 | WaitForSwap(); |
| 1741 | EXPECT_TRUE(observer.notified()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1742 | |
| 1743 | // So should resizing a layer. |
| 1744 | observer.Reset(); |
| 1745 | l2->SetBounds(gfx::Rect(0, 0, 400, 400)); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1746 | WaitForSwap(); |
| 1747 | EXPECT_TRUE(observer.notified()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1748 | |
| 1749 | // Opacity changes should alert the observers. |
| 1750 | observer.Reset(); |
| 1751 | l2->SetOpacity(0.5f); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1752 | WaitForSwap(); |
| 1753 | EXPECT_TRUE(observer.notified()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1754 | |
| 1755 | // So should setting the opacity back. |
| 1756 | observer.Reset(); |
| 1757 | l2->SetOpacity(1.0f); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1758 | WaitForSwap(); |
| 1759 | EXPECT_TRUE(observer.notified()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1760 | |
| 1761 | // Setting the transform of a layer should alert the observers. |
| 1762 | observer.Reset(); |
[email protected] | 0f0453e | 2012-10-14 18:15:35 | [diff] [blame] | 1763 | gfx::Transform transform; |
[email protected] | f7c321eb | 2012-11-26 20:13:08 | [diff] [blame] | 1764 | transform.Translate(200.0, 200.0); |
| 1765 | transform.Rotate(90.0); |
| 1766 | transform.Translate(-200.0, -200.0); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1767 | l2->SetTransform(transform); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1768 | WaitForSwap(); |
| 1769 | EXPECT_TRUE(observer.notified()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1770 | |
| 1771 | GetCompositor()->RemoveObserver(&observer); |
| 1772 | |
| 1773 | // Opacity changes should no longer alert the removed observer. |
| 1774 | observer.Reset(); |
| 1775 | l2->SetOpacity(0.5f); |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1776 | WaitForSwap(); |
[email protected] | f7972906 | 2013-04-03 20:01:50 | [diff] [blame] | 1777 | |
staraz | b14cc10cc | 2017-04-13 18:06:39 | [diff] [blame] | 1778 | EXPECT_FALSE(observer.notified()); |
[email protected] | 05fab8d | 2011-11-16 02:15:33 | [diff] [blame] | 1779 | } |
| 1780 | |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1781 | // Checks that modifying the hierarchy correctly affects final composite. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1782 | TEST_P(LayerWithRealCompositorTest, ModifyHierarchy) { |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 1783 | viz::ParentLocalSurfaceIdAllocator allocator; |
| 1784 | allocator.GenerateId(); |
| 1785 | GetCompositor()->SetScaleAndSize( |
| 1786 | 1.0f, gfx::Size(50, 50), allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1787 | |
| 1788 | // l0 |
| 1789 | // +-l11 |
| 1790 | // | +-l21 |
| 1791 | // +-l12 |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1792 | 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] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1800 | |
Peter Kasting | ee674947 | 2018-11-20 05:13:25 | [diff] [blame] | 1801 | base::FilePath ref_img1 = test_data_dir().AppendASCII("ModifyHierarchy1.png"); |
| 1802 | base::FilePath ref_img2 = test_data_dir().AppendASCII("ModifyHierarchy2.png"); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1803 | SkBitmap bitmap; |
| 1804 | |
| 1805 | l0->Add(l11.get()); |
| 1806 | l11->Add(l21.get()); |
| 1807 | l0->Add(l12.get()); |
| 1808 | DrawTree(l0.get()); |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1809 | ReadPixels(&bitmap); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1810 | ASSERT_FALSE(bitmap.empty()); |
| 1811 | // WritePNGFile(bitmap, ref_img1); |
[email protected] | ca43568 | 2013-03-29 04:09:47 | [diff] [blame] | 1812 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1813 | |
[email protected] | 5e4e61f | 2011-11-22 16:55:24 | [diff] [blame] | 1814 | l0->StackAtTop(l11.get()); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1815 | DrawTree(l0.get()); |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1816 | ReadPixels(&bitmap); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1817 | ASSERT_FALSE(bitmap.empty()); |
| 1818 | // WritePNGFile(bitmap, ref_img2); |
[email protected] | ca43568 | 2013-03-29 04:09:47 | [diff] [blame] | 1819 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1820 | |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 1821 | // should restore to original configuration |
| 1822 | l0->StackAbove(l12.get(), l11.get()); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1823 | DrawTree(l0.get()); |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1824 | ReadPixels(&bitmap); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1825 | ASSERT_FALSE(bitmap.empty()); |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 1826 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1827 | |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 1828 | // l11 back to front |
| 1829 | l0->StackAtTop(l11.get()); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1830 | DrawTree(l0.get()); |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1831 | ReadPixels(&bitmap); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1832 | ASSERT_FALSE(bitmap.empty()); |
[email protected] | ca43568 | 2013-03-29 04:09:47 | [diff] [blame] | 1833 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1834 | |
| 1835 | // should restore to original configuration |
[email protected] | 5e4e61f | 2011-11-22 16:55:24 | [diff] [blame] | 1836 | l0->StackAbove(l12.get(), l11.get()); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1837 | DrawTree(l0.get()); |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1838 | ReadPixels(&bitmap); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1839 | ASSERT_FALSE(bitmap.empty()); |
[email protected] | ca43568 | 2013-03-29 04:09:47 | [diff] [blame] | 1840 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, cc::ExactPixelComparator(true))); |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 1841 | |
| 1842 | // l11 back to front |
| 1843 | l0->StackAbove(l11.get(), l12.get()); |
| 1844 | DrawTree(l0.get()); |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1845 | ReadPixels(&bitmap); |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 1846 | ASSERT_FALSE(bitmap.empty()); |
| 1847 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, cc::ExactPixelComparator(true))); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1848 | } |
| 1849 | |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1850 | // Checks that basic background blur is working. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1851 | TEST_P(LayerWithRealCompositorTest, BackgroundBlur) { |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 1852 | viz::ParentLocalSurfaceIdAllocator allocator; |
| 1853 | allocator.GenerateId(); |
| 1854 | GetCompositor()->SetScaleAndSize( |
| 1855 | 1.0f, gfx::Size(200, 200), |
| 1856 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1857 | // l0 |
| 1858 | // +-l1 |
| 1859 | // +-l2 |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1860 | 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 Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1864 | SkColor blue_with_alpha = SkColorSetARGB(40, 10, 20, 200); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1865 | std::unique_ptr<Layer> l2 = |
| 1866 | CreateColorLayer(blue_with_alpha, gfx::Rect(50, 50, 100, 100)); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1867 | 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 Freed | 16f5c5ac | 2019-06-13 18:00:01 | [diff] [blame] | 1874 | // 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 Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1877 | 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 Freed | 16f5c5ac | 2019-06-13 18:00:01 | [diff] [blame] | 1883 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, fuzzy_comparator)); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1884 | |
| 1885 | l0->StackAtTop(l1.get()); |
| 1886 | DrawTree(l0.get()); |
| 1887 | ReadPixels(&bitmap); |
| 1888 | ASSERT_FALSE(bitmap.empty()); |
| 1889 | // WritePNGFile(bitmap, ref_img2, false); |
Mason Freed | 16f5c5ac | 2019-06-13 18:00:01 | [diff] [blame] | 1890 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, fuzzy_comparator)); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1891 | } |
| 1892 | |
| 1893 | // Checks that background blur bounds rect gets properly updated when device |
| 1894 | // scale changes. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1895 | TEST_P(LayerWithRealCompositorTest, BackgroundBlurChangeDeviceScale) { |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 1896 | viz::ParentLocalSurfaceIdAllocator allocator; |
| 1897 | allocator.GenerateId(); |
| 1898 | GetCompositor()->SetScaleAndSize( |
| 1899 | 1.0f, gfx::Size(200, 200), |
| 1900 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1901 | // l0 |
| 1902 | // +-l1 |
| 1903 | // +-l2 |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1904 | 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 Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1908 | SkColor blue_with_alpha = SkColorSetARGB(40, 10, 20, 200); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1909 | std::unique_ptr<Layer> l2 = |
| 1910 | CreateColorLayer(blue_with_alpha, gfx::Rect(50, 50, 100, 100)); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1911 | 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 Freed | 16f5c5ac | 2019-06-13 18:00:01 | [diff] [blame] | 1919 | // 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 Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1922 | 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 Freed | 16f5c5ac | 2019-06-13 18:00:01 | [diff] [blame] | 1929 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img1, fuzzy_comparator)); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1930 | |
jonross | 9746a21 | 2019-01-18 19:08:41 | [diff] [blame] | 1931 | allocator.GenerateId(); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1932 | // Now change the scale, and make sure the bounds are still correct. |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 1933 | GetCompositor()->SetScaleAndSize( |
| 1934 | 2.0f, gfx::Size(200, 200), |
| 1935 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1936 | DrawTree(l0.get()); |
| 1937 | ReadPixels(&bitmap); |
| 1938 | ASSERT_FALSE(bitmap.empty()); |
| 1939 | // WritePNGFile(bitmap, ref_img2, false); |
Mason Freed | 16f5c5ac | 2019-06-13 18:00:01 | [diff] [blame] | 1940 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img2, fuzzy_comparator)); |
Mason Freed | 7302ffc | 2018-12-20 22:35:18 | [diff] [blame] | 1941 | } |
| 1942 | |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1943 | // Opacity is rendered correctly. |
| 1944 | // Checks that modifying the hierarchy correctly affects final composite. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 1945 | TEST_P(LayerWithRealCompositorTest, Opacity) { |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 1946 | viz::ParentLocalSurfaceIdAllocator allocator; |
| 1947 | allocator.GenerateId(); |
| 1948 | GetCompositor()->SetScaleAndSize( |
| 1949 | 1.0f, gfx::Size(50, 50), allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1950 | |
| 1951 | // l0 |
| 1952 | // +-l11 |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 1953 | 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] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1957 | |
Peter Kasting | ee674947 | 2018-11-20 05:13:25 | [diff] [blame] | 1958 | base::FilePath ref_img = test_data_dir().AppendASCII("Opacity.png"); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1959 | |
| 1960 | l11->SetOpacity(0.75); |
| 1961 | l0->Add(l11.get()); |
| 1962 | DrawTree(l0.get()); |
| 1963 | SkBitmap bitmap; |
weiliangc | cb9e0df | 2014-09-22 14:55:21 | [diff] [blame] | 1964 | ReadPixels(&bitmap); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1965 | ASSERT_FALSE(bitmap.empty()); |
| 1966 | // WritePNGFile(bitmap, ref_img); |
[email protected] | ca43568 | 2013-03-29 04:09:47 | [diff] [blame] | 1967 | EXPECT_TRUE(MatchesPNGFile(bitmap, ref_img, cc::ExactPixelComparator(true))); |
[email protected] | fcb98b7 | 2011-11-18 04:29:18 | [diff] [blame] | 1968 | } |
| 1969 | |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 1970 | namespace { |
| 1971 | |
| 1972 | class SchedulePaintLayerDelegate : public LayerDelegate { |
| 1973 | public: |
| 1974 | SchedulePaintLayerDelegate() : paint_count_(0), layer_(NULL) {} |
| 1975 | |
dcheng | bc07fa0 | 2014-10-29 20:07:24 | [diff] [blame] | 1976 | ~SchedulePaintLayerDelegate() override {} |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 1977 | |
| 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 | |
danakj | c732322 | 2015-04-07 21:09:38 | [diff] [blame] | 1993 | const gfx::Rect& last_clip_rect() const { return last_clip_rect_; } |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 1994 | |
| 1995 | private: |
| 1996 | // Overridden from LayerDelegate: |
danakj | 85d970e | 2015-04-04 00:15:24 | [diff] [blame] | 1997 | void OnPaintLayer(const ui::PaintContext& context) override { |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 1998 | paint_count_++; |
| 1999 | if (!schedule_paint_rect_.IsEmpty()) { |
| 2000 | layer_->SchedulePaint(schedule_paint_rect_); |
| 2001 | schedule_paint_rect_ = gfx::Rect(); |
| 2002 | } |
danakj | c732322 | 2015-04-07 21:09:38 | [diff] [blame] | 2003 | last_clip_rect_ = context.InvalidationForTesting(); |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2004 | } |
| 2005 | |
Scott Violet | 06aff2b4 | 2017-09-08 00:26:32 | [diff] [blame] | 2006 | void OnDeviceScaleFactorChanged(float old_device_scale_factor, |
| 2007 | float new_device_scale_factor) override {} |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2008 | |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2009 | int paint_count_; |
| 2010 | Layer* layer_; |
| 2011 | gfx::Rect schedule_paint_rect_; |
danakj | c732322 | 2015-04-07 21:09:38 | [diff] [blame] | 2012 | gfx::Rect last_clip_rect_; |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2013 | |
| 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. |
| 2021 | TEST_F(LayerWithDelegateTest, SchedulePaintFromOnPaintLayer) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2022 | std::unique_ptr<Layer> root = |
| 2023 | CreateColorLayer(SK_ColorRED, gfx::Rect(0, 0, 500, 500)); |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2024 | SchedulePaintLayerDelegate child_delegate; |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2025 | std::unique_ptr<Layer> child = |
| 2026 | CreateColorLayer(SK_ColorBLUE, gfx::Rect(0, 0, 200, 200)); |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2027 | child_delegate.set_layer(child.get()); |
| 2028 | |
| 2029 | root->Add(child.get()); |
| 2030 | |
| 2031 | SchedulePaintForLayer(root.get()); |
| 2032 | DrawTree(root.get()); |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2033 | child->SchedulePaint(gfx::Rect(0, 0, 20, 20)); |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 2034 | EXPECT_EQ(1, child_delegate.GetPaintCountAndClear()); |
[email protected] | 44ed4bd | 2013-04-06 00:11:27 | [diff] [blame] | 2035 | |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2036 | // 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] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 2039 | WaitForCommit(); |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2040 | EXPECT_EQ(1, child_delegate.GetPaintCountAndClear()); |
[email protected] | 44ed4bd | 2013-04-06 00:11:27 | [diff] [blame] | 2041 | |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2042 | // Because SchedulePaint() was invoked from OnPaintLayer() |child| should |
| 2043 | // still need to be painted. |
[email protected] | 36e5ff1 | 2013-06-11 12:19:29 | [diff] [blame] | 2044 | WaitForCommit(); |
[email protected] | caa1aafd | 2012-01-12 21:56:06 | [diff] [blame] | 2045 | 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 Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2050 | TEST_P(LayerWithRealCompositorTest, ScaleUpDown) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2051 | std::unique_ptr<Layer> root = |
| 2052 | CreateColorLayer(SK_ColorWHITE, gfx::Rect(10, 20, 200, 220)); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2053 | TestLayerDelegate root_delegate; |
| 2054 | root_delegate.AddColor(SK_ColorWHITE); |
| 2055 | root->set_delegate(&root_delegate); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 2056 | root_delegate.set_layer_bounds(root->bounds()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2057 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2058 | std::unique_ptr<Layer> l1 = |
| 2059 | CreateColorLayer(SK_ColorWHITE, gfx::Rect(10, 20, 140, 180)); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2060 | TestLayerDelegate l1_delegate; |
| 2061 | l1_delegate.AddColor(SK_ColorWHITE); |
| 2062 | l1->set_delegate(&l1_delegate); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 2063 | l1_delegate.set_layer_bounds(l1->bounds()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2064 | |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2065 | viz::ParentLocalSurfaceIdAllocator allocator; |
| 2066 | allocator.GenerateId(); |
| 2067 | GetCompositor()->SetScaleAndSize( |
| 2068 | 1.0f, gfx::Size(500, 500), |
| 2069 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2070 | GetCompositor()->SetRootLayer(root.get()); |
| 2071 | root->Add(l1.get()); |
[email protected] | 260c321 | 2013-04-11 22:25:38 | [diff] [blame] | 2072 | WaitForDraw(); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2073 | |
| 2074 | EXPECT_EQ("10,20 200x220", root->bounds().ToString()); |
| 2075 | EXPECT_EQ("10,20 140x180", l1->bounds().ToString()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2076 | gfx::Size cc_bounds_size = root->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2077 | EXPECT_EQ("200x220", cc_bounds_size.ToString()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2078 | cc_bounds_size = l1->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2079 | EXPECT_EQ("140x180", cc_bounds_size.ToString()); |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2080 | // 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] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2083 | |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2084 | // Scale up to 2.0. Changing scale doesn't change the bounds in DIP. |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2085 | allocator.GenerateId(); |
| 2086 | GetCompositor()->SetScaleAndSize( |
| 2087 | 2.0f, gfx::Size(500, 500), |
| 2088 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2089 | EXPECT_EQ("10,20 200x220", root->bounds().ToString()); |
| 2090 | EXPECT_EQ("10,20 140x180", l1->bounds().ToString()); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2091 | // CC layer should still match the UI layer bounds. |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2092 | cc_bounds_size = root->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2093 | EXPECT_EQ("200x220", cc_bounds_size.ToString()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2094 | cc_bounds_size = l1->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2095 | EXPECT_EQ("140x180", cc_bounds_size.ToString()); |
weiliangc | d048acf | 2015-03-10 19:00:07 | [diff] [blame] | 2096 | // New scale factor must have been notified. Make sure painting happens at |
| 2097 | // right scale. |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2098 | EXPECT_EQ(2.0f, root_delegate.device_scale_factor()); |
| 2099 | EXPECT_EQ(2.0f, l1_delegate.device_scale_factor()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2100 | |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2101 | // Scale down back to 1.0f. |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2102 | allocator.GenerateId(); |
| 2103 | GetCompositor()->SetScaleAndSize( |
| 2104 | 1.0f, gfx::Size(500, 500), |
| 2105 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2106 | EXPECT_EQ("10,20 200x220", root->bounds().ToString()); |
| 2107 | EXPECT_EQ("10,20 140x180", l1->bounds().ToString()); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2108 | // CC layer should still match the UI layer bounds. |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2109 | cc_bounds_size = root->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2110 | EXPECT_EQ("200x220", cc_bounds_size.ToString()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2111 | cc_bounds_size = l1->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2112 | EXPECT_EQ("140x180", cc_bounds_size.ToString()); |
weiliangc | d048acf | 2015-03-10 19:00:07 | [diff] [blame] | 2113 | // New scale factor must have been notified. Make sure painting happens at |
| 2114 | // right scale. |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2115 | EXPECT_EQ(1.0f, root_delegate.device_scale_factor()); |
| 2116 | EXPECT_EQ(1.0f, l1_delegate.device_scale_factor()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2117 | |
[email protected] | 07908eb | 2012-05-09 00:15:30 | [diff] [blame] | 2118 | root_delegate.reset(); |
| 2119 | l1_delegate.reset(); |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2120 | // Just changing the size shouldn't notify the scale change nor |
| 2121 | // trigger repaint. |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2122 | allocator.GenerateId(); |
| 2123 | GetCompositor()->SetScaleAndSize( |
| 2124 | 1.0f, gfx::Size(1000, 1000), |
| 2125 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2126 | // 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] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2129 | } |
| 2130 | |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2131 | TEST_P(LayerWithRealCompositorTest, ScaleReparent) { |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2132 | viz::ParentLocalSurfaceIdAllocator allocator; |
| 2133 | allocator.GenerateId(); |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2134 | 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] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2138 | TestLayerDelegate l1_delegate; |
| 2139 | l1_delegate.AddColor(SK_ColorWHITE); |
| 2140 | l1->set_delegate(&l1_delegate); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 2141 | l1_delegate.set_layer_bounds(l1->bounds()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2142 | |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2143 | GetCompositor()->SetScaleAndSize( |
| 2144 | 1.0f, gfx::Size(500, 500), |
| 2145 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2146 | GetCompositor()->SetRootLayer(root.get()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2147 | |
| 2148 | root->Add(l1.get()); |
| 2149 | EXPECT_EQ("10,20 140x180", l1->bounds().ToString()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2150 | gfx::Size cc_bounds_size = l1->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2151 | EXPECT_EQ("140x180", cc_bounds_size.ToString()); |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2152 | EXPECT_EQ(0.0f, l1_delegate.device_scale_factor()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2153 | |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2154 | // 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 Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2158 | allocator.GenerateId(); |
| 2159 | GetCompositor()->SetScaleAndSize( |
| 2160 | 2.0f, gfx::Size(500, 500), |
| 2161 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2162 | // Sanity check on root and l1. |
| 2163 | EXPECT_EQ("10,20 200x220", root->bounds().ToString()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2164 | cc_bounds_size = l1->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2165 | EXPECT_EQ("140x180", cc_bounds_size.ToString()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2166 | |
| 2167 | root->Add(l1.get()); |
| 2168 | EXPECT_EQ("10,20 140x180", l1->bounds().ToString()); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2169 | cc_bounds_size = l1->cc_layer_for_testing()->bounds(); |
[email protected] | caa2166 | 2014-05-14 10:02:32 | [diff] [blame] | 2170 | EXPECT_EQ("140x180", cc_bounds_size.ToString()); |
[email protected] | d3f5bbc1 | 2012-05-17 00:09:04 | [diff] [blame] | 2171 | EXPECT_EQ(2.0f, l1_delegate.device_scale_factor()); |
[email protected] | cd9a61c7 | 2012-05-08 19:16:59 | [diff] [blame] | 2172 | } |
| 2173 | |
[email protected] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2174 | // 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. |
| 2178 | TEST_F(LayerWithDelegateTest, SetBoundsWhenInvisible) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2179 | std::unique_ptr<Layer> root = |
| 2180 | CreateNoTextureLayer(gfx::Rect(0, 0, 1000, 1000)); |
[email protected] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2181 | |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2182 | std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED); |
[email protected] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2183 | child->SetBounds(gfx::Rect(0, 0, 500, 500)); |
weiliangc | a032f93b | 2015-07-13 22:39:47 | [diff] [blame] | 2184 | DrawTreeLayerDelegate delegate(child->bounds()); |
[email protected] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2185 | 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] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2195 | delegate.Reset(); |
| 2196 | |
| 2197 | // Move layer. |
| 2198 | child->SetBounds(gfx::Rect(200, 200, 500, 500)); |
| 2199 | child->SetVisible(true); |
[email protected] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2200 | DrawTree(root.get()); |
| 2201 | EXPECT_FALSE(delegate.painted()); |
| 2202 | |
| 2203 | // Reset into invisible state. |
| 2204 | child->SetVisible(false); |
| 2205 | DrawTree(root.get()); |
[email protected] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2206 | delegate.Reset(); |
| 2207 | |
| 2208 | // Resize layer. |
| 2209 | child->SetBounds(gfx::Rect(200, 200, 400, 400)); |
| 2210 | child->SetVisible(true); |
[email protected] | 28c21938 | 2012-05-11 09:05:31 | [diff] [blame] | 2211 | DrawTree(root.get()); |
| 2212 | EXPECT_TRUE(delegate.painted()); |
| 2213 | } |
| 2214 | |
[email protected] | 785b0af | 2013-10-02 18:08:41 | [diff] [blame] | 2215 | TEST_F(LayerWithDelegateTest, ExternalContent) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2216 | 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] | 785b0af | 2013-10-02 18:08:41 | [diff] [blame] | 2219 | |
| 2220 | child->SetBounds(gfx::Rect(0, 0, 10, 10)); |
| 2221 | child->SetVisible(true); |
| 2222 | root->Add(child.get()); |
| 2223 | |
jbauman | f472c687 | 2014-10-13 20:06:43 | [diff] [blame] | 2224 | // The layer is already showing solid color content, so the cc layer won't |
| 2225 | // change. |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2226 | scoped_refptr<cc::Layer> before = child->cc_layer_for_testing(); |
Fady Samuel | b46e0ef | 2018-01-30 04:48:41 | [diff] [blame] | 2227 | |
jbauman | f472c687 | 2014-10-13 20:06:43 | [diff] [blame] | 2228 | child->SetShowSolidColorContent(); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2229 | EXPECT_TRUE(child->cc_layer_for_testing()); |
| 2230 | EXPECT_EQ(before.get(), child->cc_layer_for_testing()); |
[email protected] | 785b0af | 2013-10-02 18:08:41 | [diff] [blame] | 2231 | |
jbauman | 957acd5 | 2016-02-05 23:13:31 | [diff] [blame] | 2232 | // Showing surface content changes the underlying cc layer. |
Fady Samuel | 6ca6728 | 2018-06-21 23:00:41 | [diff] [blame] | 2233 | viz::FrameSinkId frame_sink_id(1u, 1u); |
| 2234 | viz::ParentLocalSurfaceIdAllocator allocator; |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2235 | before = child->cc_layer_for_testing(); |
Jonathan Ross | 89807fc | 2018-10-30 17:41:21 | [diff] [blame] | 2236 | allocator.GenerateId(); |
| 2237 | child->SetShowSurface( |
jonross | 58cab43 | 2018-11-29 02:30:30 | [diff] [blame] | 2238 | viz::SurfaceId( |
| 2239 | frame_sink_id, |
| 2240 | allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id()), |
Jonathan Ross | 89807fc | 2018-10-30 17:41:21 | [diff] [blame] | 2241 | gfx::Size(10, 10), SK_ColorWHITE, |
| 2242 | cc::DeadlinePolicy::UseDefaultDeadline(), false); |
Fady Samuel | b46e0ef | 2018-01-30 04:48:41 | [diff] [blame] | 2243 | 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 Ross | 89807fc | 2018-10-30 17:41:21 | [diff] [blame] | 2249 | allocator.GenerateId(); |
| 2250 | child->SetShowSurface( |
jonross | 58cab43 | 2018-11-29 02:30:30 | [diff] [blame] | 2251 | viz::SurfaceId( |
| 2252 | frame_sink_id, |
| 2253 | allocator.GetCurrentLocalSurfaceIdAllocation().local_surface_id()), |
Jonathan Ross | 89807fc | 2018-10-30 17:41:21 | [diff] [blame] | 2254 | gfx::Size(10, 10), SK_ColorWHITE, |
| 2255 | cc::DeadlinePolicy::UseSpecifiedDeadline(4u), false); |
Fady Samuel | b46e0ef | 2018-01-30 04:48:41 | [diff] [blame] | 2256 | EXPECT_EQ(4u, surface->deadline_in_frames()); |
[email protected] | 785b0af | 2013-10-02 18:08:41 | [diff] [blame] | 2257 | } |
| 2258 | |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 2259 | TEST_F(LayerWithDelegateTest, ExternalContentMirroring) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2260 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 2261 | |
Fady Samuel | d5c2618 | 2017-07-12 02:43:33 | [diff] [blame] | 2262 | viz::SurfaceId surface_id( |
| 2263 | viz::FrameSinkId(0, 1), |
| 2264 | viz::LocalSurfaceId(2, base::UnguessableToken::Create())); |
Saman Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 2265 | layer->SetShowSurface(surface_id, gfx::Size(10, 10), SK_ColorWHITE, |
| 2266 | cc::DeadlinePolicy::UseDefaultDeadline(), false); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 2267 | |
| 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 Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 2273 | EXPECT_EQ(surface_id, surface->surface_id()); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 2274 | |
staraz | 7d7f6eb | 2016-11-11 00:19:17 | [diff] [blame] | 2275 | surface_id = |
Fady Samuel | d5c2618 | 2017-07-12 02:43:33 | [diff] [blame] | 2276 | viz::SurfaceId(viz::FrameSinkId(1, 2), |
| 2277 | viz::LocalSurfaceId(3, base::UnguessableToken::Create())); |
Saman Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 2278 | layer->SetShowSurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE, |
| 2279 | cc::DeadlinePolicy::UseDefaultDeadline(), false); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 2280 | |
fsamuel | 3f0eb02 | 2017-02-28 19:52:16 | [diff] [blame] | 2281 | // The mirror should continue to use the same cc_layer. |
| 2282 | EXPECT_EQ(cc_layer, mirror->cc_layer_for_testing()); |
Saman Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 2283 | layer->SetShowSurface(surface_id, gfx::Size(20, 20), SK_ColorWHITE, |
| 2284 | cc::DeadlinePolicy::UseDefaultDeadline(), false); |
domlaskowski | 4b33bfe | 2016-10-27 00:34:22 | [diff] [blame] | 2285 | |
| 2286 | // Surface updates propagate to the mirror. |
Saman Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 2287 | EXPECT_EQ(surface_id, surface->surface_id()); |
samans | 47fb891 | 2016-12-14 22:24:46 | [diff] [blame] | 2288 | } |
| 2289 | |
Malay Keshav | 87c42c0 | 2019-01-15 08:37:47 | [diff] [blame] | 2290 | TEST_F(LayerWithDelegateTest, TransferableResourceMirroring) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2291 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_SOLID_COLOR); |
Malay Keshav | 87c42c0 | 2019-01-15 08:37:47 | [diff] [blame] | 2292 | |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 2293 | constexpr gfx::Size size(64, 64); |
Malay Keshav | 87c42c0 | 2019-01-15 08:37:47 | [diff] [blame] | 2294 | auto resource = viz::TransferableResource::MakeGL( |
Saman Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 2295 | gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(), |
| 2296 | size, false /* is_overlay_candidate */); |
Malay Keshav | 87c42c0 | 2019-01-15 08:37:47 | [diff] [blame] | 2297 | 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 Sami | 51c0a3e | 2019-05-02 13:43:38 | [diff] [blame] | 2326 | gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, gpu::SyncToken(), |
| 2327 | size, false /* is_overlay_candidate */); |
Malay Keshav | 87c42c0 | 2019-01-15 08:37:47 | [diff] [blame] | 2328 | 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 | |
kirr | 783d4411 | 2014-10-06 17:17:12 | [diff] [blame] | 2344 | // Verifies that layer filters still attached after changing implementation |
| 2345 | // layer. |
| 2346 | TEST_F(LayerWithDelegateTest, LayerFiltersSurvival) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2347 | std::unique_ptr<Layer> layer = CreateLayer(LAYER_TEXTURED); |
kirr | 783d4411 | 2014-10-06 17:17:12 | [diff] [blame] | 2348 | layer->SetBounds(gfx::Rect(0, 0, 10, 10)); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2349 | EXPECT_TRUE(layer->cc_layer_for_testing()); |
| 2350 | EXPECT_EQ(0u, layer->cc_layer_for_testing()->filters().size()); |
kirr | 783d4411 | 2014-10-06 17:17:12 | [diff] [blame] | 2351 | |
| 2352 | layer->SetLayerGrayscale(0.5f); |
| 2353 | EXPECT_EQ(layer->layer_grayscale(), 0.5f); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2354 | EXPECT_EQ(1u, layer->cc_layer_for_testing()->filters().size()); |
kirr | 783d4411 | 2014-10-06 17:17:12 | [diff] [blame] | 2355 | |
jbauman | 957acd5 | 2016-02-05 23:13:31 | [diff] [blame] | 2356 | // Showing surface content changes the underlying cc layer. |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2357 | scoped_refptr<cc::Layer> before = layer->cc_layer_for_testing(); |
Saman Sami | 98c52405 | 2018-10-26 17:34:57 | [diff] [blame] | 2358 | layer->SetShowSurface(viz::SurfaceId(), gfx::Size(10, 10), SK_ColorWHITE, |
| 2359 | cc::DeadlinePolicy::UseDefaultDeadline(), false); |
kirr | 783d4411 | 2014-10-06 17:17:12 | [diff] [blame] | 2360 | EXPECT_EQ(layer->layer_grayscale(), 0.5f); |
loyso | ac00846 | 2015-05-27 01:05:50 | [diff] [blame] | 2361 | 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()); |
kirr | 783d4411 | 2014-10-06 17:17:12 | [diff] [blame] | 2364 | } |
| 2365 | |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2366 | // Tests Layer::AddThreadedAnimation and Layer::RemoveThreadedAnimation. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2367 | TEST_P(LayerWithRealCompositorTest, AddRemoveThreadedAnimations) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2368 | 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] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2371 | |
| 2372 | l1->SetAnimator(LayerAnimator::CreateImplicitAnimator()); |
| 2373 | l2->SetAnimator(LayerAnimator::CreateImplicitAnimator()); |
| 2374 | |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2375 | auto* animation1 = l1->GetAnimator()->GetAnimationForTesting(); |
| 2376 | auto* animation2 = l2->GetAnimator()->GetAnimationForTesting(); |
loyso | db00688 | 2016-09-14 00:31:51 | [diff] [blame] | 2377 | |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2378 | EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2379 | |
| 2380 | // Trigger a threaded animation. |
| 2381 | l1->SetOpacity(0.5f); |
| 2382 | |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2383 | EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2384 | |
| 2385 | // Ensure we can remove a pending threaded animation. |
| 2386 | l1->GetAnimator()->StopAnimating(); |
| 2387 | |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2388 | EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2389 | |
| 2390 | // Trigger another threaded animation. |
| 2391 | l1->SetOpacity(0.2f); |
| 2392 | |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2393 | EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2394 | |
| 2395 | root->Add(l1.get()); |
| 2396 | GetCompositor()->SetRootLayer(root.get()); |
| 2397 | |
loyso | db00688 | 2016-09-14 00:31:51 | [diff] [blame] | 2398 | // Now l1 is part of a tree. |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2399 | EXPECT_TRUE(animation1->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2400 | |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2401 | l1->SetOpacity(0.1f); |
loyso | db00688 | 2016-09-14 00:31:51 | [diff] [blame] | 2402 | // IMMEDIATELY_SET_NEW_TARGET is a default preemption strategy for conflicting |
| 2403 | // animations. |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2404 | EXPECT_FALSE(animation1->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2405 | |
loyso | db00688 | 2016-09-14 00:31:51 | [diff] [blame] | 2406 | // Adding a layer to an existing tree. |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2407 | l2->SetOpacity(0.5f); |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2408 | EXPECT_TRUE(animation2->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2409 | |
| 2410 | l1->Add(l2.get()); |
Yi Gu | aa830ff | 2018-02-22 03:09:11 | [diff] [blame] | 2411 | EXPECT_TRUE(animation2->keyframe_effect()->has_any_keyframe_model()); |
[email protected] | f289146 | 2013-03-11 23:26:51 | [diff] [blame] | 2412 | } |
| 2413 | |
[email protected] | ffd1ccb | 2013-03-15 07:48:24 | [diff] [blame] | 2414 | // Tests that in-progress threaded animations complete when a Layer's |
| 2415 | // cc::Layer changes. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2416 | TEST_P(LayerWithRealCompositorTest, SwitchCCLayerAnimations) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2417 | std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED); |
| 2418 | std::unique_ptr<Layer> l1 = CreateLayer(LAYER_TEXTURED); |
[email protected] | ffd1ccb | 2013-03-15 07:48:24 | [diff] [blame] | 2419 | 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 | |
jonross | 31048b6 | 2015-05-20 02:09:25 | [diff] [blame] | 2436 | // Tests that when a LAYER_SOLID_COLOR has its CC layer switched, that |
| 2437 | // opaqueness and color set while not animating, are maintained. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2438 | TEST_P(LayerWithRealCompositorTest, SwitchCCLayerSolidColorNotAnimating) { |
jonross | 31048b6 | 2015-05-20 02:09:25 | [diff] [blame] | 2439 | SkColor transparent = SK_ColorTRANSPARENT; |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2440 | std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR); |
jonross | 31048b6 | 2015-05-20 02:09:25 | [diff] [blame] | 2441 | 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 Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2464 | TEST_P(LayerWithRealCompositorTest, SwitchCCLayerSolidColorWhileAnimating) { |
jonross | 31048b6 | 2015-05-20 02:09:25 | [diff] [blame] | 2465 | SkColor transparent = SK_ColorTRANSPARENT; |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2466 | std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR); |
jonross | 31048b6 | 2015-05-20 02:09:25 | [diff] [blame] | 2467 | 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 Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2473 | auto long_duration_animation = |
| 2474 | std::make_unique<ui::ScopedAnimationDurationScaleMode>( |
| 2475 | ui::ScopedAnimationDurationScaleMode::SLOW_DURATION); |
jonross | 31048b6 | 2015-05-20 02:09:25 | [diff] [blame] | 2476 | { |
| 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 | |
wutao | 3685073 | 2017-07-29 20:24:07 | [diff] [blame] | 2507 | // 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 Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2509 | TEST_P(LayerWithRealCompositorTest, SwitchCCLayerCacheRenderSurface) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2510 | std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED); |
| 2511 | std::unique_ptr<Layer> l1 = CreateLayer(LAYER_TEXTURED); |
wutao | 3685073 | 2017-07-29 20:24:07 | [diff] [blame] | 2512 | GetCompositor()->SetRootLayer(root.get()); |
| 2513 | root->Add(l1.get()); |
| 2514 | |
wutao | 52217d1 | 2017-08-18 02:40:31 | [diff] [blame] | 2515 | l1->AddCacheRenderSurfaceRequest(); |
wutao | 3685073 | 2017-07-29 20:24:07 | [diff] [blame] | 2516 | |
| 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 | |
wutao | 1d35eeb7 | 2017-10-12 23:01:24 | [diff] [blame] | 2524 | // Tests that when a layer with trilinear_filtering flag has its CC layer |
| 2525 | // switched, that the trilinear_filtering flag is maintained. |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2526 | TEST_P(LayerWithRealCompositorTest, SwitchCCLayerTrilinearFiltering) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2527 | std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED); |
| 2528 | std::unique_ptr<Layer> l1 = CreateLayer(LAYER_TEXTURED); |
wutao | 1d35eeb7 | 2017-10-12 23:01:24 | [diff] [blame] | 2529 | 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 Izadi | b22195c7 | 2019-07-30 02:21:15 | [diff] [blame] | 2541 | // Tests that when a layer with masks_to_bounds flag has its CC layer switched, |
| 2542 | // that the masks_to_bounds flag is maintained. |
| 2543 | TEST_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 Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2559 | // Triggerring a OnDeviceScaleFactorChanged while a layer is undergoing |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2560 | // 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. |
| 2563 | TEST_P(LayerWithRealCompositorTest, TreeMutationDuringScaleFactorChange) { |
| 2564 | TestCallbackAnimationObserver animation_observer; |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2565 | |
| 2566 | std::unique_ptr<Layer> root = CreateLayer(LAYER_SOLID_COLOR); |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2567 | GetCompositor()->SetRootLayer(root.get()); |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2568 | |
| 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 Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2576 | |
| 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 Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2595 | // |layer_to_delete| should be gone. |
| 2596 | EXPECT_FALSE(layer_to_delete); |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2597 | |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2598 | layer_to_delete = CreateLayer(LAYER_SOLID_COLOR); |
| 2599 | animation_observer.SetCallback( |
| 2600 | base::BindLambdaForTesting([&]() { layer_to_delete.reset(); })); |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2601 | |
| 2602 | std::unique_ptr<Layer> child = CreateLayer(LAYER_SOLID_COLOR); |
| 2603 | |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2604 | root->Add(layer_to_delete.get()); |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2605 | 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 Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2619 | // |layer_to_delete| should be gone. |
| 2620 | EXPECT_FALSE(layer_to_delete); |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2621 | |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2622 | layer_to_delete = CreateLayer(LAYER_SOLID_COLOR); |
| 2623 | animation_observer.SetCallback( |
| 2624 | base::BindLambdaForTesting([&]() { layer_to_delete.reset(); })); |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2625 | |
| 2626 | std::unique_ptr<Layer> child2 = CreateLayer(LAYER_SOLID_COLOR); |
| 2627 | |
Xiyuan Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2628 | root->Add(layer_to_delete.get()); |
Malay Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2629 | 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 Xia | d2bcb935 | 2020-01-10 23:02:59 | [diff] [blame] | 2644 | // |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 Keshav | 65840f0e | 2019-08-20 00:38:50 | [diff] [blame] | 2667 | } |
| 2668 | |
[email protected] | 9034a28 | 2014-06-05 03:11:47 | [diff] [blame] | 2669 | // Tests that the animators in the layer tree is added to the |
| 2670 | // animator-collection when the root-layer is set to the compositor. |
| 2671 | TEST_F(LayerWithDelegateTest, RootLayerAnimatorsInCompositor) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2672 | 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] | 9034a28 | 2014-06-05 03:11:47 | [diff] [blame] | 2675 | 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. |
| 2686 | TEST_F(LayerWithDelegateTest, AddRemoveLayerUpdatesAnimatorsFromSubtree) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2687 | 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] | 9034a28 | 2014-06-05 03:11:47 | [diff] [blame] | 2691 | 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 | |
| 2706 | TEST_F(LayerWithDelegateTest, DestroyingLayerRemovesTheAnimatorFromCollection) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2707 | std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED); |
| 2708 | std::unique_ptr<Layer> child = CreateLayer(LAYER_TEXTURED); |
[email protected] | 9034a28 | 2014-06-05 03:11:47 | [diff] [blame] | 2709 | 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 | |
bruthig | 33b1edab | 2016-03-02 02:22:35 | [diff] [blame] | 2720 | // A LayerAnimationObserver that removes a child layer from a parent when an |
| 2721 | // animation completes. |
| 2722 | class 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. |
| 2747 | TEST_F(LayerWithDelegateTest, NonAnimatingAnimatorsAreRemovedFromCollection) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2748 | 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); |
bruthig | 33b1edab | 2016-03-02 02:22:35 | [diff] [blame] | 2751 | 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 | |
ratsunny | bd5087e | 2016-12-17 05:19:25 | [diff] [blame] | 2760 | std::unique_ptr<LayerAnimationElement> element = |
bruthig | 33b1edab | 2016-03-02 02:22:35 | [diff] [blame] | 2761 | ui::LayerAnimationElement::CreateOpacityElement( |
| 2762 | 0.5f, base::TimeDelta::FromSeconds(1)); |
ratsunny | bd5087e | 2016-12-17 05:19:25 | [diff] [blame] | 2763 | LayerAnimationSequence* sequence = |
| 2764 | new LayerAnimationSequence(std::move(element)); |
bruthig | 33b1edab | 2016-03-02 02:22:35 | [diff] [blame] | 2765 | |
| 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] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 2774 | namespace { |
| 2775 | |
Roger Johannesson | 41dd59f | 2018-01-25 19:05:06 | [diff] [blame] | 2776 | std::string Vector2dFTo100thPrecisionString(const gfx::Vector2dF& vector) { |
[email protected] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 2777 | return base::StringPrintf("%.2f %0.2f", vector.x(), vector.y()); |
| 2778 | } |
| 2779 | |
| 2780 | } // namespace |
| 2781 | |
Vasiliy Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 2782 | TEST_P(LayerWithRealCompositorTest, SnapLayerToPixels) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 2783 | 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] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 2786 | |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2787 | viz::ParentLocalSurfaceIdAllocator allocator; |
| 2788 | allocator.GenerateId(); |
| 2789 | GetCompositor()->SetScaleAndSize( |
| 2790 | 1.25f, gfx::Size(100, 100), |
| 2791 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
[email protected] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 2792 | 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 Keshav | ebd73ca | 2019-06-27 22:17:27 | [diff] [blame] | 2799 | // 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] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 2802 | |
Sadrul Habib Chowdhury | a3806cc6 | 2018-12-21 06:39:12 | [diff] [blame] | 2803 | allocator.GenerateId(); |
| 2804 | GetCompositor()->SetScaleAndSize( |
| 2805 | 1.5f, gfx::Size(100, 100), |
| 2806 | allocator.GetCurrentLocalSurfaceIdAllocation()); |
Malay Keshav | ebd73ca | 2019-06-27 22:17:27 | [diff] [blame] | 2807 | // 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] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 2810 | |
| 2811 | c11->SetBounds(gfx::Rect(2, 2, 10, 10)); |
Malay Keshav | ebd73ca | 2019-06-27 22:17:27 | [diff] [blame] | 2812 | // 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] | e09c592ff | 2014-07-17 06:55:07 | [diff] [blame] | 2815 | } |
| 2816 | |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2817 | // Verify that LayerDelegate::OnLayerBoundsChanged() is called when the bounds |
| 2818 | // are set without an animation. |
| 2819 | TEST(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. |
| 2838 | TEST(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 Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 2894 | TEST(LayerDelegateTest, OnLayerTransformed) { |
| 2895 | auto layer = std::make_unique<Layer>(LAYER_TEXTURED); |
| 2896 | testing::StrictMock<TestLayerDelegate> delegate; |
| 2897 | layer->set_delegate(&delegate); |
Scott Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 2898 | 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 Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2914 | EXPECT_CALL(delegate, |
Scott Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 2915 | 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 Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 2924 | } |
| 2925 | |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2926 | // Verify that LayerDelegate::OnLayerTransformed() is called at every step of a |
| 2927 | // non-threaded transform transition. |
| 2928 | TEST(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 Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 2935 | auto layer = std::make_unique<Layer>(LAYER_TEXTURED); |
| 2936 | testing::StrictMock<TestLayerDelegate> delegate; |
| 2937 | layer->set_delegate(&delegate); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2938 | 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 Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 2957 | OnLayerTransformed(gfx::Transform(), |
| 2958 | PropertyChangeReason::FROM_ANIMATION)) |
| 2959 | .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform, |
| 2960 | PropertyChangeReason) { |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2961 | // 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 Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 2972 | 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 Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2980 | test_controller.Step(element_raw->duration() / 2); |
| 2981 | testing::Mock::VerifyAndClear(&delegate); |
| 2982 | |
| 2983 | // End the animation. |
Scott Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 2984 | EXPECT_CALL( |
| 2985 | delegate, |
| 2986 | OnLayerTransformed(step_transform, PropertyChangeReason::FROM_ANIMATION)) |
| 2987 | .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform, |
| 2988 | PropertyChangeReason) { |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2989 | // 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 Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 2997 | } |
| 2998 | |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 2999 | // Verify that LayerDelegate::OnLayerTransformed() is called at the beginning |
| 3000 | // and at the end of a threaded transform transition. |
| 3001 | TEST(LayerDelegateTest, OnLayerTransformedThreadedAnimation) { |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3002 | 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 Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3010 | layer->set_delegate(&delegate); |
| 3011 | layer->SetAnimator(animator); |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3012 | |
| 3013 | // Start the animation. |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3014 | gfx::Transform initial_transform = layer->transform(); |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3015 | gfx::Transform target_transform; |
| 3016 | target_transform.Skew(10.0f, 5.0f); |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3017 | std::unique_ptr<LayerAnimationElement> element = |
| 3018 | LayerAnimationElement::CreateTransformElement( |
| 3019 | target_transform, base::TimeDelta::FromSeconds(1)); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3020 | ASSERT_TRUE(element->IsThreaded(layer.get())); |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3021 | LayerAnimationElement* element_raw = element.get(); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3022 | EXPECT_CALL(delegate, |
Scott Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 3023 | OnLayerTransformed(gfx::Transform(), |
| 3024 | PropertyChangeReason::FROM_ANIMATION)) |
| 3025 | .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform, |
| 3026 | PropertyChangeReason) { |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3027 | // 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 Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3033 | animator->StartAnimation(new LayerAnimationSequence(std::move(element))); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3034 | testing::Mock::VerifyAndClear(&delegate); |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3035 | test_controller.StartThreadedAnimationsIfNeeded(); |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3036 | |
| 3037 | // End the animation. |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3038 | EXPECT_CALL(delegate, |
Scott Violet | ac1a808 | 2018-03-19 05:14:34 | [diff] [blame] | 3039 | OnLayerTransformed(initial_transform, |
| 3040 | PropertyChangeReason::FROM_ANIMATION)) |
| 3041 | .WillOnce(testing::Invoke([&](const gfx::Transform& old_transform, |
| 3042 | PropertyChangeReason) { |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3043 | // Verify that |layer->transform()| returns the correct value when the |
| 3044 | // delegate is notified. |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3045 | EXPECT_EQ(layer->transform(), target_transform); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3046 | EXPECT_FALSE( |
| 3047 | animator->IsAnimatingProperty(LayerAnimationElement::TRANSFORM)); |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3048 | })); |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3049 | test_controller.Step( |
| 3050 | element_raw->duration() + |
| 3051 | (element_raw->effective_start_time() - animator->last_step_time())); |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3052 | testing::Mock::VerifyAndClear(&delegate); |
Francois Doray | faa13f8c | 2017-10-25 15:45:05 | [diff] [blame] | 3053 | } |
| 3054 | |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3055 | // Verify that LayerDelegate::OnLayerOpacityChanged() is called when the opacity |
| 3056 | // is set without an animation. |
Francois Doray | 4f515ad | 2017-09-15 16:19:34 | [diff] [blame] | 3057 | TEST(LayerDelegateTest, OnLayerOpacityChanged) { |
| 3058 | auto layer = std::make_unique<Layer>(LAYER_TEXTURED); |
| 3059 | testing::StrictMock<TestLayerDelegate> delegate; |
| 3060 | layer->set_delegate(&delegate); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3061 | 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 Doray | 4f515ad | 2017-09-15 16:19:34 | [diff] [blame] | 3070 | } |
| 3071 | |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3072 | // Verify that LayerDelegate::OnLayerOpacityChanged() is called at the beginning |
| 3073 | // and at the end of a threaded opacity animation. |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 3074 | TEST(LayerDelegateTest, OnLayerOpacityChangedAnimation) { |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 3075 | 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 Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 3083 | layer->set_delegate(&delegate); |
| 3084 | layer->SetAnimator(animator); |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 3085 | |
| 3086 | // Start the animation. |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3087 | const float initial_opacity = layer->opacity(); |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3088 | const float kTargetOpacity = 0.5f; |
| 3089 | std::unique_ptr<LayerAnimationElement> element = |
| 3090 | LayerAnimationElement::CreateOpacityElement( |
| 3091 | kTargetOpacity, base::TimeDelta::FromSeconds(1)); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3092 | ASSERT_TRUE(element->IsThreaded(layer.get())); |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3093 | LayerAnimationElement* element_raw = element.get(); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3094 | 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 Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3103 | animator->StartAnimation(new LayerAnimationSequence(std::move(element))); |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3104 | testing::Mock::VerifyAndClear(&delegate); |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3105 | test_controller.StartThreadedAnimationsIfNeeded(); |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 3106 | |
Francois Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3107 | // End the animation. |
Francois Doray | 8e96261 | 2017-11-10 20:51:21 | [diff] [blame] | 3108 | 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 Doray | 4b50f62 | 2017-11-06 23:18:03 | [diff] [blame] | 3117 | test_controller.Step( |
| 3118 | element_raw->duration() + |
| 3119 | (element_raw->effective_start_time() - animator->last_step_time())); |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 3120 | testing::Mock::VerifyAndClear(&delegate); |
Francois Doray | 9b3b0128 | 2017-09-20 12:31:46 | [diff] [blame] | 3121 | } |
| 3122 | |
Francois Doray | a3a0b7f4 | 2018-08-15 15:44:32 | [diff] [blame] | 3123 | // Verify that LayerDelegate::OnLayerAlphaShapeChanged() is called when the |
| 3124 | // alpha shape of a layer is set. |
| 3125 | TEST(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 Telezhnikov | 152f6c3c | 2019-07-26 16:55:40 | [diff] [blame] | 3143 | TEST_P(LayerWithRealCompositorTest, CompositorAnimationObserverTest) { |
Mohsen Izadi | 62a338d | 2019-07-30 19:49:47 | [diff] [blame] | 3144 | std::unique_ptr<Layer> root = CreateLayer(LAYER_TEXTURED); |
lof84 | adf2ce86 | 2015-06-02 22:23:32 | [diff] [blame] | 3145 | |
| 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); |
staraz | ce75f93 | 2017-03-29 16:12:27 | [diff] [blame] | 3152 | WaitForDraw(); |
lof84 | adf2ce86 | 2015-06-02 22:23:32 | [diff] [blame] | 3153 | EXPECT_EQ(1u, animation_observer.animation_step_count()); |
| 3154 | |
dmazzoni | ead142a | 2015-06-22 18:01:01 | [diff] [blame] | 3155 | EXPECT_FALSE(animation_observer.shutdown()); |
lof84 | adf2ce86 | 2015-06-02 22:23:32 | [diff] [blame] | 3156 | ResetCompositor(); |
dmazzoni | ead142a | 2015-06-22 18:01:01 | [diff] [blame] | 3157 | EXPECT_TRUE(animation_observer.shutdown()); |
lof84 | adf2ce86 | 2015-06-02 22:23:32 | [diff] [blame] | 3158 | } |
| 3159 | |
[email protected] | cff176a | 2012-06-29 21:11:00 | [diff] [blame] | 3160 | } // namespace ui |