diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 17:21:03 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-23 16:25:15 +0000 |
commit | c551f43206405019121bd2b2c93714319a0a3300 (patch) | |
tree | 1f48c30631c421fd4bbb3c36da20183c8a2ed7d7 /chromium/cc | |
parent | 7961cea6d1041e3e454dae6a1da660b453efd238 (diff) | |
download | qtwebengine-chromium-c551f43206405019121bd2b2c93714319a0a3300.tar.gz |
BASELINE: Update Chromium to 79.0.3945.139
Change-Id: I336b7182fab9bca80b709682489c07db112eaca5
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc')
213 files changed, 11384 insertions, 15446 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn index 87e95f7d691..da40ffada58 100644 --- a/chromium/cc/BUILD.gn +++ b/chromium/cc/BUILD.gn @@ -1,6 +1,7 @@ # Copyright 2014 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. +import("//build/config/sanitizers/sanitizers.gni") import("//gpu/vulkan/features.gni") import("//cc/cc.gni") @@ -80,8 +81,6 @@ cc_component("cc") { "layers/layer_collections.h", "layers/layer_impl.cc", "layers/layer_impl.h", - "layers/layer_impl_test_properties.cc", - "layers/layer_impl_test_properties.h", "layers/layer_list_iterator.cc", "layers/layer_list_iterator.h", "layers/mirror_layer.cc", @@ -112,9 +111,10 @@ cc_component("cc") { "layers/recording_source.h", "layers/render_surface_impl.cc", "layers/render_surface_impl.h", + "layers/scrollbar_layer_base.cc", + "layers/scrollbar_layer_base.h", "layers/scrollbar_layer_impl_base.cc", "layers/scrollbar_layer_impl_base.h", - "layers/scrollbar_layer_interface.h", "layers/solid_color_layer.cc", "layers/solid_color_layer.h", "layers/solid_color_layer_impl.cc", @@ -149,6 +149,8 @@ cc_component("cc") { "layers/video_layer_impl.h", "layers/viewport.cc", "layers/viewport.h", + "metrics/begin_main_frame_metrics.cc", + "metrics/begin_main_frame_metrics.h", "metrics/compositor_frame_reporter.cc", "metrics/compositor_frame_reporter.h", "metrics/compositor_frame_reporting_controller.cc", @@ -304,8 +306,6 @@ cc_component("cc") { "trees/layer_tree_host.cc", "trees/layer_tree_host.h", "trees/layer_tree_host_client.h", - "trees/layer_tree_host_common.cc", - "trees/layer_tree_host_common.h", "trees/layer_tree_host_impl.cc", "trees/layer_tree_host_impl.h", "trees/layer_tree_host_single_thread_client.h", @@ -343,6 +343,8 @@ cc_component("cc") { "trees/render_frame_metadata.h", "trees/render_frame_metadata_observer.h", "trees/scoped_abort_remaining_swap_promises.h", + "trees/scroll_and_scale_set.cc", + "trees/scroll_and_scale_set.h", "trees/scroll_node.cc", "trees/scroll_node.h", "trees/single_thread_proxy.cc", @@ -462,6 +464,8 @@ cc_test_static_library("test_support") { "test/geometry_test_utils.h", "test/layer_test_common.cc", "test/layer_test_common.h", + "test/layer_tree_impl_test_base.cc", + "test/layer_tree_impl_test_base.h", "test/layer_tree_json_parser.cc", "test/layer_tree_json_parser.h", "test/layer_tree_pixel_resource_test.cc", @@ -667,7 +671,6 @@ cc_test("cc_unittests") { "resources/resource_pool_unittest.cc", "scheduler/scheduler_state_machine_unittest.cc", "scheduler/scheduler_unittest.cc", - "test/layer_tree_json_parser_unittest.cc", "tiles/checker_image_tracker_unittest.cc", "tiles/decoded_image_tracker_unittest.cc", "tiles/gpu_image_decode_cache_unittest.cc", @@ -680,9 +683,9 @@ cc_test("cc_unittests") { "tiles/tile_manager_unittest.cc", "tiles/tile_priority_unittest.cc", "trees/damage_tracker_unittest.cc", + "trees/draw_properties_unittest.cc", "trees/image_animation_controller_unittest.cc", "trees/layer_tree_frame_sink_unittest.cc", - "trees/layer_tree_host_common_unittest.cc", "trees/layer_tree_host_impl_unittest.cc", "trees/layer_tree_host_pixeltest_blending.cc", "trees/layer_tree_host_pixeltest_filters.cc", @@ -710,6 +713,7 @@ cc_test("cc_unittests") { "trees/occlusion_tracker_unittest.cc", "trees/occlusion_unittest.cc", "trees/presentation_time_callback_buffer_unittest.cc", + "trees/property_tree_builder_unittest.cc", "trees/property_tree_unittest.cc", "trees/swap_promise_manager_unittest.cc", "trees/tree_synchronizer_unittest.cc", @@ -811,7 +815,7 @@ cc_test("cc_perftests") { "tiles/gpu_image_decode_cache_perftest.cc", "tiles/software_image_decode_cache_perftest.cc", "tiles/tile_manager_perftest.cc", - "trees/layer_tree_host_common_perftest.cc", + "trees/draw_property_utils_perftest.cc", "trees/layer_tree_host_perftest.cc", ] diff --git a/chromium/cc/animation/animation.cc b/chromium/cc/animation/animation.cc index 2e4c5eb69ac..9d32d45f668 100644 --- a/chromium/cc/animation/animation.cc +++ b/chromium/cc/animation/animation.cc @@ -311,6 +311,13 @@ size_t Animation::TickingKeyframeModelsCount() const { return count; } +bool Animation::AffectsCustomProperty() const { + for (const auto& keyframe_effect : keyframe_effects_) + if (keyframe_effect->AffectsCustomProperty()) + return true; + return false; +} + void Animation::SetNeedsCommit() { DCHECK(animation_host_); animation_host_->SetNeedsCommit(); diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h index 12ad6058cdc..06df05510a6 100644 --- a/chromium/cc/animation/animation.h +++ b/chromium/cc/animation/animation.h @@ -107,6 +107,7 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> { void NotifyKeyframeModelAborted(const AnimationEvent& event); void NotifyKeyframeModelTakeover(const AnimationEvent& event); size_t TickingKeyframeModelsCount() const; + bool AffectsCustomProperty() const; void SetNeedsPushProperties(); diff --git a/chromium/cc/animation/animation_events.cc b/chromium/cc/animation/animation_events.cc index a353f226362..4d9387aa43e 100644 --- a/chromium/cc/animation/animation_events.cc +++ b/chromium/cc/animation/animation_events.cc @@ -16,8 +16,7 @@ AnimationEvent::AnimationEvent(AnimationEvent::Type type, group_id(group_id), target_property(target_property), monotonic_time(monotonic_time), - is_impl_only(false), - opacity(0.f) {} + is_impl_only(false) {} AnimationEvent::AnimationEvent(const AnimationEvent& other) { type = other.type; @@ -26,9 +25,6 @@ AnimationEvent::AnimationEvent(const AnimationEvent& other) { target_property = other.target_property; monotonic_time = other.monotonic_time; is_impl_only = other.is_impl_only; - opacity = other.opacity; - transform = other.transform; - filters = other.filters; animation_start_time = other.animation_start_time; if (other.curve) curve = other.curve->Clone(); @@ -41,9 +37,6 @@ AnimationEvent& AnimationEvent::operator=(const AnimationEvent& other) { target_property = other.target_property; monotonic_time = other.monotonic_time; is_impl_only = other.is_impl_only; - opacity = other.opacity; - transform = other.transform; - filters = other.filters; animation_start_time = other.animation_start_time; if (other.curve) curve = other.curve->Clone(); diff --git a/chromium/cc/animation/animation_events.h b/chromium/cc/animation/animation_events.h index 584292197ae..cec76160ce8 100644 --- a/chromium/cc/animation/animation_events.h +++ b/chromium/cc/animation/animation_events.h @@ -12,9 +12,7 @@ #include "cc/animation/animation_export.h" #include "cc/animation/keyframe_model.h" #include "cc/paint/element_id.h" -#include "cc/paint/filter_operations.h" #include "cc/trees/mutator_host.h" -#include "ui/gfx/transform.h" namespace cc { @@ -38,9 +36,6 @@ struct CC_ANIMATION_EXPORT AnimationEvent { int target_property; base::TimeTicks monotonic_time; bool is_impl_only; - float opacity; - gfx::Transform transform; - FilterOperations filters; // For continuing a scroll offset animation on the main thread. base::TimeTicks animation_start_time; diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc index b283103cc48..2e4dbb4e434 100644 --- a/chromium/cc/animation/animation_host.cc +++ b/chromium/cc/animation/animation_host.cc @@ -790,6 +790,13 @@ size_t AnimationHost::MainThreadAnimationsCount() const { return main_thread_animations_count_; } +bool AnimationHost::HasCustomPropertyAnimations() const { + for (const auto& it : ticking_animations_) + if (it->AffectsCustomProperty()) + return true; + return false; +} + bool AnimationHost::CurrentFrameHadRAF() const { return current_frame_had_raf_; } diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h index 2e3eb122c71..fa0a1a5a0a6 100644 --- a/chromium/cc/animation/animation_host.h +++ b/chromium/cc/animation/animation_host.h @@ -208,6 +208,7 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost, size_t CompositedAnimationsCount() const override; size_t MainThreadAnimationsCount() const override; + bool HasCustomPropertyAnimations() const override; bool CurrentFrameHadRAF() const override; bool NextFrameHasPendingRAF() const override; void SetAnimationCounts(size_t total_animations_count, diff --git a/chromium/cc/animation/animation_host_perftest.cc b/chromium/cc/animation/animation_host_perftest.cc index 3bd25688d50..b9926f42d6e 100644 --- a/chromium/cc/animation/animation_host_perftest.cc +++ b/chromium/cc/animation/animation_host_perftest.cc @@ -17,7 +17,7 @@ #include "cc/test/stub_layer_tree_host_single_thread_client.h" #include "cc/test/test_task_graph_runner.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { @@ -120,7 +120,7 @@ class AnimationHostPerfTest : public testing::Test { all_animations_timeline_->GetAnimationById(i)->SetNeedsPushProperties(); } - void DoTest() { + void DoTest(const std::string& test_name) { timer_.Reset(); do { // Invalidate dirty flags. @@ -130,8 +130,9 @@ class AnimationHostPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("push_properties_to", "", "", timer_.LapsPerSecond(), - "runs/s", true); + perf_test::PerfResultReporter reporter("push_properties_to", test_name); + reporter.RegisterImportantMetric("", "runs/s"); + reporter.AddResult("", timer_.LapsPerSecond()); } private: @@ -155,17 +156,17 @@ class AnimationHostPerfTest : public testing::Test { TEST_F(AnimationHostPerfTest, Push1000AnimationsPropertiesTo) { CreateAnimations(1000); - DoTest(); + DoTest("Push1000AnimationsPropertiesTo"); } TEST_F(AnimationHostPerfTest, Push10TimelinesPropertiesTo) { CreateTimelines(10); - DoTest(); + DoTest("Push10TimelinesPropertiesTo"); } TEST_F(AnimationHostPerfTest, Push1000TimelinesPropertiesTo) { CreateTimelines(1000); - DoTest(); + DoTest("Push1000TimelinesPropertiesTo"); } } // namespace cc diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc index f093553fe15..54920ea0693 100644 --- a/chromium/cc/animation/element_animations_unittest.cc +++ b/chromium/cc/animation/element_animations_unittest.cc @@ -280,6 +280,7 @@ TEST_F(ElementAnimationsTest, ->curve() ->ToScrollOffsetAnimationCurve() ->GetValue(base::TimeDelta())); + animation_->RemoveKeyframeModel(animation1_id); // Animation without initial value set. std::unique_ptr<ScrollOffsetAnimationCurve> curve( @@ -297,6 +298,7 @@ TEST_F(ElementAnimationsTest, ->curve() ->ToScrollOffsetAnimationCurve() ->GetValue(base::TimeDelta())); + animation_->RemoveKeyframeModel(animation2_id); } class TestAnimationDelegateThatDestroysAnimation diff --git a/chromium/cc/animation/keyframe_effect.cc b/chromium/cc/animation/keyframe_effect.cc index 591bc5aa01f..ecbd64a259d 100644 --- a/chromium/cc/animation/keyframe_effect.cc +++ b/chromium/cc/animation/keyframe_effect.cc @@ -248,6 +248,21 @@ void KeyframeEffect::AddKeyframeModel( keyframe_model->group() == existing_keyframe_model->group(); })); + if (keyframe_model->target_property_id() == TargetProperty::SCROLL_OFFSET) { + // We should never have more than one scroll offset animation queued on the + // same scrolling element as this would result in multiple automated + // scrolls. + DCHECK(std::none_of( + keyframe_models_.begin(), keyframe_models_.end(), + [&](const auto& existing_keyframe_model) { + return existing_keyframe_model->target_property_id() == + TargetProperty::SCROLL_OFFSET && + !existing_keyframe_model->is_finished() && + (!existing_keyframe_model->is_controlling_instance() || + existing_keyframe_model->affects_pending_elements()); + })); + } + keyframe_models_.push_back(std::move(keyframe_model)); if (has_bound_element_animations()) { @@ -453,6 +468,13 @@ size_t KeyframeEffect::TickingKeyframeModelsCount() const { return ticking_keyframe_models_count; } +bool KeyframeEffect::AffectsCustomProperty() const { + for (const auto& it : keyframe_models_) + if (it->target_property_id() == TargetProperty::CSS_CUSTOM_PROPERTY) + return true; + return false; +} + bool KeyframeEffect::HasNonDeletedKeyframeModel() const { for (const auto& keyframe_model : keyframe_models_) { if (keyframe_model->run_state() != KeyframeModel::WAITING_FOR_DELETION) diff --git a/chromium/cc/animation/keyframe_effect.h b/chromium/cc/animation/keyframe_effect.h index e4b00292602..e3816763e85 100644 --- a/chromium/cc/animation/keyframe_effect.h +++ b/chromium/cc/animation/keyframe_effect.h @@ -119,6 +119,8 @@ class CC_ANIMATION_EXPORT KeyframeEffect { bool HasTickingKeyframeModel() const; size_t TickingKeyframeModelsCount() const; + bool AffectsCustomProperty() const; + bool HasNonDeletedKeyframeModel() const; bool AnimationsPreserveAxisAlignment() const; diff --git a/chromium/cc/animation/scroll_offset_animation_curve.cc b/chromium/cc/animation/scroll_offset_animation_curve.cc index 0bc523ff275..6ec55b7472b 100644 --- a/chromium/cc/animation/scroll_offset_animation_curve.cc +++ b/chromium/cc/animation/scroll_offset_animation_curve.cc @@ -9,6 +9,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" +#include "base/numerics/ranges.h" #include "cc/animation/timing_function.h" #include "cc/base/time_util.h" #include "ui/gfx/animation/tween.h" @@ -46,7 +47,7 @@ static float MaximumDimension(const gfx::Vector2dF& delta) { static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity( double velocity) { // Clamp velocity to a sane value. - velocity = std::min(std::max(velocity, -1000.0), 1000.0); + velocity = base::ClampToRange(velocity, -1000.0, 1000.0); // Based on CubicBezierTimingFunction::EaseType::EASE_IN_OUT preset // with first control point scaled. @@ -92,15 +93,14 @@ base::TimeDelta ScrollOffsetAnimationCurve::SegmentDuration( break; case DurationBehavior::DELTA_BASED: duration = - std::min(double(std::sqrt(std::abs(MaximumDimension(delta)))), - kDeltaBasedMaxDuration); + std::min<double>(std::sqrt(std::abs(MaximumDimension(delta))), + kDeltaBasedMaxDuration); break; case DurationBehavior::INVERSE_DELTA: - duration = std::min( - std::max(kInverseDeltaOffset + - std::abs(MaximumDimension(delta)) * kInverseDeltaSlope, - kInverseDeltaMinDuration), - kInverseDeltaMaxDuration); + duration = kInverseDeltaOffset + + std::abs(MaximumDimension(delta)) * kInverseDeltaSlope; + duration = base::ClampToRange(duration, kInverseDeltaMinDuration, + kInverseDeltaMaxDuration); break; case DurationBehavior::CONSTANT_VELOCITY: duration = diff --git a/chromium/cc/base/BUILD.gn b/chromium/cc/base/BUILD.gn index 9546cd277ad..4b0775b86fe 100644 --- a/chromium/cc/base/BUILD.gn +++ b/chromium/cc/base/BUILD.gn @@ -4,7 +4,7 @@ import("//cc/cc.gni") -component("base") { +cc_component("base") { output_name = "cc_base" sources = [ "base_export.h", diff --git a/chromium/cc/base/math_util.cc b/chromium/cc/base/math_util.cc index a484a243514..0e072b98d39 100644 --- a/chromium/cc/base/math_util.cc +++ b/chromium/cc/base/math_util.cc @@ -11,6 +11,7 @@ #include <xmmintrin.h> #endif +#include "base/numerics/ranges.h" #include "base/trace_event/traced_value.h" #include "base/values.h" #include "ui/gfx/geometry/angle_conversions.h" @@ -161,8 +162,7 @@ static inline bool IsNearlyTheSame(float f, float g) { // for the base of the scale too. static const float epsilon_scale = 0.00001f; return std::abs(f - g) < - epsilon_scale * - std::max(std::max(std::abs(f), std::abs(g)), epsilon_scale); + epsilon_scale * std::max({std::abs(f), std::abs(g), epsilon_scale}); } static inline bool IsNearlyTheSame(const gfx::PointF& lhs, @@ -613,7 +613,7 @@ float MathUtil::SmallestAngleBetweenVectors(const gfx::Vector2dF& v1, const gfx::Vector2dF& v2) { double dot_product = gfx::DotProduct(v1, v2) / v1.Length() / v2.Length(); // Clamp to compensate for rounding errors. - dot_product = std::max(-1.0, std::min(1.0, dot_product)); + dot_product = base::ClampToRange(dot_product, -1.0, 1.0); return static_cast<float>(gfx::RadToDeg(std::acos(dot_product))); } diff --git a/chromium/cc/base/rtree_perftest.cc b/chromium/cc/base/rtree_perftest.cc index 3b12bf594f7..00d8a954b5c 100644 --- a/chromium/cc/base/rtree_perftest.cc +++ b/chromium/cc/base/rtree_perftest.cc @@ -6,7 +6,7 @@ #include "cc/base/rtree.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -39,8 +39,8 @@ class RTreePerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("rtree_construct", "", test_name, - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_construct", timer_.LapsPerSecond()); } void RunSearchTest(const std::string& test_name, int rect_count) { @@ -65,8 +65,8 @@ class RTreePerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("rtree_search", "", test_name, - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_search", timer_.LapsPerSecond()); } std::vector<gfx::Rect> BuildRects(int count) { @@ -85,6 +85,13 @@ class RTreePerfTest : public testing::Test { } protected: + perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { + perf_test::PerfResultReporter reporter("rtree", story_name); + reporter.RegisterImportantMetric("_construct", "runs/s"); + reporter.RegisterImportantMetric("_search", "runs/s"); + return reporter; + } + base::LapTimer timer_; }; diff --git a/chromium/cc/base/tiling_data.cc b/chromium/cc/base/tiling_data.cc index 2df754f6593..b17338e5c5c 100644 --- a/chromium/cc/base/tiling_data.cc +++ b/chromium/cc/base/tiling_data.cc @@ -6,6 +6,7 @@ #include <algorithm> +#include "base/numerics/ranges.h" #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/vector2d.h" @@ -79,7 +80,7 @@ int TilingData::TileXIndexFromSrcCoord(int src_position) const { DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); int x = (src_position - border_texels_) / (max_texture_size_.width() - 2 * border_texels_); - return std::min(std::max(x, 0), num_tiles_x_ - 1); + return base::ClampToRange(x, 0, num_tiles_x_ - 1); } int TilingData::TileYIndexFromSrcCoord(int src_position) const { @@ -89,7 +90,7 @@ int TilingData::TileYIndexFromSrcCoord(int src_position) const { DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); int y = (src_position - border_texels_) / (max_texture_size_.height() - 2 * border_texels_); - return std::min(std::max(y, 0), num_tiles_y_ - 1); + return base::ClampToRange(y, 0, num_tiles_y_ - 1); } int TilingData::FirstBorderTileXIndexFromSrcCoord(int src_position) const { @@ -99,7 +100,7 @@ int TilingData::FirstBorderTileXIndexFromSrcCoord(int src_position) const { DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); int inner_tile_size = max_texture_size_.width() - 2 * border_texels_; int x = (src_position - 2 * border_texels_) / inner_tile_size; - return std::min(std::max(x, 0), num_tiles_x_ - 1); + return base::ClampToRange(x, 0, num_tiles_x_ - 1); } int TilingData::FirstBorderTileYIndexFromSrcCoord(int src_position) const { @@ -109,7 +110,7 @@ int TilingData::FirstBorderTileYIndexFromSrcCoord(int src_position) const { DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); int inner_tile_size = max_texture_size_.height() - 2 * border_texels_; int y = (src_position - 2 * border_texels_) / inner_tile_size; - return std::min(std::max(y, 0), num_tiles_y_ - 1); + return base::ClampToRange(y, 0, num_tiles_y_ - 1); } int TilingData::LastBorderTileXIndexFromSrcCoord(int src_position) const { @@ -119,7 +120,7 @@ int TilingData::LastBorderTileXIndexFromSrcCoord(int src_position) const { DCHECK_GT(max_texture_size_.width() - 2 * border_texels_, 0); int inner_tile_size = max_texture_size_.width() - 2 * border_texels_; int x = src_position / inner_tile_size; - return std::min(std::max(x, 0), num_tiles_x_ - 1); + return base::ClampToRange(x, 0, num_tiles_x_ - 1); } int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const { @@ -129,7 +130,7 @@ int TilingData::LastBorderTileYIndexFromSrcCoord(int src_position) const { DCHECK_GT(max_texture_size_.height() - 2 * border_texels_, 0); int inner_tile_size = max_texture_size_.height() - 2 * border_texels_; int y = src_position / inner_tile_size; - return std::min(std::max(y, 0), num_tiles_y_ - 1); + return base::ClampToRange(y, 0, num_tiles_y_ - 1); } IndexRect TilingData::TileAroundIndexRect(const gfx::Rect& center_rect) const { diff --git a/chromium/cc/benchmarks/invalidation_benchmark.cc b/chromium/cc/benchmarks/invalidation_benchmark.cc index 8df14b6f4e7..08402bdc4ac 100644 --- a/chromium/cc/benchmarks/invalidation_benchmark.cc +++ b/chromium/cc/benchmarks/invalidation_benchmark.cc @@ -15,7 +15,6 @@ #include "cc/layers/picture_layer.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" #include "ui/gfx/geometry/rect.h" namespace cc { @@ -63,9 +62,8 @@ InvalidationBenchmark::InvalidationBenchmark( InvalidationBenchmark::~InvalidationBenchmark() = default; void InvalidationBenchmark::DidUpdateLayers(LayerTreeHost* layer_tree_host) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - layer_tree_host, - [this](Layer* layer) { layer->RunMicroBenchmark(this); }); + for (auto* layer : *layer_tree_host) + layer->RunMicroBenchmark(this); } void InvalidationBenchmark::RunOnLayer(PictureLayer* layer) { diff --git a/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc b/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc index 61bc65532ad..120203ca4ab 100644 --- a/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc +++ b/chromium/cc/benchmarks/rasterize_and_record_benchmark.cc @@ -22,7 +22,6 @@ #include "cc/layers/recording_source.h" #include "cc/paint/display_item_list.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" #include "ui/gfx/geometry/rect.h" namespace cc { @@ -86,9 +85,8 @@ RasterizeAndRecordBenchmark::~RasterizeAndRecordBenchmark() { void RasterizeAndRecordBenchmark::DidUpdateLayers( LayerTreeHost* layer_tree_host) { layer_tree_host_ = layer_tree_host; - LayerTreeHostCommon::CallFunctionForEveryLayer( - layer_tree_host_, - [this](Layer* layer) { layer->RunMicroBenchmark(this); }); + for (auto* layer : *layer_tree_host) + layer->RunMicroBenchmark(this); DCHECK(!results_.get()); results_ = base::WrapUnique(new base::DictionaryValue); diff --git a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc index 93b5d5dfc4e..609b925b264 100644 --- a/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc +++ b/chromium/cc/benchmarks/rasterize_and_record_benchmark_impl.cc @@ -15,7 +15,6 @@ #include "cc/layers/picture_layer_impl.h" #include "cc/raster/playback_image_provider.h" #include "cc/raster/raster_buffer_provider.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" #include "ui/gfx/geometry/axis_transform2d.h" @@ -146,11 +145,10 @@ RasterizeAndRecordBenchmarkImpl::~RasterizeAndRecordBenchmarkImpl() = default; void RasterizeAndRecordBenchmarkImpl::DidCompleteCommit( LayerTreeHostImpl* host) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - host->active_tree(), [this](LayerImpl* layer) { - rasterize_results_.total_layers++; - layer->RunMicroBenchmark(this); - }); + for (auto* layer : *host->active_tree()) { + rasterize_results_.total_layers++; + layer->RunMicroBenchmark(this); + } std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue()); result->SetDouble("rasterize_time_ms", diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h index e7794a5be53..f39e0062ffe 100644 --- a/chromium/cc/input/input_handler.h +++ b/chromium/cc/input/input_handler.h @@ -198,8 +198,8 @@ class CC_EXPORT InputHandler { virtual InputHandlerPointerResult MouseMoveAt( const gfx::Point& mouse_position) = 0; - virtual InputHandlerPointerResult MouseDown( - const gfx::PointF& mouse_position) = 0; + virtual InputHandlerPointerResult MouseDown(const gfx::PointF& mouse_position, + bool shift_modifier) = 0; virtual InputHandlerPointerResult MouseUp( const gfx::PointF& mouse_position) = 0; virtual void MouseLeave() = 0; diff --git a/chromium/cc/input/scrollbar.h b/chromium/cc/input/scrollbar.h index c63c800b1e4..4c739c69dba 100644 --- a/chromium/cc/input/scrollbar.h +++ b/chromium/cc/input/scrollbar.h @@ -20,10 +20,16 @@ static constexpr float kAutoscrollMultiplier = 20.f; static constexpr base::TimeDelta kInitialAutoscrollTimerDelay = base::TimeDelta::FromMilliseconds(250); +// Constants used to figure the how far out in the non-scrolling direction +// should trigger the thumb to snap back to its origin. These calculations are +// based on observing the behavior of the MSVC8 main window scrollbar + some +// guessing/extrapolation. +static constexpr int kOffSideMultiplier = 8; +static constexpr int kDefaultWinScrollbarThickness = 17; + namespace cc { enum ScrollbarOrientation { HORIZONTAL, VERTICAL }; -enum ScrollDirection { SCROLL_BACKWARD, SCROLL_FORWARD }; enum ScrollbarPart { THUMB, @@ -45,17 +51,29 @@ class Scrollbar { virtual gfx::Point Location() const = 0; virtual bool IsOverlay() const = 0; virtual bool HasThumb() const = 0; + virtual bool SupportsDragSnapBack() const = 0; virtual int ThumbThickness() const = 0; virtual int ThumbLength() const = 0; + + // Returns the track rect relative to the scrollbar's origin. virtual gfx::Rect TrackRect() const = 0; + // Returns the back button rect relative to the scrollbar's origin. virtual gfx::Rect BackButtonRect() const = 0; + // Returns the forward button rect relative to the scrollbar's origin. virtual gfx::Rect ForwardButtonRect() const = 0; + virtual float ThumbOpacity() const = 0; virtual bool HasTickmarks() const = 0; + + // Whether we need to repaint the part. Only THUMB and TRACK are supported. + // For TRACK, the return value means that the track, any buttons or tickmarks + // need repaint. virtual bool NeedsPaintPart(ScrollbarPart part) const = 0; - virtual void PaintPart(PaintCanvas* canvas, - ScrollbarPart part, - const gfx::Rect& content_rect) = 0; + // Paints the part. Only THUMB, TRACK and TICKMARKS are supported. When TRACK + // is specified, track, buttons and tickmarks will be painted. The canvas's + // coordinate space is relative to the part's origin. + virtual void PaintPart(PaintCanvas* canvas, ScrollbarPart part) = 0; + virtual bool UsesNinePatchThumbResource() const = 0; virtual gfx::Size NinePatchThumbCanvasSize() const = 0; virtual gfx::Rect NinePatchThumbAperture() const = 0; diff --git a/chromium/cc/input/scrollbar_animation_controller.cc b/chromium/cc/input/scrollbar_animation_controller.cc index bed51a0282d..60d7ecb8f31 100644 --- a/chromium/cc/input/scrollbar_animation_controller.cc +++ b/chromium/cc/input/scrollbar_animation_controller.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/bind.h" +#include "base/numerics/ranges.h" #include "base/time/time.h" #include "cc/trees/layer_tree_impl.h" @@ -162,7 +163,7 @@ float ScrollbarAnimationController::AnimationProgressAtTime( base::TimeTicks now) { base::TimeDelta delta = now - last_awaken_time_; float progress = delta.InSecondsF() / fade_duration_.InSecondsF(); - return std::max(std::min(progress, 1.f), 0.f); + return base::ClampToRange(progress, 0.0f, 1.0f); } void ScrollbarAnimationController::RunAnimationFrame(float progress) { diff --git a/chromium/cc/input/scrollbar_animation_controller_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_unittest.cc index 0836aeb1afa..d88bbdbf5b5 100644 --- a/chromium/cc/input/scrollbar_animation_controller_unittest.cc +++ b/chromium/cc/input/scrollbar_animation_controller_unittest.cc @@ -5,10 +5,8 @@ #include "cc/input/scrollbar_animation_controller.h" #include "cc/layers/solid_color_scrollbar_layer_impl.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/test_task_graph_runner.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -58,11 +56,11 @@ class MockScrollbarAnimationControllerClient LayerTreeHostImpl* host_impl_; }; -class ScrollbarAnimationControllerAuraOverlayTest : public testing::Test { +class ScrollbarAnimationControllerAuraOverlayTest + : public LayerTreeImplTestBase, + public testing::Test { public: - ScrollbarAnimationControllerAuraOverlayTest() - : host_impl_(&task_runner_provider_, &task_graph_runner_), - client_(&host_impl_) {} + ScrollbarAnimationControllerAuraOverlayTest() : client_(host_impl()) {} void ExpectScrollbarsOpacity(float opacity) { EXPECT_FLOAT_EQ(opacity, v_scrollbar_layer_->Opacity()); @@ -75,57 +73,47 @@ class ScrollbarAnimationControllerAuraOverlayTest : public testing::Test { const base::TimeDelta kThinningDuration = base::TimeDelta::FromSeconds(2); void SetUp() override { - std::unique_ptr<LayerImpl> scroll_layer = - LayerImpl::Create(host_impl_.active_tree(), 1); - std::unique_ptr<LayerImpl> clip = - LayerImpl::Create(host_impl_.active_tree(), 2); - clip_layer_ = clip.get(); - scroll_layer->SetElementId( - LayerIdToElementIdForTesting(scroll_layer->id())); - LayerImpl* scroll_layer_ptr = scroll_layer.get(); - const int kTrackStart = 0; const int kTrackLength = 100; const bool kIsLeftSideVerticalScrollbar = false; - const bool kIsOverlayScrollbar = true; - - std::unique_ptr<SolidColorScrollbarLayerImpl> h_scrollbar = - SolidColorScrollbarLayerImpl::Create( - host_impl_.active_tree(), 3, HORIZONTAL, kThumbThickness, - kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); - h_scrollbar->test_properties()->opacity = 0.0f; - std::unique_ptr<SolidColorScrollbarLayerImpl> v_scrollbar = - SolidColorScrollbarLayerImpl::Create( - host_impl_.active_tree(), 4, VERTICAL, kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); - v_scrollbar->test_properties()->opacity = 0.0f; - v_scrollbar_layer_ = v_scrollbar.get(); - h_scrollbar_layer_ = h_scrollbar.get(); - - scroll_layer->test_properties()->AddChild(std::move(v_scrollbar)); - scroll_layer->test_properties()->AddChild(std::move(h_scrollbar)); - clip_layer_->test_properties()->AddChild(std::move(scroll_layer)); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(clip)); + + scroll_layer_ = AddLayer<LayerImpl>(); + h_scrollbar_layer_ = AddLayer<SolidColorScrollbarLayerImpl>( + HORIZONTAL, kThumbThickness, kTrackStart, kIsLeftSideVerticalScrollbar); + v_scrollbar_layer_ = AddLayer<SolidColorScrollbarLayerImpl>( + VERTICAL, kThumbThickness, kTrackStart, kIsLeftSideVerticalScrollbar); + SetElementIdsForTesting(); + + clip_layer_ = root_layer(); + clip_layer_->SetBounds(gfx::Size(100, 100)); + + scroll_layer_->SetScrollable(gfx::Size(100, 100)); + scroll_layer_->SetBounds(gfx::Size(200, 200)); + CopyProperties(clip_layer_, scroll_layer_); + CreateTransformNode(scroll_layer_); + CreateScrollNode(scroll_layer_); v_scrollbar_layer_->SetBounds(gfx::Size(kThumbThickness, kTrackLength)); - v_scrollbar_layer_->test_properties()->position = gfx::PointF(90, 0); - v_scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id()); - v_scrollbar_layer_->test_properties()->opacity_can_animate = true; + v_scrollbar_layer_->SetScrollElementId(scroll_layer_->element_id()); + CopyProperties(scroll_layer_, v_scrollbar_layer_); + v_scrollbar_layer_->SetOffsetToTransformParent(gfx::Vector2dF(90, 0)); + auto& v_scrollbar_effect = CreateEffectNode(v_scrollbar_layer_); + v_scrollbar_effect.opacity = 0.f; + v_scrollbar_effect.has_potential_opacity_animation = true; h_scrollbar_layer_->SetBounds(gfx::Size(kTrackLength, kThumbThickness)); - h_scrollbar_layer_->test_properties()->position = gfx::PointF(0, 90); - h_scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id()); - h_scrollbar_layer_->test_properties()->opacity_can_animate = true; + h_scrollbar_layer_->SetScrollElementId(scroll_layer_->element_id()); + CopyProperties(scroll_layer_, h_scrollbar_layer_); + h_scrollbar_layer_->SetOffsetToTransformParent(gfx::Vector2dF(0, 90)); + auto& h_scrollbar_effect = CreateEffectNode(h_scrollbar_layer_); + h_scrollbar_effect.opacity = 0.f; + h_scrollbar_effect.has_potential_opacity_animation = true; - clip_layer_->SetBounds(gfx::Size(100, 100)); - scroll_layer_ptr->SetScrollable(gfx::Size(100, 100)); - scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl_.active_tree()->UpdateScrollbarGeometries(); + UpdateActiveTreeDrawProperties(); scrollbar_controller_ = ScrollbarAnimationController:: CreateScrollbarAnimationControllerAuraOverlay( - scroll_layer_ptr->element_id(), &client_, kFadeDelay, kFadeDuration, + scroll_layer_->element_id(), &client_, kFadeDelay, kFadeDuration, kThinningDuration, 0.0f); v_scrollbar_layer_->SetCurrentPos(0); h_scrollbar_layer_->SetCurrentPos(0); @@ -153,11 +141,9 @@ class ScrollbarAnimationControllerAuraOverlayTest : public testing::Test { return p; } - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; std::unique_ptr<ScrollbarAnimationController> scrollbar_controller_; LayerImpl* clip_layer_; + LayerImpl* scroll_layer_; SolidColorScrollbarLayerImpl* v_scrollbar_layer_; SolidColorScrollbarLayerImpl* h_scrollbar_layer_; NiceMock<MockScrollbarAnimationControllerClient> client_; @@ -185,16 +171,17 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, AppearOnResize) { // Make the Layer non-scrollable, scrollbar disappears. clip_layer_->SetBounds(gfx::Size(200, 200)); - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - scroll_layer->SetScrollable(gfx::Size(200, 200)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(200, 200)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(200, 200); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollUpdate(); ExpectScrollbarsOpacity(0); // Make the layer scrollable, scrollbar appears again. clip_layer_->SetBounds(gfx::Size(100, 100)); - scroll_layer->SetScrollable(gfx::Size(100, 100)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(100, 100); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollUpdate(); ExpectScrollbarsOpacity(1); } @@ -204,15 +191,14 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, HideOnResize) { base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - ASSERT_TRUE(scroll_layer); - EXPECT_EQ(gfx::Size(200, 200), scroll_layer->bounds()); + EXPECT_EQ(gfx::Size(200, 200), scroll_layer_->bounds()); // Shrink along X axis, horizontal scrollbar should appear. clip_layer_->SetBounds(gfx::Size(100, 200)); EXPECT_EQ(gfx::Size(100, 200), clip_layer_->bounds()); - scroll_layer->SetScrollable(gfx::Size(100, 200)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(100, 200)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(100, 200); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); @@ -225,8 +211,9 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, HideOnResize) { // should disappear. clip_layer_->SetBounds(gfx::Size(200, 100)); EXPECT_EQ(gfx::Size(200, 100), clip_layer_->bounds()); - scroll_layer->SetScrollable(gfx::Size(200, 100)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(200, 100)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(200, 100); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); @@ -1363,13 +1350,12 @@ TEST_F(ScrollbarAnimationControllerAuraOverlayTest, TickmakrsShowHide) { } class ScrollbarAnimationControllerAndroidTest - : public testing::Test, + : public LayerTreeImplTestBase, + public testing::Test, public ScrollbarAnimationControllerClient { public: ScrollbarAnimationControllerAndroidTest() - : host_impl_(&task_runner_provider_, &task_graph_runner_), - did_request_redraw_(false), - did_request_animate_(false) {} + : did_request_redraw_(false), did_request_animate_(false) {} void PostDelayedScrollbarAnimationTask(base::OnceClosure start_fade, base::TimeDelta delay) override { @@ -1383,7 +1369,7 @@ class ScrollbarAnimationControllerAndroidTest did_request_animate_ = true; } ScrollbarSet ScrollbarsFor(ElementId scroll_element_id) const override { - return host_impl_.ScrollbarsFor(scroll_element_id); + return host_impl()->ScrollbarsFor(scroll_element_id); } void DidChangeScrollbarVisibility() override {} @@ -1391,47 +1377,38 @@ class ScrollbarAnimationControllerAndroidTest void SetUp() override { const int kTrackStart = 0; const bool kIsLeftSideVerticalScrollbar = false; - const bool kIsOverlayScrollbar = true; // Allow opacity animations. - - std::unique_ptr<LayerImpl> scroll_layer = - LayerImpl::Create(host_impl_.active_tree(), 1); - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create( - host_impl_.active_tree(), 2, orientation(), kThumbThickness, - kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); - scrollbar->test_properties()->opacity = 0.0f; - scrollbar_layer_ = scrollbar.get(); - scrollbar_layer_->test_properties()->opacity_can_animate = true; - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_.active_tree(), 3); - - scroll_layer->SetScrollable(gfx::Size(100, 100)); - scroll_layer->SetElementId( - LayerIdToElementIdForTesting(scroll_layer->id())); - LayerImpl* scroll_layer_ptr = scroll_layer.get(); - scroll_layer->test_properties()->AddChild(std::move(scrollbar)); - root->test_properties()->AddChild(std::move(scroll_layer)); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); - - scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id()); - scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - DCHECK(host_impl_.active_tree()->ScrollbarGeometriesNeedUpdate()); - host_impl_.active_tree()->UpdateScrollbarGeometries(); + + LayerImpl* root = root_layer(); + scroll_layer_ = AddLayer<LayerImpl>(); + scrollbar_layer_ = AddLayer<SolidColorScrollbarLayerImpl>( + orientation(), kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar); + SetElementIdsForTesting(); + + scroll_layer_->SetBounds(gfx::Size(200, 200)); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); + CopyProperties(root, scroll_layer_); + CreateTransformNode(scroll_layer_); + CreateScrollNode(scroll_layer_); + + scrollbar_layer_->SetScrollElementId(scroll_layer_->element_id()); + CopyProperties(scroll_layer_, scrollbar_layer_); + auto& scrollbar_effect = CreateEffectNode(scrollbar_layer_); + scrollbar_effect.opacity = 0.f; + scrollbar_effect.has_potential_opacity_animation = true; + + UpdateActiveTreeDrawProperties(); scrollbar_controller_ = ScrollbarAnimationController::CreateScrollbarAnimationControllerAndroid( - scroll_layer_ptr->element_id(), this, - base::TimeDelta::FromSeconds(2), base::TimeDelta::FromSeconds(3), - 0.0f); + scroll_layer_->element_id(), this, base::TimeDelta::FromSeconds(2), + base::TimeDelta::FromSeconds(3), 0.0f); } virtual ScrollbarOrientation orientation() const { return HORIZONTAL; } - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; std::unique_ptr<ScrollbarAnimationController> scrollbar_controller_; + LayerImpl* scroll_layer_; SolidColorScrollbarLayerImpl* scrollbar_layer_; base::OnceClosure start_fade_; @@ -1490,15 +1467,14 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, } TEST_F(ScrollbarAnimationControllerAndroidTest, HideOnResize) { - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - ASSERT_TRUE(scroll_layer); - EXPECT_EQ(gfx::Size(200, 200), scroll_layer->bounds()); + EXPECT_EQ(gfx::Size(200, 200), scroll_layer_->bounds()); EXPECT_EQ(HORIZONTAL, scrollbar_layer_->orientation()); // Shrink along X axis, horizontal scrollbar should appear. - scroll_layer->SetScrollable(gfx::Size(100, 200)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(100, 200)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(100, 200); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); scrollbar_controller_->DidScrollUpdate(); @@ -1507,8 +1483,9 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, HideOnResize) { // Shrink along Y axis and expand along X, horizontal scrollbar // should disappear. - scroll_layer->SetScrollable(gfx::Size(200, 100)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(200, 100)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(200, 100); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); @@ -1519,15 +1496,14 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, HideOnResize) { } TEST_F(VerticalScrollbarAnimationControllerAndroidTest, HideOnResize) { - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - ASSERT_TRUE(scroll_layer); - EXPECT_EQ(gfx::Size(200, 200), scroll_layer->bounds()); + EXPECT_EQ(gfx::Size(200, 200), scroll_layer_->bounds()); EXPECT_EQ(VERTICAL, scrollbar_layer_->orientation()); // Shrink along X axis, vertical scrollbar should remain invisible. - scroll_layer->SetScrollable(gfx::Size(100, 200)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(100, 200)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(100, 200); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); scrollbar_controller_->DidScrollUpdate(); @@ -1535,8 +1511,9 @@ TEST_F(VerticalScrollbarAnimationControllerAndroidTest, HideOnResize) { scrollbar_controller_->DidScrollEnd(); // Shrink along Y axis and expand along X, vertical scrollbar should appear. - scroll_layer->SetScrollable(gfx::Size(200, 100)); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scroll_layer_->SetScrollable(gfx::Size(200, 100)); + GetScrollNode(scroll_layer_)->container_bounds = gfx::Size(200, 100); + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); @@ -1549,10 +1526,8 @@ TEST_F(VerticalScrollbarAnimationControllerAndroidTest, HideOnResize) { TEST_F(ScrollbarAnimationControllerAndroidTest, HideOnUserNonScrollableHorz) { EXPECT_EQ(HORIZONTAL, scrollbar_layer_->orientation()); - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - ASSERT_TRUE(scroll_layer); - scroll_layer->test_properties()->user_scrollable_horizontal = false; - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + GetScrollNode(scroll_layer_)->user_scrollable_horizontal = false; + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); @@ -1565,10 +1540,8 @@ TEST_F(ScrollbarAnimationControllerAndroidTest, HideOnUserNonScrollableHorz) { TEST_F(ScrollbarAnimationControllerAndroidTest, ShowOnUserNonScrollableVert) { EXPECT_EQ(HORIZONTAL, scrollbar_layer_->orientation()); - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - ASSERT_TRUE(scroll_layer); - scroll_layer->test_properties()->user_scrollable_vertical = false; - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + GetScrollNode(scroll_layer_)->user_scrollable_vertical = false; + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); @@ -1582,10 +1555,8 @@ TEST_F(VerticalScrollbarAnimationControllerAndroidTest, HideOnUserNonScrollableVert) { EXPECT_EQ(VERTICAL, scrollbar_layer_->orientation()); - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - ASSERT_TRUE(scroll_layer); - scroll_layer->test_properties()->user_scrollable_vertical = false; - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + GetScrollNode(scroll_layer_)->user_scrollable_vertical = false; + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); @@ -1599,10 +1570,8 @@ TEST_F(VerticalScrollbarAnimationControllerAndroidTest, ShowOnUserNonScrollableHorz) { EXPECT_EQ(VERTICAL, scrollbar_layer_->orientation()); - LayerImpl* scroll_layer = host_impl_.active_tree()->LayerById(1); - ASSERT_TRUE(scroll_layer); - scroll_layer->test_properties()->user_scrollable_horizontal = false; - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + GetScrollNode(scroll_layer_)->user_scrollable_horizontal = false; + UpdateActiveTreeDrawProperties(); scrollbar_controller_->DidScrollBegin(); diff --git a/chromium/cc/input/scrollbar_controller.cc b/chromium/cc/input/scrollbar_controller.cc index b66d42df486..2f4221e3d59 100644 --- a/chromium/cc/input/scrollbar_controller.cc +++ b/chromium/cc/input/scrollbar_controller.cc @@ -26,38 +26,13 @@ ScrollbarController::ScrollbarController( : layer_tree_host_impl_(layer_tree_host_impl), scrollbar_scroll_is_active_(false), currently_captured_scrollbar_(nullptr), - previous_pointer_position_(gfx::PointF(0, 0)), + last_known_pointer_position_(gfx::PointF(0, 0)), drag_processed_for_current_frame_(false), cancelable_autoscroll_task_(nullptr) {} void ScrollbarController::WillBeginImplFrame() { drag_processed_for_current_frame_ = false; - if (!autoscroll_state_.has_value()) - return; - - // TODO(arakeri): Revisit this when addressing crbug.com/967004. The - // animations need to be aborted/restarted based on the pointer location (i.e - // leaving/entering the track/arrows, reaching the track end etc). The - // autoscroll_state_ however, needs to be reset on pointer changes. - if (ShouldCancelTrackAutoscroll()) - layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort(); - - // When the scroller is autoscrolling forward, its dimensions need to be - // monitored. If the length of the scroller layer increases, the old one needs - // to be aborted and a new autoscroll animation needs to start. This needs to - // be done only for the "autoscroll forward" case. Autoscrolling backward - // always has a constant value to animate to (which is '0'. See the function - // ScrollbarController::StartAutoScrollAnimation). - if (autoscroll_state_->direction == AutoScrollDirection::AUTOSCROLL_FORWARD) { - const float scroll_layer_length = - currently_captured_scrollbar_->scroll_layer_length(); - if (autoscroll_state_->scroll_layer_length != scroll_layer_length) { - layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort(); - StartAutoScrollAnimation( - autoscroll_state_->velocity, - currently_captured_scrollbar_->scroll_element_id()); - } - } + RecomputeAutoscrollStateIfNeeded(); } gfx::Vector2dF ScrollbarController::GetThumbRelativePoint( @@ -78,16 +53,20 @@ gfx::Vector2dF ScrollbarController::GetThumbRelativePoint( // Performs hit test and prepares scroll deltas that will be used by GSB and // GSU. InputHandlerPointerResult ScrollbarController::HandlePointerDown( - const gfx::PointF position_in_widget) { - InputHandlerPointerResult scroll_result; + const gfx::PointF position_in_widget, + bool shift_modifier) { LayerImpl* layer_impl = GetLayerHitByPoint(position_in_widget); // If a non-custom scrollbar layer was not found, we return early as there is - // no point in setting additional state in the ScrollbarController. + // no point in setting additional state in the ScrollbarController. Return an + // empty InputHandlerPointerResult in this case so that when it is bubbled up + // to InputHandlerProxy::RouteToTypeSpecificHandler, the pointer event gets + // passed on to the main thread. if (!(layer_impl && layer_impl->ToScrollbarLayer())) - return scroll_result; + return InputHandlerPointerResult(); currently_captured_scrollbar_ = layer_impl->ToScrollbarLayer(); + InputHandlerPointerResult scroll_result; scroll_result.target_scroller = currently_captured_scrollbar_->scroll_element_id(); scroll_result.type = PointerResultType::kScrollbarScroll; @@ -95,18 +74,21 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown( const ScrollbarPart scrollbar_part = GetScrollbarPartFromPointerDown(position_in_widget); scroll_result.scroll_offset = GetScrollOffsetForScrollbarPart( - scrollbar_part, currently_captured_scrollbar_->orientation()); - previous_pointer_position_ = position_in_widget; + scrollbar_part, currently_captured_scrollbar_->orientation(), + shift_modifier); + last_known_pointer_position_ = position_in_widget; scrollbar_scroll_is_active_ = true; + scroll_result.scroll_units = Granularity(scrollbar_part, shift_modifier); if (scrollbar_part == ScrollbarPart::THUMB) { - scroll_result.scroll_units = - ui::input_types::ScrollGranularity::kScrollByPrecisePixel; - drag_anchor_relative_to_thumb_ = GetThumbRelativePoint(position_in_widget); - } else { - // TODO(arakeri): This needs to be updated to kLine once cc implements - // handling it. crbug.com/959441 - scroll_result.scroll_units = - ui::input_types::ScrollGranularity::kScrollByPixel; + drag_state_ = DragState(); + drag_state_->anchor_relative_to_thumb_ = + GetThumbRelativePoint(position_in_widget); + + // Record the current scroller offset. This will be needed to snap the + // thumb back to its original position if the pointer moves too far away + // from the track during a thumb drag. + drag_state_->scroll_position_at_start_ = + currently_captured_scrollbar_->current_pos(); } if (!scroll_result.scroll_offset.IsZero()) { @@ -120,7 +102,8 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown( &ScrollbarController::StartAutoScrollAnimation, base::Unretained(this), InitialDeltaToAutoscrollVelocity(scroll_result.scroll_offset), - currently_captured_scrollbar_->scroll_element_id())); + currently_captured_scrollbar_->scroll_element_id(), + scrollbar_part)); layer_tree_host_impl_->task_runner_provider() ->ImplThreadTaskRunner() ->PostDelayedTask(FROM_HERE, cancelable_autoscroll_task_->callback(), @@ -129,14 +112,134 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown( return scroll_result; } +bool ScrollbarController::SnapToDragOrigin( + const gfx::PointF pointer_position_in_widget) { + // Consult the ScrollbarTheme to check if thumb snapping is supported on the + // current platform. + if (!currently_captured_scrollbar_->SupportsDragSnapBack()) + return false; + + bool clipped = false; + const gfx::PointF pointer_position_in_layer = + GetScrollbarRelativePosition(pointer_position_in_widget, &clipped); + + if (clipped) + return false; + + layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries(); + const ScrollbarOrientation orientation = + currently_captured_scrollbar_->orientation(); + const gfx::Rect forward_track_rect = + currently_captured_scrollbar_->ForwardTrackRect(); + + // When dragging the thumb, there needs to exist "gutters" on either side of + // the track. The thickness of these gutters is a multiple of the track (or + // thumb) thickness. As long as the pointer remains within the bounds of these + // gutters in the non-scrolling direction, thumb drag proceeds as expected. + // The moment the pointer moves outside the bounds, the scroller needs to snap + // back to the drag_origin (aka the scroll offset of the parent scroller + // before the thumb drag initiated). + int track_thickness = orientation == ScrollbarOrientation::VERTICAL + ? forward_track_rect.width() + : forward_track_rect.height(); + + if (!track_thickness) { + // For overlay scrollbars (or for tests that do not set up a track + // thickness), use the thumb_thickness instead to determine the gutters. + const int thumb_thickness = currently_captured_scrollbar_->ThumbThickness(); + + // If the thumb doesn't have thickness, the gutters can't be determined. + // Snapping shouldn't occur in this case. + if (!thumb_thickness) + return false; + + track_thickness = thumb_thickness; + } + + const float gutter_thickness = kOffSideMultiplier * track_thickness; + const float gutter_min_bound = + orientation == ScrollbarOrientation::VERTICAL + ? (forward_track_rect.x() - gutter_thickness) + : (forward_track_rect.y() - gutter_thickness); + const float gutter_max_bound = + orientation == ScrollbarOrientation::VERTICAL + ? (forward_track_rect.x() + track_thickness + gutter_thickness) + : (forward_track_rect.y() + track_thickness + gutter_thickness); + + const float pointer_location = orientation == ScrollbarOrientation::VERTICAL + ? pointer_position_in_layer.x() + : pointer_position_in_layer.y(); + + return pointer_location < gutter_min_bound || + pointer_location > gutter_max_bound; +} + +ui::input_types::ScrollGranularity ScrollbarController::Granularity( + const ScrollbarPart scrollbar_part, + const bool shift_modifier) { + const bool shift_click_on_scrollbar_track = + shift_modifier && (scrollbar_part == ScrollbarPart::FORWARD_TRACK || + scrollbar_part == ScrollbarPart::BACK_TRACK); + if (shift_click_on_scrollbar_track || scrollbar_part == ScrollbarPart::THUMB) + return ui::input_types::ScrollGranularity::kScrollByPrecisePixel; + + // TODO(arakeri): This needs to be updated to kLine once cc implements + // handling it. crbug.com/959441 + return ui::input_types::ScrollGranularity::kScrollByPixel; +} + +float ScrollbarController::GetScrollDeltaForShiftClick() { + layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries(); + + bool clipped = false; + const gfx::PointF pointer_position_in_layer = + GetScrollbarRelativePosition(last_known_pointer_position_, &clipped); + + if (clipped) + return 0; + + const ScrollbarOrientation orientation = + currently_captured_scrollbar_->orientation(); + const float pointer_location = orientation == ScrollbarOrientation::VERTICAL + ? pointer_position_in_layer.y() + : pointer_position_in_layer.x(); + + // During a shift + click, the pointers current location (on the track) needs + // to be considered as the center of the thumb and the thumb origin needs to + // be calculated based on that. This will ensure that when shift + click is + // processed, the thumb will be centered on the pointer. + const int thumb_length = currently_captured_scrollbar_->ThumbLength(); + const float desired_thumb_origin = pointer_location - thumb_length / 2.f; + + const gfx::Rect thumb_rect( + currently_captured_scrollbar_->ComputeThumbQuadRect()); + const float current_thumb_origin = + orientation == ScrollbarOrientation::VERTICAL ? thumb_rect.y() + : thumb_rect.x(); + + const float delta = + round(std::abs(desired_thumb_origin - current_thumb_origin)); + return delta * GetScrollerToScrollbarRatio(); +} + gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition( const gfx::PointF pointer_position_in_widget) { layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries(); + const ScrollbarOrientation orientation = + currently_captured_scrollbar_->orientation(); + if (SnapToDragOrigin(pointer_position_in_widget)) { + const float delta = currently_captured_scrollbar_->current_pos() - + drag_state_->scroll_position_at_start_; + return orientation == ScrollbarOrientation::VERTICAL + ? gfx::ScrollOffset(0, -delta) + : gfx::ScrollOffset(-delta, 0); + } + const gfx::Rect thumb_rect( currently_captured_scrollbar_->ComputeThumbQuadRect()); const gfx::PointF drag_position_relative_to_layer = - gfx::PointF(thumb_rect.origin()) + drag_anchor_relative_to_thumb_.value(); + gfx::PointF(thumb_rect.origin()) + drag_state_->anchor_relative_to_thumb_; bool clipped = false; const gfx::PointF pointer_position_in_layer = @@ -149,29 +252,52 @@ gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition( const gfx::Vector2dF pointer_delta = pointer_position_in_layer - drag_position_relative_to_layer; + float scaled_scroller_to_scrollbar_ratio = GetScrollerToScrollbarRatio(); + float current_scroll_position = currently_captured_scrollbar_->current_pos(); + + // Thumb position needs to be floored and Values between 0 and 1 are rounded + // to one to match main thread per pixel behavior. Corresponding main thread + // code in ScrollbarTheme::ThumbPosition + float thumb_position = std::max(0.0f, current_scroll_position) / + scaled_scroller_to_scrollbar_ratio; + thumb_position = (thumb_position < 1.0 && thumb_position > 0.0) + ? 1.0 + : floorf(thumb_position); + + float delta_in_orientation = orientation == ScrollbarOrientation::VERTICAL + ? pointer_delta.y() + : pointer_delta.x(); + + // This is effectively equal to delta_in_orientation * + // scaled_scroller_to_scrollbar_ratio but is necessary due to truncated delta + // value. Floored thumb_position cancels out the rounding error introduced + // in pointer_delta due to static_cast<int> in + // ScrollbarLayerImplBase::ComputeThumbQuadRectWithThumbThicknessScale + float scroll_delta = (delta_in_orientation + thumb_position) * + scaled_scroller_to_scrollbar_ratio - + current_scroll_position; + gfx::ScrollOffset scaled_thumb_drag_delta; - const ScrollbarOrientation orientation = - currently_captured_scrollbar_->orientation(); + + // Scroll delta floored to match main thread per pixel behavior orientation == ScrollbarOrientation::VERTICAL - ? scaled_thumb_drag_delta.set_y(pointer_delta.y()) - : scaled_thumb_drag_delta.set_x(pointer_delta.x()); + ? scaled_thumb_drag_delta.set_y(floorf(scroll_delta)) + : scaled_thumb_drag_delta.set_x(floorf(scroll_delta)); - float scaled_scroller_to_scrollbar_ratio = GetScrollerToScrollbarRatio(); - scaled_thumb_drag_delta.Scale(scaled_scroller_to_scrollbar_ratio); return scaled_thumb_drag_delta; } // Performs hit test and prepares scroll deltas that will be used by GSU. -InputHandlerPointerResult ScrollbarController::HandleMouseMove( +InputHandlerPointerResult ScrollbarController::HandlePointerMove( const gfx::PointF position_in_widget) { - previous_pointer_position_ = position_in_widget; + last_known_pointer_position_ = position_in_widget; + RecomputeAutoscrollStateIfNeeded(); InputHandlerPointerResult scroll_result; // If a thumb drag is not in progress or if a GSU was already produced for a // thumb drag in this frame, there's no point in continuing on. Please see the // header file for details. - if (!drag_anchor_relative_to_thumb_.has_value() || - drag_processed_for_current_frame_) + if (!drag_state_.has_value() || drag_processed_for_current_frame_) return scroll_result; const ScrollNode* currently_scrolling_node = @@ -180,7 +306,7 @@ InputHandlerPointerResult ScrollbarController::HandleMouseMove( // Thumb drag needs a scroll_node. Clear the thumb drag state and exit if it // is unset. if (currently_scrolling_node == nullptr) { - drag_anchor_relative_to_thumb_ = base::nullopt; + drag_state_ = base::nullopt; return scroll_result; } @@ -258,30 +384,27 @@ float ScrollbarController::GetScrollerToScrollbarRatio() { const LayerImpl* owner_scroll_layer = layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId( currently_captured_scrollbar_->scroll_element_id()); - float viewport_length = + const float viewport_length = orientation == ScrollbarOrientation::VERTICAL ? owner_scroll_layer->scroll_container_bounds().height() : (owner_scroll_layer->scroll_container_bounds().width()); + + // For platforms which have use_zoom_for_dsf set to false (like Mac), the + // device_scale_factor should not be used while determining the + // scaled_scroller_to_scrollbar_ratio as thumb drag would appear jittery due + // to constant over and under corrections. + // (See ScrollbarController::ScreenSpaceScaleFactor()). float scaled_scroller_to_scrollbar_ratio = ((scroll_layer_length - viewport_length) / (scrollbar_track_length - scrollbar_thumb_length)) * - layer_tree_host_impl_->active_tree()->device_scale_factor(); - - // Avoid precision loss later on by rounding up 3 decimal places here. - // TODO(arakeri): Revisit this while fixing crbug.com/986174. There is a - // precision loss that is happening somewhere which affects root scrollbars - // only. Even though it is not visible to the end user, without rounding up, - // the scrolling tests will fail due to this precision loss. - DCHECK_GT(scaled_scroller_to_scrollbar_ratio, 0); - scaled_scroller_to_scrollbar_ratio = - ceil(scaled_scroller_to_scrollbar_ratio * 1000.0) / 1000.0; + ScreenSpaceScaleFactor(); return scaled_scroller_to_scrollbar_ratio; } -bool ScrollbarController::ShouldCancelTrackAutoscroll() { - // This function should only ever be called if an autoscroll is in progress. - DCHECK(autoscroll_state_.has_value()); +void ScrollbarController::RecomputeAutoscrollStateIfNeeded() { + if (!autoscroll_state_.has_value()) + return; layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries(); const ScrollbarOrientation orientation = @@ -291,10 +414,10 @@ bool ScrollbarController::ShouldCancelTrackAutoscroll() { bool clipped; gfx::PointF scroller_relative_position( - GetScrollbarRelativePosition(previous_pointer_position_, &clipped)); + GetScrollbarRelativePosition(last_known_pointer_position_, &clipped)); if (clipped) - return false; + return; // Based on the orientation of the scrollbar and the direction of the // autoscroll, the code below makes a decision of whether the track autoscroll @@ -312,15 +435,49 @@ bool ScrollbarController::ShouldCancelTrackAutoscroll() { pointer_position = scroller_relative_position.x(); } + // If the thumb reaches the pointer while autoscrolling, abort. if ((autoscroll_state_->direction == AutoScrollDirection::AUTOSCROLL_FORWARD && thumb_end > pointer_position) || (autoscroll_state_->direction == AutoScrollDirection::AUTOSCROLL_BACKWARD && thumb_start < pointer_position)) - return true; + layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort(); + + // When the scroller is autoscrolling forward, its dimensions need to be + // monitored. If the length of the scroller layer increases, the old one needs + // to be aborted and a new autoscroll animation needs to start. This needs to + // be done only for the "autoscroll forward" case. Autoscrolling backward + // always has a constant value to animate to (which is '0'. See the function + // ScrollbarController::StartAutoScrollAnimation). + if (autoscroll_state_->direction == AutoScrollDirection::AUTOSCROLL_FORWARD) { + const float scroll_layer_length = + currently_captured_scrollbar_->scroll_layer_length(); + if (autoscroll_state_->scroll_layer_length != scroll_layer_length) { + layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort(); + StartAutoScrollAnimation( + autoscroll_state_->velocity, + currently_captured_scrollbar_->scroll_element_id(), + autoscroll_state_->pressed_scrollbar_part); + } + } - return false; + // The animations need to be aborted/restarted based on the pointer location + // (i.e leaving/entering the track/arrows, reaching the track end etc). The + // autoscroll_state_ however, needs to be reset on pointer changes. + const gfx::RectF scrollbar_part_rect( + GetRectForScrollbarPart(autoscroll_state_->pressed_scrollbar_part)); + if (!scrollbar_part_rect.Contains(scroller_relative_position)) { + // Stop animating if pointer moves outside the rect bounds. + layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort(); + } else if (scrollbar_part_rect.Contains(scroller_relative_position) && + !layer_tree_host_impl_->mutator_host()->IsElementAnimating( + currently_captured_scrollbar_->scroll_element_id())) { + // Start animating if pointer re-enters the bounds. + StartAutoScrollAnimation(autoscroll_state_->velocity, + currently_captured_scrollbar_->scroll_element_id(), + autoscroll_state_->pressed_scrollbar_part); + } } // Helper to calculate the autoscroll velocity. @@ -333,11 +490,13 @@ float ScrollbarController::InitialDeltaToAutoscrollVelocity( return scroll_delta * kAutoscrollMultiplier; } -void ScrollbarController::StartAutoScrollAnimation(const float velocity, - ElementId element_id) { +void ScrollbarController::StartAutoScrollAnimation( + const float velocity, + ElementId element_id, + ScrollbarPart pressed_scrollbar_part) { // Autoscroll and thumb drag are mutually exclusive. Both can't be active at // the same time. - DCHECK(!drag_anchor_relative_to_thumb_.has_value()); + DCHECK(!drag_state_.has_value()); DCHECK_NE(velocity, 0); // scroll_node is set up while handling GSB. If there's no node to scroll, we @@ -372,6 +531,7 @@ void ScrollbarController::StartAutoScrollAnimation(const float velocity, autoscroll_state_ = AutoScrollState(); autoscroll_state_->velocity = velocity; autoscroll_state_->scroll_layer_length = scroll_layer_length; + autoscroll_state_->pressed_scrollbar_part = pressed_scrollbar_part; autoscroll_state_->direction = velocity < 0 ? AutoScrollDirection::AUTOSCROLL_BACKWARD : AutoScrollDirection::AUTOSCROLL_FORWARD; @@ -400,7 +560,7 @@ InputHandlerPointerResult ScrollbarController::HandlePointerUp( cancelable_autoscroll_task_.reset(); } - drag_anchor_relative_to_thumb_ = base::nullopt; + drag_state_ = base::nullopt; autoscroll_state_ = base::nullopt; return scroll_result; } @@ -414,14 +574,14 @@ LayerImpl* ScrollbarController::GetLayerHitByPoint( gfx::PointF device_viewport_point = gfx::ScalePoint( gfx::PointF(viewport_point), active_tree->device_scale_factor()); LayerImpl* layer_impl = - active_tree->FindFirstScrollingLayerOrScrollbarThatIsHitByPoint( - device_viewport_point); + active_tree->FindLayerThatIsHitByPoint(device_viewport_point); return layer_impl; } int ScrollbarController::GetScrollDeltaForScrollbarPart( - ScrollbarPart scrollbar_part) { + const ScrollbarPart scrollbar_part, + const bool shift_modifier) { int scroll_delta = 0; int viewport_length = 0; LayerImpl* owner_scroll_layer = nullptr; @@ -433,6 +593,10 @@ int ScrollbarController::GetScrollDeltaForScrollbarPart( break; case ScrollbarPart::BACK_TRACK: case ScrollbarPart::FORWARD_TRACK: + if (shift_modifier) { + scroll_delta = GetScrollDeltaForShiftClick(); + break; + } owner_scroll_layer = layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId( currently_captured_scrollbar_->scroll_element_id()); @@ -446,8 +610,20 @@ int ScrollbarController::GetScrollDeltaForScrollbarPart( default: scroll_delta = 0; } - return scroll_delta * - layer_tree_host_impl_->active_tree()->device_scale_factor(); + + return scroll_delta * ScreenSpaceScaleFactor(); +} + +float ScrollbarController::ScreenSpaceScaleFactor() const { + // TODO(arakeri): When crbug.com/716231 is fixed, this needs to be updated. + // If use_zoom_for_dsf is false, the click deltas and thumb drag ratios + // shouldn't be scaled. For example: On Mac, when the use_zoom_for_dsf is + // false and the device_scale_factor is 2, the scroll delta for pointer clicks + // on arrows would be incorrectly calculated as 80px instead of 40px. This is + // also necessary to ensure that hit testing works as intended. + return layer_tree_host_impl_->settings().use_zoom_for_dsf + ? layer_tree_host_impl_->active_tree()->device_scale_factor() + : 1.f; } gfx::PointF ScrollbarController::GetScrollbarRelativePosition( @@ -455,7 +631,17 @@ gfx::PointF ScrollbarController::GetScrollbarRelativePosition( bool* clipped) { gfx::Transform inverse_screen_space_transform( gfx::Transform::kSkipInitialization); - if (!currently_captured_scrollbar_->ScreenSpaceTransform().GetInverse( + + // If use_zoom_for_dsf is false, the ScreenSpaceTransform needs to be scaled + // down by the DSF to ensure that position_in_widget is transformed correctly. + const float scale = + !layer_tree_host_impl_->settings().use_zoom_for_dsf + ? 1.f / layer_tree_host_impl_->active_tree()->device_scale_factor() + : 1.f; + gfx::Transform scaled_screen_space_transform( + currently_captured_scrollbar_->ScreenSpaceTransform()); + scaled_screen_space_transform.PostScale(scale, scale); + if (!scaled_screen_space_transform.GetInverse( &inverse_screen_space_transform)) return gfx::PointF(0, 0); @@ -480,12 +666,28 @@ ScrollbarPart ScrollbarController::GetScrollbarPartFromPointerDown( scroller_relative_position); } +// Determines the corresponding rect for the given scrollbar part. +gfx::Rect ScrollbarController::GetRectForScrollbarPart( + const ScrollbarPart scrollbar_part) { + if (scrollbar_part == ScrollbarPart::BACK_BUTTON) + return currently_captured_scrollbar_->BackButtonRect(); + if (scrollbar_part == ScrollbarPart::FORWARD_BUTTON) + return currently_captured_scrollbar_->ForwardButtonRect(); + if (scrollbar_part == ScrollbarPart::BACK_TRACK) + return currently_captured_scrollbar_->BackTrackRect(); + if (scrollbar_part == ScrollbarPart::FORWARD_TRACK) + return currently_captured_scrollbar_->ForwardTrackRect(); + return gfx::Rect(0, 0); +} + // Determines the scroll offsets based on the ScrollbarPart and the scrollbar // orientation. gfx::ScrollOffset ScrollbarController::GetScrollOffsetForScrollbarPart( const ScrollbarPart scrollbar_part, - const ScrollbarOrientation orientation) { - float scroll_delta = GetScrollDeltaForScrollbarPart(scrollbar_part); + const ScrollbarOrientation orientation, + const bool shift_modifier) { + float scroll_delta = + GetScrollDeltaForScrollbarPart(scrollbar_part, shift_modifier); // See CreateScrollStateForGesture for more information on how these values // will be interpreted. diff --git a/chromium/cc/input/scrollbar_controller.h b/chromium/cc/input/scrollbar_controller.h index a407640ce0b..e1b13dc2e03 100644 --- a/chromium/cc/input/scrollbar_controller.h +++ b/chromium/cc/input/scrollbar_controller.h @@ -20,8 +20,9 @@ class CC_EXPORT ScrollbarController { virtual ~ScrollbarController(); InputHandlerPointerResult HandlePointerDown( - const gfx::PointF position_in_widget); - InputHandlerPointerResult HandleMouseMove( + const gfx::PointF position_in_widget, + const bool shift_modifier); + InputHandlerPointerResult HandlePointerMove( const gfx::PointF position_in_widget); InputHandlerPointerResult HandlePointerUp( const gfx::PointF position_in_widget); @@ -30,7 +31,9 @@ class CC_EXPORT ScrollbarController { // InitialDeltaToAutoscrollVelocity). This value carries a "sign" which is // needed to determine whether we should set up the autoscrolling in the // forwards or the backwards direction. - void StartAutoScrollAnimation(float velocity, ElementId element_id); + void StartAutoScrollAnimation(float velocity, + ElementId element_id, + ScrollbarPart pressed_scrollbar_part); bool ScrollbarScrollIsActive() { return scrollbar_scroll_is_active_; } ScrollbarOrientation orientation() { return currently_captured_scrollbar_->orientation(); @@ -54,8 +57,26 @@ class CC_EXPORT ScrollbarController { // Used to track the scroller length while autoscrolling. Helpful for // setting up infinite scrolling. float scroll_layer_length = 0.f; + + // Used to lookup the rect corresponding to the ScrollbarPart so that + // autoscroll animations can be played/paused depending on the current + // pointer location. + ScrollbarPart pressed_scrollbar_part; + }; + + struct CC_EXPORT DragState { + // This is used to track the pointer location relative to the thumb origin + // when a drag has started. + gfx::Vector2dF anchor_relative_to_thumb_; + + // This is needed for thumb snapping when the pointer moves too far away + // from the track while scrolling. + float scroll_position_at_start_; }; + // Returns the DSF based on whether use-zoom-for-dsf is enabled. + float ScreenSpaceScaleFactor() const; + // Helper to convert scroll offset to autoscroll velocity. float InitialDeltaToAutoscrollVelocity(gfx::ScrollOffset scroll_offset) const; @@ -66,17 +87,36 @@ class CC_EXPORT ScrollbarController { // Returns scroll offsets based on which ScrollbarPart was hit tested. gfx::ScrollOffset GetScrollOffsetForScrollbarPart( const ScrollbarPart scrollbar_part, - const ScrollbarOrientation orientation); + const ScrollbarOrientation orientation, + const bool shift_modifier); + + // Returns the rect for the ScrollbarPart. + gfx::Rect GetRectForScrollbarPart(const ScrollbarPart scrollbar_part); LayerImpl* GetLayerHitByPoint(const gfx::PointF position_in_widget); - int GetScrollDeltaForScrollbarPart(ScrollbarPart scrollbar_part); + int GetScrollDeltaForScrollbarPart(const ScrollbarPart scrollbar_part, + const bool shift_modifier); // Makes position_in_widget relative to the scrollbar. gfx::PointF GetScrollbarRelativePosition(const gfx::PointF position_in_widget, bool* clipped); - // Decides whether a track autoscroll should be aborted. - bool ShouldCancelTrackAutoscroll(); + // Decides if the scroller should snap to the offset that it was originally at + // (i.e the offset before the thumb drag). + bool SnapToDragOrigin(const gfx::PointF pointer_position_in_widget); + + // Decides whether a track autoscroll should be aborted (or restarted) due to + // the thumb reaching the pointer or the pointer leaving (or re-entering) the + // bounds. + void RecomputeAutoscrollStateIfNeeded(); + + // Shift + click is expected to do a non-animated jump to a certain offset. + float GetScrollDeltaForShiftClick(); + + // Determines if the delta needs to be animated. + ui::input_types::ScrollGranularity Granularity( + const ScrollbarPart scrollbar_part, + bool shift_modifier); // Calculates the scroll_offset based on position_in_widget and // drag_anchor_relative_to_thumb_. @@ -98,15 +138,15 @@ class CC_EXPORT ScrollbarController { const ScrollbarLayerImplBase* currently_captured_scrollbar_; // This is relative to the RenderWidget's origin. - gfx::PointF previous_pointer_position_; + gfx::PointF last_known_pointer_position_; // Holds information pertaining to autoscrolling. This member is empty if and // only if an autoscroll is *not* in progress. base::Optional<AutoScrollState> autoscroll_state_; - // This is used to track the pointer location relative to the thumb origin - // when a drag has started. It is empty if a thumb drag is *not* in progress. - base::Optional<gfx::Vector2dF> drag_anchor_relative_to_thumb_; + // Holds information pertaining to thumb drags. Useful while making decisions + // about thumb anchoring/snapping. + base::Optional<DragState> drag_state_; // Used to track if a GSU was processed for the current frame or not. Without // this, thumb drag will appear jittery. The reason this happens is because diff --git a/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc b/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc index 0515aaff879..d01e1ac2bcd 100644 --- a/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc +++ b/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc @@ -7,6 +7,7 @@ #include <algorithm> #include "base/memory/ptr_util.h" +#include "base/numerics/ranges.h" #include "base/time/time.h" #include "cc/input/scrollbar_animation_controller.h" #include "cc/layers/layer_impl.h" @@ -95,7 +96,7 @@ float SingleScrollbarAnimationControllerThinning::AnimationProgressAtTime( base::TimeTicks now) { base::TimeDelta delta = now - last_awaken_time_; float progress = delta.InSecondsF() / Duration().InSecondsF(); - return std::max(std::min(progress, 1.f), 0.f); + return base::ClampToRange(progress, 0.0f, 1.0f); } const base::TimeDelta& SingleScrollbarAnimationControllerThinning::Duration() { diff --git a/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc b/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc index a08e6aa8838..b851a58f77f 100644 --- a/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc +++ b/chromium/cc/input/single_scrollbar_animation_controller_thinning_unittest.cc @@ -5,10 +5,8 @@ #include "cc/input/single_scrollbar_animation_controller_thinning.h" #include "cc/layers/solid_color_scrollbar_layer_impl.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/test_task_graph_runner.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -51,62 +49,49 @@ class MockSingleScrollbarAnimationControllerClient LayerTreeHostImpl* host_impl_; }; -class SingleScrollbarAnimationControllerThinningTest : public testing::Test { +class SingleScrollbarAnimationControllerThinningTest + : public LayerTreeImplTestBase, + public testing::Test { public: - SingleScrollbarAnimationControllerThinningTest() - : host_impl_(&task_runner_provider_, &task_graph_runner_), - client_(&host_impl_) {} + SingleScrollbarAnimationControllerThinningTest() : client_(host_impl()) {} protected: const base::TimeDelta kThinningDuration = base::TimeDelta::FromSeconds(2); void SetUp() override { - std::unique_ptr<LayerImpl> scroll_layer = - LayerImpl::Create(host_impl_.active_tree(), 1); - std::unique_ptr<LayerImpl> clip = - LayerImpl::Create(host_impl_.active_tree(), 3); + root_layer()->SetBounds(gfx::Size(100, 100)); + auto* scroll_layer = AddLayer<LayerImpl>(); + scroll_layer->SetBounds(gfx::Size(200, 200)); + scroll_layer->SetScrollable(gfx::Size(100, 100)); scroll_layer->SetElementId( LayerIdToElementIdForTesting(scroll_layer->id())); - clip_layer_ = clip.get(); - LayerImpl* scroll_layer_ptr = scroll_layer.get(); - const int kId = 2; const int kThumbThickness = 10; const int kTrackStart = 0; const int kTrackLength = 100; const bool kIsLeftSideVerticalScrollbar = false; - const bool kIsOverlayScrollbar = true; - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create( - host_impl_.active_tree(), kId, HORIZONTAL, kThumbThickness, - kTrackStart, kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); - scrollbar_layer_ = scrollbar.get(); - - scroll_layer->test_properties()->AddChild(std::move(scrollbar)); - clip_layer_->test_properties()->AddChild(std::move(scroll_layer)); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(clip)); + scrollbar_layer_ = AddLayer<SolidColorScrollbarLayerImpl>( + HORIZONTAL, kThumbThickness, kTrackStart, kIsLeftSideVerticalScrollbar); scrollbar_layer_->SetBounds(gfx::Size(kThumbThickness, kTrackLength)); - scrollbar_layer_->test_properties()->position = gfx::PointF(90, 0); - scrollbar_layer_->SetScrollElementId(scroll_layer_ptr->element_id()); - scrollbar_layer_->test_properties()->opacity_can_animate = true; - clip_layer_->SetBounds(gfx::Size(100, 100)); - scroll_layer_ptr->SetBounds(gfx::Size(200, 200)); - host_impl_.active_tree()->UpdateScrollbarGeometries(); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + scrollbar_layer_->SetScrollElementId(scroll_layer->element_id()); + + CopyProperties(root_layer(), scroll_layer); + CreateTransformNode(scroll_layer); + CreateScrollNode(scroll_layer); + CopyProperties(scroll_layer, scrollbar_layer_); + scrollbar_layer_->SetOffsetToTransformParent(gfx::Vector2dF(90, 0)); + CreateEffectNode(scrollbar_layer_).has_potential_opacity_animation = true; + + UpdateActiveTreeDrawProperties(); scrollbar_controller_ = SingleScrollbarAnimationControllerThinning::Create( - scroll_layer_ptr->element_id(), HORIZONTAL, &client_, - kThinningDuration); + scroll_layer->element_id(), HORIZONTAL, &client_, kThinningDuration); } - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; std::unique_ptr<SingleScrollbarAnimationControllerThinning> scrollbar_controller_; - LayerImpl* clip_layer_; SolidColorScrollbarLayerImpl* scrollbar_layer_; NiceMock<MockSingleScrollbarAnimationControllerClient> client_; }; diff --git a/chromium/cc/layers/effect_tree_layer_list_iterator.cc b/chromium/cc/layers/effect_tree_layer_list_iterator.cc index dad096110a2..9270f7d4ddf 100644 --- a/chromium/cc/layers/effect_tree_layer_list_iterator.cc +++ b/chromium/cc/layers/effect_tree_layer_list_iterator.cc @@ -9,17 +9,16 @@ namespace cc { EffectTreeLayerListIterator::EffectTreeLayerListIterator( LayerTreeImpl* layer_tree_impl) : state_(EffectTreeLayerListIterator::State::END), + layer_list_iterator_(layer_tree_impl->rbegin()), current_effect_tree_index_(EffectTree::kInvalidNodeId), next_effect_tree_index_(EffectTree::kInvalidNodeId), lowest_common_effect_tree_ancestor_index_(EffectTree::kInvalidNodeId), layer_tree_impl_(layer_tree_impl), effect_tree_(&layer_tree_impl->property_trees()->effect_tree) { - layer_list_iterator_ = layer_tree_impl->rbegin(); - // Find the front-most drawn layer. while (layer_list_iterator_ != layer_tree_impl->rend() && !(*layer_list_iterator_)->contributes_to_drawn_render_surface()) { - layer_list_iterator_++; + ++layer_list_iterator_; } // If there are no drawn layers, start at the root render surface, if it @@ -46,10 +45,10 @@ void EffectTreeLayerListIterator::operator++() { switch (state_) { case State::LAYER: // Find the next drawn layer. - layer_list_iterator_++; + ++layer_list_iterator_; while (layer_list_iterator_ != layer_tree_impl_->rend() && !(*layer_list_iterator_)->contributes_to_drawn_render_surface()) { - layer_list_iterator_++; + ++layer_list_iterator_; } if (layer_list_iterator_ == layer_tree_impl_->rend()) { next_effect_tree_index_ = EffectTree::kInvalidNodeId; diff --git a/chromium/cc/layers/effect_tree_layer_list_iterator.h b/chromium/cc/layers/effect_tree_layer_list_iterator.h index c9991638ed0..577e14b5f96 100644 --- a/chromium/cc/layers/effect_tree_layer_list_iterator.h +++ b/chromium/cc/layers/effect_tree_layer_list_iterator.h @@ -99,7 +99,7 @@ class CC_EXPORT EffectTreeLayerListIterator { // When in state LAYER, this is the layer that's currently being visited. // Otherwise, this is the layer that will be visited the next time we're in // state LAYER. - LayerImplList::reverse_iterator layer_list_iterator_; + LayerTreeImpl::const_reverse_iterator layer_list_iterator_; // When in state LAYER, this is the render target effect tree index for the // currently visited layer. Otherwise, this is the the effect tree index of diff --git a/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc b/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc index ec167fc98dc..fc595f897f4 100644 --- a/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc +++ b/chromium/cc/layers/effect_tree_layer_list_iterator_unittest.cc @@ -9,9 +9,8 @@ #include "base/memory/ptr_util.h" #include "cc/layers/layer.h" #include "cc/test/fake_layer_tree_host.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_common.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "ui/gfx/transform.h" @@ -44,19 +43,23 @@ class TestLayerImpl : public LayerImpl { } \ EXPECT_EQ(itself, layer->count_); -class EffectTreeLayerListIteratorTest : public testing::Test { +class EffectTreeLayerListIteratorTest : public LayerTreeImplTestBase, + public testing::Test { public: - EffectTreeLayerListIteratorTest() - : host_impl_(&task_runner_provider_, &task_graph_runner_), id_(1) {} - - std::unique_ptr<TestLayerImpl> CreateLayer() { - return TestLayerImpl::Create(host_impl_.active_tree(), id_++); + void SetUp() override { + // This test suite needs the root layer to be TestLayerImpl. + LayerTreeImpl* active_tree = host_impl()->active_tree(); + active_tree->DetachLayers(); + active_tree->property_trees()->clear(); + active_tree->SetRootLayerForTesting(TestLayerImpl::Create(active_tree, 1)); + root_layer()->SetBounds(gfx::Size(1, 1)); + SetupRootProperties(root_layer()); } void IterateFrontToBack() { ResetCounts(); int count = 0; - for (EffectTreeLayerListIterator it(host_impl_.active_tree()); + for (EffectTreeLayerListIterator it(host_impl()->active_tree()); it.state() != EffectTreeLayerListIterator::State::END; ++it, ++count) { switch (it.state()) { case EffectTreeLayerListIterator::State::LAYER: @@ -77,23 +80,17 @@ class EffectTreeLayerListIteratorTest : public testing::Test { } void ResetCounts() { - for (LayerImpl* layer : *host_impl_.active_tree()) { + for (LayerImpl* layer : *host_impl()->active_tree()) { static_cast<TestLayerImpl*>(layer)->count_ = -1; } target_surface_count_ = std::vector<int>( - host_impl_.active_tree()->property_trees()->effect_tree.size(), -1); + host_impl()->active_tree()->property_trees()->effect_tree.size(), -1); contributing_surface_count_ = std::vector<int>( - host_impl_.active_tree()->property_trees()->effect_tree.size(), -1); + host_impl()->active_tree()->property_trees()->effect_tree.size(), -1); } protected: - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; - - int id_; - // Tracks when each render surface is visited as a target surface or // contributing surface. Indexed by effect node id. std::vector<int> target_surface_count_; @@ -101,155 +98,76 @@ class EffectTreeLayerListIteratorTest : public testing::Test { }; TEST_F(EffectTreeLayerListIteratorTest, TreeWithNoDrawnLayers) { - std::unique_ptr<TestLayerImpl> root_layer = CreateLayer(); - root_layer->SetDrawsContent(false); - - TestLayerImpl* root_ptr = root_layer.get(); - - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root_layer)); + auto* root = static_cast<TestLayerImpl*>(root_layer()); + root->SetDrawsContent(false); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, gfx::Rect(root_ptr->bounds()), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateActiveTreeDrawProperties(); IterateFrontToBack(); - EXPECT_COUNT(root_ptr, 0, -1, -1); + EXPECT_COUNT(root, 0, -1, -1); } TEST_F(EffectTreeLayerListIteratorTest, SimpleTree) { - std::unique_ptr<TestLayerImpl> root_layer = CreateLayer(); - std::unique_ptr<TestLayerImpl> first = CreateLayer(); - std::unique_ptr<TestLayerImpl> second = CreateLayer(); - std::unique_ptr<TestLayerImpl> third = CreateLayer(); - std::unique_ptr<TestLayerImpl> fourth = CreateLayer(); - - TestLayerImpl* root_ptr = root_layer.get(); - TestLayerImpl* first_ptr = first.get(); - TestLayerImpl* second_ptr = second.get(); - TestLayerImpl* third_ptr = third.get(); - TestLayerImpl* fourth_ptr = fourth.get(); - - root_layer->test_properties()->AddChild(std::move(first)); - root_layer->test_properties()->AddChild(std::move(second)); - root_layer->test_properties()->AddChild(std::move(third)); - root_layer->test_properties()->AddChild(std::move(fourth)); - - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root_layer)); - - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, gfx::Rect(root_ptr->bounds()), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + auto* root = static_cast<TestLayerImpl*>(root_layer()); + auto* first = AddLayer<TestLayerImpl>(); + CopyProperties(root, first); + auto* second = AddLayer<TestLayerImpl>(); + CopyProperties(root, second); + auto* third = AddLayer<TestLayerImpl>(); + CopyProperties(root, third); + auto* fourth = AddLayer<TestLayerImpl>(); + CopyProperties(root, fourth); + + UpdateActiveTreeDrawProperties(); IterateFrontToBack(); - EXPECT_COUNT(root_ptr, 5, -1, 4); - EXPECT_COUNT(first_ptr, 5, -1, 3); - EXPECT_COUNT(second_ptr, 5, -1, 2); - EXPECT_COUNT(third_ptr, 5, -1, 1); - EXPECT_COUNT(fourth_ptr, 5, -1, 0); + EXPECT_COUNT(root, 5, -1, 4); + EXPECT_COUNT(first, 5, -1, 3); + EXPECT_COUNT(second, 5, -1, 2); + EXPECT_COUNT(third, 5, -1, 1); + EXPECT_COUNT(fourth, 5, -1, 0); } -TEST_F(EffectTreeLayerListIteratorTest, ComplexTree) { - std::unique_ptr<TestLayerImpl> root_layer = CreateLayer(); - std::unique_ptr<TestLayerImpl> root1 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root2 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root3 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root21 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root22 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root23 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root221 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root231 = CreateLayer(); - - TestLayerImpl* root_ptr = root_layer.get(); - TestLayerImpl* root1_ptr = root1.get(); - TestLayerImpl* root2_ptr = root2.get(); - TestLayerImpl* root3_ptr = root3.get(); - TestLayerImpl* root21_ptr = root21.get(); - TestLayerImpl* root22_ptr = root22.get(); - TestLayerImpl* root23_ptr = root23.get(); - TestLayerImpl* root221_ptr = root221.get(); - TestLayerImpl* root231_ptr = root231.get(); - - root22->test_properties()->AddChild(std::move(root221)); - root23->test_properties()->AddChild(std::move(root231)); - root2->test_properties()->AddChild(std::move(root21)); - root2->test_properties()->AddChild(std::move(root22)); - root2->test_properties()->AddChild(std::move(root23)); - root_layer->test_properties()->AddChild(std::move(root1)); - root_layer->test_properties()->AddChild(std::move(root2)); - root_layer->test_properties()->AddChild(std::move(root3)); - - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root_layer)); - - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, gfx::Rect(root_ptr->bounds()), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); +TEST_F(EffectTreeLayerListIteratorTest, ComplexTreeMultiSurface) { + auto* root = static_cast<TestLayerImpl*>(root_layer()); + auto* root1 = AddLayer<TestLayerImpl>(); + CopyProperties(root, root1); - IterateFrontToBack(); - EXPECT_COUNT(root_ptr, 9, -1, 8); - EXPECT_COUNT(root1_ptr, 9, -1, 7); - EXPECT_COUNT(root2_ptr, 9, -1, 6); - EXPECT_COUNT(root21_ptr, 9, -1, 5); - EXPECT_COUNT(root22_ptr, 9, -1, 4); - EXPECT_COUNT(root221_ptr, 9, -1, 3); - EXPECT_COUNT(root23_ptr, 9, -1, 2); - EXPECT_COUNT(root231_ptr, 9, -1, 1); - EXPECT_COUNT(root3_ptr, 9, -1, 0); -} + auto* root2 = AddLayer<TestLayerImpl>(); + root2->SetDrawsContent(false); + CopyProperties(root, root2); + CreateEffectNode(root2).render_surface_reason = RenderSurfaceReason::kTest; -TEST_F(EffectTreeLayerListIteratorTest, ComplexTreeMultiSurface) { - std::unique_ptr<TestLayerImpl> root_layer = CreateLayer(); - std::unique_ptr<TestLayerImpl> root1 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root2 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root3 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root21 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root22 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root23 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root221 = CreateLayer(); - std::unique_ptr<TestLayerImpl> root231 = CreateLayer(); + auto* root21 = AddLayer<TestLayerImpl>(); + CopyProperties(root2, root21); - TestLayerImpl* root_ptr = root_layer.get(); - TestLayerImpl* root1_ptr = root1.get(); - TestLayerImpl* root2_ptr = root2.get(); - TestLayerImpl* root3_ptr = root3.get(); - TestLayerImpl* root21_ptr = root21.get(); - TestLayerImpl* root22_ptr = root22.get(); - TestLayerImpl* root23_ptr = root23.get(); - TestLayerImpl* root221_ptr = root221.get(); - TestLayerImpl* root231_ptr = root231.get(); + auto* root22 = AddLayer<TestLayerImpl>(); + CopyProperties(root2, root22); + CreateEffectNode(root22).render_surface_reason = RenderSurfaceReason::kTest; + auto* root221 = AddLayer<TestLayerImpl>(); + CopyProperties(root22, root221); - root22->test_properties()->force_render_surface = true; - root23->test_properties()->force_render_surface = true; - root2->test_properties()->force_render_surface = true; - root22->test_properties()->AddChild(std::move(root221)); - root23->test_properties()->AddChild(std::move(root231)); - root2->SetDrawsContent(false); - root2->test_properties()->AddChild(std::move(root21)); - root2->test_properties()->AddChild(std::move(root22)); - root2->test_properties()->AddChild(std::move(root23)); - root_layer->test_properties()->AddChild(std::move(root1)); - root_layer->test_properties()->AddChild(std::move(root2)); - root_layer->test_properties()->AddChild(std::move(root3)); + auto* root23 = AddLayer<TestLayerImpl>(); + CopyProperties(root2, root23); + CreateEffectNode(root23).render_surface_reason = RenderSurfaceReason::kTest; + auto* root231 = AddLayer<TestLayerImpl>(); + CopyProperties(root23, root231); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root_layer)); + auto* root3 = AddLayer<TestLayerImpl>(); + CopyProperties(root, root3); - RenderSurfaceList render_surface_list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root_ptr, gfx::Rect(root_ptr->bounds()), &render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateActiveTreeDrawProperties(); IterateFrontToBack(); - EXPECT_COUNT(root_ptr, 14, -1, 13); - EXPECT_COUNT(root1_ptr, 14, -1, 12); - EXPECT_COUNT(root2_ptr, 10, 11, -1); - EXPECT_COUNT(root21_ptr, 10, 11, 9); - EXPECT_COUNT(root22_ptr, 7, 8, 6); - EXPECT_COUNT(root221_ptr, 7, 8, 5); - EXPECT_COUNT(root23_ptr, 3, 4, 2); - EXPECT_COUNT(root231_ptr, 3, 4, 1); - EXPECT_COUNT(root3_ptr, 14, -1, 0); + EXPECT_COUNT(root, 14, -1, 13); + EXPECT_COUNT(root1, 14, -1, 12); + EXPECT_COUNT(root2, 10, 11, -1); + EXPECT_COUNT(root21, 10, 11, 9); + EXPECT_COUNT(root22, 7, 8, 6); + EXPECT_COUNT(root221, 7, 8, 5); + EXPECT_COUNT(root23, 3, 4, 2); + EXPECT_COUNT(root231, 3, 4, 1); + EXPECT_COUNT(root3, 14, -1, 0); } } // namespace diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc index 4aa941a85d9..4d82dfede6c 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl.cc +++ b/chromium/cc/layers/heads_up_display_layer_impl.cc @@ -884,10 +884,6 @@ SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(PaintCanvas* canvas, status = "off (device)"; color = SK_ColorRED; break; - case GpuRasterizationStatus::OFF_VIEWPORT: - status = "off (viewport)"; - color = SK_ColorYELLOW; - break; case GpuRasterizationStatus::MSAA_CONTENT: status = "MSAA (content)"; color = SK_ColorCYAN; diff --git a/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc b/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc index f5dc43ee1bb..8cc10dd4b50 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc +++ b/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc @@ -9,6 +9,7 @@ #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host_impl.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -39,71 +40,55 @@ void CheckDrawLayer(HeadsUpDisplayLayerImpl* layer, EXPECT_EQ(0u, data.num_incomplete_tiles); } -TEST(HeadsUpDisplayLayerImplTest, ResourcelessSoftwareDrawAfterResourceLoss) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - std::unique_ptr<HeadsUpDisplayLayerImpl> layer_ptr = - HeadsUpDisplayLayerImpl::Create(host_impl.pending_tree(), 1); - layer_ptr->SetBounds(gfx::Size(100, 100)); - layer_ptr->set_visible_layer_rect(gfx::Rect(100, 100)); - - HeadsUpDisplayLayerImpl* layer = layer_ptr.get(); - - host_impl.pending_tree()->SetRootLayerForTesting(std::move(layer_ptr)); - host_impl.pending_tree()->BuildLayerListAndPropertyTreesForTesting(); +class HeadsUpDisplayLayerImplTest : public LayerTreeImplTestBase, + public ::testing::Test {}; + +TEST_F(HeadsUpDisplayLayerImplTest, ResourcelessSoftwareDrawAfterResourceLoss) { + host_impl()->CreatePendingTree(); + auto* root = EnsureRootLayerInPendingTree(); + auto* layer = AddLayerInPendingTree<HeadsUpDisplayLayerImpl>(); + layer->SetBounds(gfx::Size(100, 100)); + layer->set_visible_layer_rect(gfx::Rect(100, 100)); + CopyProperties(root, layer); + + UpdatePendingTreeDrawProperties(); // Check regular hardware draw is ok. - CheckDrawLayer(layer, host_impl.layer_tree_frame_sink(), - host_impl.resource_provider(), - layer_tree_frame_sink->context_provider(), DRAW_MODE_HARDWARE); + CheckDrawLayer(layer, layer_tree_frame_sink(), resource_provider(), + layer_tree_frame_sink()->context_provider(), + DRAW_MODE_HARDWARE); // Simulate a resource loss on transitioning to resourceless software mode. layer->ReleaseResources(); // Should skip resourceless software draw and not crash in UpdateHudTexture. - CheckDrawLayer(layer, host_impl.layer_tree_frame_sink(), - host_impl.resource_provider(), - layer_tree_frame_sink->context_provider(), + CheckDrawLayer(layer, layer_tree_frame_sink(), resource_provider(), + layer_tree_frame_sink()->context_provider(), DRAW_MODE_RESOURCELESS_SOFTWARE); } -TEST(HeadsUpDisplayLayerImplTest, CPUAndGPURasterCanvas) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.CreatePendingTree(); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - std::unique_ptr<HeadsUpDisplayLayerImpl> layer_ptr = - HeadsUpDisplayLayerImpl::Create(host_impl.pending_tree(), 1); - layer_ptr->SetBounds(gfx::Size(100, 100)); - layer_ptr->set_visible_layer_rect(gfx::Rect(100, 100)); - - HeadsUpDisplayLayerImpl* layer = layer_ptr.get(); - - host_impl.pending_tree()->SetRootLayerForTesting(std::move(layer_ptr)); - host_impl.pending_tree()->BuildLayerListAndPropertyTreesForTesting(); +TEST_F(HeadsUpDisplayLayerImplTest, CPUAndGPURasterCanvas) { + host_impl()->CreatePendingTree(); + auto* root = EnsureRootLayerInPendingTree(); + auto* layer = AddLayerInPendingTree<HeadsUpDisplayLayerImpl>(); + layer->SetBounds(gfx::Size(100, 100)); + CopyProperties(root, layer); + + UpdatePendingTreeDrawProperties(); // Check Ganesh canvas drawing is ok. - CheckDrawLayer(layer, host_impl.layer_tree_frame_sink(), - host_impl.resource_provider(), - layer_tree_frame_sink->context_provider(), DRAW_MODE_HARDWARE); + CheckDrawLayer(layer, layer_tree_frame_sink(), resource_provider(), + layer_tree_frame_sink()->context_provider(), + DRAW_MODE_HARDWARE); - host_impl.ReleaseLayerTreeFrameSink(); - layer_tree_frame_sink = FakeLayerTreeFrameSink::CreateSoftware(); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); + host_impl()->ReleaseLayerTreeFrameSink(); + auto layer_tree_frame_sink = FakeLayerTreeFrameSink::CreateSoftware(); + host_impl()->InitializeFrameSink(layer_tree_frame_sink.get()); // Check SW canvas drawing is ok. - CheckDrawLayer(layer, host_impl.layer_tree_frame_sink(), - host_impl.resource_provider(), nullptr, DRAW_MODE_SOFTWARE); + CheckDrawLayer(layer, layer_tree_frame_sink.get(), resource_provider(), + nullptr, DRAW_MODE_SOFTWARE); + host_impl()->ReleaseLayerTreeFrameSink(); } } // namespace diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc index f622b2e9537..063e39f34f7 100644 --- a/chromium/cc/layers/layer.cc +++ b/chromium/cc/layers/layer.cc @@ -18,7 +18,6 @@ #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "cc/base/simple_enclosed_region.h" -#include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/layer_client.h" #include "cc/layers/layer_impl.h" #include "cc/layers/picture_layer.h" @@ -39,35 +38,77 @@ namespace cc { +struct SameSizeAsLayer : public base::RefCounted<SameSizeAsLayer> { + private: + SameSizeAsLayer(); + virtual ~SameSizeAsLayer(); + + void* pointers[2]; + struct { + LayerList children; + gfx::Rect update_rect; + gfx::Size bounds; + gfx::Rect clip_rect; + scoped_refptr<PictureLayer> mask_layer; + int layer_id; + float opacity; + SkBlendMode blend_mode; + unsigned bitfields; + gfx::PointF position; + gfx::Transform transform; + gfx::Point3F transform_origin; + SkColor background_color; + FilterOperations filters[2]; + base::Optional<gfx::RRectF> backdrop_filter_bounds; + gfx::PointF filters_origin; + float backdrop_filter_quality; + gfx::RoundedCornersF corner_radii; + gfx::ScrollOffset scroll_offset; + gfx::Size scroll_container_bounds; + int mirror_count; + Region non_fast_scrollable_region; + TouchActionRegion touch_action_region; + ElementId element_id; + base::WeakPtr<LayerClient> client; + std::unique_ptr<base::trace_event::TracedValue> debug_info; + base::RepeatingCallback<void()> did_scroll_callback; + std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests; + } inputs; + int int_fields[7]; + gfx::Vector2dF offset; + unsigned bitfields; + SkColor safe_opaque_background_color; + int owner_node_id; + uint64_t compositing_reasons; +}; + +static_assert(sizeof(Layer) == sizeof(SameSizeAsLayer), + "Layer should stay small"); + base::AtomicSequenceNumber g_next_layer_id; Layer::Inputs::Inputs(int layer_id) - : layer_id(layer_id), - masks_to_bounds(false), - mask_layer(nullptr), + : mask_layer(nullptr), + layer_id(layer_id), opacity(1.f), blend_mode(SkBlendMode::kSrcOver), - is_root_for_isolated_group(false), + masks_to_bounds(false), hit_testable(false), contents_opaque(false), is_drawable(false), double_sided(true), - should_flatten_transform(true), - sorting_context_id(0), use_parent_backface_visibility(false), - background_color(0), - backdrop_filter_quality(1.0f), - corner_radii({0, 0, 0, 0}), is_fast_rounded_corner(false), scrollable(false), is_scrollbar(false), user_scrollable_horizontal(true), user_scrollable_vertical(true), - main_thread_scrolling_reasons( - MainThreadScrollingReason::kNotScrollingOnMain), has_will_change_transform_hint(false), trilinear_filtering(false), hide_layer_and_subtree(false), + background_color(0), + backdrop_filter_quality(1.0f), + corner_radii({0, 0, 0, 0}), mirror_count(0) {} Layer::Inputs::~Inputs() = default; @@ -77,19 +118,18 @@ scoped_refptr<Layer> Layer::Create() { } Layer::Layer() - : ignore_set_needs_commit_(false), - paint_count_(0), - parent_(nullptr), + : parent_(nullptr), layer_tree_host_(nullptr), // Layer IDs start from 1. inputs_(g_next_layer_id.GetNext() + 1), + paint_count_(0), num_descendants_that_draw_content_(0), transform_tree_index_(TransformTree::kInvalidNodeId), effect_tree_index_(EffectTree::kInvalidNodeId), clip_tree_index_(ClipTree::kInvalidNodeId), scroll_tree_index_(ScrollTree::kInvalidNodeId), property_tree_sequence_number_(-1), - should_flatten_screen_space_transform_from_property_tree_(false), + ignore_set_needs_commit_(false), draws_content_(false), should_check_backface_visibility_(false), cache_render_surface_(false), @@ -101,8 +141,8 @@ Layer::Layer() has_clip_node_(false), subtree_has_copy_request_(false), safe_opaque_background_color_(0), - compositing_reasons_(0), - owner_node_id_(0) {} + owner_node_id_(0), + compositing_reasons_(0) {} Layer::~Layer() { // Our parent should be holding a reference to us so there should be no @@ -114,10 +154,6 @@ Layer::~Layer() { // Remove the parent reference from all children and dependents. RemoveAllChildren(); - if (inputs_.mask_layer.get()) { - DCHECK_EQ(this, inputs_.mask_layer->parent()); - inputs_.mask_layer->RemoveFromParent(); - } } void Layer::SetLayerTreeHost(LayerTreeHost* host) { @@ -162,9 +198,6 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) { for (size_t i = 0; i < inputs_.children.size(); ++i) inputs_.children[i]->SetLayerTreeHost(host); - if (inputs_.mask_layer.get()) - inputs_.mask_layer->SetLayerTreeHost(host); - if (host && !host->IsUsingLayerLists() && host->mutator_host()->IsElementAnimating(element_id())) { host->SetNeedsCommit(); @@ -238,6 +271,11 @@ void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) { child->SetSubtreePropertyChanged(); index = std::min(index, inputs_.children.size()); + if (inputs_.mask_layer && index && index == inputs_.children.size()) { + // Ensure that the mask layer is always the last child. + DCHECK_EQ(inputs_.mask_layer, inputs_.children.back().get()); + index--; + } inputs_.children.insert(inputs_.children.begin() + index, child); SetNeedsFullTreeSync(); } @@ -245,16 +283,12 @@ void Layer::InsertChild(scoped_refptr<Layer> child, size_t index) { void Layer::RemoveFromParent() { DCHECK(IsPropertyChangeAllowed()); if (parent_) - parent_->RemoveChildOrDependent(this); + parent_->RemoveChild(this); } -void Layer::RemoveChildOrDependent(Layer* child) { - if (inputs_.mask_layer.get() == child) { - inputs_.mask_layer->SetParent(nullptr); +void Layer::RemoveChild(Layer* child) { + if (child == inputs_.mask_layer) inputs_.mask_layer = nullptr; - SetNeedsFullTreeSync(); - return; - } for (auto iter = inputs_.children.begin(); iter != inputs_.children.end(); ++iter) { @@ -327,7 +361,7 @@ void Layer::SetBounds(const gfx::Size& size) { // Rounded corner clipping, bounds clipping and mask clipping can result in // new areas of subtrees being exposed on a bounds change. Ensure the damaged // areas are updated. - if (masks_to_bounds() || inputs_.mask_layer.get() || HasRoundedCorner()) { + if (masks_to_bounds() || IsMaskedByChild() || HasRoundedCorner()) { SetSubtreePropertyChanged(); SetPropertyTreesNeedRebuild(); } @@ -343,25 +377,6 @@ void Layer::SetBounds(const gfx::Size& size) { SetNeedsCommit(); } -void Layer::SetSnapContainerData(base::Optional<SnapContainerData> data) { - DCHECK(IsPropertyChangeAllowed()); - if (snap_container_data() == data) - return; - inputs_.snap_container_data = std::move(data); - if (!layer_tree_host_) - return; - - if (scrollable() && !layer_tree_host_->IsUsingLayerLists()) { - auto& scroll_tree = layer_tree_host_->property_trees()->scroll_tree; - if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_)) - scroll_node->snap_container_data = inputs_.snap_container_data; - else - SetPropertyTreesNeedRebuild(); - } - - SetNeedsCommit(); -} - Layer* Layer::RootLayer() { Layer* layer = this; while (layer->parent()) @@ -557,7 +572,8 @@ gfx::RectF Layer::EffectiveClipRect() { // Layer needs to clip to its bounds as well apply a clip rect. Intersect the // two to get the effective clip. - if (masks_to_bounds() || mask_layer() || filters().HasFilterThatMovesPixels()) + if (masks_to_bounds() || IsMaskedByChild() || + filters().HasFilterThatMovesPixels()) return gfx::IntersectRects(layer_bounds, clip_rect_f); // Clip rect is the only clip effecting the layer. @@ -566,26 +582,27 @@ gfx::RectF Layer::EffectiveClipRect() { void Layer::SetMaskLayer(scoped_refptr<PictureLayer> mask_layer) { DCHECK(IsPropertyChangeAllowed()); - if (inputs_.mask_layer.get() == mask_layer) - return; DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists()); - if (inputs_.mask_layer.get()) { + if (inputs_.mask_layer == mask_layer) + return; + if (inputs_.mask_layer) { DCHECK_EQ(this, inputs_.mask_layer->parent()); inputs_.mask_layer->RemoveFromParent(); } - inputs_.mask_layer = mask_layer; - if (inputs_.mask_layer.get()) { + // Clear mask_layer first and set it later because InsertChild() checks it to + // ensure the mask layer is the last child. + inputs_.mask_layer = nullptr; + if (mask_layer) { // The mask layer should not have any children. - DCHECK(inputs_.mask_layer->children().empty()); + DCHECK(mask_layer->children().empty()); - inputs_.mask_layer->RemoveFromParent(); - DCHECK(!inputs_.mask_layer->parent()); - inputs_.mask_layer->SetParent(this); - inputs_.mask_layer->SetLayerMaskType( - Layer::LayerMaskType::SINGLE_TEXTURE_MASK); + mask_layer->inputs_.position = gfx::PointF(); + mask_layer->SetIsDrawable(true); + mask_layer->SetBlendMode(SkBlendMode::kDstIn); + AddChild(mask_layer); } + inputs_.mask_layer = mask_layer.get(); SetSubtreePropertyChanged(); - SetNeedsFullTreeSync(); } void Layer::SetFilters(const FilterOperations& filters) { @@ -759,15 +776,6 @@ void Layer::SetBlendMode(SkBlendMode blend_mode) { SetPropertyTreesNeedRebuild(); } -void Layer::SetIsRootForIsolatedGroup(bool root) { - DCHECK(IsPropertyChangeAllowed()); - if (inputs_.is_root_for_isolated_group == root) - return; - inputs_.is_root_for_isolated_group = root; - SetPropertyTreesNeedRebuild(); - SetNeedsCommit(); -} - void Layer::SetHitTestable(bool should_hit_test) { DCHECK(IsPropertyChangeAllowed()); if (inputs_.hit_testable == should_hit_test) @@ -792,6 +800,14 @@ void Layer::SetContentsOpaque(bool opaque) { } void Layer::SetPosition(const gfx::PointF& position) { + // The mask layer should always be at the same location as the masked layer + // which is its parent, so its position should be always zero. + if (parent() && parent()->inputs_.mask_layer == this) { + DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists()); + DCHECK(inputs_.position.IsOrigin()); + return; + } + DCHECK(IsPropertyChangeAllowed()); if (inputs_.position == position) return; @@ -1043,54 +1059,6 @@ bool Layer::GetUserScrollableVertical() const { return inputs_.user_scrollable_vertical; } -uint32_t Layer::GetMainThreadScrollingReasons() const { - // When using layer lists, main thread scrolling reasons are stored in scroll - // nodes. - if (layer_tree_host() && layer_tree_host()->IsUsingLayerLists()) { - auto& scroll_tree = layer_tree_host()->property_trees()->scroll_tree; - if (auto* scroll_node = scroll_tree.Node(scroll_tree_index_)) - return scroll_node->main_thread_scrolling_reasons; - return MainThreadScrollingReason::kNotScrollingOnMain; - } - return inputs_.main_thread_scrolling_reasons; -} - -void Layer::AddMainThreadScrollingReasons( - uint32_t main_thread_scrolling_reasons) { - DCHECK(IsPropertyChangeAllowed()); - DCHECK(main_thread_scrolling_reasons); - - // When layer lists are used, the main thread scrolling reasons should be set - // on property tree nodes directly. - // TODO(pdr): Uncomment this check when https://crbug.com/919969 is fixed. - // DCHECK(!layer_tree_host() || !layer_tree_host()->IsUsingLayerLists()); - - // Layer should only see non-transient scrolling reasons. Transient scrolling - // reasons are computed per hit test. - DCHECK(MainThreadScrollingReason::MainThreadCanSetScrollReasons( - main_thread_scrolling_reasons)); - uint32_t new_reasons = - inputs_.main_thread_scrolling_reasons | main_thread_scrolling_reasons; - if (inputs_.main_thread_scrolling_reasons == new_reasons) - return; - inputs_.main_thread_scrolling_reasons = new_reasons; - SetPropertyTreesNeedRebuild(); - SetNeedsCommit(); -} - -void Layer::ClearMainThreadScrollingReasons( - uint32_t main_thread_scrolling_reasons_to_clear) { - DCHECK(IsPropertyChangeAllowed()); - DCHECK(main_thread_scrolling_reasons_to_clear); - uint32_t new_reasons = ~main_thread_scrolling_reasons_to_clear & - inputs_.main_thread_scrolling_reasons; - if (new_reasons == inputs_.main_thread_scrolling_reasons) - return; - inputs_.main_thread_scrolling_reasons = new_reasons; - SetPropertyTreesNeedRebuild(); - SetNeedsCommit(); -} - void Layer::SetNonFastScrollableRegion(const Region& region) { DCHECK(IsPropertyChangeAllowed()); if (inputs_.non_fast_scrollable_region == region) @@ -1155,16 +1123,6 @@ void Layer::SetDoubleSided(bool double_sided) { SetSubtreePropertyChanged(); } -void Layer::Set3dSortingContextId(int id) { - DCHECK(IsPropertyChangeAllowed()); - if (id == inputs_.sorting_context_id) - return; - inputs_.sorting_context_id = id; - SetNeedsCommit(); - SetPropertyTreesNeedRebuild(); - SetSubtreePropertyChanged(); -} - void Layer::SetTransformTreeIndex(int index) { DCHECK(IsPropertyChangeAllowed()); if (transform_tree_index_ == index) @@ -1255,23 +1213,9 @@ void Layer::SetPropertyTreesNeedRebuild() { layer_tree_host_->property_trees()->needs_rebuild = true; } -void Layer::SetShouldFlattenTransform(bool should_flatten) { - DCHECK(IsPropertyChangeAllowed()); - if (inputs_.should_flatten_transform == should_flatten) - return; - inputs_.should_flatten_transform = should_flatten; - SetNeedsCommit(); - SetPropertyTreesNeedRebuild(); - SetSubtreePropertyChanged(); -} - #if DCHECK_IS_ON() std::string Layer::DebugName() const { - if (inputs_.client) { - if (auto debug_info = inputs_.client->TakeDebugInfo(this)) - return debug_info->ToBaseValue()->FindKey("layer_name")->GetString(); - } - return ""; + return inputs_.client ? inputs_.client->LayerDebugName(this) : ""; } #endif @@ -1361,6 +1305,11 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { "Layer::PushPropertiesTo"); DCHECK(layer_tree_host_); + if (inputs_.mask_layer) { + DCHECK_EQ(bounds(), inputs_.mask_layer->bounds()); + DCHECK(inputs_.mask_layer->position().IsOrigin()); + } + // The element id should be set first because other setters may // depend on it. Referencing element id on a layer is // deprecated. http://crbug.com/709137 @@ -1398,8 +1347,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetWheelEventHandlerRegion(Region()); } layer->SetContentsOpaque(inputs_.contents_opaque); - layer->SetShouldFlattenScreenSpaceTransformFromPropertyTree( - should_flatten_screen_space_transform_from_property_tree_); layer->SetUseParentBackfaceVisibility(inputs_.use_parent_backface_visibility); layer->SetShouldCheckBackfaceVisibility(should_check_backface_visibility_); @@ -1439,9 +1386,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { needs_show_scrollbars_ = false; subtree_property_changed_ = false; inputs_.update_rect = gfx::Rect(); - - if (mask_layer()) - DCHECK_EQ(bounds().ToString(), mask_layer()->bounds().ToString()); } void Layer::TakeCopyRequests( @@ -1519,15 +1463,6 @@ void Layer::SetSubtreePropertyChanged() { SetNeedsPushProperties(); } -void Layer::SetShouldFlattenScreenSpaceTransformFromPropertyTree( - bool should_flatten) { - if (should_flatten_screen_space_transform_from_property_tree_ == - should_flatten) - return; - should_flatten_screen_space_transform_from_property_tree_ = should_flatten; - SetNeedsPushProperties(); -} - void Layer::SetMayContainVideo(bool yes) { if (may_contain_video_ == yes) return; diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h index d1fcf363947..054f3884a38 100644 --- a/chromium/cc/layers/layer.h +++ b/chromium/cc/layers/layer.h @@ -14,6 +14,7 @@ #include <unordered_map> #include <vector> +#include "base/auto_reset.h" #include "base/callback.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" @@ -72,13 +73,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { INVALID_ID = -1, }; - // A layer can be attached to another layer as a mask for it. These - // describe how the mask would be generated as a texture in that case. - enum LayerMaskType { - NOT_MASK = 0, - SINGLE_TEXTURE_MASK, - }; - // Factory to create a new Layer, with a unique id. static scoped_refptr<Layer> Create(); @@ -189,16 +183,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void SetBounds(const gfx::Size& bounds); const gfx::Size& bounds() const { return inputs_.bounds; } - // Set and get the snapping behaviour for compositor-thread scrolling of - // this layer. The default value of null means there is no snapping for the - // layer. - // TODO(crbug.com/836884) With blink-gen-property-trees this is stored on the - // ScrollNode and can be removed here. - void SetSnapContainerData(base::Optional<SnapContainerData> data); - const base::Optional<SnapContainerData>& snap_container_data() const { - return inputs_.snap_container_data; - } - // Set or get that this layer clips its subtree to within its bounds. Content // of children will be intersected with the bounds of this layer when true. void SetMasksToBounds(bool masks_to_bounds); @@ -217,8 +201,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { // channel of the mask layer's content is used as an alpha mask of this // layer's content. IOW the mask's alpha is multiplied by this layer's alpha // for each matching pixel. + // This is for layer tree mode only. void SetMaskLayer(scoped_refptr<PictureLayer> mask_layer); - PictureLayer* mask_layer() { return inputs_.mask_layer.get(); } + bool IsMaskedByChild() const { return !!inputs_.mask_layer; } // Marks the |dirty_rect| as being changed, which will cause a commit and // the compositor to submit a new frame with a damage rect that includes the @@ -273,15 +258,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void SetBlendMode(SkBlendMode blend_mode); SkBlendMode blend_mode() const { return inputs_.blend_mode; } - // A layer is root for an isolated group when it and all its descendants are - // drawn over a black and fully transparent background, creating an isolated - // group. It should be used along with SetBlendMode(), in order to restrict - // layers within the group to blend with layers outside this group. - void SetIsRootForIsolatedGroup(bool root); - bool is_root_for_isolated_group() const { - return inputs_.is_root_for_isolated_group; - } - // Set or get the list of filter effects to be applied to the contents of the // layer and its subtree (together as a single composited entity) when // drawing them into their target. @@ -310,10 +286,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { return inputs_.backdrop_filter_bounds; } - const ElementId backdrop_mask_element_id() const { - return inputs_.backdrop_mask_element_id; - } - void SetBackdropFilterQuality(const float quality); float backdrop_filter_quality() const { return inputs_.backdrop_filter_quality; @@ -396,19 +368,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { bool GetUserScrollableHorizontal() const; bool GetUserScrollableVertical() const; - // Set or get if this layer is able to be scrolled on the compositor thread. - // This only applies for layers that are marked as scrollable, not for layers - // that are moved by a scroll parent. When any reason is present, the layer - // will not be scrolled on the compositor thread. The reasons are a set of - // bitflags from MainThreadScrollingReason, used to track the reason for - // debugging and reporting. - // AddMainThreadScrollingReasons() is used to add flags to the current set, - // and ClearMainThreadScrollingReasons() removes flags from the current set. - void AddMainThreadScrollingReasons(uint32_t main_thread_scrolling_reasons); - void ClearMainThreadScrollingReasons( - uint32_t main_thread_scrolling_reasons_to_clear); - uint32_t GetMainThreadScrollingReasons() const; - // Set or get an area of this layer within which initiating a scroll can not // be done from the compositor thread. Within this area, if the user attempts // to start a scroll, the events must be sent to the main thread and processed @@ -493,25 +452,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { return inputs_.use_parent_backface_visibility; } - // Set or get if the subtree of this layer is composited in 3d-space, or if - // the layers are flattened into the plane of this layer. This supports the - // transform-style CSS property. - void SetShouldFlattenTransform(bool flatten); - bool should_flatten_transform() const { - return inputs_.should_flatten_transform; - } - - // Set or get a 3d sorting context for this layer, where adjacent layers (in a - // pre-order traversal) with the same id are sorted as a group and may occlude - // each other based on their z-position, including intersecting each other and - // each occluding the other layer partially. Layers in different sorting - // contexts will be composited and occlude in tree order (children occlude - // ancestors and earlier siblings in the children list). If the |id| is 0, - // then the layer is not part of any sorting context, and is always composited - // in tree order. - void Set3dSortingContextId(int id); - int sorting_context_id() const { return inputs_.sorting_context_id; } - // When true the layer may contribute to the compositor's output. When false, // it does not. This property does not apply to children of the layer, they // may contribute while this layer does not. The layer itself will determine @@ -749,15 +689,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { return should_check_backface_visibility_; } - // Internal to property tree construction. The value here derives from - // should_flatten_transform() along with other state, and is for internal use - // in order to flatten the layer's ScreenSpaceTransform() in cases where the - // property tree did not handle it. - void SetShouldFlattenScreenSpaceTransformFromPropertyTree(bool should); - bool should_flatten_screen_space_transform_from_property_tree() const { - return should_flatten_screen_space_transform_from_property_tree_; - } - #if DCHECK_IS_ON() // For debugging, containing information about the associated DOM, etc. std::string DebugName() const; @@ -829,11 +760,11 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { // be changed while the frame is being generated for commit. bool IsPropertyChangeAllowed() const; - // When true, the layer is about to perform an update. Any commit requests - // will be handled implicitly after the update completes. - bool ignore_set_needs_commit_; + void IncreasePaintCount() { ++paint_count_; } - int paint_count_; + base::AutoReset<bool> IgnoreSetNeedsCommit() { + return base::AutoReset<bool>(&ignore_set_needs_commit_, true); + } private: friend class base::RefCounted<Layer>; @@ -852,7 +783,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void SetParent(Layer* layer); // This should only be called from RemoveFromParent(). - void RemoveChildOrDependent(Layer* child); + void RemoveChild(Layer* child); // When we detach or attach layer to new LayerTreeHost, all property trees' // indices becomes invalid. @@ -875,50 +806,65 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { explicit Inputs(int layer_id); ~Inputs(); - int layer_id; - LayerList children; gfx::Rect update_rect; gfx::Size bounds; - bool masks_to_bounds; gfx::Rect clip_rect; - scoped_refptr<PictureLayer> mask_layer; + // If not null, points to one of child layers which is set as mask layer + // by SetMaskLayer(). + Layer* mask_layer; + + int layer_id; float opacity; SkBlendMode blend_mode; - bool is_root_for_isolated_group : 1; + bool masks_to_bounds : 1; // Hit testing depends on this bit. bool hit_testable : 1; bool contents_opaque : 1; - gfx::PointF position; - gfx::Transform transform; - gfx::Point3F transform_origin; - bool is_drawable : 1; bool double_sided : 1; - bool should_flatten_transform : 1; - - // Layers that share a sorting context id will be sorted together in 3d - // space. 0 is a special value that means this layer will not be sorted - // and will be drawn in paint order. - int sorting_context_id; bool use_parent_backface_visibility : 1; + // If set, disables this layer's rounded corner from triggering a render + // surface on itself if possible. + bool is_fast_rounded_corner : 1; + + // Indicates that this layer will need a scroll property node and that this + // layer's bounds correspond to the scroll node's bounds (both |bounds| and + // |scroll_container_bounds|). + bool scrollable : 1; + + // Indicates that this layer is a scrollbar. + bool is_scrollbar : 1; + + bool user_scrollable_horizontal : 1; + bool user_scrollable_vertical : 1; + + bool has_will_change_transform_hint : 1; + + bool trilinear_filtering : 1; + + bool hide_layer_and_subtree : 1; + + gfx::PointF position; + gfx::Transform transform; + gfx::Point3F transform_origin; + SkColor background_color; FilterOperations filters; FilterOperations backdrop_filters; base::Optional<gfx::RRectF> backdrop_filter_bounds; - ElementId backdrop_mask_element_id; gfx::PointF filters_origin; float backdrop_filter_quality; @@ -926,39 +872,19 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { // top left, top right, bottom right, bottom left gfx::RoundedCornersF corner_radii; - // If set, disables this layer's rounded corner from triggering a render - // surface on itself if possible. - bool is_fast_rounded_corner : 1; - gfx::ScrollOffset scroll_offset; // Size of the scroll container that this layer scrolls in. gfx::Size scroll_container_bounds; - // Indicates that this layer will need a scroll property node and that this - // layer's bounds correspond to the scroll node's bounds (both |bounds| and - // |scroll_container_bounds|). - bool scrollable : 1; - - // Indicates that this layer is a scrollbar. - bool is_scrollbar : 1; - - bool user_scrollable_horizontal : 1; - bool user_scrollable_vertical : 1; + int mirror_count; - uint32_t main_thread_scrolling_reasons; Region non_fast_scrollable_region; TouchActionRegion touch_action_region; ElementId element_id; - bool has_will_change_transform_hint : 1; - - bool trilinear_filtering : 1; - - bool hide_layer_and_subtree : 1; - // The following elements can not and are not serialized. base::WeakPtr<LayerClient> client; std::unique_ptr<base::trace_event::TracedValue> debug_info; @@ -966,10 +892,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)> did_scroll_callback; std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests; - - base::Optional<SnapContainerData> snap_container_data; - - int mirror_count; }; Layer* parent_; @@ -981,6 +903,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { Inputs inputs_; + int paint_count_; int num_descendants_that_draw_content_; int transform_tree_index_; int effect_tree_index_; @@ -988,7 +911,12 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { int scroll_tree_index_; int property_tree_sequence_number_; gfx::Vector2dF offset_to_transform_parent_; - bool should_flatten_screen_space_transform_from_property_tree_ : 1; + + // When true, the layer is about to perform an update. Any commit requests + // will be handled implicitly after the update completes. Not a bitfield + // because it's used in base::AutoReset. + bool ignore_set_needs_commit_; + bool draws_content_ : 1; bool should_check_backface_visibility_ : 1; // Force use of and cache render surface. @@ -1001,9 +929,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { bool has_clip_node_ : 1; // This value is valid only when LayerTreeHost::has_copy_request() is true bool subtree_has_copy_request_ : 1; + SkColor safe_opaque_background_color_; - uint64_t compositing_reasons_; int owner_node_id_; + uint64_t compositing_reasons_; }; } // namespace cc diff --git a/chromium/cc/layers/layer_client.h b/chromium/cc/layers/layer_client.h index fb4b6408f29..75aeff13ab6 100644 --- a/chromium/cc/layers/layer_client.h +++ b/chromium/cc/layers/layer_client.h @@ -6,6 +6,7 @@ #define CC_LAYERS_LAYER_CLIENT_H_ #include <memory> +#include <string> #include "cc/cc_export.h" @@ -31,6 +32,8 @@ class CC_EXPORT LayerClient { virtual std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo( const Layer* layer) = 0; + virtual std::string LayerDebugName(const Layer* layer) const = 0; + virtual void DidChangeScrollbarsHiddenIfOverlay(bool) = 0; protected: diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc index fe128b9ef69..6653d2cfc24 100644 --- a/chromium/cc/layers/layer_impl.cc +++ b/chromium/cc/layers/layer_impl.cc @@ -26,7 +26,6 @@ #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/mutator_host.h" @@ -51,9 +50,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, : layer_id_(id), layer_tree_impl_(tree_impl), will_always_push_properties_(will_always_push_properties), - test_properties_(nullptr), scrollable_(false), - should_flatten_screen_space_transform_from_property_tree_(false), layer_property_changed_not_from_property_trees_(false), layer_property_changed_from_property_trees_(false), may_contain_video_(false), @@ -64,8 +61,7 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, draws_content_(false), contributes_to_drawn_render_surface_(false), hit_testable_(false), - is_resized_by_browser_controls_(false), - viewport_layer_type_(NOT_VIEWPORT_LAYER), + is_inner_viewport_scroll_layer_(false), background_color_(0), safe_opaque_background_color_(0), transform_tree_index_(TransformTree::kInvalidNodeId), @@ -356,8 +352,6 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->has_transform_node_ = has_transform_node_; layer->offset_to_transform_parent_ = offset_to_transform_parent_; - layer->should_flatten_screen_space_transform_from_property_tree_ = - should_flatten_screen_space_transform_from_property_tree_; layer->masks_to_bounds_ = masks_to_bounds_; layer->contents_opaque_ = contents_opaque_; layer->may_contain_video_ = may_contain_video_; @@ -422,14 +416,6 @@ bool LayerImpl::IsAffectedByPageScale() const { ->in_subtree_of_page_scale_layer; } -bool LayerImpl::IsResizedByBrowserControls() const { - return is_resized_by_browser_controls_; -} - -void LayerImpl::SetIsResizedByBrowserControls(bool resized) { - is_resized_by_browser_controls_ = resized; -} - std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() const { std::unique_ptr<base::DictionaryValue> result(new base::DictionaryValue); result->SetInteger("LayerId", id()); @@ -447,15 +433,6 @@ std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() const { list->AppendInteger(offset_to_transform_parent().y()); result->Set("OffsetToTransformParent", std::move(list)); - const gfx::Transform& gfx_transform = - const_cast<LayerImpl*>(this)->test_properties()->transform; - double transform[16]; - gfx_transform.matrix().asColMajord(transform); - list = std::make_unique<base::ListValue>(); - for (int i = 0; i < 16; ++i) - list->AppendDouble(transform[i]); - result->Set("Transform", std::move(list)); - result->SetBoolean("DrawsContent", draws_content_); result->SetBoolean("HitTestable", hit_testable_); result->SetBoolean("Is3dSorted", Is3dSorted()); @@ -488,17 +465,6 @@ std::unique_ptr<base::DictionaryValue> LayerImpl::LayerAsJson() const { return result; } -std::unique_ptr<base::DictionaryValue> LayerImpl::LayerTreeAsJson() { - std::unique_ptr<base::DictionaryValue> result = LayerAsJson(); - - auto list = std::make_unique<base::ListValue>(); - for (size_t i = 0; i < test_properties()->children.size(); ++i) - list->Append(test_properties()->children[i]->LayerTreeAsJson()); - result->Set("Children", std::move(list)); - - return result; -} - bool LayerImpl::LayerPropertyChanged() const { return layer_property_changed_not_from_property_trees_ || LayerPropertyChangedFromPropertyTrees(); @@ -562,23 +528,15 @@ bool LayerImpl::IsActive() const { } gfx::Size LayerImpl::bounds() const { - // As an optimization, we do not need to include the viewport bounds delta if - // the layer is not a viewport layer. - if (viewport_layer_type_ == NOT_VIEWPORT_LAYER) { - DCHECK(ViewportBoundsDelta().IsZero()); + if (!is_inner_viewport_scroll_layer_) return bounds_; - } - auto viewport_bounds_delta = gfx::ToCeiledVector2d(ViewportBoundsDelta()); + + auto viewport_bounds_delta = gfx::ToCeiledVector2d( + GetPropertyTrees()->inner_viewport_scroll_bounds_delta()); return gfx::Size(bounds_.width() + viewport_bounds_delta.x(), bounds_.height() + viewport_bounds_delta.y()); } -gfx::SizeF LayerImpl::BoundsForScrolling() const { - auto viewport_bounds_delta = ViewportBoundsDelta(); - return gfx::SizeF(bounds_.width() + viewport_bounds_delta.x(), - bounds_.height() + viewport_bounds_delta.y()); -} - void LayerImpl::SetBounds(const gfx::Size& bounds) { if (bounds_ == bounds) return; @@ -592,61 +550,6 @@ void LayerImpl::SetBounds(const gfx::Size& bounds) { NoteLayerPropertyChanged(); } -void LayerImpl::SetViewportBoundsDelta(const gfx::Vector2dF& bounds_delta) { - DCHECK(IsActive()); - - if (bounds_delta == ViewportBoundsDelta()) - return; - - PropertyTrees* property_trees = GetPropertyTrees(); - switch (viewport_layer_type_) { - case (INNER_VIEWPORT_CONTAINER): - property_trees->SetInnerViewportContainerBoundsDelta(bounds_delta); - break; - case (OUTER_VIEWPORT_CONTAINER): - property_trees->SetOuterViewportContainerBoundsDelta(bounds_delta); - break; - case (INNER_VIEWPORT_SCROLL): - property_trees->SetInnerViewportScrollBoundsDelta(bounds_delta); - break; - case (OUTER_VIEWPORT_SCROLL): - // OUTER_VIEWPORT_SCROLL should not have viewport bounds deltas. - NOTREACHED(); - } - - // Viewport scrollbar positions are determined using the viewport bounds - // delta. - layer_tree_impl()->SetScrollbarGeometriesNeedUpdate(); - - if (masks_to_bounds()) { - // If layer is clipping, then update the clip node using the new bounds. - ClipNode* clip_node = property_trees->clip_tree.Node(clip_tree_index()); - CHECK(clip_node); - DCHECK_EQ(clip_node->id, clip_tree_index()); - clip_node->clip = gfx::RectF(gfx::PointF() + offset_to_transform_parent(), - gfx::SizeF(bounds())); - property_trees->clip_tree.set_needs_update(true); - - property_trees->full_tree_damaged = true; - layer_tree_impl()->set_needs_update_draw_properties(); - } else { - NoteLayerPropertyChanged(); - } -} - -gfx::Vector2dF LayerImpl::ViewportBoundsDelta() const { - switch (viewport_layer_type_) { - case (INNER_VIEWPORT_CONTAINER): - return GetPropertyTrees()->inner_viewport_container_bounds_delta(); - case (OUTER_VIEWPORT_CONTAINER): - return GetPropertyTrees()->outer_viewport_container_bounds_delta(); - case (INNER_VIEWPORT_SCROLL): - return GetPropertyTrees()->inner_viewport_scroll_bounds_delta(); - default: - return gfx::Vector2dF(); - } -} - ScrollbarLayerImplBase* LayerImpl::ToScrollbarLayer() { return nullptr; } @@ -1001,7 +904,11 @@ float LayerImpl::GetIdealContentsScale() const { gfx::Vector2dF transform_scales = MathUtil::ComputeTransform2dScaleComponents(transform, default_scale); - return std::max(transform_scales.x(), transform_scales.y()); + + constexpr float kMaxScaleRatio = 5.f; + float lower_scale = std::min(transform_scales.x(), transform_scales.y()); + float higher_scale = std::max(transform_scales.x(), transform_scales.y()); + return std::min(kMaxScaleRatio * lower_scale, higher_scale); } PropertyTrees* LayerImpl::GetPropertyTrees() const { @@ -1035,4 +942,62 @@ bool LayerImpl::is_surface_layer() const { return false; } +static float TranslationFromActiveTreeLayerScreenSpaceTransform( + LayerImpl* pending_tree_layer) { + LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl(); + if (layer_tree_impl) { + LayerImpl* active_tree_layer = + layer_tree_impl->FindActiveTreeLayerById(pending_tree_layer->id()); + if (active_tree_layer) { + gfx::Transform active_tree_screen_space_transform = + active_tree_layer->draw_properties().screen_space_transform; + if (active_tree_screen_space_transform.IsIdentity()) + return 0.f; + if (active_tree_screen_space_transform.ApproximatelyEqual( + pending_tree_layer->draw_properties().screen_space_transform)) + return 0.f; + return (active_tree_layer->draw_properties() + .screen_space_transform.To2dTranslation() - + pending_tree_layer->draw_properties() + .screen_space_transform.To2dTranslation()) + .Length(); + } + } + return 0.f; +} + +// A layer jitters if its screen space transform is same on two successive +// commits, but has changed in between the commits. CalculateLayerJitter +// computes the jitter for the layer. +int LayerImpl::CalculateJitter() { + float jitter = 0.f; + performance_properties().translation_from_last_frame = 0.f; + performance_properties().last_commit_screen_space_transform = + draw_properties().screen_space_transform; + + if (!visible_layer_rect().IsEmpty()) { + if (draw_properties().screen_space_transform.ApproximatelyEqual( + performance_properties().last_commit_screen_space_transform)) { + float translation_from_last_commit = + TranslationFromActiveTreeLayerScreenSpaceTransform(this); + if (translation_from_last_commit > 0.f) { + performance_properties().num_fixed_point_hits++; + performance_properties().translation_from_last_frame = + translation_from_last_commit; + if (performance_properties().num_fixed_point_hits > + LayerTreeImpl::kFixedPointHitsThreshold) { + // Jitter = Translation from fixed point * sqrt(Area of the layer). + // The square root of the area is used instead of the area to match + // the dimensions of both terms on the rhs. + jitter += translation_from_last_commit * + sqrt(visible_layer_rect().size().GetArea()); + } + } else { + performance_properties().num_fixed_point_hits = 0; + } + } + } + return jitter; +} + } // namespace cc diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h index 6f8ae9d41bf..b054f7f196e 100644 --- a/chromium/cc/layers/layer_impl.h +++ b/chromium/cc/layers/layer_impl.h @@ -25,7 +25,6 @@ #include "cc/layers/draw_mode.h" #include "cc/layers/draw_properties.h" #include "cc/layers/layer_collections.h" -#include "cc/layers/layer_impl_test_properties.h" #include "cc/layers/performance_properties.h" #include "cc/layers/render_surface_impl.h" #include "cc/layers/touch_action_region.h" @@ -113,14 +112,6 @@ class CC_EXPORT LayerImpl { return offset_to_transform_parent_; } - void SetShouldFlattenScreenSpaceTransformFromPropertyTree( - bool should_flatten) { - should_flatten_screen_space_transform_from_property_tree_ = should_flatten; - } - bool should_flatten_screen_space_transform_from_property_tree() const { - return should_flatten_screen_space_transform_from_property_tree_; - } - bool is_clipped() const { return draw_properties_.is_clipped; } LayerTreeImpl* layer_tree_impl() const { return layer_tree_impl_; } @@ -174,12 +165,6 @@ class CC_EXPORT LayerImpl { void SetHitTestable(bool should_hit_test); bool HitTestable() const; - LayerImplTestProperties* test_properties() { - if (!test_properties_) - test_properties_.reset(new LayerImplTestProperties(this)); - return test_properties_.get(); - } - void SetBackgroundColor(SkColor background_color); SkColor background_color() const { return background_color_; } void SetSafeOpaqueBackgroundColor(SkColor background_color); @@ -213,9 +198,6 @@ class CC_EXPORT LayerImpl { return use_parent_backface_visibility_; } - bool IsResizedByBrowserControls() const; - void SetIsResizedByBrowserControls(bool resized); - void SetShouldCheckBackfaceVisibility(bool should_check_backface_visibility) { should_check_backface_visibility_ = should_check_backface_visibility; } @@ -269,29 +251,9 @@ class CC_EXPORT LayerImpl { void SetBounds(const gfx::Size& bounds); gfx::Size bounds() const; - // Like bounds() but doesn't snap to int. Lossy on giant pages (e.g. millions - // of pixels) due to use of single precision float. - gfx::SizeF BoundsForScrolling() const; - - // Viewport bounds delta are only used for viewport layers and account for - // changes in the viewport layers from browser controls and page scale - // factors. These deltas are only set on the active tree. - // TODO(bokan): These methods should be unneeded now that LTHI sets these - // directly on the property trees. - void SetViewportBoundsDelta(const gfx::Vector2dF& bounds_delta); - gfx::Vector2dF ViewportBoundsDelta() const; - - void SetViewportLayerType(ViewportLayerType type) { - // Once set as a viewport layer type, the viewport type should not change. - DCHECK(viewport_layer_type() == NOT_VIEWPORT_LAYER || - viewport_layer_type() == type); - viewport_layer_type_ = type; - } - ViewportLayerType viewport_layer_type() const { - return static_cast<ViewportLayerType>(viewport_layer_type_); - } - bool is_viewport_layer_type() const { - return viewport_layer_type() != NOT_VIEWPORT_LAYER; + + void set_is_inner_viewport_scroll_layer() { + is_inner_viewport_scroll_layer_ = true; } void SetCurrentScrollOffset(const gfx::ScrollOffset& scroll_offset); @@ -348,9 +310,6 @@ class CC_EXPORT LayerImpl { virtual gfx::Rect GetDamageRect() const; virtual std::unique_ptr<base::DictionaryValue> LayerAsJson() const; - // TODO(pdr): This should be removed because there is no longer a tree - // of layers, only a list. - std::unique_ptr<base::DictionaryValue> LayerTreeAsJson(); // This includes |layer_property_changed_not_from_property_trees_| and // property_trees changes. @@ -474,6 +433,8 @@ class CC_EXPORT LayerImpl { // TODO(sunxd): Remove this function and replace it with visitor pattern. virtual bool is_surface_layer() const; + int CalculateJitter(); + protected: // When |will_always_push_properties| is true, the layer will not itself set // its SetNeedsPushProperties() state, as it expects to be always pushed to @@ -505,8 +466,6 @@ class CC_EXPORT LayerImpl { LayerTreeImpl* const layer_tree_impl_; const bool will_always_push_properties_ : 1; - std::unique_ptr<LayerImplTestProperties> test_properties_; - // Properties synchronized from the associated Layer. gfx::Size bounds_; @@ -520,8 +479,6 @@ class CC_EXPORT LayerImpl { // |scroll_container_bounds|). bool scrollable_ : 1; - bool should_flatten_screen_space_transform_from_property_tree_ : 1; - // Tracks if drawing-related properties have changed since last redraw. // TODO(wutao): We want to distinquish the sources of change so that we can // reuse the cache of render pass. For example, we can reuse the cache when @@ -542,13 +499,8 @@ class CC_EXPORT LayerImpl { // Tracks if this layer should participate in hit testing. bool hit_testable_ : 1; - bool is_resized_by_browser_controls_ : 1; - // TODO(bokan): This can likely be removed after blink-gen-property-trees - // is shipped. https://crbug.com/836884. - static_assert(LAST_VIEWPORT_LAYER_TYPE < (1u << 3), - "enough bits for ViewportLayerType (viewport_layer_type_)"); - uint8_t viewport_layer_type_ : 3; // ViewportLayerType + bool is_inner_viewport_scroll_layer_ : 1; Region non_fast_scrollable_region_; TouchActionRegion touch_action_region_; diff --git a/chromium/cc/layers/layer_impl_test_properties.cc b/chromium/cc/layers/layer_impl_test_properties.cc deleted file mode 100644 index 838bfb94f22..00000000000 --- a/chromium/cc/layers/layer_impl_test_properties.cc +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cc/layers/layer_impl_test_properties.h" - -#include "cc/layers/layer_impl.h" -#include "cc/trees/layer_tree_impl.h" -#include "components/viz/common/frame_sinks/copy_output_request.h" - -namespace cc { - -LayerImplTestProperties::LayerImplTestProperties(LayerImpl* owning_layer) - : owning_layer(owning_layer), - double_sided(true), - trilinear_filtering(false), - cache_render_surface(false), - force_render_surface(false), - is_container_for_fixed_position_layers(false), - should_flatten_transform(true), - hide_layer_and_subtree(false), - opacity_can_animate(false), - subtree_has_copy_request(false), - sorting_context_id(0), - opacity(1.f), - blend_mode(SkBlendMode::kSrcOver), - mask_layer(nullptr), - parent(nullptr) {} - -LayerImplTestProperties::~LayerImplTestProperties() = default; - -void LayerImplTestProperties::AddChild(std::unique_ptr<LayerImpl> child) { - child->test_properties()->parent = owning_layer; - children.push_back(child.get()); - owning_layer->layer_tree_impl()->AddLayer(std::move(child)); - owning_layer->layer_tree_impl()->BuildLayerListForTesting(); -} - -std::unique_ptr<LayerImpl> LayerImplTestProperties::RemoveChild( - LayerImpl* child) { - auto it = std::find(children.begin(), children.end(), child); - if (it != children.end()) - children.erase(it); - auto layer = owning_layer->layer_tree_impl()->RemoveLayer(child->id()); - owning_layer->layer_tree_impl()->BuildLayerListForTesting(); - return layer; -} - -void LayerImplTestProperties::SetMaskLayer(std::unique_ptr<LayerImpl> mask) { - if (mask_layer) - owning_layer->layer_tree_impl()->RemoveLayer(mask_layer->id()); - mask_layer = mask.get(); - if (mask) - owning_layer->layer_tree_impl()->AddLayer(std::move(mask)); -} - -} // namespace cc diff --git a/chromium/cc/layers/layer_impl_test_properties.h b/chromium/cc/layers/layer_impl_test_properties.h deleted file mode 100644 index d5405f0d583..00000000000 --- a/chromium/cc/layers/layer_impl_test_properties.h +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CC_LAYERS_LAYER_IMPL_TEST_PROPERTIES_H_ -#define CC_LAYERS_LAYER_IMPL_TEST_PROPERTIES_H_ - -#include <set> -#include <vector> - -#include "cc/input/scroll_snap_data.h" -#include "cc/layers/layer_collections.h" -#include "cc/paint/element_id.h" -#include "cc/paint/filter_operations.h" -#include "third_party/skia/include/core/SkBlendMode.h" -#include "ui/gfx/geometry/point3_f.h" -#include "ui/gfx/rrect_f.h" -#include "ui/gfx/transform.h" - -namespace viz { -class CopyOutputRequest; -} - -namespace cc { - -class LayerImpl; - -struct CC_EXPORT LayerImplTestProperties { - explicit LayerImplTestProperties(LayerImpl* owning_layer); - ~LayerImplTestProperties(); - - void AddChild(std::unique_ptr<LayerImpl> child); - std::unique_ptr<LayerImpl> RemoveChild(LayerImpl* child); - void SetMaskLayer(std::unique_ptr<LayerImpl> mask); - - LayerImpl* owning_layer; - bool double_sided; - bool trilinear_filtering; - bool cache_render_surface; - bool force_render_surface; - bool is_container_for_fixed_position_layers; - bool should_flatten_transform; - bool hide_layer_and_subtree; - bool opacity_can_animate; - bool subtree_has_copy_request; - int sorting_context_id; - float opacity; - FilterOperations filters; - FilterOperations backdrop_filters; - base::Optional<gfx::RRectF> backdrop_filter_bounds; - ElementId backdrop_mask_element_id; - float backdrop_filter_quality; - gfx::PointF filters_origin; - SkBlendMode blend_mode; - gfx::Point3F transform_origin; - gfx::Transform transform; - gfx::PointF position; - std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests; - LayerImplList children; - LayerImpl* mask_layer; - LayerImpl* parent; - uint32_t main_thread_scrolling_reasons = 0; - bool user_scrollable_horizontal = true; - bool user_scrollable_vertical = true; - base::Optional<SnapContainerData> snap_container_data; - gfx::RRectF rounded_corner_bounds; -}; - -} // namespace cc - -#endif // CC_LAYERS_LAYER_IMPL_TEST_PROPERTIES_H_ diff --git a/chromium/cc/layers/layer_impl_unittest.cc b/chromium/cc/layers/layer_impl_unittest.cc index 4dc4d5b24af..8de7247dd7b 100644 --- a/chromium/cc/layers/layer_impl_unittest.cc +++ b/chromium/cc/layers/layer_impl_unittest.cc @@ -10,11 +10,8 @@ #include "cc/paint/filter_operation.h" #include "cc/paint/filter_operations.h" #include "cc/test/animation_test_common.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_frame_sink.h" -#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/test_task_graph_runner.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/tree_synchronizer.h" @@ -55,19 +52,19 @@ namespace { EXPECT_FALSE(child->LayerPropertyChanged()); \ EXPECT_FALSE(grand_child->LayerPropertyChanged()); -#define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking(); \ - host_impl.ForcePrepareToDraw(); \ - EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties()); \ - code_to_test; \ - EXPECT_TRUE(host_impl.active_tree()->needs_update_draw_properties()); +#define VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ + host_impl()->ForcePrepareToDraw(); \ + EXPECT_FALSE(host_impl()->active_tree()->needs_update_draw_properties()); \ + code_to_test; \ + EXPECT_TRUE(host_impl()->active_tree()->needs_update_draw_properties()); -#define VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ - root->layer_tree_impl()->ResetAllChangeTracking(); \ - host_impl.ForcePrepareToDraw(); \ - EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties()); \ - code_to_test; \ - EXPECT_FALSE(host_impl.active_tree()->needs_update_draw_properties()); +#define VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(code_to_test) \ + root->layer_tree_impl()->ResetAllChangeTracking(); \ + host_impl()->ForcePrepareToDraw(); \ + EXPECT_FALSE(host_impl()->active_tree()->needs_update_draw_properties()); \ + code_to_test; \ + EXPECT_FALSE(host_impl()->active_tree()->needs_update_draw_properties()); static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) { gfx::ScrollOffset delta = layer_impl->layer_tree_impl() @@ -77,39 +74,32 @@ static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) { return gfx::Vector2dF(delta.x(), delta.y()); } -TEST(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) { +class LayerImplTest : public LayerTreeImplTestBase, public ::testing::Test { + public: + using LayerTreeImplTestBase::LayerTreeImplTestBase; +}; + +TEST_F(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) { // // This test checks that LayerPropertyChanged() has the correct behavior. // // The constructor on this will fake that we are on the correct thread. // Create a simple LayerImpl tree: - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - host_impl.CreatePendingTree(); - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl.pending_tree(), 2); - LayerImpl* root = root_ptr.get(); - host_impl.pending_tree()->SetRootLayerForTesting(std::move(root_ptr)); - - root->test_properties()->force_render_surface = true; + host_impl()->CreatePendingTree(); + LayerImpl* root = EnsureRootLayerInPendingTree(); root->SetMasksToBounds(true); + CreateClipNode(root); root->layer_tree_impl()->ResetAllChangeTracking(); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl.pending_tree(), 7)); - LayerImpl* child = root->test_properties()->children[0]; - child->test_properties()->AddChild( - LayerImpl::Create(host_impl.pending_tree(), 8)); - LayerImpl* grand_child = child->test_properties()->children[0]; - host_impl.pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + LayerImpl* child = AddLayerInPendingTree<LayerImpl>(); + CopyProperties(root, child); + LayerImpl* grand_child = AddLayerInPendingTree<LayerImpl>(); + CopyProperties(child, grand_child); - // Adding children is an internal operation and should not mark layers as + UpdatePendingTreeDrawProperties(); + + // Creating children is an internal operation and should not mark layers as // changed. EXPECT_FALSE(root->LayerPropertyChanged()); EXPECT_FALSE(child->LayerPropertyChanged()); @@ -131,20 +121,21 @@ TEST(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) { EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE( root->SetUpdateRect(arbitrary_rect)); EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(arbitrary_size)); - host_impl.pending_tree()->property_trees()->needs_rebuild = true; - host_impl.pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + UpdatePendingTreeDrawProperties(); // Changing these properties affects the entire subtree of layers. - EXECUTE_AND_VERIFY_SUBTREE_CHANGED(host_impl.pending_tree()->SetFilterMutated( - root->element_id(), arbitrary_filters)); - EXECUTE_AND_VERIFY_SUBTREE_CHANGED(host_impl.pending_tree()->SetFilterMutated( - root->element_id(), FilterOperations())); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( - host_impl.pending_tree()->SetOpacityMutated(root->element_id(), - arbitrary_number)); + host_impl()->pending_tree()->SetFilterMutated(root->element_id(), + arbitrary_filters)); + EXECUTE_AND_VERIFY_SUBTREE_CHANGED( + host_impl()->pending_tree()->SetFilterMutated(root->element_id(), + FilterOperations())); EXECUTE_AND_VERIFY_SUBTREE_CHANGED( - host_impl.pending_tree()->SetTransformMutated(root->element_id(), - arbitrary_transform)); + host_impl()->pending_tree()->SetOpacityMutated(root->element_id(), + arbitrary_number)); + EXECUTE_AND_VERIFY_SUBTREE_CHANGED( + host_impl()->pending_tree()->SetTransformMutated(root->element_id(), + arbitrary_transform)); // Changing these properties only affects the layer itself. EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetDrawsContent(true)); @@ -163,105 +154,21 @@ TEST(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) { EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(root->SetBounds(root->bounds())); } -TEST(LayerImplTest, VerifyActiveLayerChangesAreTrackedProperly) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl.active_tree(), 2); - LayerImpl* root = root_ptr.get(); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - - root->test_properties()->AddChild( - LayerImpl::Create(host_impl.active_tree(), 7)); - LayerImpl* child = root->test_properties()->children[0]; - root->SetScrollable(gfx::Size(100, 100)); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - - // Make root the outer viewport container layer. This ensures the later call - // to |SetViewportBoundsDelta| will be on a viewport layer. - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.outer_viewport_container = root->id(); - host_impl.active_tree()->SetViewportLayersFromIds(viewport_ids); - - root->SetMasksToBounds(true); - host_impl.active_tree()->property_trees()->needs_rebuild = true; - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - root->layer_tree_impl()->ResetAllChangeTracking(); - - // SetViewportBoundsDelta changes subtree only when masks_to_bounds is true. - root->SetViewportBoundsDelta(gfx::Vector2d(222, 333)); - EXPECT_TRUE(root->LayerPropertyChanged()); - EXPECT_TRUE(root->LayerPropertyChangedFromPropertyTrees()); - EXPECT_FALSE(root->LayerPropertyChangedNotFromPropertyTrees()); - EXPECT_TRUE(host_impl.active_tree()->property_trees()->full_tree_damaged); - - root->SetMasksToBounds(false); - host_impl.active_tree()->property_trees()->needs_rebuild = true; - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - root->layer_tree_impl()->ResetAllChangeTracking(); - - // SetViewportBoundsDelta does not change the subtree without masks_to_bounds. - root->SetViewportBoundsDelta(gfx::Vector2d(333, 444)); - EXPECT_TRUE(root->LayerPropertyChanged()); - EXPECT_FALSE(root->LayerPropertyChangedFromPropertyTrees()); - EXPECT_TRUE(root->LayerPropertyChangedNotFromPropertyTrees()); - EXPECT_FALSE(host_impl.active_tree()->property_trees()->full_tree_damaged); - - host_impl.active_tree()->property_trees()->needs_rebuild = true; - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - root->layer_tree_impl()->ResetAllChangeTracking(); - - // Ensure some node is affected by the outer viewport bounds delta. This - // ensures the later call to |SetViewportBoundsDelta| will require a - // transform tree update. - TransformTree& transform_tree = - host_impl.active_tree()->property_trees()->transform_tree; - transform_tree.AddNodeAffectedByOuterViewportBoundsDelta( - child->transform_tree_index()); - EXPECT_FALSE(transform_tree.needs_update()); - root->SetViewportBoundsDelta(gfx::Vector2d(111, 222)); - EXPECT_TRUE(transform_tree.needs_update()); - - host_impl.active_tree()->property_trees()->needs_rebuild = true; - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - root->layer_tree_impl()->ResetAllChangeTracking(); +TEST_F(LayerImplTest, VerifyNeedsUpdateDrawProperties) { + LayerImpl* root = root_layer(); + LayerImpl* layer = AddLayer<LayerImpl>(); + layer->SetBounds(gfx::Size(100, 100)); + layer->SetScrollable(gfx::Size(1, 1)); + LayerImpl* layer2 = AddLayer<LayerImpl>(); + SetElementIdsForTesting(); - // Ensure scrolling changes the transform tree but does not damage all trees. - root->ScrollBy(gfx::Vector2d(7, 9)); - EXPECT_TRUE(transform_tree.needs_update()); - EXPECT_TRUE(root->LayerPropertyChanged()); - EXPECT_TRUE(root->LayerPropertyChangedFromPropertyTrees()); - EXPECT_FALSE(root->LayerPropertyChangedNotFromPropertyTrees()); - EXPECT_FALSE(host_impl.active_tree()->property_trees()->full_tree_damaged); -} + CopyProperties(root, layer); + CreateTransformNode(layer); + CreateScrollNode(layer); + CopyProperties(root, layer2); -TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - host_impl.active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl.active_tree(), 1)); - LayerImpl* root = host_impl.active_tree()->root_layer_for_testing(); - std::unique_ptr<LayerImpl> layer_ptr = - LayerImpl::Create(host_impl.active_tree(), 2); - LayerImpl* layer = layer_ptr.get(); - root->test_properties()->AddChild(std::move(layer_ptr)); - layer->SetScrollable(gfx::Size(1, 1)); - std::unique_ptr<LayerImpl> layer2_ptr = - LayerImpl::Create(host_impl.active_tree(), 3); - LayerImpl* layer2 = layer2_ptr.get(); - root->test_properties()->AddChild(std::move(layer2_ptr)); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - DCHECK(host_impl.CanDraw()); + DCHECK(host_impl()->CanDraw()); + UpdateActiveTreeDrawProperties(); float arbitrary_number = 0.352f; gfx::Size arbitrary_size = gfx::Size(111, 222); @@ -280,26 +187,29 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { // Create a render surface, because we must have a render surface if we have // filters. - layer->test_properties()->force_render_surface = true; - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; + UpdateActiveTreeDrawProperties(); // Related filter functions. - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(host_impl.active_tree()->SetFilterMutated( - root->element_id(), arbitrary_filters)); + VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( + host_impl()->active_tree()->SetFilterMutated(root->element_id(), + arbitrary_filters)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( - host_impl.active_tree()->SetFilterMutated(root->element_id(), - arbitrary_filters)); - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(host_impl.active_tree()->SetFilterMutated( - root->element_id(), FilterOperations())); - VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(host_impl.active_tree()->SetFilterMutated( - root->element_id(), arbitrary_filters)); + host_impl()->active_tree()->SetFilterMutated(root->element_id(), + arbitrary_filters)); + VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( + host_impl()->active_tree()->SetFilterMutated(root->element_id(), + FilterOperations())); + VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( + host_impl()->active_tree()->SetFilterMutated(root->element_id(), + arbitrary_filters)); // Related scrolling functions. VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(large_size)); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->set_needs_update_draw_properties(); - host_impl.active_tree()->UpdateDrawProperties(); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); + VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(arbitrary_vector2d)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->ScrollBy(gfx::Vector2d())); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( @@ -314,30 +224,30 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { gfx::ScrollOffset(arbitrary_vector2d.x(), arbitrary_vector2d.y()))); // Unrelated functions, always set to new values, always set needs update. - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->set_needs_update_draw_properties(); - host_impl.active_tree()->UpdateDrawProperties(); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true); layer->NoteLayerPropertyChanged()); + CreateClipNode(layer); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true); layer->NoteLayerPropertyChanged()); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( layer->SetBackgroundColor(arbitrary_color)); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( - host_impl.active_tree()->SetOpacityMutated(layer->element_id(), - arbitrary_number)); + host_impl()->active_tree()->SetOpacityMutated(layer->element_id(), + arbitrary_number)); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES( - host_impl.active_tree()->SetTransformMutated(layer->element_id(), - arbitrary_transform)); + host_impl()->active_tree()->SetTransformMutated(layer->element_id(), + arbitrary_transform)); VERIFY_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetBounds(arbitrary_size); layer->NoteLayerPropertyChanged()); // Unrelated functions, set to the same values, no needs update. - layer->test_properties()->filters = arbitrary_filters; - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + GetEffectNode(layer)->filters = arbitrary_filters; + UpdateActiveTreeDrawProperties(); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES( - host_impl.active_tree()->SetFilterMutated(layer->element_id(), - arbitrary_filters)); + host_impl()->active_tree()->SetFilterMutated(layer->element_id(), + arbitrary_filters)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetMasksToBounds(true)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetContentsOpaque(true)); VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetDrawsContent(true)); @@ -347,58 +257,10 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { VERIFY_NO_NEEDS_UPDATE_DRAW_PROPERTIES(layer->SetElementId(ElementId(2))); } -TEST(LayerImplTest, SafeOpaqueBackgroundColor) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - host_impl.active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl.active_tree(), 1)); - LayerImpl* layer = host_impl.active_tree()->root_layer_for_testing(); - - for (int contents_opaque = 0; contents_opaque < 2; ++contents_opaque) { - for (int layer_opaque = 0; layer_opaque < 2; ++layer_opaque) { - for (int host_opaque = 0; host_opaque < 2; ++host_opaque) { - layer->SetContentsOpaque(!!contents_opaque); - layer->SetBackgroundColor(layer_opaque ? SK_ColorRED - : SK_ColorTRANSPARENT); - host_impl.active_tree()->set_background_color( - host_opaque ? SK_ColorRED : SK_ColorTRANSPARENT); - host_impl.active_tree()->property_trees()->needs_rebuild = true; - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - - SkColor safe_color = layer->SafeOpaqueBackgroundColor(); - if (contents_opaque) { - EXPECT_EQ(SkColorGetA(safe_color), 255u) - << "Flags: " << contents_opaque << ", " << layer_opaque << ", " - << host_opaque << "\n"; - } else { - EXPECT_NE(SkColorGetA(safe_color), 255u) - << "Flags: " << contents_opaque << ", " << layer_opaque << ", " - << host_opaque << "\n"; - } - } - } - } -} - -TEST(LayerImplTest, PerspectiveTransformHasReasonableScale) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - LayerTreeSettings settings; - FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &task_graph_runner); - auto owned_layer = LayerImpl::Create(host_impl.active_tree(), 1); - LayerImpl* layer = owned_layer.get(); +TEST_F(LayerImplTest, PerspectiveTransformHasReasonableScale) { + LayerImpl* layer = root_layer(); layer->SetBounds(gfx::Size(10, 10)); layer->set_contributes_to_drawn_render_surface(true); - host_impl.active_tree()->SetRootLayerForTesting(std::move(owned_layer)); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); // Ensure that we are close to the maximum scale for the matrix. { @@ -443,50 +305,36 @@ TEST(LayerImplTest, PerspectiveTransformHasReasonableScale) { } } -class LayerImplScrollTest : public testing::Test { +class LayerImplScrollTest : public LayerImplTest { public: - LayerImplScrollTest() : LayerImplScrollTest(LayerTreeSettings()) {} + LayerImplScrollTest() : LayerImplScrollTest(LayerListSettings()) {} explicit LayerImplScrollTest(const LayerTreeSettings& settings) - : host_impl_(settings, &task_runner_provider_, &task_graph_runner_), - root_id_(7) { - host_impl_.active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_.active_tree(), root_id_)); - host_impl_.active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(LayerImpl::Create(host_impl_.active_tree(), root_id_ + 1)); + : LayerImplTest(settings) { + LayerImpl* root = root_layer(); + root->SetBounds(gfx::Size(1, 1)); + + layer_ = AddLayer<LayerImpl>(); + SetElementIdsForTesting(); // Set the max scroll offset by noting that the root layer has bounds (1,1), // thus whatever bounds are set for the layer will be the max scroll // offset plus 1 in each direction. - host_impl_.active_tree()->root_layer_for_testing()->SetBounds( - gfx::Size(1, 1)); - layer()->SetScrollable(gfx::Size(1, 1)); - gfx::Vector2d max_scroll_offset(51, 81); - layer()->SetBounds(gfx::Size(max_scroll_offset.x(), max_scroll_offset.y())); - host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + layer_->SetScrollable(gfx::Size(1, 1)); + layer_->SetBounds(gfx::Size(51, 81)); + CopyProperties(root, layer_); + CreateTransformNode(layer_); + CreateScrollNode(layer_); + UpdateActiveTreeDrawProperties(); } - LayerImpl* layer() { - return host_impl_.active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0]; - } + LayerImpl* layer() { return layer_; } ScrollTree* scroll_tree(LayerImpl* layer_impl) { return &layer_impl->layer_tree_impl()->property_trees()->scroll_tree; } - LayerTreeHostImpl& host_impl() { return host_impl_; } - - LayerTreeImpl* tree() { return host_impl_.active_tree(); } - private: - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; - int root_id_; + LayerImpl* layer_; }; class CommitToPendingTreeLayerImplScrollTest : public LayerImplScrollTest { @@ -494,9 +342,9 @@ class CommitToPendingTreeLayerImplScrollTest : public LayerImplScrollTest { CommitToPendingTreeLayerImplScrollTest() : LayerImplScrollTest(settings()) {} LayerTreeSettings settings() { - LayerTreeSettings tree_settings; - tree_settings.commit_to_active_tree = false; - return tree_settings; + LayerListSettings settings; + settings.commit_to_active_tree = false; + return settings; } }; @@ -592,9 +440,8 @@ TEST_F(LayerImplScrollTest, ScrollUserUnscrollableLayer) { gfx::ScrollOffset scroll_offset(10, 5); gfx::Vector2dF scroll_delta(20.5f, 8.5f); - layer()->test_properties()->user_scrollable_vertical = false; - layer()->layer_tree_impl()->property_trees()->needs_rebuild = true; - layer()->layer_tree_impl()->BuildLayerListAndPropertyTreesForTesting(); + GetScrollNode(layer())->user_scrollable_vertical = false; + UpdateDrawProperties(layer()->layer_tree_impl()); scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->element_id(), scroll_offset); gfx::Vector2dF unscrolled = layer()->ScrollBy(scroll_delta); @@ -606,9 +453,9 @@ TEST_F(LayerImplScrollTest, ScrollUserUnscrollableLayer) { // |LayerImpl::all_touch_action_regions_| is a cache of all regions on // |LayerImpl::touch_action_region_| and must be invalidated on changes. TEST_F(LayerImplScrollTest, TouchActionRegionCacheInvalidation) { - host_impl().CreatePendingTree(); + host_impl()->CreatePendingTree(); std::unique_ptr<LayerImpl> pending_layer = - LayerImpl::Create(host_impl().pending_tree(), 2); + LayerImpl::Create(host_impl()->pending_tree(), 2); TouchActionRegion region; region.Union(kTouchActionNone, gfx::Rect(0, 0, 50, 50)); @@ -633,7 +480,7 @@ TEST_F(CommitToPendingTreeLayerImplScrollTest, gfx::ScrollOffset scroll_offset(10, 5); gfx::Vector2dF scroll_delta(12, 18); - host_impl().CreatePendingTree(); + host_impl()->CreatePendingTree(); scroll_tree(layer())->UpdateScrollOffsetBaseForTesting(layer()->element_id(), scroll_offset); @@ -645,7 +492,7 @@ TEST_F(CommitToPendingTreeLayerImplScrollTest, scroll_tree(layer())->CollectScrollDeltasForTesting(); std::unique_ptr<LayerImpl> pending_layer = - LayerImpl::Create(host_impl().sync_tree(), layer()->id()); + LayerImpl::Create(host_impl()->sync_tree(), layer()->id()); pending_layer->SetElementId( LayerIdToElementIdForTesting(pending_layer->id())); scroll_tree(pending_layer.get()) @@ -659,5 +506,54 @@ TEST_F(CommitToPendingTreeLayerImplScrollTest, pending_layer->CurrentScrollOffset()); } +TEST_F(LayerImplTest, JitterTest) { + host_impl()->CreatePendingTree(); + auto* root_layer = EnsureRootLayerInPendingTree(); + root_layer->SetBounds(gfx::Size(50, 50)); + SetupViewport(root_layer, gfx::Size(100, 100), gfx::Size(100, 100)); + auto* scroll_layer = + host_impl()->pending_tree()->InnerViewportScrollLayerForTesting(); + auto* content_layer = AddLayerInPendingTree<LayerImpl>(); + content_layer->SetBounds(gfx::Size(100, 100)); + content_layer->SetDrawsContent(true); + CopyProperties( + host_impl()->pending_tree()->OuterViewportScrollLayerForTesting(), + content_layer); + UpdatePendingTreeDrawProperties(); + + host_impl()->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); + const int scroll = 5; + int accumulated_scroll = 0; + for (int i = 0; i < LayerTreeImpl::kFixedPointHitsThreshold + 1; ++i) { + host_impl()->ActivateSyncTree(); + accumulated_scroll += scroll; + SetScrollOffset( + host_impl()->active_tree()->InnerViewportScrollLayerForTesting(), + gfx::ScrollOffset(0, accumulated_scroll)); + UpdateActiveTreeDrawProperties(); + + host_impl()->CreatePendingTree(); + LayerTreeImpl* pending_tree = host_impl()->pending_tree(); + pending_tree->set_source_frame_number(i + 1); + pending_tree->PushPageScaleFromMainThread(1.f, 1.f, 1.f); + // Simulate scroll offset pushed from the main thread. + SetScrollOffset(scroll_layer, gfx::ScrollOffset(0, accumulated_scroll)); + // The scroll done on the active tree is undone on the pending tree. + content_layer->SetOffsetToTransformParent( + gfx::Vector2dF(0, accumulated_scroll)); + content_layer->SetNeedsPushProperties(); + UpdateDrawProperties(pending_tree); + + float jitter = content_layer->CalculateJitter(); + // There should not be any jitter measured till we hit the fixed point hits + // threshold. 250 is sqrt(50 * 50) * 5. 50x50 is the visible bounds of + // content (clipped by the viewport). 5 is the distance between the + // locations of the content in the pending tree and the active tree. + float expected_jitter = + (i == pending_tree->kFixedPointHitsThreshold) ? 250 : 0; + EXPECT_EQ(jitter, expected_jitter); + } +} + } // namespace } // namespace cc diff --git a/chromium/cc/layers/layer_list_iterator.cc b/chromium/cc/layers/layer_list_iterator.cc index 7ff7c68ca6e..7e2066b089a 100644 --- a/chromium/cc/layers/layer_list_iterator.cc +++ b/chromium/cc/layers/layer_list_iterator.cc @@ -5,67 +5,38 @@ #include "cc/layers/layer_list_iterator.h" #include "cc/layers/layer.h" -#include "cc/layers/layer_impl.h" namespace cc { -static Layer* Parent(Layer* layer) { - return layer->parent(); -} - -static LayerImpl* Parent(LayerImpl* layer) { - return layer->test_properties()->parent; -} -template <typename LayerType> -LayerListIterator<LayerType>::LayerListIterator(LayerType* root_layer) +LayerListIterator::LayerListIterator(Layer* root_layer) : current_layer_(root_layer) { - DCHECK(!root_layer || !Parent(root_layer)); + DCHECK(!root_layer || !root_layer->parent()); list_indices_.push_back(0); } -static LayerImplList& Children(LayerImpl* layer) { - return layer->test_properties()->children; -} - -static const LayerList& Children(Layer* layer) { - return layer->children(); -} +LayerListIterator::LayerListIterator(const LayerListIterator& other) = default; -static LayerImpl* ChildAt(LayerImpl* layer, int index) { - return layer->test_properties()->children[index]; -} +LayerListIterator::~LayerListIterator() = default; -static Layer* ChildAt(Layer* layer, int index) { - return layer->children()[index].get(); -} - -template <typename LayerType> -LayerListIterator<LayerType>::LayerListIterator( - const LayerListIterator<LayerType>& other) = default; - -template <typename LayerType> -LayerListIterator<LayerType>::~LayerListIterator() = default; - -template <typename LayerType> -LayerListIterator<LayerType>& LayerListIterator<LayerType>::operator++() { +LayerListIterator& LayerListIterator::operator++() { // case 0: done if (!current_layer_) return *this; // case 1: descend. - if (!Children(current_layer_).empty()) { - current_layer_ = ChildAt(current_layer_, 0); + if (!current_layer_->children().empty()) { + current_layer_ = current_layer_->children()[0].get(); list_indices_.push_back(0); return *this; } - for (LayerType* parent = Parent(current_layer_); parent; - parent = Parent(parent)) { + for (Layer* parent = current_layer_->parent(); parent; + parent = parent->parent()) { // We now try and advance in some list of siblings. // case 2: Advance to a sibling. - if (list_indices_.back() + 1 < Children(parent).size()) { + if (list_indices_.back() + 1 < parent->children().size()) { ++list_indices_.back(); - current_layer_ = ChildAt(parent, list_indices_.back()); + current_layer_ = parent->children()[list_indices_.back()].get(); return *this; } @@ -77,58 +48,47 @@ LayerListIterator<LayerType>& LayerListIterator<LayerType>::operator++() { return *this; } -template <typename LayerType> -LayerListReverseIterator<LayerType>::LayerListReverseIterator( - LayerType* root_layer) - : LayerListIterator<LayerType>(root_layer) { +LayerListReverseIterator::LayerListReverseIterator(Layer* root_layer) + : LayerListIterator(root_layer) { DescendToRightmostInSubtree(); } -template <typename LayerType> -LayerListReverseIterator<LayerType>::~LayerListReverseIterator() = default; +LayerListReverseIterator::~LayerListReverseIterator() = default; // We will only support prefix increment. -template <typename LayerType> -LayerListIterator<LayerType>& LayerListReverseIterator<LayerType>:: -operator++() { +LayerListIterator& LayerListReverseIterator::operator++() { // case 0: done - if (!current_layer()) + if (!current_layer_) return *this; // case 1: we're the leftmost sibling. - if (!list_indices().back()) { - list_indices().pop_back(); - this->current_layer_ = Parent(current_layer()); + if (!list_indices_.back()) { + list_indices_.pop_back(); + current_layer_ = current_layer_->parent(); return *this; } // case 2: we're not the leftmost sibling. In this case, we want to move one // sibling over, and then descend to the rightmost descendant in that subtree. - CHECK(Parent(current_layer())); - --list_indices().back(); + CHECK(current_layer_->parent()); + --list_indices_.back(); this->current_layer_ = - ChildAt(Parent(current_layer()), list_indices().back()); + current_layer_->parent()->children()[list_indices_.back()].get(); DescendToRightmostInSubtree(); return *this; } -template <typename LayerType> -void LayerListReverseIterator<LayerType>::DescendToRightmostInSubtree() { - if (!current_layer()) +void LayerListReverseIterator::DescendToRightmostInSubtree() { + if (!current_layer_) return; - if (Children(current_layer()).empty()) + if (current_layer_->children().empty()) return; - size_t last_index = Children(current_layer()).size() - 1; - this->current_layer_ = ChildAt(current_layer(), last_index); - list_indices().push_back(last_index); + size_t last_index = current_layer_->children().size() - 1; + this->current_layer_ = current_layer_->children()[last_index].get(); + list_indices_.push_back(last_index); DescendToRightmostInSubtree(); } -template class LayerListIterator<Layer>; -template class LayerListIterator<LayerImpl>; -template class LayerListReverseIterator<Layer>; -template class LayerListReverseIterator<LayerImpl>; - } // namespace cc diff --git a/chromium/cc/layers/layer_list_iterator.h b/chromium/cc/layers/layer_list_iterator.h index da092b951ec..e06686fae5a 100644 --- a/chromium/cc/layers/layer_list_iterator.h +++ b/chromium/cc/layers/layer_list_iterator.h @@ -12,49 +12,46 @@ namespace cc { -// This visits a tree of layers in drawing order. For LayerImpls, this is only -// useful for tests, since there's no LayerImpl tree outside unit tests. -template <typename LayerType> +class Layer; + +// This visits a tree of layers in drawing order. class CC_EXPORT LayerListIterator { public: - explicit LayerListIterator(LayerType* root_layer); - LayerListIterator(const LayerListIterator<LayerType>& other); + explicit LayerListIterator(Layer* root_layer); + LayerListIterator(const LayerListIterator& other); virtual ~LayerListIterator(); - bool operator==(const LayerListIterator<LayerType>& other) const { + bool operator==(const LayerListIterator& other) const { return current_layer_ == other.current_layer_; } - bool operator!=(const LayerListIterator<LayerType>& other) const { + bool operator!=(const LayerListIterator& other) const { return !(*this == other); } // We will only support prefix increment. virtual LayerListIterator& operator++(); - LayerType* operator->() const { return current_layer_; } - LayerType* operator*() const { return current_layer_; } + Layer* operator->() const { return current_layer_; } + Layer* operator*() const { return current_layer_; } protected: // The implementation of this iterator is currently tied tightly to the layer // tree, but it should be straightforward to reimplement in terms of a list // when it's ready. - LayerType* current_layer_; + Layer* current_layer_; std::vector<size_t> list_indices_; }; -template <typename LayerType> -class CC_EXPORT LayerListReverseIterator : public LayerListIterator<LayerType> { +class CC_EXPORT LayerListReverseIterator : public LayerListIterator { public: - explicit LayerListReverseIterator(LayerType* root_layer); + explicit LayerListReverseIterator(Layer* root_layer); ~LayerListReverseIterator() override; // We will only support prefix increment. - LayerListIterator<LayerType>& operator++() override; + LayerListIterator& operator++() override; private: void DescendToRightmostInSubtree(); - LayerType* current_layer() { return this->current_layer_; } - std::vector<size_t>& list_indices() { return this->list_indices_; } }; } // namespace cc diff --git a/chromium/cc/layers/layer_list_iterator_unittest.cc b/chromium/cc/layers/layer_list_iterator_unittest.cc index f3f62fc11f4..d0dce4bda6c 100644 --- a/chromium/cc/layers/layer_list_iterator_unittest.cc +++ b/chromium/cc/layers/layer_list_iterator_unittest.cc @@ -8,12 +8,9 @@ #include "base/containers/adapters.h" #include "cc/animation/animation_host.h" -#include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host.h" -#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -100,8 +97,8 @@ TEST(LayerListIteratorTest, VerifyNullFirstLayer) { // Ensures that if an iterator is constructed with a nullptr, that it can be // iterated without issue and that it remains equal to any other // null-initialized iterator. - LayerListIterator<Layer> it(nullptr); - LayerListIterator<Layer> end(nullptr); + LayerListIterator it(nullptr); + LayerListIterator end(nullptr); EXPECT_EQ(it, end); ++it; @@ -189,188 +186,8 @@ TEST(LayerListReverseIteratorTest, VerifyNullFirstLayer) { // Ensures that if an iterator is constructed with a nullptr, that it can be // iterated without issue and that it remains equal to any other // null-initialized iterator. - LayerListReverseIterator<Layer> it(nullptr); - LayerListReverseIterator<Layer> end(nullptr); - - EXPECT_EQ(it, end); - ++it; - EXPECT_EQ(it, end); -} - -// LayerImpl version unit tests - -TEST(LayerListIteratorTest, VerifyTraversalOrderImpl) { - // Unfortunate preamble. - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - - // This test constructs the following tree. - // 1 - // +-2 - // | +-3 - // | +-4 - // + 5 - // +-6 - // +-7 - // We expect to visit all seven layers in that order. - std::unique_ptr<LayerImpl> layer1 = - LayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<LayerImpl> layer2 = - LayerImpl::Create(host_impl.active_tree(), 2); - std::unique_ptr<LayerImpl> layer3 = - LayerImpl::Create(host_impl.active_tree(), 3); - std::unique_ptr<LayerImpl> layer4 = - LayerImpl::Create(host_impl.active_tree(), 4); - std::unique_ptr<LayerImpl> layer5 = - LayerImpl::Create(host_impl.active_tree(), 5); - std::unique_ptr<LayerImpl> layer6 = - LayerImpl::Create(host_impl.active_tree(), 6); - std::unique_ptr<LayerImpl> layer7 = - LayerImpl::Create(host_impl.active_tree(), 7); - - layer2->test_properties()->AddChild(std::move(layer3)); - layer2->test_properties()->AddChild(std::move(layer4)); - - layer5->test_properties()->AddChild(std::move(layer6)); - layer5->test_properties()->AddChild(std::move(layer7)); - - layer1->test_properties()->AddChild(std::move(layer2)); - layer1->test_properties()->AddChild(std::move(layer5)); - - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); - host_impl.active_tree()->BuildLayerListForTesting(); - - int i = 1; - for (auto* layer : *host_impl.active_tree()) { - EXPECT_EQ(i++, layer->id()); - } - EXPECT_EQ(8, i); -} - -TEST(LayerListIteratorTest, VerifySingleLayerImpl) { - // Unfortunate preamble. - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - - // This test constructs a tree consisting of a single layer. - std::unique_ptr<LayerImpl> layer1 = - LayerImpl::Create(host_impl.active_tree(), 1); - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); - host_impl.active_tree()->BuildLayerListForTesting(); - - int i = 1; - for (auto* layer : *host_impl.active_tree()) { - EXPECT_EQ(i++, layer->id()); - } - EXPECT_EQ(2, i); -} - -TEST(LayerListIteratorTest, VerifyNullFirstLayerImpl) { - // Ensures that if an iterator is constructed with a nullptr, that it can be - // iterated without issue and that it remains equal to any other - // null-initialized iterator. - LayerListIterator<LayerImpl> it(nullptr); - LayerListIterator<LayerImpl> end(nullptr); - - EXPECT_EQ(it, end); - ++it; - EXPECT_EQ(it, end); -} - -TEST(LayerListReverseIteratorTest, VerifyTraversalOrderImpl) { - // Unfortunate preamble. - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - - // This test constructs the following tree. - // 1 - // +-2 - // | +-3 - // | +-4 - // + 5 - // +-6 - // +-7 - // We expect to visit all seven layers in reverse order. - std::unique_ptr<LayerImpl> layer1 = - LayerImpl::Create(host_impl.active_tree(), 1); - std::unique_ptr<LayerImpl> layer2 = - LayerImpl::Create(host_impl.active_tree(), 2); - std::unique_ptr<LayerImpl> layer3 = - LayerImpl::Create(host_impl.active_tree(), 3); - std::unique_ptr<LayerImpl> layer4 = - LayerImpl::Create(host_impl.active_tree(), 4); - std::unique_ptr<LayerImpl> layer5 = - LayerImpl::Create(host_impl.active_tree(), 5); - std::unique_ptr<LayerImpl> layer6 = - LayerImpl::Create(host_impl.active_tree(), 6); - std::unique_ptr<LayerImpl> layer7 = - LayerImpl::Create(host_impl.active_tree(), 7); - - layer2->test_properties()->AddChild(std::move(layer3)); - layer2->test_properties()->AddChild(std::move(layer4)); - - layer5->test_properties()->AddChild(std::move(layer6)); - layer5->test_properties()->AddChild(std::move(layer7)); - - layer1->test_properties()->AddChild(std::move(layer2)); - layer1->test_properties()->AddChild(std::move(layer5)); - - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); - host_impl.active_tree()->BuildLayerListForTesting(); - - int i = 7; - - for (auto* layer : base::Reversed(*host_impl.active_tree())) { - EXPECT_EQ(i--, layer->id()); - } - - EXPECT_EQ(0, i); -} - -TEST(LayerListReverseIteratorTest, VerifySingleLayerImpl) { - // Unfortunate preamble. - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - host_impl.SetVisible(true); - EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); - - // This test constructs a tree consisting of a single layer. - std::unique_ptr<LayerImpl> layer1 = - LayerImpl::Create(host_impl.active_tree(), 1); - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer1)); - host_impl.active_tree()->BuildLayerListForTesting(); - - int i = 1; - for (auto* layer : base::Reversed(*host_impl.active_tree())) { - EXPECT_EQ(i--, layer->id()); - } - EXPECT_EQ(0, i); -} - -TEST(LayerListReverseIteratorTest, VerifyNullFirstLayerImpl) { - // Ensures that if an iterator is constructed with a nullptr, that it can be - // iterated without issue and that it remains equal to any other - // null-initialized iterator. - LayerListReverseIterator<LayerImpl> it(nullptr); - LayerListReverseIterator<LayerImpl> end(nullptr); + LayerListReverseIterator it(nullptr); + LayerListReverseIterator end(nullptr); EXPECT_EQ(it, end); ++it; diff --git a/chromium/cc/layers/layer_perftest.cc b/chromium/cc/layers/layer_perftest.cc index c2171885cbb..debe50559e7 100644 --- a/chromium/cc/layers/layer_perftest.cc +++ b/chromium/cc/layers/layer_perftest.cc @@ -14,7 +14,7 @@ #include "cc/test/stub_layer_tree_host_single_thread_client.h" #include "cc/test/test_task_graph_runner.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -45,6 +45,14 @@ class LayerPerfTest : public testing::Test { layer_tree_host_ = nullptr; } + perf_test::PerfResultReporter SetUpReporter( + const std::string& metric_basename, + const std::string& story_name) { + perf_test::PerfResultReporter reporter(metric_basename, story_name); + reporter.RegisterImportantMetric("", "runs/s"); + return reporter; + } + FakeImplTaskRunnerProvider task_runner_provider_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; @@ -91,12 +99,9 @@ TEST_F(LayerPerfTest, PushPropertiesTo) { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("push_properties_to", - "", - "props_changed", - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = + SetUpReporter("push_properties_to", "props_changed"); + reporter.AddResult("", timer_.LapsPerSecond()); // Properties didn't change. timer_.Reset(); @@ -105,12 +110,8 @@ TEST_F(LayerPerfTest, PushPropertiesTo) { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("push_properties_to", - "", - "props_didnt_change", - timer_.LapsPerSecond(), - "runs/s", - true); + reporter = SetUpReporter("push_properties_to", "props_didnt_change"); + reporter.AddResult("", timer_.LapsPerSecond()); } TEST_F(LayerPerfTest, ImplPushPropertiesTo) { @@ -147,8 +148,9 @@ TEST_F(LayerPerfTest, ImplPushPropertiesTo) { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("impl_push_properties_to", "", "props_changed", - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = + SetUpReporter("impl_push_properties_to", "props_changed"); + reporter.AddResult("", timer_.LapsPerSecond()); // Properties didn't change. timer_.Reset(); @@ -157,8 +159,8 @@ TEST_F(LayerPerfTest, ImplPushPropertiesTo) { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("impl_push_properties_to", "", "props_didnt_change", - timer_.LapsPerSecond(), "runs/s", true); + reporter = SetUpReporter("impl_push_properties_to", "props_didnt_change"); + reporter.AddResult("", timer_.LapsPerSecond()); } } // namespace diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc index 2c240f9e081..9a8503b51d6 100644 --- a/chromium/cc/layers/layer_unittest.cc +++ b/chromium/cc/layers/layer_unittest.cc @@ -13,7 +13,6 @@ #include "cc/animation/animation_id_provider.h" #include "cc/animation/keyframed_animation_curve.h" #include "cc/base/math_util.h" -#include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/layer_impl.h" #include "cc/layers/picture_layer.h" #include "cc/layers/solid_color_scrollbar_layer.h" @@ -288,6 +287,7 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) { EXPECT_SET_NEEDS_COMMIT(1, top->SetBounds(arbitrary_size)); EXPECT_SET_NEEDS_COMMIT(0, mask_layer1->SetBounds(arbitrary_size)); EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(1); + EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AtLeast(1)); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetMaskLayer(mask_layer1)); // Set up the impl layers after the full tree is constructed, including the @@ -334,22 +334,6 @@ TEST_F(LayerTest, LayerPropertyChangedForSubtree) { grand_child->PushPropertiesTo(grand_child_impl.get())); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); - EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetShouldFlattenTransform(false)); - EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET( - top->PushPropertiesTo(top_impl.get()); - child->PushPropertiesTo(child_impl.get()); - child2->PushPropertiesTo(child2_impl.get()); - grand_child->PushPropertiesTo(grand_child_impl.get())); - - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); - EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->Set3dSortingContextId(1)); - EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET( - top->PushPropertiesTo(top_impl.get()); - child->PushPropertiesTo(child_impl.get()); - child2->PushPropertiesTo(child2_impl.get()); - grand_child->PushPropertiesTo(grand_child_impl.get())); - - EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXECUTE_AND_VERIFY_SUBTREE_CHANGED(top->SetTrilinearFiltering(true)); EXECUTE_AND_VERIFY_SUBTREE_CHANGES_RESET( top->PushPropertiesTo(top_impl.get()); @@ -497,6 +481,75 @@ TEST_F(LayerTest, AddAndRemoveChild) { EXPECT_SET_NEEDS_FULL_TREE_SYNC(AtLeast(1), child->RemoveFromParent()); } +TEST_F(LayerTest, SetMaskLayer) { + scoped_refptr<Layer> parent = Layer::Create(); + FakeContentLayerClient client; + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + mask->SetPosition(gfx::PointF(88, 99)); + + parent->SetMaskLayer(mask); + ASSERT_EQ(1u, parent->children().size()); + EXPECT_EQ(parent.get(), mask->parent()); + EXPECT_EQ(mask.get(), parent->children()[0]); + EXPECT_TRUE(parent->IsMaskedByChild()); + + // Should ignore mask layer's position. + EXPECT_TRUE(mask->position().IsOrigin()); + mask->SetPosition(gfx::PointF(11, 22)); + EXPECT_TRUE(mask->position().IsOrigin()); + + parent->SetMaskLayer(mask); + ASSERT_EQ(1u, parent->children().size()); + EXPECT_EQ(parent.get(), mask->parent()); + EXPECT_EQ(mask.get(), parent->children()[0]); + EXPECT_TRUE(parent->IsMaskedByChild()); + + scoped_refptr<PictureLayer> mask2 = PictureLayer::Create(&client); + parent->SetMaskLayer(mask2); + EXPECT_FALSE(mask->parent()); + ASSERT_EQ(1u, parent->children().size()); + EXPECT_EQ(parent.get(), mask2->parent()); + EXPECT_EQ(mask2.get(), parent->children()[0]); + EXPECT_TRUE(parent->IsMaskedByChild()); + + parent->SetMaskLayer(nullptr); + EXPECT_EQ(0u, parent->children().size()); + EXPECT_FALSE(mask2->parent()); + EXPECT_FALSE(parent->IsMaskedByChild()); +} + +TEST_F(LayerTest, RemoveMaskLayerFromParent) { + scoped_refptr<Layer> parent = Layer::Create(); + FakeContentLayerClient client; + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + + parent->SetMaskLayer(mask); + mask->RemoveFromParent(); + EXPECT_EQ(0u, parent->children().size()); + EXPECT_FALSE(mask->parent()); + EXPECT_FALSE(parent->IsMaskedByChild()); + + scoped_refptr<PictureLayer> mask2 = PictureLayer::Create(&client); + parent->SetMaskLayer(mask2); + EXPECT_TRUE(parent->IsMaskedByChild()); +} + +TEST_F(LayerTest, AddChildAfterSetMaskLayer) { + scoped_refptr<Layer> parent = Layer::Create(); + FakeContentLayerClient client; + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); + parent->SetMaskLayer(mask); + EXPECT_TRUE(parent->IsMaskedByChild()); + + parent->AddChild(Layer::Create()); + EXPECT_EQ(mask.get(), parent->children().back().get()); + EXPECT_TRUE(parent->IsMaskedByChild()); + + parent->InsertChild(Layer::Create(), parent->children().size()); + EXPECT_EQ(mask.get(), parent->children().back().get()); + EXPECT_TRUE(parent->IsMaskedByChild()); +} + TEST_F(LayerTest, AddSameChildTwice) { EXPECT_CALL(*layer_tree_host_, SetNeedsFullTreeSync()).Times(AtLeast(1)); @@ -848,58 +901,6 @@ TEST_F(LayerTest, CheckSetNeedsDisplayCausesCorrectBehavior) { EXPECT_TRUE(LayerNeedsDisplay(test_layer.get())); } -TEST_F(LayerTest, TestSettingMainThreadScrollingReason) { - scoped_refptr<Layer> test_layer = Layer::Create(); - EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, - layer_tree_host_->SetRootLayer(test_layer)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsDrawable(true)); - - // sanity check of initial test condition - EXPECT_FALSE(LayerNeedsDisplay(test_layer.get())); - - uint32_t reasons = 0, reasons_to_clear = 0, reasons_after_clearing = 0; - reasons |= MainThreadScrollingReason::kThreadedScrollingDisabled; - reasons |= MainThreadScrollingReason::kHandlingScrollFromMainThread; - reasons |= MainThreadScrollingReason::kScrollbarScrolling; - - reasons_to_clear |= MainThreadScrollingReason::kHandlingScrollFromMainThread; - - reasons_after_clearing |= - MainThreadScrollingReason::kThreadedScrollingDisabled; - reasons_after_clearing |= MainThreadScrollingReason::kScrollbarScrolling; - - // Check that the reasons are added correctly. - EXPECT_SET_NEEDS_COMMIT( - 1, test_layer->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kThreadedScrollingDisabled)); - EXPECT_SET_NEEDS_COMMIT( - 1, test_layer->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kHandlingScrollFromMainThread)); - EXPECT_SET_NEEDS_COMMIT(1, - test_layer->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kScrollbarScrolling)); - EXPECT_EQ(reasons, test_layer->GetMainThreadScrollingReasons()); - - // Check that the reasons can be selectively cleared. - EXPECT_SET_NEEDS_COMMIT( - 1, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear)); - EXPECT_EQ(reasons_after_clearing, - test_layer->GetMainThreadScrollingReasons()); - - // Check that clearing non-set reasons doesn't set needs commit. - reasons_to_clear = 0; - reasons_to_clear |= MainThreadScrollingReason::kFrameOverlay; - EXPECT_SET_NEEDS_COMMIT( - 0, test_layer->ClearMainThreadScrollingReasons(reasons_to_clear)); - EXPECT_EQ(reasons_after_clearing, - test_layer->GetMainThreadScrollingReasons()); - - // Check that adding an existing condition doesn't set needs commit. - EXPECT_SET_NEEDS_COMMIT( - 0, test_layer->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kThreadedScrollingDisabled)); -} - TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { scoped_refptr<Layer> test_layer = Layer::Create(); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, @@ -924,7 +925,6 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsFastRoundedCorner(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetOpacity(0.5f)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetBlendMode(SkBlendMode::kHue)); - EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetIsRootForIsolatedGroup(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetContentsOpaque(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetPosition(gfx::PointF(4.f, 9.f))); // We can use any layer pointer here since we aren't syncing for real. @@ -932,9 +932,6 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetUserScrollable(true, false)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetScrollOffset( gfx::ScrollOffset(10, 10))); - EXPECT_SET_NEEDS_COMMIT( - 1, test_layer->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kThreadedScrollingDisabled)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetNonFastScrollableRegion( Region(gfx::Rect(1, 1, 2, 2)))); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetTransform( @@ -948,6 +945,7 @@ TEST_F(LayerTest, CheckPropertyChangeCausesCorrectBehavior) { EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetHideLayerAndSubtree(true)); EXPECT_SET_NEEDS_COMMIT(1, test_layer->SetElementId(ElementId(2))); + EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(1); EXPECT_SET_NEEDS_FULL_TREE_SYNC(1, test_layer->SetMaskLayer(mask_layer1)); // The above tests should not have caused a change to the needs_display flag. @@ -966,7 +964,6 @@ TEST_F(LayerTest, PushPropertiesAccumulatesUpdateRect) { layer_tree_host_->SetRootLayer(test_layer)); host_impl_.active_tree()->SetRootLayerForTesting(std::move(impl_layer)); - host_impl_.active_tree()->BuildLayerListForTesting(); LayerImpl* impl_layer_ptr = host_impl_.active_tree()->LayerById(1); test_layer->SetNeedsDisplayRect(gfx::Rect(5, 5)); test_layer->PushPropertiesTo(impl_layer_ptr); @@ -1097,9 +1094,6 @@ void AssertLayerTreeHostMatchesForSubtree(Layer* layer, LayerTreeHost* host) { for (size_t i = 0; i < layer->children().size(); ++i) AssertLayerTreeHostMatchesForSubtree(layer->children()[i].get(), host); - - if (layer->mask_layer()) - AssertLayerTreeHostMatchesForSubtree(layer->mask_layer(), host); } class LayerLayerTreeHostTest : public testing::Test {}; diff --git a/chromium/cc/layers/mirror_layer_impl.cc b/chromium/cc/layers/mirror_layer_impl.cc index 80363cd0a4d..7a916bf5d69 100644 --- a/chromium/cc/layers/mirror_layer_impl.cc +++ b/chromium/cc/layers/mirror_layer_impl.cc @@ -55,8 +55,7 @@ void MirrorLayerImpl::AppendQuads(viz::RenderPass* render_pass, auto* quad = render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); quad->SetNew(shared_quad_state, content_rect, unoccluded_content_rect, mirrored_layer_id_, mask_resource_id, mask_uv_rect, - mask_texture_size, /*mask_applies_to_backdrop=*/false, - mirrored_effect_node->surface_contents_scale, + mask_texture_size, mirrored_effect_node->surface_contents_scale, mirrored_effect_node->filters_origin, gfx::RectF(gfx::Rect(content_rect.size())), !layer_tree_impl()->settings().enable_edge_anti_aliasing, 0.f); diff --git a/chromium/cc/layers/nine_patch_layer_impl_unittest.cc b/chromium/cc/layers/nine_patch_layer_impl_unittest.cc index bd853412370..7b22ec44742 100644 --- a/chromium/cc/layers/nine_patch_layer_impl_unittest.cc +++ b/chromium/cc/layers/nine_patch_layer_impl_unittest.cc @@ -12,7 +12,7 @@ #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_ui_resource_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/single_thread_proxy.h" #include "components/viz/common/quads/texture_draw_quad.h" #include "testing/gmock/include/gmock/gmock.h" @@ -56,7 +56,7 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size, NinePatchLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->test_properties()->force_render_surface = true; + SetupRootProperties(layer.get()); UIResourceId uid = 1; bool is_opaque = false; @@ -67,11 +67,10 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size, layer->SetImageBounds(bitmap_size); layer->SetLayout(aperture_rect, border, gfx::Rect(), fill_center, false); host_impl.active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl.active_tree()); AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + host_impl.active_tree()->root_layer()->AppendQuads(render_pass.get(), &data); // Verify quad rects const auto& quads = render_pass->quad_list; @@ -169,7 +168,7 @@ void NinePatchLayerLayoutTestWithOcclusion(const gfx::Size& bitmap_size, NinePatchLayerImpl::Create(host_impl.active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->test_properties()->force_render_surface = true; + SetupRootProperties(layer.get()); UIResourceId uid = 1; bool is_opaque = false; @@ -180,11 +179,10 @@ void NinePatchLayerLayoutTestWithOcclusion(const gfx::Size& bitmap_size, layer->SetImageBounds(bitmap_size); layer->SetLayout(aperture_rect, border, occlusion, false, false); host_impl.active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl.active_tree()); AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + host_impl.active_tree()->root_layer()->AppendQuads(render_pass.get(), &data); // Verify quad rects const auto& quads = render_pass->quad_list; @@ -350,7 +348,7 @@ TEST(NinePatchLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; SkBitmap sk_bitmap; sk_bitmap.allocN32Pixels(10, 10); @@ -360,11 +358,12 @@ TEST(NinePatchLayerImplTest, Occlusion) { impl.host_impl()->CreateUIResource(uid, bitmap); NinePatchLayerImpl* nine_patch_layer_impl = - impl.AddChildToRoot<NinePatchLayerImpl>(); + impl.AddLayer<NinePatchLayerImpl>(); nine_patch_layer_impl->SetBounds(layer_size); nine_patch_layer_impl->SetDrawsContent(true); nine_patch_layer_impl->SetUIResourceId(uid); nine_patch_layer_impl->SetImageBounds(gfx::Size(10, 10)); + CopyProperties(impl.root_layer(), nine_patch_layer_impl); gfx::Rect aperture = gfx::Rect(3, 3, 4, 4); gfx::Rect border = gfx::Rect(300, 300, 400, 400); @@ -377,8 +376,7 @@ TEST(NinePatchLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendQuadsWithOcclusion(nine_patch_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_size)); EXPECT_EQ(9u, impl.quad_list().size()); } @@ -387,7 +385,7 @@ TEST(NinePatchLayerImplTest, Occlusion) { gfx::Rect occluded(nine_patch_layer_impl->visible_layer_rect()); impl.AppendQuadsWithOcclusion(nine_patch_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -397,8 +395,8 @@ TEST(NinePatchLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(nine_patch_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs nine quads, three of which are partially occluded, and // three fully occluded. EXPECT_EQ(6u, impl.quad_list().size()); @@ -410,7 +408,7 @@ TEST(NinePatchLayerImplTest, OpaqueRect) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; SkBitmap sk_bitmap_opaque; sk_bitmap_opaque.allocN32Pixels(10, 10); @@ -431,10 +429,11 @@ TEST(NinePatchLayerImplTest, OpaqueRect) { impl.host_impl()->CreateUIResource(uid_alpha, bitmap_alpha); - NinePatchLayerImpl *nine_patch_layer_impl = - impl.AddChildToRoot<NinePatchLayerImpl>(); + NinePatchLayerImpl* nine_patch_layer_impl = + impl.AddLayer<NinePatchLayerImpl>(); nine_patch_layer_impl->SetBounds(layer_size); nine_patch_layer_impl->SetDrawsContent(true); + CopyProperties(impl.root_layer(), nine_patch_layer_impl); impl.CalcDrawProps(viewport_size); diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer.cc b/chromium/cc/layers/painted_overlay_scrollbar_layer.cc index e6fcf5ff6ec..d46146ef57d 100644 --- a/chromium/cc/layers/painted_overlay_scrollbar_layer.cc +++ b/chromium/cc/layers/painted_overlay_scrollbar_layer.cc @@ -31,45 +31,33 @@ std::unique_ptr<LayerImpl> PaintedOverlayScrollbarLayer::CreateLayerImpl( } scoped_refptr<PaintedOverlayScrollbarLayer> -PaintedOverlayScrollbarLayer::Create(std::unique_ptr<Scrollbar> scrollbar, - ElementId scroll_element_id) { - return base::WrapRefCounted(new PaintedOverlayScrollbarLayer( - std::move(scrollbar), scroll_element_id)); +PaintedOverlayScrollbarLayer::Create(std::unique_ptr<Scrollbar> scrollbar) { + return base::WrapRefCounted( + new PaintedOverlayScrollbarLayer(std::move(scrollbar))); } PaintedOverlayScrollbarLayer::PaintedOverlayScrollbarLayer( - std::unique_ptr<Scrollbar> scrollbar, - ElementId scroll_element_id) + std::unique_ptr<Scrollbar> scrollbar) : scrollbar_(std::move(scrollbar)), - scroll_element_id_(scroll_element_id), thumb_thickness_(scrollbar_->ThumbThickness()), thumb_length_(scrollbar_->ThumbLength()) { + DCHECK(scrollbar_->HasThumb()); + DCHECK(scrollbar_->IsOverlay()); DCHECK(scrollbar_->UsesNinePatchThumbResource()); - SetIsScrollbar(true); } PaintedOverlayScrollbarLayer::~PaintedOverlayScrollbarLayer() = default; -void PaintedOverlayScrollbarLayer::SetScrollElementId(ElementId element_id) { - if (element_id == scroll_element_id_) - return; - - scroll_element_id_ = element_id; - SetNeedsCommit(); -} - bool PaintedOverlayScrollbarLayer::OpacityCanAnimateOnImplThread() const { return scrollbar_->IsOverlay(); } void PaintedOverlayScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { - Layer::PushPropertiesTo(layer); + ScrollbarLayerBase::PushPropertiesTo(layer); PaintedOverlayScrollbarLayerImpl* scrollbar_layer = static_cast<PaintedOverlayScrollbarLayerImpl*>(layer); - scrollbar_layer->SetScrollElementId(scroll_element_id_); - scrollbar_layer->SetThumbThickness(thumb_thickness_); scrollbar_layer->SetThumbLength(thumb_length_); if (scrollbar_->Orientation() == HORIZONTAL) { @@ -106,7 +94,7 @@ void PaintedOverlayScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { track_resource_.reset(); } - Layer::SetLayerTreeHost(host); + ScrollbarLayerBase::SetLayerTreeHost(host); } gfx::Rect PaintedOverlayScrollbarLayer::OriginThumbRectForPainting() const { @@ -117,9 +105,6 @@ bool PaintedOverlayScrollbarLayer::Update() { bool updated = false; updated |= Layer::Update(); - DCHECK(scrollbar_->HasThumb()); - DCHECK(scrollbar_->IsOverlay()); - DCHECK(scrollbar_->UsesNinePatchThumbResource()); updated |= UpdateProperty(scrollbar_->TrackRect(), &track_rect_); updated |= UpdateProperty(scrollbar_->Location(), &location_); updated |= UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_); @@ -143,15 +128,9 @@ bool PaintedOverlayScrollbarLayer::PaintThumbIfNeeded() { SkBitmap skbitmap; skbitmap.allocN32Pixels(paint_rect.width(), paint_rect.height()); SkiaPaintCanvas canvas(skbitmap); + canvas.clear(SK_ColorTRANSPARENT); - SkRect content_skrect = RectToSkRect(paint_rect); - PaintFlags flags; - flags.setAntiAlias(false); - flags.setBlendMode(SkBlendMode::kClear); - canvas.drawRect(content_skrect, flags); - canvas.clipRect(content_skrect); - - scrollbar_->PaintPart(&canvas, THUMB, paint_rect); + scrollbar_->PaintPart(&canvas, THUMB); // Make sure that the pixels are no longer mutable to unavoid unnecessary // allocation and copying. skbitmap.setImmutable(); @@ -183,15 +162,9 @@ bool PaintedOverlayScrollbarLayer::PaintTickmarks() { SkBitmap skbitmap; skbitmap.allocN32Pixels(paint_rect.width(), paint_rect.height()); SkiaPaintCanvas canvas(skbitmap); + canvas.clear(SK_ColorTRANSPARENT); - SkRect content_skrect = RectToSkRect(paint_rect); - PaintFlags flags; - flags.setAntiAlias(false); - flags.setBlendMode(SkBlendMode::kClear); - canvas.drawRect(content_skrect, flags); - canvas.clipRect(content_skrect); - - scrollbar_->PaintPart(&canvas, TICKMARKS, paint_rect); + scrollbar_->PaintPart(&canvas, TICKMARKS); // Make sure that the pixels are no longer mutable to unavoid unnecessary // allocation and copying. skbitmap.setImmutable(); diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer.h b/chromium/cc/layers/painted_overlay_scrollbar_layer.h index 931d96cc810..4838fb89452 100644 --- a/chromium/cc/layers/painted_overlay_scrollbar_layer.h +++ b/chromium/cc/layers/painted_overlay_scrollbar_layer.h @@ -8,14 +8,14 @@ #include "cc/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/layer.h" -#include "cc/layers/scrollbar_layer_interface.h" -#include "cc/layers/scrollbar_theme_painter.h" +#include "cc/layers/scrollbar_layer_base.h" #include "cc/resources/scoped_ui_resource.h" namespace cc { -class CC_EXPORT PaintedOverlayScrollbarLayer : public ScrollbarLayerInterface, - public Layer { +// For composited overlay scrollbars with nine-patch thumb. For overlay +// scrollbars whose thumb is not nine-patch, use PaintedScrollbarLayer. +class CC_EXPORT PaintedOverlayScrollbarLayer : public ScrollbarLayerBase { public: std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; @@ -23,22 +23,15 @@ class CC_EXPORT PaintedOverlayScrollbarLayer : public ScrollbarLayerInterface, PaintedOverlayScrollbarLayer& operator=(const PaintedOverlayScrollbarLayer&) = delete; static scoped_refptr<PaintedOverlayScrollbarLayer> Create( - std::unique_ptr<Scrollbar> scrollbar, - ElementId scroll_element_id = ElementId()); + std::unique_ptr<Scrollbar> scrollbar); bool OpacityCanAnimateOnImplThread() const override; - - // ScrollbarLayerInterface - void SetScrollElementId(ElementId element_id) override; - - // Layer interface bool Update() override; void SetLayerTreeHost(LayerTreeHost* host) override; void PushPropertiesTo(LayerImpl* layer) override; protected: - PaintedOverlayScrollbarLayer(std::unique_ptr<Scrollbar> scrollbar, - ElementId scroll_element_id); + explicit PaintedOverlayScrollbarLayer(std::unique_ptr<Scrollbar> scrollbar); ~PaintedOverlayScrollbarLayer() override; private: @@ -57,7 +50,6 @@ class CC_EXPORT PaintedOverlayScrollbarLayer : public ScrollbarLayerInterface, bool PaintTickmarks(); std::unique_ptr<Scrollbar> scrollbar_; - ElementId scroll_element_id_; int thumb_thickness_; int thumb_length_; diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc b/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc index db2867dc4a9..e1a77c3adf2 100644 --- a/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc @@ -19,9 +19,7 @@ class MockScrollbar : public FakeScrollbar { public: MockScrollbar() : FakeScrollbar(true, true, true) {} - void PaintPart(PaintCanvas* canvas, - ScrollbarPart part, - const gfx::Rect& content_rect) override { + void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override { if (part == TICKMARKS) paint_tickmarks_called_ = true; } diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc index 83df997f2b0..eca1517e8a1 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.cc +++ b/chromium/cc/layers/painted_scrollbar_layer.cc @@ -11,10 +11,6 @@ #include "cc/trees/layer_tree_host.h" #include "third_party/skia/include/core/SkBitmap.h" -namespace { -static constexpr int kMaxScrollbarDimension = 8192; -} - namespace cc { std::unique_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( @@ -25,50 +21,37 @@ std::unique_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( } scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create( - std::unique_ptr<Scrollbar> scrollbar, - ElementId scroll_element_id) { - return base::WrapRefCounted( - new PaintedScrollbarLayer(std::move(scrollbar), scroll_element_id)); + std::unique_ptr<Scrollbar> scrollbar) { + return base::WrapRefCounted(new PaintedScrollbarLayer(std::move(scrollbar))); } PaintedScrollbarLayer::PaintedScrollbarLayer( - std::unique_ptr<Scrollbar> scrollbar, - ElementId scroll_element_id) + std::unique_ptr<Scrollbar> scrollbar) : scrollbar_(std::move(scrollbar)), - scroll_element_id_(scroll_element_id), internal_contents_scale_(1.f), + supports_drag_snap_back_(false), thumb_thickness_(scrollbar_->ThumbThickness()), thumb_length_(scrollbar_->ThumbLength()), is_overlay_(scrollbar_->IsOverlay()), has_thumb_(scrollbar_->HasThumb()), - thumb_opacity_(scrollbar_->ThumbOpacity()) { - SetIsScrollbar(true); -} + thumb_opacity_(scrollbar_->ThumbOpacity()) {} PaintedScrollbarLayer::~PaintedScrollbarLayer() = default; -void PaintedScrollbarLayer::SetScrollElementId(ElementId element_id) { - if (element_id == scroll_element_id_) - return; - - scroll_element_id_ = element_id; - SetNeedsCommit(); -} - bool PaintedScrollbarLayer::OpacityCanAnimateOnImplThread() const { return scrollbar_->IsOverlay(); } void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { - Layer::PushPropertiesTo(layer); + ScrollbarLayerBase::PushPropertiesTo(layer); PaintedScrollbarLayerImpl* scrollbar_layer = static_cast<PaintedScrollbarLayerImpl*>(layer); - scrollbar_layer->SetScrollElementId(scroll_element_id_); scrollbar_layer->set_internal_contents_scale_and_bounds( internal_contents_scale_, internal_content_bounds_); + scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_); scrollbar_layer->SetThumbThickness(thumb_thickness_); scrollbar_layer->SetBackButtonRect(back_button_rect_); scrollbar_layer->SetForwardButtonRect(forward_button_rect_); @@ -103,7 +86,7 @@ void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) { thumb_resource_ = nullptr; } - Layer::SetLayerTreeHost(host); + ScrollbarLayerBase::SetLayerTreeHost(host); } gfx::Rect PaintedScrollbarLayer::ScrollbarLayerRectToContentRect( @@ -132,6 +115,7 @@ gfx::Rect PaintedScrollbarLayer::OriginThumbRect() const { } void PaintedScrollbarLayer::UpdateThumbAndTrackGeometry() { + UpdateProperty(scrollbar_->SupportsDragSnapBack(), &supports_drag_snap_back_); UpdateProperty(scrollbar_->TrackRect(), &track_rect_); UpdateProperty(scrollbar_->BackButtonRect(), &back_button_rect_); UpdateProperty(scrollbar_->ForwardButtonRect(), &forward_button_rect_); @@ -169,9 +153,8 @@ void PaintedScrollbarLayer::UpdateInternalContentScale() { bool PaintedScrollbarLayer::Update() { { - base::AutoReset<bool> ignore_set_needs_commit(&ignore_set_needs_commit_, - true); - Layer::Update(); + auto ignore_set_needs_commit = IgnoreSetNeedsCommit(); + ScrollbarLayerBase::Update(); UpdateInternalContentScale(); } @@ -240,13 +223,23 @@ UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart( // Pages can end up requesting arbitrarily large scrollbars. Prevent this // from crashing due to OOM and try something smaller. SkBitmap skbitmap; - if (!skbitmap.tryAllocN32Pixels(content_rect.width(), - content_rect.height())) { - content_rect.Intersect( - gfx::Rect(requested_content_rect.x(), requested_content_rect.y(), - kMaxScrollbarDimension, kMaxScrollbarDimension)); - skbitmap.allocN32Pixels(content_rect.width(), content_rect.height()); + bool allocation_succeeded = + skbitmap.tryAllocN32Pixels(content_rect.width(), content_rect.height()); + // Assuming 4bpp, caps at 4M. + constexpr int kMinScrollbarDimension = 1024; + int dimension = std::max(content_rect.width(), content_rect.height()) / 2; + while (!allocation_succeeded && dimension >= kMinScrollbarDimension) { + content_rect.Intersect(gfx::Rect(requested_content_rect.x(), + requested_content_rect.y(), dimension, + dimension)); + allocation_succeeded = + skbitmap.tryAllocN32Pixels(content_rect.width(), content_rect.height()); + if (!allocation_succeeded) + dimension = dimension / 2; } + CHECK(allocation_succeeded) + << "Failed to allocate memory for scrollbar at dimension : " << dimension; + SkiaPaintCanvas canvas(skbitmap); canvas.clear(SK_ColorTRANSPARENT); @@ -255,13 +248,8 @@ UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart( float scale_y = content_rect.height() / static_cast<float>(layer_rect.height()); canvas.scale(SkFloatToScalar(scale_x), SkFloatToScalar(scale_y)); - // TODO(pdr): Scrollbars are painted with an offset (see Scrollbar::PaintPart) - // and the canvas is translated so that scrollbars are drawn at the origin. - // Refactor this code to not use an offset at all so Scrollbar::PaintPart - // paints at the origin and no translation is needed below. - canvas.translate(-layer_rect.x(), -layer_rect.y()); - scrollbar_->PaintPart(&canvas, part, layer_rect); + scrollbar_->PaintPart(&canvas, part); // Make sure that the pixels are no longer mutable to unavoid unnecessary // allocation and copying. skbitmap.setImmutable(); diff --git a/chromium/cc/layers/painted_scrollbar_layer.h b/chromium/cc/layers/painted_scrollbar_layer.h index 1062ada84d6..444c042d0d3 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.h +++ b/chromium/cc/layers/painted_scrollbar_layer.h @@ -8,30 +8,22 @@ #include "cc/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/layers/layer.h" -#include "cc/layers/scrollbar_layer_interface.h" -#include "cc/layers/scrollbar_theme_painter.h" +#include "cc/layers/scrollbar_layer_base.h" #include "cc/resources/scoped_ui_resource.h" namespace cc { -class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, - public Layer { +class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerBase { public: std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; static scoped_refptr<PaintedScrollbarLayer> Create( - std::unique_ptr<Scrollbar> scrollbar, - ElementId element_id = ElementId()); + std::unique_ptr<Scrollbar> scrollbar); PaintedScrollbarLayer(const PaintedScrollbarLayer&) = delete; PaintedScrollbarLayer& operator=(const PaintedScrollbarLayer&) = delete; bool OpacityCanAnimateOnImplThread() const override; - - // ScrollbarLayerInterface - void SetScrollElementId(ElementId element_id) override; - - // Layer interface bool Update() override; void SetLayerTreeHost(LayerTreeHost* host) override; void PushPropertiesTo(LayerImpl* layer) override; @@ -41,8 +33,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, } protected: - PaintedScrollbarLayer(std::unique_ptr<Scrollbar> scrollbar, - ElementId scroll_element_id); + explicit PaintedScrollbarLayer(std::unique_ptr<Scrollbar> scrollbar); ~PaintedScrollbarLayer() override; // For unit tests @@ -80,6 +71,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, // Snapshot of properties taken in UpdateThumbAndTrackGeometry and used in // PushPropertiesTo. + bool supports_drag_snap_back_; int thumb_thickness_; int thumb_length_; gfx::Point location_; diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc index c6426b6c4f8..6b9d5829ba5 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc @@ -43,6 +43,7 @@ PaintedScrollbarLayerImpl::PaintedScrollbarLayerImpl( thumb_ui_resource_id_(0), thumb_opacity_(1.f), internal_contents_scale_(1.f), + supports_drag_snap_back_(false), thumb_thickness_(0), thumb_length_(0), track_start_(0), @@ -68,6 +69,7 @@ void PaintedScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { scrollbar_layer->set_internal_contents_scale_and_bounds( internal_contents_scale_, internal_content_bounds_); + scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_); scrollbar_layer->SetThumbThickness(thumb_thickness_); scrollbar_layer->SetThumbLength(thumb_length_); scrollbar_layer->SetTrackStart(track_start_); @@ -161,6 +163,18 @@ gfx::Rect PaintedScrollbarLayerImpl::GetEnclosingRectInTargetSpace() const { return GetScaledEnclosingRectInTargetSpace(internal_contents_scale_); } +void PaintedScrollbarLayerImpl::SetSupportsDragSnapBack( + bool supports_drag_snap_back) { + if (supports_drag_snap_back_ == supports_drag_snap_back) + return; + supports_drag_snap_back_ = supports_drag_snap_back; + NoteLayerPropertyChanged(); +} + +bool PaintedScrollbarLayerImpl::SupportsDragSnapBack() const { + return supports_drag_snap_back_; +} + void PaintedScrollbarLayerImpl::SetThumbThickness(int thumb_thickness) { if (thumb_thickness_ == thumb_thickness) return; diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.h b/chromium/cc/layers/painted_scrollbar_layer_impl.h index 37be215c49c..75f22053b8e 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.h +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.h @@ -38,6 +38,7 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { AppendQuadsData* append_quads_data) override; gfx::Rect GetEnclosingRectInTargetSpace() const override; + void SetSupportsDragSnapBack(bool supports_drag_snap_back); void SetBackButtonRect(gfx::Rect back_button_rect); void SetForwardButtonRect(gfx::Rect forward_button_rect); void SetThumbThickness(int thumb_thickness); @@ -60,6 +61,7 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { internal_content_bounds_ = content_bounds; } + bool SupportsDragSnapBack() const override; gfx::Rect BackButtonRect() const override; gfx::Rect ForwardButtonRect() const override; gfx::Rect BackTrackRect() const override; @@ -92,6 +94,7 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { float internal_contents_scale_; gfx::Size internal_content_bounds_; + bool supports_drag_snap_back_; int thumb_thickness_; int thumb_length_; int track_start_; diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc index d2d4c6af676..3115841e84d 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc @@ -7,7 +7,7 @@ #include <stddef.h> #include "cc/resources/ui_resource_bitmap.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "components/viz/common/quads/draw_quad.h" #include "components/viz/common/quads/texture_draw_quad.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,7 +22,7 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) { gfx::Size viewport_size(1000, 1000); float thumb_opacity = 0.2f; - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; SkBitmap thumb_sk_bitmap; thumb_sk_bitmap.allocN32Pixels(10, 10); @@ -41,7 +41,7 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) { ScrollbarOrientation orientation = VERTICAL; PaintedScrollbarLayerImpl* scrollbar_layer_impl = - impl.AddChildToRoot<PaintedScrollbarLayerImpl>(orientation, false, false); + impl.AddLayer<PaintedScrollbarLayerImpl>(orientation, false, false); scrollbar_layer_impl->SetBounds(layer_size); scrollbar_layer_impl->SetContentsOpaque(true); scrollbar_layer_impl->set_internal_contents_scale_and_bounds( @@ -56,6 +56,7 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) { scrollbar_layer_impl->set_track_ui_resource_id(track_uid); scrollbar_layer_impl->set_thumb_ui_resource_id(thumb_uid); scrollbar_layer_impl->set_thumb_opacity(thumb_opacity); + CopyProperties(impl.root_layer(), scrollbar_layer_impl); impl.CalcDrawProps(viewport_size); @@ -69,8 +70,8 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); EXPECT_EQ(2u, impl.quad_list().size()); EXPECT_EQ(0u, partially_occluded_count); @@ -115,7 +116,7 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) { gfx::Rect occluded(scrollbar_layer_impl->visible_layer_rect()); impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -125,8 +126,8 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs two quads, which is partially occluded. EXPECT_EQ(2u, impl.quad_list().size()); EXPECT_EQ(2u, partially_occluded_count); diff --git a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc index b29ee4a7e46..1852f6417f5 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc @@ -8,8 +8,8 @@ #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_scrollbar.h" +#include "cc/test/layer_test_common.h" #include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_common.h" #include "testing/gmock/include/gmock/gmock.h" using ::testing::Mock; @@ -21,11 +21,11 @@ namespace { class MockScrollbar : public FakeScrollbar { public: - MockScrollbar() : FakeScrollbar(true, true, true) {} - MOCK_METHOD3(PaintPart, - void(PaintCanvas* canvas, - ScrollbarPart part, - const gfx::Rect& content_rect)); + MockScrollbar() + : FakeScrollbar(/*paint*/ true, + /*has_thumb*/ true, + /*is_overlay*/ false) {} + MOCK_METHOD2(PaintPart, void(PaintCanvas* canvas, ScrollbarPart part)); }; TEST(PaintedScrollbarLayerTest, NeedsPaint) { @@ -44,10 +44,7 @@ TEST(PaintedScrollbarLayerTest, NeedsPaint) { scrollbar_layer->SetBounds(gfx::Size(100, 100)); layer_tree_host->SetRootLayer(scrollbar_layer); - - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - scrollbar_layer.get(), gfx::Rect(scrollbar_layer->bounds())); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateDrawProperties(layer_tree_host.get()); EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host.get()); @@ -55,28 +52,28 @@ TEST(PaintedScrollbarLayerTest, NeedsPaint) { // yet been initialized. scrollbar->set_needs_paint_thumb(false); scrollbar->set_needs_paint_track(false); - EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(1); - EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(1); + EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(1); + EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(1); scrollbar_layer->Update(); Mock::VerifyAndClearExpectations(scrollbar); // The next update will paint nothing because the first update caused a paint. - EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(0); - EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(0); + EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(0); + EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(0); scrollbar_layer->Update(); Mock::VerifyAndClearExpectations(scrollbar); // Enable the thumb. - EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(1); - EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(0); + EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(1); + EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(0); scrollbar->set_needs_paint_thumb(true); scrollbar->set_needs_paint_track(false); scrollbar_layer->Update(); Mock::VerifyAndClearExpectations(scrollbar); // Enable the track. - EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(0); - EXPECT_CALL(*scrollbar, PaintPart(_, TRACK, _)).Times(1); + EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(0); + EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(1); scrollbar->set_needs_paint_thumb(false); scrollbar->set_needs_paint_track(true); scrollbar_layer->Update(); diff --git a/chromium/cc/layers/picture_image_layer.cc b/chromium/cc/layers/picture_image_layer.cc index 203a8a612d1..f9999f60d58 100644 --- a/chromium/cc/layers/picture_image_layer.cc +++ b/chromium/cc/layers/picture_image_layer.cc @@ -26,7 +26,7 @@ PictureImageLayer::~PictureImageLayer() { std::unique_ptr<LayerImpl> PictureImageLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { - auto layer_impl = PictureLayerImpl::Create(tree_impl, id(), mask_type()); + auto layer_impl = PictureLayerImpl::Create(tree_impl, id()); layer_impl->set_is_directly_composited_image(true); return std::move(layer_impl); } diff --git a/chromium/cc/layers/picture_layer.cc b/chromium/cc/layers/picture_layer.cc index fb313fa9605..d6c2c095d20 100644 --- a/chromium/cc/layers/picture_layer.cc +++ b/chromium/cc/layers/picture_layer.cc @@ -30,9 +30,7 @@ scoped_refptr<PictureLayer> PictureLayer::Create(ContentLayerClient* client) { } PictureLayer::PictureLayer(ContentLayerClient* client) - : instrumentation_object_tracker_(id()), - update_source_frame_number_(-1), - mask_type_(LayerMaskType::NOT_MASK) { + : instrumentation_object_tracker_(id()), update_source_frame_number_(-1) { picture_layer_inputs_.client = client; } @@ -46,18 +44,18 @@ PictureLayer::~PictureLayer() = default; std::unique_ptr<LayerImpl> PictureLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { - return PictureLayerImpl::Create(tree_impl, id(), mask_type_); + return PictureLayerImpl::Create(tree_impl, id()); } void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) { // TODO(enne): http://crbug.com/918126 debugging CHECK(this); + PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); + Layer::PushPropertiesTo(base_layer); TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "PictureLayer::PushPropertiesTo"); - PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); - layer_impl->SetLayerMaskType(mask_type()); DropRecordingSourceContentIfInvalid(); layer_impl->SetNearestNeighbor(picture_layer_inputs_.nearest_neighbor); @@ -65,6 +63,7 @@ void PictureLayer::PushPropertiesTo(LayerImpl* base_layer) { ShouldUseTransformedRasterization()); layer_impl->set_gpu_raster_max_texture_size( layer_tree_host()->device_viewport_rect().size()); + layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask()); // TODO(enne): http://crbug.com/918126 debugging CHECK(this); @@ -150,7 +149,7 @@ bool PictureLayer::Update() { layer_tree_host()->recording_scale_factor()); SetNeedsPushProperties(); - paint_count_++; + IncreasePaintCount(); } else { // If this invalidation did not affect the recording source, then it can be // cleared as an optimization. @@ -160,10 +159,6 @@ bool PictureLayer::Update() { return updated; } -void PictureLayer::SetLayerMaskType(LayerMaskType mask_type) { - mask_type_ = mask_type; -} - sk_sp<SkPicture> PictureLayer::GetPicture() const { // We could either flatten the RecordingSource into a single SkPicture, or // paint a fresh one depending on what we intend to do with it. For now we @@ -235,6 +230,14 @@ bool PictureLayer::HasDrawableContent() const { return picture_layer_inputs_.client && Layer::HasDrawableContent(); } +void PictureLayer::SetIsBackdropFilterMask(bool is_backdrop_filter_mask) { + if (picture_layer_inputs_.is_backdrop_filter_mask == is_backdrop_filter_mask) + return; + + picture_layer_inputs_.is_backdrop_filter_mask = is_backdrop_filter_mask; + SetNeedsCommit(); +} + void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) { benchmark->RunOnLayer(this); } diff --git a/chromium/cc/layers/picture_layer.h b/chromium/cc/layers/picture_layer.h index 097782aa4cf..8150e1514fc 100644 --- a/chromium/cc/layers/picture_layer.h +++ b/chromium/cc/layers/picture_layer.h @@ -37,6 +37,11 @@ class CC_EXPORT PictureLayer : public Layer { return picture_layer_inputs_.transformed_rasterization_allowed; } + void SetIsBackdropFilterMask(bool is_backdrop_filter_mask); + bool is_backdrop_filter_mask() const { + return picture_layer_inputs_.is_backdrop_filter_mask; + } + // Layer interface. std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; void SetLayerTreeHost(LayerTreeHost* host) override; @@ -58,9 +63,6 @@ class CC_EXPORT PictureLayer : public Layer { const DisplayItemList* GetDisplayItemList(); - void SetLayerMaskType(LayerMaskType mask_type); - LayerMaskType mask_type() { return mask_type_; } - protected: // Encapsulates all data, callbacks or interfaces received from the embedder. struct PictureLayerInputs { @@ -70,6 +72,7 @@ class CC_EXPORT PictureLayer : public Layer { ContentLayerClient* client = nullptr; bool nearest_neighbor = false; bool transformed_rasterization_allowed = false; + bool is_backdrop_filter_mask = false; gfx::Rect recorded_viewport; scoped_refptr<DisplayItemList> display_list; size_t painter_reported_memory_usage = 0; @@ -99,7 +102,6 @@ class CC_EXPORT PictureLayer : public Layer { Region last_updated_invalidation_; int update_source_frame_number_; - LayerMaskType mask_type_; }; } // namespace cc diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc index 20ee14ed392..2369a6610ef 100644 --- a/chromium/cc/layers/picture_layer_impl.cc +++ b/chromium/cc/layers/picture_layer_impl.cc @@ -14,6 +14,7 @@ #include "base/metrics/histogram_macros.h" #include "base/no_destructor.h" +#include "base/numerics/ranges.h" #include "base/time/time.h" #include "base/trace_event/traced_value.h" #include "build/build_config.h" @@ -77,9 +78,7 @@ gfx::Rect SafeIntersectRects(const gfx::Rect& one, const gfx::Rect& two) { } // namespace -PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, - int id, - Layer::LayerMaskType mask_type) +PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id, /*will_always_push_properties=*/true), twin_layer_(nullptr), tilings_(CreatePictureLayerTilingSet()), @@ -92,7 +91,7 @@ PictureLayerImpl::PictureLayerImpl(LayerTreeImpl* tree_impl, raster_source_scale_(0.f), raster_contents_scale_(0.f), low_res_raster_contents_scale_(0.f), - mask_type_(mask_type), + is_backdrop_filter_mask_(false), was_screen_space_transform_animating_(false), only_used_low_res_last_append_quads_(false), nearest_neighbor_(false), @@ -126,32 +125,21 @@ PictureLayerImpl::~PictureLayerImpl() { UnregisterAnimatedImages(); } -void PictureLayerImpl::SetLayerMaskType(Layer::LayerMaskType mask_type) { - if (mask_type_ == mask_type) - return; - // It is expected that a layer can never change from being a mask to not being - // one and vice versa. Only changes that make mask layer single <-> multi are - // expected. - DCHECK(mask_type_ != Layer::LayerMaskType::NOT_MASK && - mask_type != Layer::LayerMaskType::NOT_MASK); - mask_type_ = mask_type; -} - const char* PictureLayerImpl::LayerTypeAsString() const { return "cc::PictureLayerImpl"; } std::unique_ptr<LayerImpl> PictureLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { - return PictureLayerImpl::Create(tree_impl, id(), mask_type()); + return PictureLayerImpl::Create(tree_impl, id()); } void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { PictureLayerImpl* layer_impl = static_cast<PictureLayerImpl*>(base_layer); + LayerImpl::PushPropertiesTo(base_layer); - layer_impl->SetLayerMaskType(mask_type()); // Twin relationships should never change once established. DCHECK(!twin_layer_ || twin_layer_ == layer_impl); DCHECK(!twin_layer_ || layer_impl->twin_layer_ == this); @@ -164,6 +152,7 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { layer_impl->SetNearestNeighbor(nearest_neighbor_); layer_impl->SetUseTransformedRasterization(use_transformed_rasterization_); + layer_impl->SetIsBackdropFilterMask(is_backdrop_filter_mask_); // Solid color layers have no tilings. DCHECK(!raster_source_->IsSolidColor() || tilings_->num_tilings() == 0); @@ -196,6 +185,13 @@ void PictureLayerImpl::PushPropertiesTo(LayerImpl* base_layer) { void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, AppendQuadsData* append_quads_data) { + // RenderSurfaceImpl::AppendQuads sets mask properties in the DrawQuad for + // the masked surface, which will apply to both the backdrop filter and the + // contents of the masked surface, so we should not append quads of the mask + // layer in DstIn blend mode which would apply the mask in another codepath. + if (is_backdrop_filter_mask_) + return; + // The bounds and the pile size may differ if the pile wasn't updated (ie. // PictureLayer::Update didn't happen). In that case the pile will be empty. DCHECK(raster_source_->GetSize().IsEmpty() || @@ -226,11 +222,7 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, gfx::Rect scaled_visible_layer_rect = shared_quad_state->visible_quad_layer_rect; - Occlusion occlusion; - // TODO(sunxd): Compute the correct occlusion for mask layers. - if (mask_type_ == Layer::LayerMaskType::NOT_MASK) { - occlusion = draw_properties().occlusion_in_content_space; - } + Occlusion occlusion = draw_properties().occlusion_in_content_space; EffectNode* effect_node = GetEffectTree().Node(effect_tree_index()); SolidColorLayerImpl::AppendSolidQuads( @@ -249,13 +241,10 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, tilings_->num_tilings() ? MaximumTilingContentsScale() : 1.f; PopulateScaledSharedQuadState(shared_quad_state, max_contents_scale, contents_opaque()); - Occlusion scaled_occlusion; - if (mask_type_ == Layer::LayerMaskType::NOT_MASK) { - scaled_occlusion = - draw_properties() - .occlusion_in_content_space.GetOcclusionWithGivenDrawTransform( - shared_quad_state->quad_to_target_transform); - } + Occlusion scaled_occlusion = + draw_properties() + .occlusion_in_content_space.GetOcclusionWithGivenDrawTransform( + shared_quad_state->quad_to_target_transform); if (current_draw_mode_ == DRAW_MODE_RESOURCELESS_SOFTWARE) { DCHECK(shared_quad_state->quad_layer_rect.origin() == gfx::Point(0, 0)); @@ -444,8 +433,7 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, float alpha = (SkColorGetA(draw_info.solid_color()) * (1.0f / 255.0f)) * shared_quad_state->opacity; - if (mask_type_ != Layer::LayerMaskType::NOT_MASK || - alpha >= std::numeric_limits<float>::epsilon()) { + if (alpha >= std::numeric_limits<float>::epsilon()) { auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SolidColorDrawQuad>(); quad->SetNew( @@ -465,8 +453,7 @@ void PictureLayerImpl::AppendQuads(viz::RenderPass* render_pass, if (!has_draw_quad) { // Checkerboard. SkColor color = SafeOpaqueBackgroundColor(); - if (mask_type_ == Layer::LayerMaskType::NOT_MASK && - ShowDebugBorders(DebugBorderType::LAYER)) { + if (ShowDebugBorders(DebugBorderType::LAYER)) { // Fill the whole tile with the missing tile color. color = DebugColors::DefaultCheckerboardColor(); } @@ -817,11 +804,10 @@ std::unique_ptr<Tile> PictureLayerImpl::CreateTile( const Tile::CreateInfo& info) { int flags = 0; - // We don't handle solid color masks if mask tiling is disabled, we also don't - // handle solid color single texture masks if the flag is enabled, so we - // shouldn't bother analyzing those. + // We don't handle solid color single texture masks for backdrop filters, + // so we shouldn't bother analyzing those. // Otherwise, always analyze to maximize memory savings. - if (mask_type_ != Layer::LayerMaskType::SINGLE_TEXTURE_MASK) + if (!is_backdrop_filter_mask_) flags = Tile::USE_PICTURE_ANALYSIS; if (contents_opaque()) @@ -911,6 +897,12 @@ void PictureLayerImpl::GetContentsResourceId( viz::ResourceId* resource_id, gfx::Size* resource_size, gfx::SizeF* resource_uv_size) const { + // We need contents resource for backdrop filter masks only. + if (!is_backdrop_filter_mask()) { + *resource_id = 0; + return; + } + // The bounds and the pile size may differ if the pile wasn't updated (ie. // PictureLayer::Update didn't happen). In that case the pile will be empty. DCHECK(raster_source_->GetSize().IsEmpty() || @@ -1125,7 +1117,7 @@ void PictureLayerImpl::RecalculateRasterScales() { float min_scale = MinimumContentsScale(); float max_scale = std::max(1.f, MinimumContentsScale()); float clamped_ideal_source_scale_ = - std::max(min_scale, std::min(ideal_source_scale_, max_scale)); + base::ClampToRange(ideal_source_scale_, min_scale, max_scale); while (raster_source_scale_ < clamped_ideal_source_scale_) raster_source_scale_ *= 2.f; @@ -1133,7 +1125,7 @@ void PictureLayerImpl::RecalculateRasterScales() { raster_source_scale_ /= 2.f; raster_source_scale_ = - std::max(min_scale, std::min(raster_source_scale_, max_scale)); + base::ClampToRange(raster_source_scale_, min_scale, max_scale); raster_page_scale_ = 1.f; raster_device_scale_ = 1.f; @@ -1278,12 +1270,12 @@ void PictureLayerImpl::CleanUpTilingsOnActiveLayer( PictureLayerImpl* twin = GetPendingOrActiveTwinLayer(); if (twin && twin->CanHaveTilings()) { - min_acceptable_high_res_scale = std::min( - min_acceptable_high_res_scale, - std::min(twin->raster_contents_scale_, twin->ideal_contents_scale_)); - max_acceptable_high_res_scale = std::max( - max_acceptable_high_res_scale, - std::max(twin->raster_contents_scale_, twin->ideal_contents_scale_)); + min_acceptable_high_res_scale = + std::min({min_acceptable_high_res_scale, twin->raster_contents_scale_, + twin->ideal_contents_scale_}); + max_acceptable_high_res_scale = + std::max({max_acceptable_high_res_scale, twin->raster_contents_scale_, + twin->ideal_contents_scale_}); } PictureLayerTilingSet* twin_set = twin ? twin->tilings_.get() : nullptr; @@ -1353,10 +1345,9 @@ float PictureLayerImpl::MaximumContentsScale() const { // have tilings that would become larger than the max_texture_size since they // use a single tile for the entire tiling. Other layers can have tilings such // that dimension * scale does not overflow. - float max_dimension = - static_cast<float>(mask_type_ == Layer::LayerMaskType::SINGLE_TEXTURE_MASK - ? layer_tree_impl()->max_texture_size() - : std::numeric_limits<int>::max()); + float max_dimension = static_cast<float>( + is_backdrop_filter_mask_ ? layer_tree_impl()->max_texture_size() + : std::numeric_limits<int>::max()); int higher_dimension = std::max(bounds().width(), bounds().height()); float max_scale = max_dimension / higher_dimension; @@ -1430,7 +1421,7 @@ void PictureLayerImpl::UpdateIdealScales() { DCHECK_GT(min_contents_scale, 0.f); ideal_device_scale_ = layer_tree_impl()->device_scale_factor(); - if (layer_tree_impl()->PageScaleLayer()) { + if (layer_tree_impl()->PageScaleTransformNode()) { ideal_page_scale_ = IsAffectedByPageScale() ? layer_tree_impl()->current_page_scale_factor() : 1.f; @@ -1450,9 +1441,8 @@ void PictureLayerImpl::UpdateIdealScales() { ideal_contents_scale_ = GetIdealContentsScale() * external_page_scale_factor; } - ideal_contents_scale_ = - std::min(kMaxIdealContentsScale, - std::max(ideal_contents_scale_, min_contents_scale)); + ideal_contents_scale_ = base::ClampToRange( + ideal_contents_scale_, min_contents_scale, kMaxIdealContentsScale); ideal_source_scale_ = ideal_contents_scale_ / ideal_page_scale_ / ideal_device_scale_; } diff --git a/chromium/cc/layers/picture_layer_impl.h b/chromium/cc/layers/picture_layer_impl.h index 6a2d2ea160b..d2459c42af7 100644 --- a/chromium/cc/layers/picture_layer_impl.h +++ b/chromium/cc/layers/picture_layer_impl.h @@ -34,17 +34,19 @@ class CC_EXPORT PictureLayerImpl public PictureLayerTilingClient, public ImageAnimationController::AnimationDriver { public: - static std::unique_ptr<PictureLayerImpl> - Create(LayerTreeImpl* tree_impl, int id, Layer::LayerMaskType mask_type) { - return base::WrapUnique(new PictureLayerImpl(tree_impl, id, mask_type)); + static std::unique_ptr<PictureLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new PictureLayerImpl(tree_impl, id)); } PictureLayerImpl(const PictureLayerImpl&) = delete; ~PictureLayerImpl() override; PictureLayerImpl& operator=(const PictureLayerImpl&) = delete; - Layer::LayerMaskType mask_type() const { return mask_type_; } - void SetLayerMaskType(Layer::LayerMaskType type); + void SetIsBackdropFilterMask(bool is_backdrop_filter_mask) { + is_backdrop_filter_mask_ = is_backdrop_filter_mask; + } + bool is_backdrop_filter_mask() const { return is_backdrop_filter_mask_; } // LayerImpl overrides. const char* LayerTypeAsString() const override; @@ -158,9 +160,7 @@ class CC_EXPORT PictureLayerImpl void InvalidatePaintWorklets(const PaintWorkletInput::PropertyKey& key); protected: - PictureLayerImpl(LayerTreeImpl* tree_impl, - int id, - Layer::LayerMaskType mask_type); + PictureLayerImpl(LayerTreeImpl* tree_impl, int id); PictureLayerTiling* AddTiling(const gfx::AxisTransform2d& contents_transform); void RemoveAllTilings(); void AddTilingsForRasterScale(); @@ -223,7 +223,7 @@ class CC_EXPORT PictureLayerImpl float raster_contents_scale_; float low_res_raster_contents_scale_; - Layer::LayerMaskType mask_type_; + bool is_backdrop_filter_mask_ : 1; bool was_screen_space_transform_animating_ : 1; bool only_used_low_res_last_append_quads_ : 1; diff --git a/chromium/cc/layers/picture_layer_impl_perftest.cc b/chromium/cc/layers/picture_layer_impl_perftest.cc index 56bf774aad3..e9a87d6e833 100644 --- a/chromium/cc/layers/picture_layer_impl_perftest.cc +++ b/chromium/cc/layers/picture_layer_impl_perftest.cc @@ -6,16 +6,13 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/timer/lap_timer.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_frame_sink.h" -#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_raster_source.h" -#include "cc/test/test_task_graph_runner.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/tiles/tiling_set_raster_queue_all.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -37,50 +34,42 @@ void AddTiling(float scale, tiling_tiles.begin(), tiling_tiles.end(), std::back_inserter(*all_tiles)); } -class PictureLayerImplPerfTest : public testing::Test { +class PictureLayerImplPerfTest : public LayerTreeImplTestBase, + public testing::Test { public: PictureLayerImplPerfTest() - : task_runner_provider_(base::ThreadTaskRunnerHandle::Get()), - layer_tree_frame_sink_(FakeLayerTreeFrameSink::Create3d()), - host_impl_(LayerTreeSettings(), - &task_runner_provider_, - &task_graph_runner_), - timer_(kWarmupRuns, + : timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) {} PictureLayerImplPerfTest(const PictureLayerImplPerfTest&) = delete; PictureLayerImplPerfTest& operator=(const PictureLayerImplPerfTest&) = delete; - void SetUp() override { - host_impl_.SetVisible(true); - host_impl_.InitializeFrameSink(layer_tree_frame_sink_.get()); - } - void SetupPendingTree(const gfx::Size& layer_bounds) { scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilled(layer_bounds); - host_impl_.CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl_.pending_tree(); + host_impl()->CreatePendingTree(); + LayerTreeImpl* pending_tree = host_impl()->pending_tree(); pending_tree->DetachLayers(); std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 7, - raster_source); + FakePictureLayerImpl::Create(pending_tree, 7, raster_source); pending_layer->SetDrawsContent(true); - pending_layer->test_properties()->force_render_surface = true; + pending_layer_ = pending_layer.get(); + pending_tree->SetElementIdsForTesting(); + SetupRootProperties(pending_layer_); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); - pending_tree->BuildLayerListAndPropertyTreesForTesting(); - pending_layer_ = static_cast<FakePictureLayerImpl*>( - host_impl_.pending_tree()->LayerById(7)); + PrepareForUpdateDrawProperties(pending_tree); + // Don't update draw properties because the tilings will conflict with the + // tilings that will be added in the tests. } void RunRasterQueueConstructAndIterateTest(const std::string& test_name, int num_tiles, const gfx::Rect& viewport_rect) { - host_impl_.active_tree()->SetDeviceViewportRect(viewport_rect); - host_impl_.pending_tree()->UpdateDrawProperties(); + host_impl()->active_tree()->SetDeviceViewportRect(viewport_rect); + host_impl()->pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { @@ -96,19 +85,21 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("tiling_set_raster_queue_construct_and_iterate", "", - test_name, timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_raster_queue_construct_and_iterate", + timer_.LapsPerSecond()); } void RunRasterQueueConstructTest(const std::string& test_name, const gfx::Rect& viewport) { - host_impl_.active_tree()->SetDeviceViewportRect(viewport); - host_impl_.pending_tree() + host_impl()->active_tree()->SetDeviceViewportRect(viewport); + host_impl() + ->pending_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( pending_layer_->element_id(), gfx::ScrollOffset(viewport.x(), viewport.y())); - host_impl_.pending_tree()->UpdateDrawProperties(); + host_impl()->pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { @@ -118,15 +109,15 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("tiling_set_raster_queue_construct", "", test_name, - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_raster_queue_construct", timer_.LapsPerSecond()); } void RunEvictionQueueConstructAndIterateTest(const std::string& test_name, int num_tiles, const gfx::Rect& viewport_rect) { - host_impl_.active_tree()->SetDeviceViewportRect(viewport_rect); - host_impl_.pending_tree()->UpdateDrawProperties(); + host_impl()->active_tree()->SetDeviceViewportRect(viewport_rect); + host_impl()->pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { @@ -142,20 +133,21 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("tiling_set_eviction_queue_construct_and_iterate", - "", test_name, timer_.LapsPerSecond(), "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_eviction_queue_construct_and_iterate", + timer_.LapsPerSecond()); } void RunEvictionQueueConstructTest(const std::string& test_name, const gfx::Rect& viewport) { - host_impl_.active_tree()->SetDeviceViewportRect(viewport); - host_impl_.pending_tree() + host_impl()->active_tree()->SetDeviceViewportRect(viewport); + host_impl() + ->pending_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( pending_layer_->element_id(), gfx::ScrollOffset(viewport.x(), viewport.y())); - host_impl_.pending_tree()->UpdateDrawProperties(); + host_impl()->pending_tree()->UpdateDrawProperties(); timer_.Reset(); do { @@ -165,15 +157,21 @@ class PictureLayerImplPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("tiling_set_eviction_queue_construct", "", test_name, - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_eviction_queue_construct", timer_.LapsPerSecond()); } protected: - TestTaskGraphRunner task_graph_runner_; - FakeImplTaskRunnerProvider task_runner_provider_; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink_; - FakeLayerTreeHostImpl host_impl_; + perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { + perf_test::PerfResultReporter reporter("tiling_set", story_name); + reporter.RegisterImportantMetric("_raster_queue_construct_and_iterate", + "runs/s"); + reporter.RegisterImportantMetric("_raster_queue_construct", "runs/s"); + reporter.RegisterImportantMetric("_eviction_queue_construct_and_iterate", + "runs/s"); + return reporter; + } + FakePictureLayerImpl* pending_layer_; base::LapTimer timer_; }; @@ -181,7 +179,7 @@ class PictureLayerImplPerfTest : public testing::Test { TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstructAndIterate) { SetupPendingTree(gfx::Size(10000, 10000)); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; pending_layer_->AddTiling( gfx::AxisTransform2d(low_res_factor, gfx::Vector2dF())); @@ -199,7 +197,7 @@ TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstructAndIterate) { TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstruct) { SetupPendingTree(gfx::Size(10000, 10000)); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; pending_layer_->AddTiling( gfx::AxisTransform2d(low_res_factor, gfx::Vector2dF())); @@ -216,7 +214,7 @@ TEST_F(PictureLayerImplPerfTest, TilingSetRasterQueueConstruct) { TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstructAndIterate) { SetupPendingTree(gfx::Size(10000, 10000)); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; std::vector<Tile*> all_tiles; AddTiling(low_res_factor, pending_layer_, &all_tiles); @@ -225,8 +223,9 @@ TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstructAndIterate) { AddTiling(1.0f, pending_layer_, &all_tiles); AddTiling(2.0f, pending_layer_, &all_tiles); - ASSERT_TRUE(host_impl_.tile_manager() != nullptr); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); + ASSERT_TRUE(host_impl()->tile_manager() != nullptr); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + all_tiles); RunEvictionQueueConstructAndIterateTest("32_100x100", 32, gfx::Rect(100, 100)); @@ -241,7 +240,7 @@ TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstructAndIterate) { TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstruct) { SetupPendingTree(gfx::Size(10000, 10000)); - float low_res_factor = host_impl_.settings().low_res_contents_scale_factor; + float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; std::vector<Tile*> all_tiles; AddTiling(low_res_factor, pending_layer_, &all_tiles); @@ -250,8 +249,9 @@ TEST_F(PictureLayerImplPerfTest, TilingSetEvictionQueueConstruct) { AddTiling(1.0f, pending_layer_, &all_tiles); AddTiling(2.0f, pending_layer_, &all_tiles); - ASSERT_TRUE(host_impl_.tile_manager() != nullptr); - host_impl_.tile_manager()->InitializeTilesWithResourcesForTesting(all_tiles); + ASSERT_TRUE(host_impl()->tile_manager() != nullptr); + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + all_tiles); RunEvictionQueueConstructTest("0_0_100x100", gfx::Rect(0, 0, 100, 100)); RunEvictionQueueConstructTest("5000_0_100x100", gfx::Rect(5000, 0, 100, 100)); diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc index 60eba27ab33..77fb24781a6 100644 --- a/chromium/cc/layers/picture_layer_impl_unittest.cc +++ b/chromium/cc/layers/picture_layer_impl_unittest.cc @@ -28,7 +28,7 @@ #include "cc/test/fake_raster_source.h" #include "cc/test/fake_recording_source.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/test/skia_common.h" #include "cc/test/test_layer_tree_host_base.h" #include "cc/test/test_paint_worklet_input.h" @@ -79,7 +79,7 @@ class PictureLayerImplTest : public TestLayerTreeHostBase { } LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings; + auto settings = TestLayerTreeHostBase::CreateSettings(); settings.commit_to_active_tree = false; settings.create_low_res_tiling = true; return settings; @@ -270,6 +270,17 @@ class PictureLayerImplTest : public TestLayerTreeHostBase { void TestQuadsForSolidColor(bool test_for_solid, bool partial_opaque); }; +// Legacy PictureLayerImplTest which forces SW rasterization. New tests should +// default to the more common GPU rasterization path. +class LegacySWPictureLayerImplTest : public PictureLayerImplTest { + public: + LayerTreeSettings CreateSettings() override { + auto settings = PictureLayerImplTest::CreateSettings(); + settings.gpu_rasterization_disabled = true; + return settings; + } +}; + class CommitToActiveTreePictureLayerImplTest : public PictureLayerImplTest { public: LayerTreeSettings CreateSettings() override { @@ -279,16 +290,16 @@ class CommitToActiveTreePictureLayerImplTest : public PictureLayerImplTest { } }; -class NoLowResPictureLayerImplTest : public PictureLayerImplTest { +class NoLowResPictureLayerImplTest : public LegacySWPictureLayerImplTest { public: LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + LayerTreeSettings settings = LegacySWPictureLayerImplTest::CreateSettings(); settings.create_low_res_tiling = false; return settings; } }; -TEST_F(PictureLayerImplTest, CloneNoInvalidation) { +TEST_F(LegacySWPictureLayerImplTest, CloneNoInvalidation) { gfx::Size layer_bounds(400, 400); SetupDefaultTrees(layer_bounds); @@ -301,7 +312,7 @@ TEST_F(PictureLayerImplTest, CloneNoInvalidation) { EXPECT_TRUE(tilings->tiling_at(i)->AllTilesForTesting().empty()); } -TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { +TEST_F(LegacySWPictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(400, 400); SetupDefaultTrees(layer_bounds); @@ -318,7 +329,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { host_impl()->SetExternalTilePriorityConstraints( viewport_rect_for_tile_priority, transform_for_tile_priority); - host_impl()->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->active_tree()); // Verify the viewport rect for tile priority is used in picture layer tiling. EXPECT_EQ(viewport_rect_for_tile_priority, @@ -341,7 +352,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { transform_for_tile_priority.Rotate(45); host_impl()->SetExternalTilePriorityConstraints( viewport_rect_for_tile_priority, transform_for_tile_priority); - host_impl()->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->active_tree()); EXPECT_EQ(viewport_rect_for_tile_priority, active_layer()->viewport_rect_for_tile_priority_in_content_space()); @@ -354,7 +365,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { } } -TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) { +TEST_F(LegacySWPictureLayerImplTest, ViewportRectForTilePriorityIsCached) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(400, 400); SetupDefaultTrees(layer_bounds); @@ -369,7 +380,7 @@ TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) { host_impl()->SetExternalTilePriorityConstraints( viewport_rect_for_tile_priority, transform_for_tile_priority); - host_impl()->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->active_tree()); EXPECT_EQ(viewport_rect_for_tile_priority, active_layer()->viewport_rect_for_tile_priority_in_content_space()); @@ -384,7 +395,7 @@ TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) { // should remain to be the previously cached value. EXPECT_EQ(viewport_rect_for_tile_priority, active_layer()->viewport_rect_for_tile_priority_in_content_space()); - host_impl()->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->active_tree()); // Now the UpdateDrawProperties is called. The viewport rect for tile // priority should be the latest value. @@ -392,7 +403,7 @@ TEST_F(PictureLayerImplTest, ViewportRectForTilePriorityIsCached) { active_layer()->viewport_rect_for_tile_priority_in_content_space()); } -TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { +TEST_F(LegacySWPictureLayerImplTest, ClonePartialInvalidation) { gfx::Size layer_bounds(400, 400); gfx::Rect layer_invalidation(150, 200, 30, 180); @@ -469,7 +480,7 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { } } -TEST_F(PictureLayerImplTest, CloneFullInvalidation) { +TEST_F(LegacySWPictureLayerImplTest, CloneFullInvalidation) { gfx::Size layer_bounds(300, 500); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -491,7 +502,7 @@ TEST_F(PictureLayerImplTest, CloneFullInvalidation) { } } -TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { +TEST_F(LegacySWPictureLayerImplTest, UpdateTilesCreatesTilings) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); @@ -565,7 +576,7 @@ TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { active_layer()->tilings()->tiling_at(3)->contents_scale_key()); } -TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { +TEST_F(LegacySWPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); @@ -625,7 +636,7 @@ TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 7.26f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); } -TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) { +TEST_F(LegacySWPictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) { // This test makes sure that if a layer can have tilings, then a commit makes // it not able to have tilings (empty size), and then a future commit that // makes it valid again should be able to create tilings. @@ -654,7 +665,7 @@ TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) { ASSERT_EQ(0u, active_layer()->tilings()->num_tilings()); } -TEST_F(PictureLayerImplTest, LowResTilingStaysOnActiveTree) { +TEST_F(LegacySWPictureLayerImplTest, LowResTilingStaysOnActiveTree) { gfx::Size layer_bounds(1300, 1900); scoped_refptr<FakeRasterSource> valid_raster_source = @@ -681,7 +692,7 @@ TEST_F(PictureLayerImplTest, LowResTilingStaysOnActiveTree) { EXPECT_EQ(low_res_tiling, other_low_res_tiling); } -TEST_F(PictureLayerImplTest, ZoomOutCrash) { +TEST_F(LegacySWPictureLayerImplTest, ZoomOutCrash) { gfx::Size layer_bounds(1300, 1900); // Set up the high and low res tilings before pinch zoom. @@ -696,7 +707,7 @@ TEST_F(PictureLayerImplTest, ZoomOutCrash) { EXPECT_EQ(active_layer()->tilings()->NumHighResTilings(), 1); } -TEST_F(PictureLayerImplTest, ScaledBoundsOverflowInt) { +TEST_F(LegacySWPictureLayerImplTest, ScaledBoundsOverflowInt) { // Limit visible size. gfx::Size viewport_size(1, 1); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -726,7 +737,7 @@ TEST_F(PictureLayerImplTest, ScaledBoundsOverflowInt) { &state, adjusted_scale, active_layer()->contents_opaque()); } -TEST_F(PictureLayerImplTest, PinchGestureTilings) { +TEST_F(LegacySWPictureLayerImplTest, PinchGestureTilings) { gfx::Size layer_bounds(1300, 1900); float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; @@ -735,8 +746,8 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { ResetTilingsAndRasterScales(); SetContentsScaleOnBothLayers(2.f, 1.0f, 2.f, 1.0f, 0.f, false); - EXPECT_EQ(active_layer()->num_tilings(), 2u); - EXPECT_EQ(pending_layer()->num_tilings(), 1u); + ASSERT_EQ(active_layer()->num_tilings(), 2u); + ASSERT_EQ(pending_layer()->num_tilings(), 1u); EXPECT_EQ(active_layer()->tilings()->tiling_at(0)->contents_scale_key(), 2.f); EXPECT_EQ(active_layer()->tilings()->tiling_at(1)->contents_scale_key(), 2.f * low_res_factor); @@ -753,7 +764,7 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { // Zoom out by a small amount. We should create a tiling at half // the scale (2/kMaxScaleRatioDuringPinch). SetContentsScaleOnBothLayers(1.8f, 1.0f, 1.8f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ( 2.0f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); EXPECT_FLOAT_EQ( @@ -772,14 +783,14 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { // use that tiling as high-res, and not create a new tiling. SetContentsScaleOnBothLayers(low_res_factor * 2.1f, 1.0f, low_res_factor * 2.1f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FALSE( active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION)); // Zoom in a lot now. Since we increase by increments of // kMaxScaleRatioDuringPinch, this will create a new tiling at 4.0. SetContentsScaleOnBothLayers(3.8f, 1.0f, 3.8f, 1.f, 0.f, false); - EXPECT_EQ(4u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ( 4.0f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); // Although one of the tilings matches the low resolution scale, it still @@ -798,7 +809,7 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { // After pinch ends, set the scale to what the raster scale was updated to // (checked above). SetContentsScaleOnBothLayers(4.0f, 1.0f, 4.0f, 1.f, 0.f, false); - EXPECT_EQ(4u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ( 4.0f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); // Now that we stopped pinching, the low resolution tiling that existed should @@ -809,7 +820,7 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { EXPECT_EQ(LOW_RESOLUTION, low_res_tiling->resolution()); } -TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) { +TEST_F(LegacySWPictureLayerImplTest, SnappedTilingDuringZoom) { gfx::Size layer_bounds(2600, 3800); SetupDefaultTrees(layer_bounds); @@ -818,7 +829,7 @@ TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) { // Set up the high and low res tilings before pinch zoom. SetContentsScaleOnBothLayers(0.24f, 1.0f, 0.24f, 1.0f, 0.f, false); - EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ( 0.24f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); EXPECT_FLOAT_EQ( @@ -833,7 +844,7 @@ TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) { // Zoom out by a small amount. We should create a tiling at half // the scale (1/kMaxScaleRatioDuringPinch). SetContentsScaleOnBothLayers(0.2f, 1.0f, 0.2f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ( 0.24f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); EXPECT_FLOAT_EQ( @@ -847,22 +858,22 @@ TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) { // Zoom out further, close to our low-res scale factor. We should // use that tiling as high-res, and not create a new tiling. SetContentsScaleOnBothLayers(0.1f, 1.0f, 0.1f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); // Zoom in. 0.25(desired_scale) should be snapped to 0.24 during zoom-in // because 0.25(desired_scale) is within the ratio(1.2). SetContentsScaleOnBothLayers(0.25f, 1.0f, 0.25f, 1.0f, 0.f, false); - EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); // Zoom in a lot. Since we move in factors of two, we should get a scale that // is a power of 2 times 0.24. SetContentsScaleOnBothLayers(1.f, 1.0f, 1.f, 1.0f, 0.f, false); - EXPECT_EQ(4u, active_layer()->tilings()->num_tilings()); + ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); EXPECT_FLOAT_EQ( 1.92f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); } -TEST_F(PictureLayerImplTest, CleanUpTilings) { +TEST_F(LegacySWPictureLayerImplTest, CleanUpTilings) { gfx::Size layer_bounds(1300, 1900); std::vector<PictureLayerTiling*> used_tilings; @@ -1039,7 +1050,7 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { active_layer()->tilings()->tiling_at(1)->contents_scale_key()); } -TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { +TEST_F(LegacySWPictureLayerImplTest, DontAddLowResDuringAnimation) { // Make sure this layer covers multiple tiles, since otherwise low // res won't get created because it is too small. gfx::Size tile_size(host_impl()->settings().default_tile_size); @@ -1106,7 +1117,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { EXPECT_EQ(1u, pending_layer()->num_tilings()); } -TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { +TEST_F(LegacySWPictureLayerImplTest, DontAddLowResForSmallLayers) { gfx::Size layer_bounds(host_impl()->settings().default_tile_size); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -1158,31 +1169,26 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { EXPECT_EQ(pending_layer()->num_tilings(), 1u); // Mask layers dont create low res since they always fit on one tile. - std::unique_ptr<FakePictureLayerImpl> mask = - FakePictureLayerImpl::CreateMaskWithRasterSource( - host_impl()->pending_tree(), 3, pending_raster_source); - mask->SetBounds(layer_bounds); - mask->SetDrawsContent(true); - pending_layer()->test_properties()->SetMaskLayer(std::move(mask)); - pending_layer()->test_properties()->force_render_surface = true; - RebuildPropertyTreesOnPendingTree(); - host_impl()->pending_tree()->UpdateDrawProperties(); - - FakePictureLayerImpl* mask_raw = static_cast<FakePictureLayerImpl*>( - pending_layer()->test_properties()->mask_layer); + CreateEffectNode(pending_layer()); + auto* mask = AddLayer<FakePictureLayerImpl>(host_impl()->pending_tree(), + pending_raster_source); + SetupMaskProperties(pending_layer(), mask); + + UpdateDrawProperties(host_impl()->pending_tree()); + // We did an UpdateDrawProperties above, which will set a contents scale on // the mask layer, so allow us to reset the contents scale. - mask_raw->ReleaseTileResources(); - mask_raw->RecreateTileResources(); + mask->ReleaseTileResources(); + mask->RecreateTileResources(); SetupDrawPropertiesAndUpdateTiles( - mask_raw, contents_scale, device_scale, page_scale, - maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_EQ(mask_raw->HighResTiling()->contents_scale_key(), contents_scale); - EXPECT_EQ(mask_raw->num_tilings(), 1u); + mask, contents_scale, device_scale, page_scale, maximum_animation_scale, + starting_animation_scale, animating_transform); + EXPECT_EQ(mask->HighResTiling()->contents_scale_key(), contents_scale); + EXPECT_EQ(mask->num_tilings(), 1u); } -TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { +TEST_F(LegacySWPictureLayerImplTest, HugeBackdropFilterMasksGetScaledDown) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); @@ -1191,20 +1197,15 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(valid_raster_source); - std::unique_ptr<FakePictureLayerImpl> mask_ptr = - FakePictureLayerImpl::CreateMaskWithRasterSource( - host_impl()->pending_tree(), 3, valid_raster_source); - mask_ptr->SetBounds(layer_bounds); - mask_ptr->SetDrawsContent(true); - pending_layer()->test_properties()->SetMaskLayer(std::move(mask_ptr)); - pending_layer()->test_properties()->force_render_surface = true; + CreateEffectNode(pending_layer()) + .backdrop_filters.Append(FilterOperation::CreateInvertFilter(1.0)); + auto* pending_mask = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), valid_raster_source); + SetupMaskProperties(pending_layer(), pending_mask); + ASSERT_TRUE(pending_mask->is_backdrop_filter_mask()); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->UpdateDrawProperties(); - - FakePictureLayerImpl* pending_mask = static_cast<FakePictureLayerImpl*>( - pending_layer()->test_properties()->mask_layer); + UpdateDrawProperties(host_impl()->pending_tree()); EXPECT_EQ(1.f, pending_mask->HighResTiling()->contents_scale_key()); EXPECT_EQ(1u, pending_mask->num_tilings()); @@ -1247,10 +1248,10 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { SetupPendingTree(huge_raster_source); pending_mask->SetBounds(huge_bounds); - pending_mask->SetRasterSourceOnPending(huge_raster_source, Region()); + pending_mask->SetRasterSource(huge_raster_source, Region()); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); // The mask tiling gets scaled down. EXPECT_LT(pending_mask->HighResTiling()->contents_scale_key(), 1.f); @@ -1303,17 +1304,17 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { SetupPendingTree(extra_huge_raster_source); pending_mask->SetBounds(extra_huge_bounds); - pending_mask->SetRasterSourceOnPending(extra_huge_raster_source, Region()); + pending_mask->SetRasterSource(extra_huge_raster_source, Region()); EXPECT_FALSE(pending_mask->CanHaveTilings()); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); EXPECT_EQ(0u, pending_mask->num_tilings()); } -TEST_F(PictureLayerImplTest, ScaledMaskLayer) { +TEST_F(LegacySWPictureLayerImplTest, ScaledBackdropFilterMaskLayer) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); @@ -1324,20 +1325,15 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) { FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(valid_raster_source); - std::unique_ptr<FakePictureLayerImpl> mask_ptr = - FakePictureLayerImpl::CreateMaskWithRasterSource( - host_impl()->pending_tree(), 3, valid_raster_source); - mask_ptr->SetBounds(layer_bounds); - mask_ptr->SetDrawsContent(true); - pending_layer()->test_properties()->SetMaskLayer(std::move(mask_ptr)); - pending_layer()->test_properties()->force_render_surface = true; + CreateEffectNode(pending_layer()) + .backdrop_filters.Append(FilterOperation::CreateInvertFilter(1.0)); + auto* pending_mask = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), valid_raster_source); + SetupMaskProperties(pending_layer(), pending_mask); + ASSERT_TRUE(pending_mask->is_backdrop_filter_mask()); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->UpdateDrawProperties(); - - FakePictureLayerImpl* pending_mask = static_cast<FakePictureLayerImpl*>( - pending_layer()->test_properties()->mask_layer); + UpdateDrawProperties(host_impl()->pending_tree()); // Masks are scaled, and do not have a low res tiling. EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale_key()); @@ -1366,7 +1362,52 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) { EXPECT_EQ(gfx::SizeF(1.0f, 1.0f), mask_uv_size); } -TEST_F(PictureLayerImplTest, ReleaseTileResources) { +TEST_F(LegacySWPictureLayerImplTest, ScaledMaskLayer) { + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + + gfx::Size layer_bounds(1000, 1000); + + SetInitialDeviceScaleFactor(1.3f); + + scoped_refptr<FakeRasterSource> valid_raster_source = + FakeRasterSource::CreateFilled(layer_bounds); + SetupPendingTree(valid_raster_source); + + CreateEffectNode(pending_layer()); + auto* pending_mask = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), valid_raster_source); + SetupMaskProperties(pending_layer(), pending_mask); + ASSERT_FALSE(pending_mask->is_backdrop_filter_mask()); + + host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); + UpdateDrawProperties(host_impl()->pending_tree()); + + // Masks are scaled, and do not have a low res tiling. + EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale_key()); + EXPECT_EQ(1u, pending_mask->num_tilings()); + + host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( + pending_mask->HighResTiling()->AllTilesForTesting()); + + ActivateTree(); + + FakePictureLayerImpl* active_mask = static_cast<FakePictureLayerImpl*>( + host_impl()->active_tree()->LayerById(pending_mask->id())); + + // Non-backdrop-filter mask layers are tiled normally. + EXPECT_EQ(36u, active_mask->HighResTiling()->AllTilesForTesting().size()); + // And don't have mask resources. + viz::ResourceId mask_resource_id; + gfx::Size mask_texture_size; + gfx::SizeF mask_uv_size; + active_mask->GetContentsResourceId(&mask_resource_id, &mask_texture_size, + &mask_uv_size); + EXPECT_EQ(0u, mask_resource_id); + EXPECT_EQ(gfx::Size(), mask_texture_size); + EXPECT_EQ(gfx::SizeF(), mask_uv_size); +} + +TEST_F(LegacySWPictureLayerImplTest, ReleaseTileResources) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); @@ -1391,7 +1432,7 @@ TEST_F(PictureLayerImplTest, ReleaseTileResources) { } // ReleaseResources should behave identically to ReleaseTileResources. -TEST_F(PictureLayerImplTest, ReleaseResources) { +TEST_F(LegacySWPictureLayerImplTest, ReleaseResources) { gfx::Size layer_bounds(1300, 1900); SetupDefaultTrees(layer_bounds); EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); @@ -1410,7 +1451,7 @@ TEST_F(PictureLayerImplTest, ReleaseResources) { EXPECT_EQ(0u, pending_layer()->num_tilings()); } -TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) { +TEST_F(LegacySWPictureLayerImplTest, ClampTilesToMaxTileSize) { gfx::Size layer_bounds(5000, 5000); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -1450,7 +1491,7 @@ TEST_F(PictureLayerImplTest, ClampTilesToMaxTileSize) { EXPECT_GE(140, tile->content_rect().height()); } -TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) { +TEST_F(LegacySWPictureLayerImplTest, ClampSingleTileToToMaxTileSize) { gfx::Size layer_bounds(500, 500); SetupDefaultTrees(layer_bounds); EXPECT_GE(active_layer()->tilings()->num_tilings(), 1u); @@ -1490,7 +1531,7 @@ TEST_F(PictureLayerImplTest, ClampSingleTileToToMaxTileSize) { EXPECT_GE(140, tile->content_rect().height()); } -TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) { +TEST_F(LegacySWPictureLayerImplTest, DisallowTileDrawQuads) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(1300, 1900); @@ -1518,7 +1559,7 @@ TEST_F(PictureLayerImplTest, DisallowTileDrawQuads) { EXPECT_EQ(render_pass->quad_list.front()->visible_rect, layer_rect); } -TEST_F(PictureLayerImplTest, ResourcelessPartialRecording) { +TEST_F(LegacySWPictureLayerImplTest, ResourcelessPartialRecording) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(700, 650); @@ -1555,7 +1596,7 @@ TEST_F(PictureLayerImplTest, ResourcelessPartialRecording) { EXPECT_FALSE(quad->needs_blending); } -TEST_F(PictureLayerImplTest, ResourcelessEmptyRecording) { +TEST_F(LegacySWPictureLayerImplTest, ResourcelessEmptyRecording) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(700, 650); @@ -1576,7 +1617,7 @@ TEST_F(PictureLayerImplTest, ResourcelessEmptyRecording) { EXPECT_EQ(0U, render_pass->quad_list.size()); } -TEST_F(PictureLayerImplTest, FarScrolledQuadsShifted) { +TEST_F(LegacySWPictureLayerImplTest, FarScrolledQuadsShifted) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(1000, 10000); @@ -1653,7 +1694,7 @@ TEST_F(PictureLayerImplTest, FarScrolledQuadsShifted) { EXPECT_FLOAT_EQ(max_transformed_y, 6000.f); } -TEST_F(PictureLayerImplTest, FarScrolledSolidColorQuadsShifted) { +TEST_F(LegacySWPictureLayerImplTest, FarScrolledSolidColorQuadsShifted) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(1000, 10000); @@ -1731,7 +1772,7 @@ TEST_F(PictureLayerImplTest, FarScrolledSolidColorQuadsShifted) { EXPECT_FLOAT_EQ(max_transformed_y, 10000.f); } -TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) { +TEST_F(LegacySWPictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(1500, 1500); @@ -1761,7 +1802,7 @@ TEST_F(PictureLayerImplTest, SolidColorLayerHasVisibleFullCoverage) { EXPECT_TRUE(remaining.IsEmpty()); } -TEST_F(PictureLayerImplTest, TileScalesWithSolidColorRasterSource) { +TEST_F(LegacySWPictureLayerImplTest, TileScalesWithSolidColorRasterSource) { gfx::Size layer_bounds(200, 200); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -1840,7 +1881,7 @@ TEST_F(NoLowResPictureLayerImplTest, host_impl()->SetExternalTilePriorityConstraints( external_viewport_for_tile_priority, transform_for_tile_priority); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); // Set visible content rect that is different from // external_viewport_for_tile_priority. @@ -1879,8 +1920,7 @@ TEST_F(NoLowResPictureLayerImplTest, EXPECT_GT(num_outside, 0); // Activate and draw active layer. - host_impl()->ActivateSyncTree(); - host_impl()->active_tree()->UpdateDrawProperties(); + ActivateTree(); active_layer()->draw_properties().visible_layer_rect = visible_layer_rect; std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); @@ -1895,7 +1935,7 @@ TEST_F(NoLowResPictureLayerImplTest, EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, HighResTileIsComplete) { +TEST_F(LegacySWPictureLayerImplTest, HighResTileIsComplete) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); @@ -1925,7 +1965,7 @@ TEST_F(PictureLayerImplTest, HighResTileIsComplete) { EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) { +TEST_F(LegacySWPictureLayerImplTest, HighResTileIsIncomplete) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); @@ -1948,7 +1988,7 @@ TEST_F(PictureLayerImplTest, HighResTileIsIncomplete) { EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) { +TEST_F(LegacySWPictureLayerImplTest, HighResTileIsIncompleteLowResComplete) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); @@ -1976,7 +2016,7 @@ TEST_F(PictureLayerImplTest, HighResTileIsIncompleteLowResComplete) { EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) { +TEST_F(LegacySWPictureLayerImplTest, LowResTileIsIncomplete) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); @@ -2013,7 +2053,7 @@ TEST_F(PictureLayerImplTest, LowResTileIsIncomplete) { EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, +TEST_F(LegacySWPictureLayerImplTest, HighResAndIdealResTileIsCompleteWhenRasterScaleIsNotIdeal) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); @@ -2079,7 +2119,7 @@ TEST_F(PictureLayerImplTest, EXPECT_FALSE(active_layer()->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, AppendQuadsDataForCheckerboard) { +TEST_F(LegacySWPictureLayerImplTest, AppendQuadsDataForCheckerboard) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(100, 100); @@ -2106,7 +2146,7 @@ TEST_F(PictureLayerImplTest, AppendQuadsDataForCheckerboard) { EXPECT_TRUE(active_layer()->only_used_low_res_last_append_quads()); } -TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveAllReady) { +TEST_F(LegacySWPictureLayerImplTest, HighResRequiredWhenActiveAllReady) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -2123,7 +2163,7 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveAllReady) { AssertAllTilesRequired(pending_layer()->HighResTiling()); } -TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) { +TEST_F(LegacySWPictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -2149,7 +2189,7 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenMissingHighResFlagOn) { AssertNoTilesRequired(active_layer()->LowResTiling()); } -TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { +TEST_F(LegacySWPictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -2170,7 +2210,7 @@ TEST_F(PictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { AssertNoTilesRequired(active_layer()->LowResTiling()); } -TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) { +TEST_F(LegacySWPictureLayerImplTest, DisallowRequiredForActivation) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -2194,7 +2234,7 @@ TEST_F(PictureLayerImplTest, DisallowRequiredForActivation) { AssertNoTilesRequired(active_layer()->LowResTiling()); } -TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { +TEST_F(LegacySWPictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -2223,7 +2263,7 @@ TEST_F(PictureLayerImplTest, NothingRequiredIfActiveMissingTiles) { AssertNoTilesRequired(pending_layer()->HighResTiling()); } -TEST_F(PictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) { +TEST_F(LegacySWPictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) { gfx::Size layer_bounds(400, 400); gfx::Size tile_size(100, 100); @@ -2247,7 +2287,8 @@ TEST_F(PictureLayerImplTest, HighResRequiredIfActiveCantHaveTiles) { AssertAllTilesRequired(pending_layer()->HighResTiling()); } -TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) { +TEST_F(LegacySWPictureLayerImplTest, + HighResRequiredWhenActiveHasDifferentBounds) { gfx::Size pending_layer_bounds(400, 400); gfx::Size active_layer_bounds(200, 200); gfx::Size tile_size(100, 100); @@ -2272,7 +2313,7 @@ TEST_F(PictureLayerImplTest, HighResRequiredWhenActiveHasDifferentBounds) { AssertNoTilesRequired(active_layer()->LowResTiling()); } -TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) { +TEST_F(LegacySWPictureLayerImplTest, ActivateUninitializedLayer) { gfx::Size layer_bounds(400, 400); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -2280,15 +2321,15 @@ TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) { host_impl()->CreatePendingTree(); LayerTreeImpl* pending_tree = host_impl()->pending_tree(); + int kLayerId = 2; std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(), - pending_raster_source); + FakePictureLayerImpl::Create(pending_tree, kLayerId, + pending_raster_source); pending_layer->SetDrawsContent(true); + auto* raw_pending_layer = pending_layer.get(); + SetupRootProperties(raw_pending_layer); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); - pending_tree->BuildLayerListAndPropertyTreesForTesting(); - - FakePictureLayerImpl* raw_pending_layer = static_cast<FakePictureLayerImpl*>( - host_impl()->pending_tree()->LayerById(layer_id())); + PrepareForUpdateDrawProperties(pending_tree); // Set some state on the pending layer, make sure it is not clobbered // by a sync from the active layer. This could happen because if the @@ -2300,13 +2341,13 @@ TEST_F(PictureLayerImplTest, ActivateUninitializedLayer) { host_impl()->ActivateSyncTree(); FakePictureLayerImpl* raw_active_layer = static_cast<FakePictureLayerImpl*>( - host_impl()->active_tree()->LayerById(layer_id())); + host_impl()->active_tree()->LayerById(kLayerId)); EXPECT_EQ(0u, raw_active_layer->num_tilings()); EXPECT_EQ(raster_page_scale, raw_active_layer->raster_page_scale()); } -TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { +TEST_F(LegacySWPictureLayerImplTest, ShareTilesOnNextFrame) { gfx::Size layer_bounds(1500, 1500); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -2364,7 +2405,7 @@ TEST_F(PictureLayerImplTest, ShareTilesOnNextFrame) { EXPECT_TRUE(pending_tiling->TileAt(1, 1)); } -TEST_F(PictureLayerImplTest, PendingHasNoTilesWithNoInvalidation) { +TEST_F(LegacySWPictureLayerImplTest, PendingHasNoTilesWithNoInvalidation) { SetupDefaultTrees(gfx::Size(1500, 1500)); EXPECT_GE(active_layer()->num_tilings(), 1u); @@ -2387,7 +2428,7 @@ TEST_F(PictureLayerImplTest, PendingHasNoTilesWithNoInvalidation) { EXPECT_FALSE(pending_tiling->TileAt(1, 1)); } -TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) { +TEST_F(LegacySWPictureLayerImplTest, ShareInvalidActiveTreeTiles) { gfx::Size layer_bounds(1500, 1500); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -2423,7 +2464,7 @@ TEST_F(PictureLayerImplTest, ShareInvalidActiveTreeTiles) { EXPECT_FALSE(pending_tiling->TileAt(1, 1)); } -TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) { +TEST_F(LegacySWPictureLayerImplTest, RecreateInvalidPendingTreeTiles) { // Set some invalidation on the pending tree. We should replace raster tiles // that touch this. SetupDefaultTreesWithInvalidation(gfx::Size(1500, 1500), gfx::Rect(1, 1)); @@ -2450,7 +2491,16 @@ TEST_F(PictureLayerImplTest, RecreateInvalidPendingTreeTiles) { EXPECT_NE(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0)); } -TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { +class MSAAEnabledPictureLayerImplTest : public PictureLayerImplTest { + public: + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + settings.gpu_rasterization_msaa_sample_count = 1; + return settings; + } +}; + +TEST_F(MSAAEnabledPictureLayerImplTest, SyncTilingAfterMSAAToggles) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(10, 10); @@ -2465,15 +2515,16 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f)); EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f)); - // Gpu rasterization is disabled by default. - EXPECT_FALSE(host_impl()->use_gpu_rasterization()); + // MSAA is disabled by default. + EXPECT_FALSE(host_impl()->use_msaa()); EXPECT_EQ(0u, pending_layer()->release_tile_resources_count()); EXPECT_EQ(0u, active_layer()->release_tile_resources_count()); EXPECT_EQ(0u, pending_layer()->release_resources_count()); EXPECT_EQ(0u, active_layer()->release_resources_count()); - // Toggling the gpu rasterization clears all tilings on both trees. - host_impl()->SetHasGpuRasterizationTrigger(true); + // Toggling MSAA clears all tilings on both trees. + host_impl()->SetContentHasSlowPaths(true); host_impl()->CommitComplete(); + EXPECT_TRUE(host_impl()->use_msaa()); EXPECT_EQ(1u, pending_layer()->release_tile_resources_count()); EXPECT_EQ(1u, active_layer()->release_tile_resources_count()); EXPECT_EQ(1u, pending_layer()->release_resources_count()); @@ -2490,11 +2541,11 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { SetupPendingTree(pending_raster_source); EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f)); - // Toggling the gpu rasterization clears all tilings on both trees. - EXPECT_TRUE(host_impl()->use_gpu_rasterization()); - host_impl()->SetHasGpuRasterizationTrigger(false); + // Toggling msaa clears all tilings on both trees. + host_impl()->SetContentHasSlowPaths(false); + EXPECT_TRUE(host_impl()->use_msaa()); host_impl()->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl()->gpu_rasterization_status()); EXPECT_EQ(2u, pending_layer()->release_tile_resources_count()); EXPECT_EQ(2u, active_layer()->release_tile_resources_count()); @@ -2502,13 +2553,12 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { EXPECT_EQ(2u, active_layer()->release_resources_count()); host_impl()->NotifyReadyToActivate(); - host_impl()->SetHasGpuRasterizationTrigger(true); host_impl()->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl()->gpu_rasterization_status()); } -TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) { +TEST_F(LegacySWPictureLayerImplTest, HighResCreatedWhenBoundsShrink) { // Put 0.5 as high res. SetInitialDeviceScaleFactor(0.5f); @@ -2538,13 +2588,11 @@ TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) { EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution()); } -TEST_F(PictureLayerImplTest, LowResTilingWithoutGpuRasterization) { +TEST_F(LegacySWPictureLayerImplTest, LowResTilingWithoutGpuRasterization) { gfx::Size default_tile_size(host_impl()->settings().default_tile_size); gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); - host_impl()->SetHasGpuRasterizationTrigger(false); - SetupDefaultTrees(layer_bounds); EXPECT_FALSE(host_impl()->use_gpu_rasterization()); // Should have only a high-res tiling. @@ -2559,8 +2607,6 @@ TEST_F(CommitToActiveTreePictureLayerImplTest, gfx::Size default_tile_size(host_impl()->settings().default_tile_size); gfx::Size layer_bounds(default_tile_size.width() * 4, default_tile_size.height() * 4); - - host_impl()->SetHasGpuRasterizationTrigger(true); host_impl()->CommitComplete(); SetupDefaultTrees(layer_bounds); @@ -2574,7 +2620,6 @@ TEST_F(CommitToActiveTreePictureLayerImplTest, TEST_F(CommitToActiveTreePictureLayerImplTest, RequiredTilesWithGpuRasterization) { - host_impl()->SetHasGpuRasterizationTrigger(true); host_impl()->CommitComplete(); gfx::Size viewport_size(1000, 1000); @@ -2600,7 +2645,6 @@ TEST_F(CommitToActiveTreePictureLayerImplTest, TEST_F(CommitToActiveTreePictureLayerImplTest, RequiredTilesWithGpuRasterizationAndFractionalDsf) { - host_impl()->SetHasGpuRasterizationTrigger(true); host_impl()->CommitComplete(); gfx::Size viewport_size(1502, 2560); @@ -2623,7 +2667,7 @@ TEST_F(CommitToActiveTreePictureLayerImplTest, EXPECT_EQ(4u, active_layer()->HighResTiling()->AllTilesForTesting().size()); } -TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) { +TEST_F(LegacySWPictureLayerImplTest, NoTilingIfDoesNotDrawContent) { // Set up layers with tilings. SetupDefaultTrees(gfx::Size(10, 10)); SetContentsScaleOnBothLayers(1.f, 1.f, 1.f, 1.f, 0.f, false); @@ -2643,7 +2687,7 @@ TEST_F(PictureLayerImplTest, NoTilingIfDoesNotDrawContent) { EXPECT_EQ(0u, active_layer()->num_tilings()); } -TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) { +TEST_F(LegacySWPictureLayerImplTest, FirstTilingDuringPinch) { SetupDefaultTrees(gfx::Size(10, 10)); // We start with a tiling at scale 1. @@ -2658,7 +2702,7 @@ TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) { EXPECT_EQ(4.f, pending_layer()->HighResTiling()->contents_scale_key()); } -TEST_F(PictureLayerImplTest, PinchingTooSmall) { +TEST_F(LegacySWPictureLayerImplTest, PinchingTooSmall) { SetupDefaultTrees(gfx::Size(10, 10)); // We start with a tiling at scale 1. @@ -2674,7 +2718,7 @@ TEST_F(PictureLayerImplTest, PinchingTooSmall) { pending_layer()->HighResTiling()->contents_scale_key()); } -TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) { +TEST_F(LegacySWPictureLayerImplTest, PinchingTooSmallWithContentsScale) { SetupDefaultTrees(gfx::Size(10, 10)); ResetTilingsAndRasterScales(); @@ -2699,7 +2743,8 @@ TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) { pending_layer()->HighResTiling()->contents_scale_key()); } -TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { +TEST_F(LegacySWPictureLayerImplTest, + ConsiderAnimationStartScaleForRasterScale) { gfx::Size viewport_size(1000, 1000); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -2757,7 +2802,7 @@ TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); } -TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { +TEST_F(LegacySWPictureLayerImplTest, HighResTilingDuringAnimation) { gfx::Size viewport_size(1000, 1000); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -2902,7 +2947,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 11.f); } -TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationAspectRatio) { +TEST_F(LegacySWPictureLayerImplTest, HighResTilingDuringAnimationAspectRatio) { gfx::Size viewport_size(2000, 1000); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -2930,7 +2975,8 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationAspectRatio) { EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 15.f); } -TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationAspectRatioTooLarge) { +TEST_F(LegacySWPictureLayerImplTest, + HighResTilingDuringAnimationAspectRatioTooLarge) { gfx::Size viewport_size(2000, 1000); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -2959,7 +3005,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimationAspectRatioTooLarge) { page_scale * device_scale); } -TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { +TEST_F(LegacySWPictureLayerImplTest, TilingSetRasterQueue) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(500, 500)); @@ -3090,7 +3136,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { EXPECT_TRUE(queue->IsEmpty()); } -TEST_F(PictureLayerImplTest, TilingSetRasterQueueActiveTree) { +TEST_F(LegacySWPictureLayerImplTest, TilingSetRasterQueueActiveTree) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(500, 500)); @@ -3122,7 +3168,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueueActiveTree) { EXPECT_TRUE(queue->IsEmpty()); } -TEST_F(PictureLayerImplTest, TilingSetRasterQueueRequiredNoHighRes) { +TEST_F(LegacySWPictureLayerImplTest, TilingSetRasterQueueRequiredNoHighRes) { scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilledSolidColor(gfx::Size(1024, 1024)); @@ -3138,7 +3184,7 @@ TEST_F(PictureLayerImplTest, TilingSetRasterQueueRequiredNoHighRes) { EXPECT_TRUE(queue->IsEmpty()); } -TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { +TEST_F(LegacySWPictureLayerImplTest, TilingSetEvictionQueue) { gfx::Size layer_bounds(1000, 1000); float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; @@ -3285,12 +3331,12 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { EXPECT_EQ(all_tiles_set.size(), unique_tiles.size()); } -TEST_F(PictureLayerImplTest, Occlusion) { +TEST_F(LegacySWPictureLayerImplTest, Occlusion) { gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -3307,8 +3353,7 @@ TEST_F(PictureLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendQuadsWithOcclusion(active_layer(), occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_bounds)); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_bounds)); EXPECT_EQ(100u, impl.quad_list().size()); } @@ -3317,7 +3362,7 @@ TEST_F(PictureLayerImplTest, Occlusion) { gfx::Rect occluded(active_layer()->visible_layer_rect()); impl.AppendQuadsWithOcclusion(active_layer(), occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -3327,25 +3372,24 @@ TEST_F(PictureLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(active_layer(), occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs one quad, which is partially occluded. EXPECT_EQ(100u - 10u, impl.quad_list().size()); EXPECT_EQ(10u + 10u, partially_occluded_count); } } -TEST_F(PictureLayerImplTest, OcclusionOnSolidColorPictureLayer) { +TEST_F(LegacySWPictureLayerImplTest, OcclusionOnSolidColorPictureLayer) { gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilledSolidColor(layer_bounds); - SetupPendingTree(std::move(pending_raster_source), gfx::Size(), Region(), - Layer::LayerMaskType::NOT_MASK); + SetupPendingTree(std::move(pending_raster_source), gfx::Size(), Region()); // Device scale factor should not affect a non-mask solid color layer. host_impl()->pending_tree()->SetDeviceScaleFactor(2.f); ActivateTree(); @@ -3356,8 +3400,7 @@ TEST_F(PictureLayerImplTest, OcclusionOnSolidColorPictureLayer) { impl.AppendQuadsWithOcclusion(active_layer(), occluded); size_t partial_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded(impl.quad_list(), occluded, - &partial_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, &partial_occluded_count); // Because of the implementation of test helper AppendQuadsWithOcclusion, // the occlusion will have a scale transform resulted from the device scale // factor. A single partially overlapped DrawQuad of 500x500 will be added. @@ -3366,17 +3409,17 @@ TEST_F(PictureLayerImplTest, OcclusionOnSolidColorPictureLayer) { } } -TEST_F(PictureLayerImplTest, IgnoreOcclusionOnSolidColorMask) { +TEST_F(LegacySWPictureLayerImplTest, IgnoreOcclusionOnSolidColorMask) { gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilledSolidColor(layer_bounds); - SetupPendingTree(std::move(pending_raster_source), gfx::Size(), Region(), - Layer::LayerMaskType::SINGLE_TEXTURE_MASK); + SetupPendingTree(std::move(pending_raster_source), gfx::Size(), Region()); + host_impl()->pending_tree()->SetDeviceScaleFactor(2.f); ActivateTree(); @@ -3386,8 +3429,8 @@ TEST_F(PictureLayerImplTest, IgnoreOcclusionOnSolidColorMask) { impl.AppendQuadsWithOcclusion(active_layer(), occluded); size_t partial_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded(impl.quad_list(), gfx::Rect(), - &partial_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), gfx::Rect(), + &partial_occluded_count); // None of the quads shall be occluded because mask layers ignores // occlusion. EXPECT_EQ(1u, impl.quad_list().size()); @@ -3395,7 +3438,7 @@ TEST_F(PictureLayerImplTest, IgnoreOcclusionOnSolidColorMask) { } } -TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { +TEST_F(LegacySWPictureLayerImplTest, RasterScaleChangeWithoutAnimation) { gfx::Size tile_size(host_impl()->settings().default_tile_size); SetupDefaultTrees(tile_size); @@ -3465,7 +3508,7 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); } -TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) { +TEST_F(LegacySWPictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); @@ -3490,7 +3533,7 @@ TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) { EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } -TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) { +TEST_F(LegacySWPictureLayerImplTest, HighResReadyToDrawEnoughToActivate) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); @@ -3509,7 +3552,7 @@ TEST_F(PictureLayerImplTest, HighResReadyToDrawEnoughToActivate) { EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } -TEST_F(PictureLayerImplTest, ActiveHighResReadyNotEnoughToActivate) { +TEST_F(LegacySWPictureLayerImplTest, ActiveHighResReadyNotEnoughToActivate) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(1000, 1000); @@ -3843,7 +3886,7 @@ TEST_F(NoLowResPictureLayerImplTest, ReleaseTileResources) { EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); } -TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) { +TEST_F(LegacySWPictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(1000, 2000); @@ -3883,7 +3926,8 @@ TEST_F(PictureLayerImplTest, SharedQuadStateContainsMaxTilingScale) { ->visible_quad_layer_rect.ToString()); } -class PictureLayerImplTestWithDelegatingRenderer : public PictureLayerImplTest { +class PictureLayerImplTestWithDelegatingRenderer + : public LegacySWPictureLayerImplTest { public: std::unique_ptr<LayerTreeFrameSink> CreateLayerTreeFrameSink() override { return FakeLayerTreeFrameSink::Create3d(); @@ -3902,7 +3946,7 @@ TEST_F(PictureLayerImplTestWithDelegatingRenderer, SetupPendingTree(pending_raster_source); pending_layer()->SetBounds(layer_bounds); ActivateTree(); - host_impl()->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->active_tree()); std::vector<Tile*> tiles = active_layer()->HighResTiling()->AllTilesForTesting(); host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); @@ -3938,10 +3982,11 @@ TEST_F(PictureLayerImplTestWithDelegatingRenderer, render_pass->quad_list.back()->material); } -class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { +class OcclusionTrackingPictureLayerImplTest + : public LegacySWPictureLayerImplTest { public: LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings = PictureLayerImplTest::CreateSettings(); + LayerTreeSettings settings = LegacySWPictureLayerImplTest::CreateSettings(); settings.use_occlusion_for_tile_prioritization = true; return settings; } @@ -3998,7 +4043,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(500, 500); - gfx::PointF occluding_layer_position(310.f, 0.f); + gfx::Vector2dF occluding_layer_position(310.f, 0.f); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -4028,17 +4073,15 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, EXPECT_EQ(unoccluded_tile_count, 25); // Partial occlusion. - pending_layer()->test_properties()->AddChild( - LayerImpl::Create(host_impl()->pending_tree(), 1)); - LayerImpl* layer1 = pending_layer()->test_properties()->children[0]; + LayerImpl* layer1 = AddLayer<LayerImpl>(host_impl()->pending_tree()); layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); - layer1->test_properties()->position = occluding_layer_position; + CopyProperties(pending_layer(), layer1); + layer1->SetOffsetToTransformParent(occluding_layer_position); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); unoccluded_tile_count = 0; queue.reset(new TilingSetRasterQueueAll( @@ -4058,12 +4101,11 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, EXPECT_EQ(20, unoccluded_tile_count); // Full occlusion. - layer1->test_properties()->position = gfx::PointF(); + layer1->SetOffsetToTransformParent(gfx::Vector2dF()); layer1->NoteLayerPropertyChanged(); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); unoccluded_tile_count = 0; queue.reset(new TilingSetRasterQueueAll( @@ -4090,7 +4132,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(500, 500); - gfx::PointF occluding_layer_position(310.f, 0.f); + gfx::Vector2dF occluding_layer_position(310.f, 0.f); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -4123,17 +4165,15 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, } // Partial occlusion. - pending_layer()->test_properties()->AddChild( - LayerImpl::Create(host_impl()->pending_tree(), 1)); - LayerImpl* layer1 = pending_layer()->test_properties()->children[0]; + LayerImpl* layer1 = AddLayer<LayerImpl>(host_impl()->pending_tree()); layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); - layer1->test_properties()->position = occluding_layer_position; + CopyProperties(pending_layer(), layer1); + layer1->SetOffsetToTransformParent(occluding_layer_position); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); @@ -4166,12 +4206,11 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, } // Full occlusion. - layer1->test_properties()->position = gfx::PointF(); + layer1->SetOffsetToTransformParent(gfx::Vector2dF()); layer1->NoteLayerPropertyChanged(); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(200)); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); @@ -4210,7 +4249,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(500, 500); - gfx::PointF occluding_layer_position(310.f, 0.f); + gfx::Vector2dF occluding_layer_position(310.f, 0.f); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -4220,13 +4259,12 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { SetupPendingTreeWithFixedTileSize(pending_raster_source, tile_size, Region()); ASSERT_TRUE(pending_layer()->CanHaveTilings()); - pending_layer()->test_properties()->AddChild( - LayerImpl::Create(host_impl()->pending_tree(), 1)); - LayerImpl* layer1 = pending_layer()->test_properties()->children[0]; + LayerImpl* layer1 = AddLayer<LayerImpl>(host_impl()->pending_tree()); layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); - layer1->test_properties()->position = occluding_layer_position; + CopyProperties(pending_layer(), layer1); + layer1->SetOffsetToTransformParent(occluding_layer_position); pending_layer()->tilings()->RemoveAllTilings(); float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; @@ -4246,10 +4284,9 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { ->AddTiling(gfx::AxisTransform2d(2.0f, gfx::Vector2dF())) ->set_resolution(HIGH_RESOLUTION); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); // UpdateDrawProperties with the occluding layer. - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); EXPECT_EQ(5u, pending_layer()->num_tilings()); @@ -4293,7 +4330,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(1000, 1000); - gfx::PointF occluding_layer_position(310.f, 0.f); + gfx::Vector2dF occluding_layer_position(310.f, 0.f); gfx::Rect invalidation_rect(230, 230, 102, 102); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -4305,13 +4342,12 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { SetupPendingTree(active_raster_source); // Partially occlude the active layer. - pending_layer()->test_properties()->AddChild( - LayerImpl::Create(host_impl()->pending_tree(), 2)); - LayerImpl* layer1 = pending_layer()->test_properties()->children[0]; + LayerImpl* layer1 = AddLayer<LayerImpl>(host_impl()->pending_tree()); layer1->SetBounds(layer_bounds); layer1->SetDrawsContent(true); layer1->SetContentsOpaque(true); - layer1->test_properties()->position = occluding_layer_position; + CopyProperties(pending_layer(), layer1); + layer1->SetOffsetToTransformParent(occluding_layer_position); ActivateTree(); @@ -4385,8 +4421,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, gfx::Size tile_size(102, 102); gfx::Size layer_bounds(1000, 1000); gfx::Size viewport_size(1000, 1000); - gfx::PointF pending_occluding_layer_position(310.f, 0.f); - gfx::PointF active_occluding_layer_position(0.f, 310.f); + gfx::Vector2dF pending_occluding_layer_position(310.f, 0.f); + gfx::Vector2dF active_occluding_layer_position(0.f, 310.f); gfx::Rect invalidation_rect(230, 230, 152, 152); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); @@ -4400,15 +4436,14 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, SetupPendingTreeWithFixedTileSize(active_raster_source, tile_size, Region()); // Partially occlude the active layer. - pending_layer()->test_properties()->AddChild( - LayerImpl::Create(host_impl()->pending_tree(), 2)); LayerImpl* active_occluding_layer = - pending_layer()->test_properties()->children[0]; + AddLayer<LayerImpl>(host_impl()->pending_tree()); active_occluding_layer->SetBounds(layer_bounds); active_occluding_layer->SetDrawsContent(true); active_occluding_layer->SetContentsOpaque(true); - active_occluding_layer->test_properties()->position = - active_occluding_layer_position; + CopyProperties(pending_layer(), active_occluding_layer); + active_occluding_layer->SetOffsetToTransformParent( + active_occluding_layer_position); ActivateTree(); // Partially invalidate the pending layer. Tiles inside the invalidation rect @@ -4417,23 +4452,22 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, invalidation_rect); // Partially occlude the pending layer in a different way. - pending_layer()->test_properties()->AddChild( - LayerImpl::Create(host_impl()->pending_tree(), 3)); LayerImpl* pending_occluding_layer = - pending_layer()->test_properties()->children[0]; - pending_occluding_layer->SetBounds(layer_bounds); - pending_occluding_layer->SetDrawsContent(true); - pending_occluding_layer->SetContentsOpaque(true); - pending_occluding_layer->test_properties()->position = - pending_occluding_layer_position; + host_impl()->pending_tree()->LayerById(active_occluding_layer->id()); + ASSERT_EQ(active_occluding_layer->bounds(), + pending_occluding_layer->bounds()); + ASSERT_TRUE(pending_occluding_layer->DrawsContent()); + ASSERT_TRUE(pending_occluding_layer->contents_opaque()); + pending_occluding_layer->SetOffsetToTransformParent( + pending_occluding_layer_position); + pending_occluding_layer->NoteLayerPropertyChanged(); EXPECT_EQ(1u, pending_layer()->num_tilings()); EXPECT_EQ(2u, active_layer()->num_tilings()); - RebuildPropertyTreesOnPendingTree(); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); // UpdateDrawProperties with the occluding layer. - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); float dest_scale = std::max(active_layer()->MaximumTilingContentsScale(), pending_layer()->MaximumTilingContentsScale()); @@ -4540,7 +4574,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, pending_layer()->set_has_valid_tile_priorities(true); } -TEST_F(PictureLayerImplTest, PendingOrActiveTwinLayer) { +TEST_F(LegacySWPictureLayerImplTest, PendingOrActiveTwinLayer) { gfx::Size layer_bounds(1000, 1000); scoped_refptr<FakeRasterSource> raster_source = @@ -4663,19 +4697,19 @@ void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid, EXPECT_EQ(expected, render_pass->quad_list.front()->material); } -TEST_F(PictureLayerImplTest, DrawSolidQuads) { +TEST_F(LegacySWPictureLayerImplTest, DrawSolidQuads) { TestQuadsForSolidColor(true, false); } -TEST_F(PictureLayerImplTest, DrawNonSolidQuads) { +TEST_F(LegacySWPictureLayerImplTest, DrawNonSolidQuads) { TestQuadsForSolidColor(false, false); } -TEST_F(PictureLayerImplTest, DrawTransparentQuads) { +TEST_F(LegacySWPictureLayerImplTest, DrawTransparentQuads) { TestQuadsForSolidColor(false, true); } -TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { +TEST_F(LegacySWPictureLayerImplTest, NonSolidToSolidNoTilings) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(200, 200); @@ -4705,7 +4739,6 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { SetupPendingTree(raster_source1); ActivateTree(); - host_impl()->active_tree()->UpdateDrawProperties(); // We've started with a solid layer that contains some tilings. ASSERT_TRUE(active_layer()->tilings()); @@ -4730,7 +4763,7 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); } -TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) { +TEST_F(LegacySWPictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(400, 4000); @@ -4786,7 +4819,7 @@ TEST_F(PictureLayerImplTest, ChangeInViewportAllowsTilingUpdates) { EXPECT_TRUE(host_impl()->tile_manager()->IsReadyToActivate()); } -TEST_F(PictureLayerImplTest, CloneMissingRecordings) { +TEST_F(LegacySWPictureLayerImplTest, CloneMissingRecordings) { gfx::Size tile_size(100, 100); gfx::Size layer_bounds(400, 400); @@ -4847,7 +4880,7 @@ TEST_F(PictureLayerImplTest, CloneMissingRecordings) { EXPECT_EQ(tile22, active_tiling->TileAt(2, 2)->id()); } -TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) { +TEST_F(LegacySWPictureLayerImplTest, ScrollPastLiveTilesRectAndBack) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); @@ -4892,7 +4925,7 @@ TEST_F(PictureLayerImplTest, ScrollPastLiveTilesRectAndBack) { EXPECT_FALSE(active_layer()->HighResTiling()->live_tiles_rect().IsEmpty()); } -TEST_F(PictureLayerImplTest, ScrollPropagatesToPending) { +TEST_F(LegacySWPictureLayerImplTest, ScrollPropagatesToPending) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size layer_bounds(1000, 1000); @@ -4904,7 +4937,7 @@ TEST_F(PictureLayerImplTest, ScrollPropagatesToPending) { SetupDefaultTrees(layer_bounds); active_layer()->SetCurrentScrollOffset(gfx::ScrollOffset(0.0, 50.0)); - host_impl()->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->active_tree()); EXPECT_EQ("0,50 100x100", active_layer() ->HighResTiling() ->GetCurrentVisibleRectForTesting() @@ -4914,14 +4947,17 @@ TEST_F(PictureLayerImplTest, ScrollPropagatesToPending) { ->HighResTiling() ->GetCurrentVisibleRectForTesting() .ToString()); - host_impl()->pending_tree()->UpdateDrawProperties(); + // Scroll offset in property trees is not propagated from the active tree to + // the pending tree. + SetScrollOffset(pending_layer(), active_layer()->CurrentScrollOffset()); + UpdateDrawProperties(host_impl()->pending_tree()); EXPECT_EQ("0,50 100x100", pending_layer() ->HighResTiling() ->GetCurrentVisibleRectForTesting() .ToString()); } -TEST_F(PictureLayerImplTest, UpdateLCDInvalidatesPendingTree) { +TEST_F(LegacySWPictureLayerImplTest, UpdateLCDInvalidatesPendingTree) { host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); gfx::Size tile_size(102, 102); @@ -4952,7 +4988,7 @@ TEST_F(PictureLayerImplTest, UpdateLCDInvalidatesPendingTree) { EXPECT_NE(tiles[i], new_tiles[i]); } -TEST_F(PictureLayerImplTest, TilingAllTilesDone) { +TEST_F(LegacySWPictureLayerImplTest, TilingAllTilesDone) { gfx::Size tile_size = host_impl()->settings().default_tile_size; size_t tile_mem = 4 * tile_size.width() * tile_size.height(); gfx::Size layer_bounds(1000, 1000); @@ -5006,20 +5042,25 @@ class TileSizeTest : public PictureLayerImplTest { } }; -TEST_F(TileSizeTest, TileSizes) { - host_impl()->CreatePendingTree(); +class LegacySWTileSizeTest : public TileSizeTest { + public: + LayerTreeSettings CreateSettings() override { + LayerTreeSettings settings = TileSizeTest::CreateSettings(); + settings.gpu_rasterization_disabled = true; + return settings; + } +}; - LayerTreeImpl* pending_tree = host_impl()->pending_tree(); - std::unique_ptr<FakePictureLayerImpl> layer = - FakePictureLayerImpl::Create(pending_tree, layer_id()); +TEST_F(LegacySWTileSizeTest, SWTileSizes) { + SetupPendingTree(); + auto* layer = pending_layer(); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(1000, 1000)); gfx::Size result; - host_impl()->SetHasGpuRasterizationTrigger(false); host_impl()->CommitComplete(); EXPECT_EQ(host_impl()->gpu_rasterization_status(), - GpuRasterizationStatus::OFF_VIEWPORT); + GpuRasterizationStatus::OFF_DEVICE); host_impl()->NotifyReadyToActivate(); // Default tile-size for large layers. @@ -5036,11 +5077,19 @@ TEST_F(TileSizeTest, TileSizes) { result = layer->CalculateTileSize(gfx::Size(199, 199)); EXPECT_EQ(result.width(), 200); EXPECT_EQ(result.height(), 200); +} + +TEST_F(TileSizeTest, GPUTileSizes) { + SetupPendingTree(); + auto* layer = pending_layer(); + + host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(1000, 1000)); + gfx::Size result; + + host_impl()->CommitComplete(); // Gpu-rasterization uses 25% viewport-height tiles. // The +2's below are for border texels. - host_impl()->SetHasGpuRasterizationTrigger(true); - host_impl()->CommitComplete(); EXPECT_EQ(host_impl()->gpu_rasterization_status(), GpuRasterizationStatus::ON); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(2000, 2000)); @@ -5073,18 +5122,13 @@ TEST_F(TileSizeTest, TileSizes) { EXPECT_EQ(result.height(), 512); // 500 + 2, 32-byte aligned. } -class HalfWidthTileTest : public PictureLayerImplTest { -}; +class HalfWidthTileTest : public PictureLayerImplTest {}; TEST_F(HalfWidthTileTest, TileSizes) { - host_impl()->CreatePendingTree(); - - LayerTreeImpl* pending_tree = host_impl()->pending_tree(); - std::unique_ptr<FakePictureLayerImpl> layer = - FakePictureLayerImpl::Create(pending_tree, layer_id()); + SetupPendingTree(); + auto* layer = pending_layer(); gfx::Size result; - host_impl()->SetHasGpuRasterizationTrigger(true); host_impl()->CommitComplete(); EXPECT_EQ(host_impl()->gpu_rasterization_status(), GpuRasterizationStatus::ON); @@ -5141,7 +5185,7 @@ TEST_F(NoLowResPictureLayerImplTest, LowResWasHighResCollision) { pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); } -TEST_F(PictureLayerImplTest, HighResWasLowResCollision) { +TEST_F(LegacySWPictureLayerImplTest, HighResWasLowResCollision) { gfx::Size layer_bounds(1300, 1900); float low_res_factor = host_impl()->settings().low_res_contents_scale_factor; @@ -5206,7 +5250,7 @@ TEST_F(PictureLayerImplTest, HighResWasLowResCollision) { EXPECT_FALSE(tilings->tiling_at(1)->may_contain_low_resolution_tiles()); } -TEST_F(PictureLayerImplTest, CompositedImageCalculateContentsScale) { +TEST_F(LegacySWPictureLayerImplTest, CompositedImageCalculateContentsScale) { gfx::Size layer_bounds(400, 400); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); @@ -5215,20 +5259,21 @@ TEST_F(PictureLayerImplTest, CompositedImageCalculateContentsScale) { LayerTreeImpl* pending_tree = host_impl()->pending_tree(); std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(), - pending_raster_source); + FakePictureLayerImpl::Create(pending_tree, root_id(), + pending_raster_source); pending_layer->set_is_directly_composited_image(true); pending_layer->SetDrawsContent(true); FakePictureLayerImpl* pending_layer_ptr = pending_layer.get(); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); - pending_tree->BuildLayerListAndPropertyTreesForTesting(); + SetupRootProperties(pending_layer_ptr); + UpdateDrawProperties(pending_tree); SetupDrawPropertiesAndUpdateTiles(pending_layer_ptr, 2.f, 3.f, 4.f, 1.f, 1.f, false); EXPECT_FLOAT_EQ(1.f, pending_layer_ptr->MaximumTilingContentsScale()); } -TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) { +TEST_F(LegacySWPictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) { gfx::Size layer_bounds(400, 400); gfx::Rect layer_rect(layer_bounds); scoped_refptr<FakeRasterSource> pending_raster_source = @@ -5239,14 +5284,15 @@ TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) { LayerTreeImpl* pending_tree = host_impl()->pending_tree(); std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(), - pending_raster_source); + FakePictureLayerImpl::Create(pending_tree, root_id(), + pending_raster_source); pending_layer->set_is_directly_composited_image(true); pending_layer->SetDrawsContent(true); FakePictureLayerImpl* pending_layer_ptr = pending_layer.get(); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); pending_tree->SetDeviceViewportRect(layer_rect); - pending_tree->BuildLayerListAndPropertyTreesForTesting(); + SetupRootProperties(pending_layer_ptr); + UpdateDrawProperties(pending_tree); // Set PictureLayerImpl::ideal_contents_scale_ to 2.f. const float suggested_ideal_contents_scale = 2.f; @@ -5265,7 +5311,7 @@ TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) { host_impl()->ActivateSyncTree(); FakePictureLayerImpl* active_layer = static_cast<FakePictureLayerImpl*>( - host_impl()->active_tree()->root_layer_for_testing()); + host_impl()->active_tree()->root_layer()); SetupDrawPropertiesAndUpdateTiles( active_layer, suggested_ideal_contents_scale, device_scale_factor, page_scale_factor, animation_contents_scale, animation_contents_scale, @@ -5292,22 +5338,13 @@ TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) { EXPECT_EQ(0, data.num_incomplete_tiles); } -TEST_F(PictureLayerImplTest, CompositedImageRasterScaleChanges) { +TEST_F(LegacySWPictureLayerImplTest, CompositedImageRasterScaleChanges) { gfx::Size layer_bounds(400, 400); scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - host_impl()->CreatePendingTree(); - LayerTreeImpl* pending_tree = host_impl()->pending_tree(); - - std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, layer_id(), - pending_raster_source); - pending_layer->set_is_directly_composited_image(true); - pending_layer->SetDrawsContent(true); - FakePictureLayerImpl* pending_layer_ptr = pending_layer.get(); - pending_tree->SetRootLayerForTesting(std::move(pending_layer)); - pending_tree->BuildLayerListAndPropertyTreesForTesting(); + SetupPendingTree(pending_raster_source); + pending_layer()->set_is_directly_composited_image(true); float expected_contents_scale = 0.25f; for (int i = 1; i < 30; ++i) { @@ -5322,10 +5359,11 @@ TEST_F(PictureLayerImplTest, CompositedImageRasterScaleChanges) { expected_contents_scale = 1.f; break; } - SetupDrawPropertiesAndUpdateTiles(pending_layer_ptr, ideal_contents_scale, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), ideal_contents_scale, 1.f, 1.f, 1.f, 1.f, false); EXPECT_FLOAT_EQ(expected_contents_scale, - pending_layer_ptr->picture_layer_tiling_set() + pending_layer() + ->picture_layer_tiling_set() ->FindTilingWithResolution(HIGH_RESOLUTION) ->contents_scale_key()) << "ideal_contents_scale: " << ideal_contents_scale; @@ -5344,17 +5382,19 @@ TEST_F(PictureLayerImplTest, CompositedImageRasterScaleChanges) { expected_contents_scale = 0.25f; break; } - SetupDrawPropertiesAndUpdateTiles(pending_layer_ptr, ideal_contents_scale, + SetupDrawPropertiesAndUpdateTiles(pending_layer(), ideal_contents_scale, 1.f, 1.f, 1.f, 1.f, false); EXPECT_FLOAT_EQ(expected_contents_scale, - pending_layer_ptr->picture_layer_tiling_set() + pending_layer() + ->picture_layer_tiling_set() ->FindTilingWithResolution(HIGH_RESOLUTION) ->contents_scale_key()) << "ideal_contents_scale: " << ideal_contents_scale; } } -TEST_F(PictureLayerImplTest, ChangeRasterTranslationNukePendingLayerTiles) { +TEST_F(LegacySWPictureLayerImplTest, + ChangeRasterTranslationNukePendingLayerTiles) { gfx::Size layer_bounds(200, 200); gfx::Size tile_size(256, 256); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); @@ -5423,7 +5463,8 @@ TEST_F(PictureLayerImplTest, ChangeRasterTranslationNukePendingLayerTiles) { } } -TEST_F(PictureLayerImplTest, ChangeRasterTranslationNukeActiveLayerTiles) { +TEST_F(LegacySWPictureLayerImplTest, + ChangeRasterTranslationNukeActiveLayerTiles) { gfx::Size layer_bounds(200, 200); gfx::Size tile_size(256, 256); SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); @@ -5484,7 +5525,7 @@ TEST_F(PictureLayerImplTest, ChangeRasterTranslationNukeActiveLayerTiles) { } } -TEST_F(PictureLayerImplTest, AnimatedImages) { +TEST_F(LegacySWPictureLayerImplTest, AnimatedImages) { gfx::Size layer_bounds(1000, 1000); // Set up a raster source with 2 animated images. @@ -5538,7 +5579,7 @@ TEST_F(PictureLayerImplTest, AnimatedImages) { EXPECT_FALSE(active_layer()->ShouldAnimate(image2.stable_id())); } -TEST_F(PictureLayerImplTest, PaintWorkletInputs) { +TEST_F(LegacySWPictureLayerImplTest, PaintWorkletInputs) { gfx::Size layer_bounds(1000, 1000); // Set up a raster source with 2 PaintWorkletInputs. @@ -5591,7 +5632,7 @@ TEST_F(PictureLayerImplTest, PaintWorkletInputs) { EXPECT_TRUE(pending_layer()->GetPaintWorkletRecordMap().contains(input3)); } -TEST_F(PictureLayerImplTest, NoTilingsUsesScaleOne) { +TEST_F(LegacySWPictureLayerImplTest, NoTilingsUsesScaleOne) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_bounds(1000, 10000); diff --git a/chromium/cc/layers/picture_layer_unittest.cc b/chromium/cc/layers/picture_layer_unittest.cc index 40772076c72..9f8feabe10d 100644 --- a/chromium/cc/layers/picture_layer_unittest.cc +++ b/chromium/cc/layers/picture_layer_unittest.cc @@ -19,6 +19,8 @@ #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/fake_proxy.h" #include "cc/test/fake_recording_source.h" +#include "cc/test/layer_test_common.h" +#include "cc/test/property_tree_test_utils.h" #include "cc/test/skia_common.h" #include "cc/test/stub_layer_tree_host_single_thread_client.h" #include "cc/test/test_task_graph_runner.h" @@ -105,9 +107,8 @@ TEST(PictureLayerTest, InvalidateRasterAfterUpdate) { host_impl.CreatePendingTree(); host_impl.pending_tree()->SetRootLayerForTesting( FakePictureLayerImpl::Create(host_impl.pending_tree(), 1)); - host_impl.pending_tree()->BuildLayerListForTesting(); FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>( - host_impl.pending_tree()->root_layer_for_testing()); + host_impl.pending_tree()->root_layer()); layer->PushPropertiesTo(layer_impl); EXPECT_EQ(invalidation_bounds, @@ -146,9 +147,8 @@ TEST(PictureLayerTest, InvalidateRasterWithoutUpdate) { host_impl.CreatePendingTree(); host_impl.pending_tree()->SetRootLayerForTesting( FakePictureLayerImpl::Create(host_impl.pending_tree(), 1)); - host_impl.pending_tree()->BuildLayerListForTesting(); FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>( - host_impl.pending_tree()->root_layer_for_testing()); + host_impl.pending_tree()->root_layer()); layer->PushPropertiesTo(layer_impl); EXPECT_EQ(gfx::Rect(), layer_impl->GetPendingInvalidation()->bounds()); @@ -183,19 +183,18 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink( FakeLayerTreeFrameSink::Create3d()); - LayerTreeSettings layer_tree_settings = LayerTreeSettings(); FakeLayerTreeHostImpl host_impl( - layer_tree_settings, &impl_task_runner_provider, &task_graph_runner); + LayerListSettings(), &impl_task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeFrameSink(layer_tree_frame_sink.get())); host_impl.CreatePendingTree(); host_impl.pending_tree()->SetRootLayerForTesting( FakePictureLayerImpl::Create(host_impl.pending_tree(), 1)); - host_impl.pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - FakePictureLayerImpl* layer_impl = static_cast<FakePictureLayerImpl*>( - host_impl.pending_tree()->root_layer_for_testing()); + host_impl.pending_tree()->root_layer()); + SetupRootProperties(layer_impl); + UpdateDrawProperties(host_impl.pending_tree()); layer->PushPropertiesTo(layer_impl); @@ -206,29 +205,26 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { // By updating the draw proprties on the active tree, we will set the viewport // rect for tile priorities to something non-empty. - host_impl.active_tree()->BuildPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl.active_tree()); layer->SetBounds(gfx::Size(11, 11)); host_impl.CreatePendingTree(); layer_impl = static_cast<FakePictureLayerImpl*>( - host_impl.pending_tree()->root_layer_for_testing()); + host_impl.pending_tree()->root_layer()); // We should now have invalid contents and should therefore clear the // recording source. layer->PushPropertiesTo(layer_impl); - host_impl.pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl.pending_tree()); host_impl.ActivateSyncTree(); std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->WillDraw( - DRAW_MODE_SOFTWARE, nullptr); - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); - host_impl.active_tree()->root_layer_for_testing()->DidDraw(nullptr); + host_impl.active_tree()->root_layer()->WillDraw(DRAW_MODE_SOFTWARE, nullptr); + host_impl.active_tree()->root_layer()->AppendQuads(render_pass.get(), &data); + host_impl.active_tree()->root_layer()->DidDraw(nullptr); } TEST(PictureLayerTest, HasSlowPaths) { diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc index 06ae3fe4ec0..287ce4abeac 100644 --- a/chromium/cc/layers/render_surface_impl.cc +++ b/chromium/cc/layers/render_surface_impl.cc @@ -122,11 +122,6 @@ float RenderSurfaceImpl::GetDebugBorderWidth() const { layer_tree_impl_ ? layer_tree_impl_->device_scale_factor() : 1); } -LayerImpl* RenderSurfaceImpl::MaskLayer() { - int mask_layer_id = OwningEffectNode()->mask_layer_id; - return layer_tree_impl_->LayerById(mask_layer_id); -} - LayerImpl* RenderSurfaceImpl::BackdropMaskLayer() const { ElementId mask_element_id = OwningEffectNode()->backdrop_mask_element_id; if (!mask_element_id) @@ -134,10 +129,6 @@ LayerImpl* RenderSurfaceImpl::BackdropMaskLayer() const { return layer_tree_impl_->LayerByElementId(mask_element_id); } -bool RenderSurfaceImpl::HasMask() const { - return OwningEffectNode()->mask_layer_id != Layer::INVALID_ID; -} - bool RenderSurfaceImpl::HasMaskingContributingSurface() const { return OwningEffectNode()->has_masking_child; } @@ -427,14 +418,7 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode, GetDebugBorderWidth()); } - DCHECK(!(MaskLayer() && BackdropMaskLayer())) - << "Can't support both a mask_layer and a backdrop_mask_layer"; - bool mask_applies_to_backdrop = BackdropMaskLayer(); - PictureLayerImpl* mask_layer = - mask_applies_to_backdrop - ? static_cast<PictureLayerImpl*>(BackdropMaskLayer()) - : static_cast<PictureLayerImpl*>(MaskLayer()); - + LayerImpl* mask_layer = BackdropMaskLayer(); viz::ResourceId mask_resource_id = 0; gfx::Size mask_texture_size; gfx::RectF mask_uv_rect; @@ -456,13 +440,17 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode, gfx::SizeF mask_uv_size; mask_layer->GetContentsResourceId(&mask_resource_id, &mask_texture_size, &mask_uv_size); - gfx::SizeF unclipped_mask_target_size = gfx::ScaleSize( - gfx::SizeF(OwningEffectNode()->unscaled_mask_target_size), - surface_contents_scale.x(), surface_contents_scale.y()); + gfx::SizeF unclipped_mask_target_size = + gfx::ScaleSize(gfx::SizeF(mask_layer->bounds()), + surface_contents_scale.x(), surface_contents_scale.y()); + gfx::Vector2dF mask_offset = gfx::ScaleVector2d( + mask_layer->offset_to_transform_parent(), surface_contents_scale.x(), + surface_contents_scale.y()); // Convert content_rect from target space to normalized mask UV space. // Where |unclipped_mask_target_size| maps to |mask_uv_size|. mask_uv_rect = gfx::ScaleRect( - gfx::RectF(content_rect()), + // Translate content_rect into mask resource's space. + gfx::RectF(content_rect()) - mask_offset, mask_uv_size.width() / unclipped_mask_target_size.width(), mask_uv_size.height() / unclipped_mask_target_size.height()); } @@ -471,8 +459,7 @@ void RenderSurfaceImpl::AppendQuads(DrawMode draw_mode, auto* quad = render_pass->CreateAndAppendDrawQuad<viz::RenderPassDrawQuad>(); quad->SetNew(shared_quad_state, content_rect(), unoccluded_content_rect, id(), mask_resource_id, mask_uv_rect, mask_texture_size, - mask_applies_to_backdrop, surface_contents_scale, - FiltersOrigin(), tex_coord_rect, + surface_contents_scale, FiltersOrigin(), tex_coord_rect, !layer_tree_impl_->settings().enable_edge_anti_aliasing, OwningEffectNode()->backdrop_filter_quality); } diff --git a/chromium/cc/layers/render_surface_impl.h b/chromium/cc/layers/render_surface_impl.h index 38fcaea82b9..545c840247f 100644 --- a/chromium/cc/layers/render_surface_impl.h +++ b/chromium/cc/layers/render_surface_impl.h @@ -154,8 +154,6 @@ class CC_EXPORT RenderSurfaceImpl { uint64_t id() const { return stable_id_; } - LayerImpl* MaskLayer(); - bool HasMask() const; bool HasMaskingContributingSurface() const; const FilterOperations& Filters() const; diff --git a/chromium/cc/layers/render_surface_impl_unittest.cc b/chromium/cc/layers/render_surface_impl_unittest.cc index 879c1c3663d..46f9c263a0f 100644 --- a/chromium/cc/layers/render_surface_impl_unittest.cc +++ b/chromium/cc/layers/render_surface_impl_unittest.cc @@ -9,7 +9,7 @@ #include "cc/layers/append_quads_data.h" #include "cc/test/fake_mask_layer_impl.h" #include "cc/test/fake_raster_source.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "components/viz/common/quads/render_pass_draw_quad.h" #include "testing/gtest/include/gtest/gtest.h" @@ -20,12 +20,14 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; - LayerImpl* owning_layer_impl = impl.AddChildToRoot<LayerImpl>(); + LayerImpl* owning_layer_impl = impl.AddLayer<LayerImpl>(); owning_layer_impl->SetBounds(layer_size); owning_layer_impl->SetDrawsContent(true); - owning_layer_impl->test_properties()->force_render_surface = true; + CopyProperties(impl.root_layer(), owning_layer_impl); + CreateEffectNode(owning_layer_impl).render_surface_reason = + RenderSurfaceReason::kTest; impl.CalcDrawProps(viewport_size); @@ -37,8 +39,7 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendSurfaceQuadsWithOcclusion(render_surface_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_size)); EXPECT_EQ(1u, impl.quad_list().size()); } @@ -47,7 +48,7 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) { gfx::Rect occluded(owning_layer_impl->visible_layer_rect()); impl.AppendSurfaceQuadsWithOcclusion(render_surface_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -57,8 +58,8 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) { impl.AppendSurfaceQuadsWithOcclusion(render_surface_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs one quad, which is partially occluded. EXPECT_EQ(1u, impl.quad_list().size()); EXPECT_EQ(1u, partially_occluded_count); @@ -67,55 +68,40 @@ TEST(RenderSurfaceLayerImplTest, Occlusion) { static std::unique_ptr<viz::RenderPass> DoAppendQuadsWithScaledMask( DrawMode draw_mode, - float device_scale_factor, - Layer::LayerMaskType mask_type) { + float device_scale_factor) { gfx::Size layer_size(1000, 1000); gfx::Rect viewport_rect(1000, 1000); float scale_factor = 2; scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilledSolidColor(layer_size); - LayerTreeSettings settings; - LayerTestCommon::LayerImplTest impl(settings); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(impl.host_impl()->active_tree(), 2); - std::unique_ptr<LayerImpl> surface = - LayerImpl::Create(impl.host_impl()->active_tree(), 3); - surface->SetBounds(layer_size); - surface->test_properties()->force_render_surface = true; + LayerTreeImplTestBase impl; + auto* root = impl.root_layer(); + auto* surface = impl.AddLayer<LayerImpl>(); + surface->SetBounds(layer_size); gfx::Transform scale; scale.Scale(scale_factor, scale_factor); - surface->test_properties()->transform = scale; + CopyProperties(root, surface); + CreateTransformNode(surface).local = scale; + CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; - std::unique_ptr<FakeMaskLayerImpl> mask_layer = FakeMaskLayerImpl::Create( - impl.host_impl()->active_tree(), 4, raster_source, mask_type); + auto* mask_layer = impl.AddLayer<FakeMaskLayerImpl>(raster_source); mask_layer->set_resource_size( gfx::ScaleToCeiledSize(layer_size, scale_factor)); - mask_layer->SetDrawsContent(true); - mask_layer->SetBounds(layer_size); - surface->test_properties()->SetMaskLayer(std::move(mask_layer)); + SetupMaskProperties(surface, mask_layer); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(impl.host_impl()->active_tree(), 5); + auto* child = impl.AddLayer<LayerImpl>(); child->SetDrawsContent(true); child->SetBounds(layer_size); + CopyProperties(surface, child); + + LayerTreeImpl* active_tree = impl.host_impl()->active_tree(); + active_tree->SetDeviceScaleFactor(device_scale_factor); + active_tree->SetDeviceViewportRect(viewport_rect); + UpdateDrawProperties(active_tree); - surface->test_properties()->AddChild(std::move(child)); - root->test_properties()->AddChild(std::move(surface)); - impl.host_impl()->active_tree()->SetRootLayerForTesting(std::move(root)); - - impl.host_impl()->active_tree()->SetDeviceScaleFactor(device_scale_factor); - impl.host_impl()->active_tree()->SetDeviceViewportRect(viewport_rect); - impl.host_impl()->active_tree()->BuildLayerListAndPropertyTreesForTesting(); - impl.host_impl()->active_tree()->UpdateDrawProperties(); - - LayerImpl* surface_raw = impl.host_impl() - ->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0]; - RenderSurfaceImpl* render_surface_impl = GetRenderSurface(surface_raw); + RenderSurfaceImpl* render_surface_impl = GetRenderSurface(surface); std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); AppendQuadsData append_quads_data; render_surface_impl->AppendQuads(draw_mode, render_pass.get(), @@ -124,19 +110,20 @@ static std::unique_ptr<viz::RenderPass> DoAppendQuadsWithScaledMask( } TEST(RenderSurfaceLayerImplTest, AppendQuadsWithScaledMask) { - std::unique_ptr<viz::RenderPass> render_pass = DoAppendQuadsWithScaledMask( - DRAW_MODE_HARDWARE, 1.f, Layer::LayerMaskType::SINGLE_TEXTURE_MASK); + std::unique_ptr<viz::RenderPass> render_pass = + DoAppendQuadsWithScaledMask(DRAW_MODE_HARDWARE, 1.f); DCHECK(render_pass->quad_list.front()); const viz::RenderPassDrawQuad* quad = viz::RenderPassDrawQuad::MaterialCast(render_pass->quad_list.front()); - EXPECT_EQ(gfx::RectF(0, 0, 1, 1), quad->mask_uv_rect); + // Mask layers don't use quad's mask functionality. + EXPECT_EQ(gfx::RectF(), quad->mask_uv_rect); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), quad->filters_scale); + EXPECT_EQ(0u, quad->mask_resource_id()); } TEST(RenderSurfaceLayerImplTest, ResourcelessAppendQuadsSkipMask) { std::unique_ptr<viz::RenderPass> render_pass = - DoAppendQuadsWithScaledMask(DRAW_MODE_RESOURCELESS_SOFTWARE, 1.f, - Layer::LayerMaskType::SINGLE_TEXTURE_MASK); + DoAppendQuadsWithScaledMask(DRAW_MODE_RESOURCELESS_SOFTWARE, 1.f); DCHECK(render_pass->quad_list.front()); const viz::RenderPassDrawQuad* quad = viz::RenderPassDrawQuad::MaterialCast(render_pass->quad_list.front()); @@ -145,8 +132,8 @@ TEST(RenderSurfaceLayerImplTest, ResourcelessAppendQuadsSkipMask) { TEST(RenderSurfaceLayerImplTest, AppendQuadsWithSolidColorMaskAndDeviceScaleFactor) { - std::unique_ptr<viz::RenderPass> render_pass = DoAppendQuadsWithScaledMask( - DRAW_MODE_HARDWARE, 2.f, Layer::LayerMaskType::SINGLE_TEXTURE_MASK); + std::unique_ptr<viz::RenderPass> render_pass = + DoAppendQuadsWithScaledMask(DRAW_MODE_HARDWARE, 2.f); DCHECK(render_pass->quad_list.front()); const viz::RenderPassDrawQuad* quad = viz::RenderPassDrawQuad::MaterialCast(render_pass->quad_list.front()); @@ -155,8 +142,8 @@ TEST(RenderSurfaceLayerImplTest, // With tiled mask layer, we only generate mask quads for visible rect. In // this case |quad_layer_rect| is not fully covered, but // |visible_quad_layer_rect| is fully covered. - LayerTestCommon::VerifyQuadsExactlyCoverRect( - render_pass->quad_list, quad->shared_quad_state->visible_quad_layer_rect); + VerifyQuadsExactlyCoverRect(render_pass->quad_list, + quad->shared_quad_state->visible_quad_layer_rect); } } // namespace diff --git a/chromium/cc/layers/render_surface_unittest.cc b/chromium/cc/layers/render_surface_unittest.cc index 3f7790008ab..f3f5307237d 100644 --- a/chromium/cc/layers/render_surface_unittest.cc +++ b/chromium/cc/layers/render_surface_unittest.cc @@ -10,7 +10,7 @@ #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/test/mock_occlusion_tracker.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" @@ -40,7 +40,7 @@ namespace { // does not intersect with visible_layer_rect. class FakePictureLayerImplForRenderSurfaceTest : public FakePictureLayerImpl { public: - static std::unique_ptr<FakePictureLayerImplForRenderSurfaceTest> CreateMask( + static std::unique_ptr<FakePictureLayerImplForRenderSurfaceTest> Create( LayerTreeImpl* tree_impl, int id) { return base::WrapUnique( @@ -76,9 +76,7 @@ class FakePictureLayerImplForRenderSurfaceTest : public FakePictureLayerImpl { protected: FakePictureLayerImplForRenderSurfaceTest(LayerTreeImpl* tree_impl, int id) - : FakePictureLayerImpl(tree_impl, - id, - Layer::LayerMaskType::SINGLE_TEXTURE_MASK) {} + : FakePictureLayerImpl(tree_impl, id) {} std::vector<gfx::Rect> quad_rects_; }; @@ -88,24 +86,19 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) { // This test checks that SurfacePropertyChanged() has the correct behavior. // - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<LayerImpl> owning_layer = - LayerImpl::Create(host_impl.active_tree(), 1); - owning_layer->test_properties()->force_render_surface = true; + LayerTreeImplTestBase impl; + LayerImpl* root = impl.root_layer(); + LayerTreeImpl* active_tree = impl.host_impl()->active_tree(); + + LayerImpl* layer = impl.AddLayer<LayerImpl>(); + CopyProperties(root, layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; + + UpdateDrawProperties(active_tree); gfx::Rect test_rect(3, 4, 5, 6); - host_impl.active_tree()->ResetAllChangeTracking(); - host_impl.active_tree()->SetRootLayerForTesting(std::move(owning_layer)); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); - - RenderSurfaceImpl* render_surface = - GetRenderSurface(host_impl.active_tree()->root_layer_for_testing()); + active_tree->ResetAllChangeTracking(); + + RenderSurfaceImpl* render_surface = GetRenderSurface(layer); ASSERT_TRUE(render_surface); // Currently, the content_rect, clip_rect, and @@ -114,10 +107,9 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) { EXECUTE_AND_VERIFY_SURFACE_CHANGED( render_surface->SetContentRectForTesting(test_rect)); - host_impl.active_tree()->SetOpacityMutated( - host_impl.active_tree()->root_layer_for_testing()->element_id(), 0.5f); + active_tree->SetOpacityMutated(root->element_id(), 0.5f); EXPECT_TRUE(render_surface->SurfacePropertyChanged()); - host_impl.active_tree()->ResetAllChangeTracking(); + active_tree->ResetAllChangeTracking(); // Setting the surface properties to the same values again should not be // considered "change". @@ -126,8 +118,9 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) { EXECUTE_AND_VERIFY_SURFACE_DID_NOT_CHANGE( render_surface->SetContentRectForTesting(test_rect)); + constexpr int kArbitraryLayerId = 200; std::unique_ptr<LayerImpl> dummy_mask = - LayerImpl::Create(host_impl.active_tree(), 2); + LayerImpl::Create(active_tree, kArbitraryLayerId); gfx::Transform dummy_matrix; dummy_matrix.Translate(1.0, 2.0); @@ -141,33 +134,20 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) { } TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<LayerImpl> root_layer = - LayerImpl::Create(host_impl.active_tree(), 1); - - int owning_layer_id = 2; - std::unique_ptr<LayerImpl> owning_layer = - LayerImpl::Create(host_impl.active_tree(), owning_layer_id); - owning_layer->test_properties()->force_render_surface = true; + LayerTreeImplTestBase impl; + LayerImpl* root = impl.root_layer(); + LayerImpl* layer = impl.AddLayer<LayerImpl>(); + CopyProperties(root, layer); + auto& effect_node = CreateEffectNode(layer); + effect_node.render_surface_reason = RenderSurfaceReason::kBlendMode; SkBlendMode blend_mode = SkBlendMode::kSoftLight; - owning_layer->test_properties()->blend_mode = blend_mode; + effect_node.blend_mode = blend_mode; - root_layer->test_properties()->AddChild(std::move(owning_layer)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root_layer)); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(impl.host_impl()->active_tree()); - ASSERT_TRUE( - GetRenderSurface(host_impl.active_tree()->LayerById(owning_layer_id))); - RenderSurfaceImpl* render_surface = - GetRenderSurface(host_impl.active_tree()->LayerById(owning_layer_id)); + RenderSurfaceImpl* render_surface = GetRenderSurface(layer); + ASSERT_TRUE(render_surface); gfx::Rect content_rect(0, 0, 50, 50); gfx::Rect clip_rect(5, 5, 40, 40); @@ -202,30 +182,18 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) { } TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectRenderPass) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<LayerImpl> root_layer = - LayerImpl::Create(host_impl.active_tree(), 1); - - int owning_layer_id = 2; - std::unique_ptr<LayerImpl> owning_layer = - LayerImpl::Create(host_impl.active_tree(), owning_layer_id); - owning_layer->test_properties()->force_render_surface = true; - - root_layer->test_properties()->AddChild(std::move(owning_layer)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root_layer)); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); - - ASSERT_TRUE( - GetRenderSurface(host_impl.active_tree()->LayerById(owning_layer_id))); - RenderSurfaceImpl* render_surface = - GetRenderSurface(host_impl.active_tree()->LayerById(owning_layer_id)); + LayerTreeImplTestBase impl; + LayerImpl* root = impl.root_layer(); + + LayerImpl* layer = impl.AddLayer<LayerImpl>(); + CopyProperties(root, layer); + auto& effect_node = CreateEffectNode(layer); + effect_node.render_surface_reason = RenderSurfaceReason::kTest; + + UpdateDrawProperties(impl.host_impl()->active_tree()); + + RenderSurfaceImpl* render_surface = GetRenderSurface(layer); + ASSERT_TRUE(render_surface); gfx::Rect content_rect(0, 0, 50, 50); gfx::Transform origin; @@ -242,58 +210,37 @@ TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectRenderPass) { } TEST(RenderSurfaceTest, SanityCheckSurfaceIgnoreMaskLayerOcclusion) { - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink = - FakeLayerTreeFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); + LayerTreeImplTestBase impl; + LayerImpl* root = impl.root_layer(); // Set a big enough viewport to show the entire render pass. - host_impl.active_tree()->SetDeviceViewportRect(gfx::Rect(1000, 1000)); - - std::unique_ptr<LayerImpl> root_layer = - LayerImpl::Create(host_impl.active_tree(), 1); + impl.host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(1000, 1000)); - int owning_layer_id = 2; - std::unique_ptr<LayerImpl> owning_layer = - LayerImpl::Create(host_impl.active_tree(), owning_layer_id); + auto* layer = impl.AddLayer<LayerImpl>(); + layer->SetBounds(gfx::Size(200, 100)); + layer->SetDrawsContent(true); + CopyProperties(root, layer); + CreateEffectNode(layer); - int mask_layer_id = 3; - std::unique_ptr<FakePictureLayerImplForRenderSurfaceTest> mask_layer = - FakePictureLayerImplForRenderSurfaceTest::CreateMask( - host_impl.active_tree(), mask_layer_id); - - mask_layer->SetBounds(gfx::Size(200, 100)); + auto* mask_layer = impl.AddLayer<FakePictureLayerImplForRenderSurfaceTest>(); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(mask_layer->bounds())); - mask_layer->SetRasterSourceOnActive(raster_source, Region()); - mask_layer->SetDrawsContent(true); + mask_layer->SetRasterSource(raster_source, Region()); std::vector<gfx::Rect> quad_rects; quad_rects.push_back(gfx::Rect(0, 0, 100, 100)); quad_rects.push_back(gfx::Rect(100, 0, 100, 100)); mask_layer->SetQuadRectsForTesting(quad_rects); + SetupMaskProperties(layer, mask_layer); + + UpdateDrawProperties(impl.host_impl()->active_tree()); - owning_layer->SetBounds(gfx::Size(200, 100)); - owning_layer->SetDrawsContent(true); - owning_layer->test_properties()->SetMaskLayer(std::move(mask_layer)); - root_layer->test_properties()->AddChild(std::move(owning_layer)); - host_impl.active_tree()->SetRootLayerForTesting(std::move(root_layer)); - host_impl.SetVisible(true); - host_impl.InitializeFrameSink(layer_tree_frame_sink.get()); - host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl.active_tree()->UpdateDrawProperties(); - - RenderSurfaceImpl* render_surface = - GetRenderSurface(host_impl.active_tree()->LayerById(owning_layer_id)); + RenderSurfaceImpl* render_surface = GetRenderSurface(layer); ASSERT_TRUE(render_surface); gfx::Rect content_rect(0, 0, 200, 100); gfx::Rect occluded(0, 0, 200, 100); render_surface->SetContentRectForTesting(content_rect); - host_impl.active_tree() - ->LayerById(mask_layer_id) - ->draw_properties() - .occlusion_in_content_space = + mask_layer->draw_properties().occlusion_in_content_space = Occlusion(gfx::Transform(), SimpleEnclosedRegion(occluded), SimpleEnclosedRegion(occluded)); diff --git a/chromium/cc/layers/scrollbar_layer_base.cc b/chromium/cc/layers/scrollbar_layer_base.cc new file mode 100644 index 00000000000..14c743b9eb9 --- /dev/null +++ b/chromium/cc/layers/scrollbar_layer_base.cc @@ -0,0 +1,31 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/layers/scrollbar_layer_base.h" + +#include "cc/layers/scrollbar_layer_impl_base.h" + +namespace cc { + +ScrollbarLayerBase::ScrollbarLayerBase() { + SetIsScrollbar(true); +} + +ScrollbarLayerBase::~ScrollbarLayerBase() = default; + +void ScrollbarLayerBase::SetScrollElementId(ElementId element_id) { + if (element_id == scroll_element_id_) + return; + + scroll_element_id_ = element_id; + SetNeedsCommit(); +} + +void ScrollbarLayerBase::PushPropertiesTo(LayerImpl* layer) { + Layer::PushPropertiesTo(layer); + static_cast<ScrollbarLayerImplBase*>(layer)->SetScrollElementId( + scroll_element_id_); +} + +} // namespace cc diff --git a/chromium/cc/layers/scrollbar_layer_base.h b/chromium/cc/layers/scrollbar_layer_base.h new file mode 100644 index 00000000000..00c5dfa3491 --- /dev/null +++ b/chromium/cc/layers/scrollbar_layer_base.h @@ -0,0 +1,29 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_LAYERS_SCROLLBAR_LAYER_BASE_H_ +#define CC_LAYERS_SCROLLBAR_LAYER_BASE_H_ + +#include "cc/cc_export.h" +#include "cc/layers/layer.h" + +namespace cc { + +class CC_EXPORT ScrollbarLayerBase : public Layer { + public: + void SetScrollElementId(ElementId element_id); + + void PushPropertiesTo(LayerImpl* layer) override; + + protected: + ScrollbarLayerBase(); + ~ScrollbarLayerBase() override; + + private: + ElementId scroll_element_id_; +}; + +} // namespace cc + +#endif // CC_LAYERS_SCROLLBAR_LAYER_BASE_H_ diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.cc b/chromium/cc/layers/scrollbar_layer_impl_base.cc index 419b0517b81..45540e311a4 100644 --- a/chromium/cc/layers/scrollbar_layer_impl_base.cc +++ b/chromium/cc/layers/scrollbar_layer_impl_base.cc @@ -5,6 +5,8 @@ #include "cc/layers/scrollbar_layer_impl_base.h" #include <algorithm> + +#include "base/numerics/ranges.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/scroll_node.h" @@ -213,7 +215,7 @@ gfx::Rect ScrollbarLayerImplBase::ComputeThumbQuadRectWithThumbThicknessScale( float maximum = scroll_layer_length() - clip_layer_length(); // With the length known, we can compute the thumb's position. - float clamped_current_pos = std::min(std::max(current_pos(), 0.f), maximum); + float clamped_current_pos = base::ClampToRange(current_pos(), 0.0f, maximum); int thumb_offset = TrackStart(); if (maximum > 0) { @@ -282,6 +284,10 @@ bool ScrollbarLayerImplBase::HasFindInPageTickmarks() const { return false; } +bool ScrollbarLayerImplBase::SupportsDragSnapBack() const { + return false; +} + gfx::Rect ScrollbarLayerImplBase::BackButtonRect() const { return gfx::Rect(0, 0); } diff --git a/chromium/cc/layers/scrollbar_layer_impl_base.h b/chromium/cc/layers/scrollbar_layer_impl_base.h index b1c225235b5..fcb1096184d 100644 --- a/chromium/cc/layers/scrollbar_layer_impl_base.h +++ b/chromium/cc/layers/scrollbar_layer_impl_base.h @@ -72,6 +72,7 @@ class CC_EXPORT ScrollbarLayerImplBase : public LayerImpl { virtual gfx::Rect ForwardButtonRect() const; virtual gfx::Rect BackTrackRect() const; virtual gfx::Rect ForwardTrackRect() const; + virtual bool SupportsDragSnapBack() const; virtual ScrollbarPart IdentifyScrollbarPart( const gfx::PointF position_in_widget) const; // Only PaintedOverlayScrollbar(Aura Overlay Scrollbar) need to know diff --git a/chromium/cc/layers/scrollbar_layer_interface.h b/chromium/cc/layers/scrollbar_layer_interface.h deleted file mode 100644 index 661028e4a9a..00000000000 --- a/chromium/cc/layers/scrollbar_layer_interface.h +++ /dev/null @@ -1,27 +0,0 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CC_LAYERS_SCROLLBAR_LAYER_INTERFACE_H_ -#define CC_LAYERS_SCROLLBAR_LAYER_INTERFACE_H_ - -#include "cc/cc_export.h" -#include "cc/input/scrollbar.h" - -namespace cc { - -class CC_EXPORT ScrollbarLayerInterface { - public: - ScrollbarLayerInterface(const ScrollbarLayerInterface&) = delete; - ScrollbarLayerInterface& operator=(const ScrollbarLayerInterface&) = delete; - - virtual void SetScrollElementId(ElementId element_id) = 0; - - protected: - ScrollbarLayerInterface() {} - virtual ~ScrollbarLayerInterface() {} -}; - -} // namespace cc - -#endif // CC_LAYERS_SCROLLBAR_LAYER_INTERFACE_H_ diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc index 39740d0633e..98a5011c0c3 100644 --- a/chromium/cc/layers/scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/scrollbar_layer_unittest.cc @@ -13,7 +13,7 @@ #include "cc/layers/painted_overlay_scrollbar_layer.h" #include "cc/layers/painted_scrollbar_layer.h" #include "cc/layers/painted_scrollbar_layer_impl.h" -#include "cc/layers/scrollbar_layer_interface.h" +#include "cc/layers/scrollbar_layer_base.h" #include "cc/layers/solid_color_scrollbar_layer.h" #include "cc/layers/solid_color_scrollbar_layer_impl.h" #include "cc/resources/ui_resource_manager.h" @@ -24,14 +24,13 @@ #include "cc/test/fake_painted_scrollbar_layer.h" #include "cc/test/fake_scrollbar.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/test/layer_tree_test.h" #include "cc/test/mock_occlusion_tracker.h" #include "cc/test/stub_layer_tree_host_single_thread_client.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/occlusion_tracker.h" #include "cc/trees/scroll_node.h" @@ -145,16 +144,16 @@ class BaseScrollbarLayerTest : public testing::Test { int track_start) { scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> child1 = Layer::Create(); - scoped_refptr<Layer> child2; + scoped_refptr<ScrollbarLayerBase> child2; if (use_solid_color_scrollbar) { const bool kIsLeftSideVerticalScrollbar = false; - child2 = SolidColorScrollbarLayer::Create( - scrollbar->Orientation(), thumb_thickness, track_start, - kIsLeftSideVerticalScrollbar, child1->element_id()); + child2 = SolidColorScrollbarLayer::Create(scrollbar->Orientation(), + thumb_thickness, track_start, + kIsLeftSideVerticalScrollbar); } else { - child2 = PaintedScrollbarLayer::Create(std::move(scrollbar), - child1->element_id()); + child2 = PaintedScrollbarLayer::Create(std::move(scrollbar)); } + child2->SetScrollElementId(child1->element_id()); layer_tree_root->AddChild(child1); layer_tree_root->InsertChild(child2, reverse_order ? 0 : 1); scrollbar_layer_id_ = reverse_order ? child1->id() : child2->id(); @@ -208,8 +207,8 @@ TEST_F(ScrollbarLayerTest, RepaintOverlayWhenResourceDisposed) { new FakePaintedOverlayScrollbar); FakePaintedOverlayScrollbar* fake_scrollbar = scrollbar.get(); scoped_refptr<PaintedOverlayScrollbarLayer> scrollbar_layer = - PaintedOverlayScrollbarLayer::Create(std::move(scrollbar), - layer_tree_root->element_id()); + PaintedOverlayScrollbarLayer::Create(std::move(scrollbar)); + scrollbar_layer->SetScrollElementId(layer_tree_root->element_id()); // Setup. { @@ -255,6 +254,9 @@ TEST_F(ScrollbarLayerTest, RepaintOverlayWhenResourceDisposed) { class FakeNinePatchScrollbar : public FakeScrollbar { public: + FakeNinePatchScrollbar() + : FakeScrollbar(/*paint*/ true, /*has_thumb*/ true, /*is_overlay*/ true) { + } bool UsesNinePatchThumbResource() const override { return true; } }; @@ -268,14 +270,14 @@ TEST_F(ScrollbarLayerTest, ScrollElementIdPushedAcrossCommit) { layer_b->SetElementId(LayerIdToElementIdForTesting(layer_b->id())); scoped_refptr<PaintedScrollbarLayer> painted_scrollbar_layer = - PaintedScrollbarLayer::Create(std::move(scrollbar1), - layer_a->element_id()); + PaintedScrollbarLayer::Create(std::move(scrollbar1)); + painted_scrollbar_layer->SetScrollElementId(layer_a->element_id()); scoped_refptr<PaintedOverlayScrollbarLayer> painted_overlay_scrollbar_layer = - PaintedOverlayScrollbarLayer::Create(std::move(scrollbar2), - layer_a->element_id()); + PaintedOverlayScrollbarLayer::Create(std::move(scrollbar2)); + painted_overlay_scrollbar_layer->SetScrollElementId(layer_a->element_id()); scoped_refptr<SolidColorScrollbarLayer> solid_color_scrollbar_layer = - SolidColorScrollbarLayer::Create(VERTICAL, 1, 1, false, - layer_a->element_id()); + SolidColorScrollbarLayer::Create(VERTICAL, 1, 1, false); + solid_color_scrollbar_layer->SetScrollElementId(layer_a->element_id()); layer_tree_host_->SetRootLayer(layer_tree_root); layer_tree_root->AddChild(layer_a); @@ -334,8 +336,9 @@ TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) { scoped_refptr<Layer> scroll_layer = Layer::Create(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); scoped_refptr<Layer> content_layer = Layer::Create(); - scoped_refptr<Layer> scrollbar_layer = PaintedScrollbarLayer::Create( - std::move(scrollbar), scroll_layer->element_id()); + scoped_refptr<PaintedScrollbarLayer> scrollbar_layer = + PaintedScrollbarLayer::Create(std::move(scrollbar)); + scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); // Choose bounds to give max_scroll_offset = (30, 50). layer_tree_root->SetBounds(gfx::Size(70, 150)); @@ -635,11 +638,12 @@ TEST_F(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) { scoped_refptr<Layer> scroll_layer = Layer::Create(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); scoped_refptr<Layer> child1 = Layer::Create(); - scoped_refptr<Layer> child2; const bool kIsLeftSideVerticalScrollbar = false; - child2 = SolidColorScrollbarLayer::Create( - scrollbar->Orientation(), kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, scroll_layer->element_id()); + scoped_refptr<SolidColorScrollbarLayer> child2 = + SolidColorScrollbarLayer::Create(scrollbar->Orientation(), + kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar); + child2->SetScrollElementId(scroll_layer->element_id()); scroll_layer->AddChild(child1); scroll_layer->InsertChild(child2, 1); layer_tree_root->AddChild(scroll_layer); @@ -695,7 +699,8 @@ TEST_F(ScrollbarLayerTest, ScrollbarLayerOpacity) { const bool kIsLeftSideVerticalScrollbar = false; scrollbar_layer = SolidColorScrollbarLayer::Create( scrollbar->Orientation(), kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, scroll_layer->element_id()); + kIsLeftSideVerticalScrollbar); + scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); scrollbar_layer->SetElementId(ElementId(300)); scroll_layer->AddChild(child1); scroll_layer->InsertChild(scrollbar_layer, 1); @@ -768,11 +773,12 @@ TEST_F(ScrollbarLayerTest, ScrollbarLayerPushProperties) { scoped_refptr<Layer> scroll_layer = Layer::Create(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); scoped_refptr<Layer> child1 = Layer::Create(); - scoped_refptr<Layer> scrollbar_layer; const bool kIsLeftSideVerticalScrollbar = false; - scrollbar_layer = SolidColorScrollbarLayer::Create( - scrollbar->Orientation(), kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, scroll_layer->element_id()); + scoped_refptr<SolidColorScrollbarLayer> scrollbar_layer = + SolidColorScrollbarLayer::Create(scrollbar->Orientation(), + kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar); + scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); scroll_layer->AddChild(child1); scroll_layer->InsertChild(scrollbar_layer, 1); layer_tree_root->AddChild(scroll_layer); @@ -805,65 +811,58 @@ TEST_F(ScrollbarLayerTest, ScrollbarLayerPushProperties) { TEST_F(ScrollbarLayerTest, SubPixelCanScrollOrientation) { gfx::Size viewport_size(980, 980); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; - LayerImpl* scroll_layer = impl.AddChildToRoot<LayerImpl>(); + LayerImpl* scroll_layer = impl.AddLayer<LayerImpl>(); scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); const int kTrackStart = 0; const int kThumbThickness = 10; const bool kIsLeftSideVerticalScrollbar = false; - const bool kIsOverlayScrollbar = false; SolidColorScrollbarLayerImpl* scrollbar_layer = - impl.AddChild<SolidColorScrollbarLayerImpl>( - scroll_layer, HORIZONTAL, kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); + impl.AddLayer<SolidColorScrollbarLayerImpl>(HORIZONTAL, kThumbThickness, + kTrackStart, + kIsLeftSideVerticalScrollbar); scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); scroll_layer->SetScrollable(gfx::Size(980, 980)); scroll_layer->SetBounds(gfx::Size(980, 980)); - impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(impl.root_layer(), scroll_layer); + CreateTransformNode(scroll_layer); + CreateScrollNode(scroll_layer); + CopyProperties(scroll_layer, scrollbar_layer); + DCHECK(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); - impl.CalcDrawProps(viewport_size); // Fake clip layer length to scrollbar to mock rounding error. scrollbar_layer->SetClipLayerLength(979.999939f); - impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); + impl.CalcDrawProps(viewport_size); EXPECT_FALSE(scrollbar_layer->CanScrollOrientation()); // Fake clip layer length to scrollable. scrollbar_layer->SetClipLayerLength(979.0f); - impl.host_impl()->active_tree()->BuildPropertyTreesForTesting(); + impl.CalcDrawProps(viewport_size); EXPECT_TRUE(scrollbar_layer->CanScrollOrientation()); } TEST_F(ScrollbarLayerTest, LayerChangesAffectingScrollbarGeometries) { - LayerTestCommon::LayerImplTest impl; - - LayerImpl* clip_layer = impl.AddChildToRoot<LayerImpl>(); - LayerImpl* scroll_layer = impl.AddChild<LayerImpl>(clip_layer); - scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); - - // Make clip_layer the inner viewport container layer. This ensures the later - // call to |SetViewportBoundsDelta| will be on a viewport layer. - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.inner_viewport_container = clip_layer->id(); - impl.host_impl()->active_tree()->SetViewportLayersFromIds(viewport_ids); + LayerTreeImplTestBase impl; + SetupViewport(impl.root_layer(), gfx::Size(), gfx::Size(900, 900)); + auto* scroll_layer = impl.OuterViewportScrollLayer(); const int kTrackStart = 0; const int kThumbThickness = 10; const bool kIsLeftSideVerticalScrollbar = false; - const bool kIsOverlayScrollbar = false; SolidColorScrollbarLayerImpl* scrollbar_layer = - impl.AddChild<SolidColorScrollbarLayerImpl>( - scroll_layer, HORIZONTAL, kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, kIsOverlayScrollbar); + impl.AddLayer<SolidColorScrollbarLayerImpl>(HORIZONTAL, kThumbThickness, + kTrackStart, + kIsLeftSideVerticalScrollbar); scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); @@ -878,28 +877,16 @@ TEST_F(ScrollbarLayerTest, LayerChangesAffectingScrollbarGeometries) { EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); - clip_layer->SetBounds(gfx::Size(900, 900)); - // The clip layer for scrolling is managed independently of the scroll - // container bounds so changing the clip does not require an update. - EXPECT_FALSE( - impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); - scroll_layer->SetBounds(gfx::Size(980, 980)); // Changes to the bounds should also require an update. EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); - clip_layer->SetViewportBoundsDelta(gfx::Vector2dF(1, 2)); - EXPECT_TRUE(impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); - impl.host_impl()->active_tree()->UpdateScrollbarGeometries(); - // Not changing the current value should not require an update. scroll_layer->SetScrollable(gfx::Size(900, 900)); - clip_layer->SetBounds(gfx::Size(900, 900)); scroll_layer->SetBounds(gfx::Size(980, 980)); - clip_layer->SetViewportBoundsDelta(gfx::Vector2dF(1, 2)); - EXPECT_TRUE( - !impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); + EXPECT_FALSE( + impl.host_impl()->active_tree()->ScrollbarGeometriesNeedUpdate()); } TEST_F(AuraScrollbarLayerTest, ScrollbarLayerCreateAfterSetScrollable) { @@ -929,9 +916,11 @@ TEST_F(AuraScrollbarLayerTest, ScrollbarLayerCreateAfterSetScrollable) { host_impl->ActivateSyncTree(); std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true)); - scoped_refptr<Layer> scrollbar_layer = SolidColorScrollbarLayer::Create( - scrollbar->Orientation(), kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, scroll_layer->element_id()); + scoped_refptr<SolidColorScrollbarLayer> scrollbar_layer = + SolidColorScrollbarLayer::Create(scrollbar->Orientation(), + kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar); + scrollbar_layer->SetScrollElementId(scroll_layer->element_id()); scroll_layer->InsertChild(scrollbar_layer, 1); layer_tree_host_->UpdateLayers(); @@ -957,24 +946,13 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { const int kThumbThickness = 3; const int kTrackStart = 0; const bool kIsLeftSideVerticalScrollbar = false; - const bool kIsOverlayScrollbar = false; - - horizontal_scrollbar_layer_ = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - 1, - HORIZONTAL, - kThumbThickness, - kTrackStart, - kIsLeftSideVerticalScrollbar, - kIsOverlayScrollbar); - vertical_scrollbar_layer_ = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - 2, - VERTICAL, - kThumbThickness, - kTrackStart, - kIsLeftSideVerticalScrollbar, - kIsOverlayScrollbar); + + horizontal_scrollbar_layer_ = SolidColorScrollbarLayerImpl::Create( + host_impl_->active_tree(), 1, HORIZONTAL, kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar); + vertical_scrollbar_layer_ = SolidColorScrollbarLayerImpl::Create( + host_impl_->active_tree(), 2, VERTICAL, kThumbThickness, kTrackStart, + kIsLeftSideVerticalScrollbar); } protected: @@ -1060,26 +1038,24 @@ class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest { std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false)); scoped_refptr<Layer> layer_tree_root = Layer::Create(); scoped_refptr<Layer> content_layer = Layer::Create(); - scoped_refptr<Layer> scrollbar_layer; + scoped_refptr<ScrollbarLayerBase> scrollbar_layer; if (use_solid_color_scrollbar) { const int kThumbThickness = 3; const int kTrackStart = 0; const bool kIsLeftSideVerticalScrollbar = false; scrollbar_layer = SolidColorScrollbarLayer::Create( scrollbar->Orientation(), kThumbThickness, kTrackStart, - kIsLeftSideVerticalScrollbar, layer_tree_root->element_id()); + kIsLeftSideVerticalScrollbar); } else { - scrollbar_layer = PaintedScrollbarLayer::Create( - std::move(scrollbar), layer_tree_root->element_id()); + scrollbar_layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); } + scrollbar_layer->SetScrollElementId(layer_tree_root->element_id()); layer_tree_root->AddChild(content_layer); layer_tree_root->AddChild(scrollbar_layer); layer_tree_host_->SetRootLayer(layer_tree_root); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - layer_tree_root.get(), layer_tree_host_->device_viewport_rect()); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateDrawProperties(layer_tree_host_.get()); scrollbar_layer->SetIsDrawable(true); scrollbar_layer->SetBounds(gfx::Size(100, 100)); @@ -1138,10 +1114,7 @@ TEST_F(ScrollbarLayerTestResourceCreationAndRelease, TestResourceUpdate) { layer_tree_root->AddChild(scrollbar_layer); layer_tree_host_->SetRootLayer(layer_tree_root); - - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - layer_tree_root.get(), layer_tree_host_->device_viewport_rect()); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateDrawProperties(layer_tree_host_.get()); scrollbar_layer->SetIsDrawable(true); scrollbar_layer->SetBounds(gfx::Size(100, 15)); @@ -1312,10 +1285,7 @@ class ScaledScrollbarLayerTestResourceCreation : public ScrollbarLayerTest { EXPECT_EQ(scrollbar_layer->layer_tree_host(), layer_tree_host_.get()); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - layer_tree_root.get(), layer_tree_host_->device_viewport_rect()); - inputs.device_scale_factor = test_scale; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateDrawProperties(layer_tree_host_.get()); layer_tree_host_->SetViewportRectAndScale( layer_tree_host_->device_viewport_rect(), test_scale, @@ -1380,15 +1350,13 @@ class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest { scrollbar_layer->SetBounds(scrollbar_rect.size()); scrollbar_layer->SetPosition(gfx::PointF(scrollbar_rect.origin())); scrollbar_layer->fake_scrollbar()->set_location(scrollbar_rect.origin()); - scrollbar_layer->fake_scrollbar()->set_track_rect(scrollbar_rect); + scrollbar_layer->fake_scrollbar()->set_track_rect( + gfx::Rect(scrollbar_rect.size())); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - layer_tree_root.get(), layer_tree_host_->device_viewport_rect()); - inputs.device_scale_factor = test_scale; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); layer_tree_host_->SetViewportRectAndScale( layer_tree_host_->device_viewport_rect(), test_scale, layer_tree_host_->local_surface_id_allocation_from_parent()); + UpdateDrawProperties(layer_tree_host_.get()); scrollbar_layer->Update(); diff --git a/chromium/cc/layers/scrollbar_theme_painter.h b/chromium/cc/layers/scrollbar_theme_painter.h deleted file mode 100644 index 2733f44d42d..00000000000 --- a/chromium/cc/layers/scrollbar_theme_painter.h +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CC_LAYERS_SCROLLBAR_THEME_PAINTER_H_ -#define CC_LAYERS_SCROLLBAR_THEME_PAINTER_H_ - -#include "cc/cc_export.h" - -class SkCanvas; - -namespace gfx { -class Rect; -} - -namespace cc { - -class CC_EXPORT ScrollbarThemePainter { - public: - virtual ~ScrollbarThemePainter() {} - - virtual void PaintScrollbarBackground(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintTrackBackground(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintBackTrackPart(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintForwardTrackPart(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintBackButtonStart(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintBackButtonEnd(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintForwardButtonStart(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintForwardButtonEnd(SkCanvas* canvas, - const gfx::Rect& rect) = 0; - virtual void PaintTickmarks(SkCanvas* canvas, const gfx::Rect& rect) = 0; - virtual void PaintThumb(SkCanvas* canvas, const gfx::Rect& rect) = 0; -}; - -} // namespace cc - -#endif // CC_LAYERS_SCROLLBAR_THEME_PAINTER_H_ diff --git a/chromium/cc/layers/solid_color_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_layer_impl_unittest.cc index 5d1c3068a60..1e5bb9af082 100644 --- a/chromium/cc/layers/solid_color_layer_impl_unittest.cc +++ b/chromium/cc/layers/solid_color_layer_impl_unittest.cc @@ -11,12 +11,7 @@ #include "cc/animation/animation_host.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/solid_color_layer.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_host.h" -#include "cc/test/layer_test_common.h" -#include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_common.h" -#include "cc/trees/single_thread_proxy.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "components/viz/common/quads/solid_color_draw_quad.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -24,55 +19,48 @@ namespace cc { namespace { -TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) { +class SolidColorLayerImplTest : public LayerTreeImplTestBase, + public ::testing::Test {}; + +TEST_F(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) { std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_size = gfx::Size(800, 600); gfx::Rect visible_layer_rect = gfx::Rect(layer_size); + root_layer()->SetBounds(layer_size); - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<SolidColorLayerImpl> layer = - SolidColorLayerImpl::Create(host_impl.active_tree(), 1); - layer->draw_properties().visible_layer_rect = visible_layer_rect; - layer->draw_properties().opacity = 1.f; + auto* layer = AddLayer<SolidColorLayerImpl>(); layer->SetBounds(layer_size); + layer->SetDrawsContent(true); layer->SetBackgroundColor(SK_ColorRED); - layer->test_properties()->force_render_surface = true; - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root_layer(), layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; + UpdateActiveTreeDrawProperties(); AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + layer->AppendQuads(render_pass.get(), &data); - LayerTestCommon::VerifyQuadsExactlyCoverRect(render_pass->quad_list, - visible_layer_rect); + VerifyQuadsExactlyCoverRect(render_pass->quad_list, visible_layer_rect); } -TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { +TEST_F(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { SkColor test_color = 0xFFA55AFF; - std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); - gfx::Size layer_size = gfx::Size(100, 100); gfx::Rect visible_layer_rect = gfx::Rect(layer_size); + root_layer()->SetBounds(layer_size); - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<SolidColorLayerImpl> layer = - SolidColorLayerImpl::Create(host_impl.active_tree(), 1); - layer->draw_properties().visible_layer_rect = visible_layer_rect; - layer->draw_properties().opacity = 1.f; + auto* layer = AddLayer<SolidColorLayerImpl>(); layer->SetBounds(layer_size); + layer->SetDrawsContent(true); layer->SetBackgroundColor(test_color); - layer->test_properties()->force_render_surface = true; - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root_layer(), layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; + UpdateActiveTreeDrawProperties(); + + EXPECT_EQ(visible_layer_rect, layer->draw_properties().visible_layer_rect); + AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + layer->AppendQuads(render_pass.get(), &data); ASSERT_EQ(render_pass->quad_list.size(), 1U); EXPECT_EQ( @@ -81,29 +69,24 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { test_color); } -TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { +TEST_F(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { const float opacity = 0.5f; - std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); - gfx::Size layer_size = gfx::Size(100, 100); - gfx::Rect visible_layer_rect = gfx::Rect(layer_size); - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<SolidColorLayerImpl> layer = - SolidColorLayerImpl::Create(host_impl.active_tree(), 1); - layer->draw_properties().visible_layer_rect = visible_layer_rect; + auto* layer = AddLayer<SolidColorLayerImpl>(); + layer->SetDrawsContent(true); layer->SetBounds(layer_size); - layer->draw_properties().opacity = opacity; - layer->test_properties()->force_render_surface = true; layer->SetBackgroundColor(SK_ColorRED); - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root_layer(), layer); + auto& effect_node = CreateEffectNode(layer); + effect_node.opacity = opacity; + UpdateActiveTreeDrawProperties(); + + EXPECT_EQ(opacity, layer->draw_properties().opacity); + AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + layer->AppendQuads(render_pass.get(), &data); ASSERT_EQ(render_pass->quad_list.size(), 1U); EXPECT_EQ(opacity, viz::SolidColorDrawQuad::MaterialCast( @@ -112,61 +95,74 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { EXPECT_TRUE(render_pass->quad_list.front()->ShouldDrawWithBlending()); } -TEST(SolidColorLayerImplTest, VerifyEliminateTransparentAlpha) { - SkColor test_color = 0; - +TEST_F(SolidColorLayerImplTest, VerifyCorrectRenderSurfaceOpacityInQuad) { + const float opacity = 0.5f; std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); + gfx::Size layer_size = gfx::Size(100, 100); + + auto* layer = AddLayer<SolidColorLayerImpl>(); + layer->SetDrawsContent(true); + layer->SetBounds(layer_size); + layer->SetBackgroundColor(SK_ColorRED); + CopyProperties(root_layer(), layer); + auto& effect_node = CreateEffectNode(layer); + effect_node.render_surface_reason = RenderSurfaceReason::kTest; + effect_node.opacity = opacity; + UpdateActiveTreeDrawProperties(); + // Opacity is applied on render surface, so the layer doesn't have opacity. + EXPECT_EQ(1.f, layer->draw_properties().opacity); + + AppendQuadsData data; + layer->AppendQuads(render_pass.get(), &data); + + ASSERT_EQ(render_pass->quad_list.size(), 1U); + // Opacity is applied on render surface, so the quad doesn't have opacity. + EXPECT_EQ( + 1.f, viz::SolidColorDrawQuad::MaterialCast(render_pass->quad_list.front()) + ->shared_quad_state->opacity); + EXPECT_FALSE(render_pass->quad_list.front()->ShouldDrawWithBlending()); +} + +TEST_F(SolidColorLayerImplTest, VerifyEliminateTransparentAlpha) { + SkColor test_color = 0; + std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); gfx::Size layer_size = gfx::Size(100, 100); - gfx::Rect visible_layer_rect = gfx::Rect(layer_size); - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<SolidColorLayerImpl> layer = - SolidColorLayerImpl::Create(host_impl.active_tree(), 1); - layer->draw_properties().visible_layer_rect = visible_layer_rect; - layer->draw_properties().opacity = 1.f; + auto* layer = AddLayer<SolidColorLayerImpl>(); layer->SetBounds(layer_size); + layer->SetDrawsContent(true); layer->SetBackgroundColor(test_color); - layer->test_properties()->force_render_surface = true; - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); - AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + CopyProperties(root_layer(), layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; + UpdateActiveTreeDrawProperties(); + AppendQuadsData data; + layer->AppendQuads(render_pass.get(), &data); EXPECT_EQ(render_pass->quad_list.size(), 0U); } -TEST(SolidColorLayerImplTest, VerifyEliminateTransparentOpacity) { +TEST_F(SolidColorLayerImplTest, VerifyEliminateTransparentOpacity) { SkColor test_color = 0xFFA55AFF; - std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); - gfx::Size layer_size = gfx::Size(100, 100); - gfx::Rect visible_layer_rect = gfx::Rect(layer_size); - FakeImplTaskRunnerProvider task_runner_provider; - TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); - std::unique_ptr<SolidColorLayerImpl> layer = - SolidColorLayerImpl::Create(host_impl.active_tree(), 1); - layer->draw_properties().visible_layer_rect = visible_layer_rect; - layer->draw_properties().opacity = 0.f; + auto* layer = AddLayer<SolidColorLayerImpl>(); layer->SetBounds(layer_size); + layer->SetDrawsContent(true); layer->SetBackgroundColor(test_color); - layer->test_properties()->force_render_surface = true; - host_impl.active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl.active_tree()->BuildPropertyTreesForTesting(); - AppendQuadsData data; - host_impl.active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + CopyProperties(root_layer(), layer); + auto& effect_node = CreateEffectNode(layer); + effect_node.render_surface_reason = RenderSurfaceReason::kTest; + effect_node.opacity = 0.f; + UpdateActiveTreeDrawProperties(); + AppendQuadsData data; + layer->AppendQuads(render_pass.get(), &data); EXPECT_EQ(render_pass->quad_list.size(), 0U); } -TEST(SolidColorLayerImplTest, VerifyNeedsBlending) { +TEST_F(SolidColorLayerImplTest, VerifyNeedsBlending) { gfx::Size layer_size = gfx::Size(100, 100); scoped_refptr<SolidColorLayer> layer = SolidColorLayer::Create(); @@ -183,9 +179,7 @@ TEST(SolidColorLayerImplTest, VerifyNeedsBlending) { &client, &task_graph_runner, animation_host.get()); host->SetRootLayer(root); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - root.get(), gfx::Rect(500, 500)); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateDrawProperties(host.get()); EXPECT_FALSE(layer->contents_opaque()); layer->SetBackgroundColor(SkColorSetARGB(255, 10, 20, 30)); @@ -242,49 +236,45 @@ TEST(SolidColorLayerImplTest, VerifyNeedsBlending) { } } -TEST(SolidColorLayerImplTest, Occlusion) { +TEST_F(SolidColorLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; - - SolidColorLayerImpl* solid_color_layer_impl = - impl.AddChildToRoot<SolidColorLayerImpl>(); + auto* solid_color_layer_impl = AddLayer<SolidColorLayerImpl>(); solid_color_layer_impl->SetBackgroundColor(SkColorSetARGB(255, 10, 20, 30)); solid_color_layer_impl->SetBounds(layer_size); solid_color_layer_impl->SetDrawsContent(true); + CopyProperties(root_layer(), solid_color_layer_impl); - impl.CalcDrawProps(viewport_size); + CalcDrawProps(viewport_size); { SCOPED_TRACE("No occlusion"); gfx::Rect occluded; - impl.AppendQuadsWithOcclusion(solid_color_layer_impl, occluded); + AppendQuadsWithOcclusion(solid_color_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); - EXPECT_EQ(1u, impl.quad_list().size()); + VerifyQuadsExactlyCoverRect(quad_list(), gfx::Rect(layer_size)); + EXPECT_EQ(1u, quad_list().size()); } { SCOPED_TRACE("Full occlusion"); gfx::Rect occluded(solid_color_layer_impl->visible_layer_rect()); - impl.AppendQuadsWithOcclusion(solid_color_layer_impl, occluded); + AppendQuadsWithOcclusion(solid_color_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); - EXPECT_EQ(impl.quad_list().size(), 0u); + VerifyQuadsExactlyCoverRect(quad_list(), gfx::Rect()); + EXPECT_EQ(quad_list().size(), 0u); } { SCOPED_TRACE("Partial occlusion"); gfx::Rect occluded(200, 0, 800, 1000); - impl.AppendQuadsWithOcclusion(solid_color_layer_impl, occluded); + AppendQuadsWithOcclusion(solid_color_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(quad_list(), occluded, &partially_occluded_count); // 4 quads are completely occluded, 8 are partially occluded. - EXPECT_EQ(1u, impl.quad_list().size()); + EXPECT_EQ(1u, quad_list().size()); EXPECT_EQ(1u, partially_occluded_count); } } diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.cc b/chromium/cc/layers/solid_color_scrollbar_layer.cc index e91ad78fd38..92e321f2d67 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer.cc +++ b/chromium/cc/layers/solid_color_scrollbar_layer.cc @@ -13,54 +13,31 @@ namespace cc { std::unique_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { - const bool kIsOverlayScrollbar = true; - return SolidColorScrollbarLayerImpl::Create( - tree_impl, id(), solid_color_scrollbar_layer_inputs_.orientation, - solid_color_scrollbar_layer_inputs_.thumb_thickness, - solid_color_scrollbar_layer_inputs_.track_start, - solid_color_scrollbar_layer_inputs_.is_left_side_vertical_scrollbar, - kIsOverlayScrollbar); + return SolidColorScrollbarLayerImpl::Create(tree_impl, id(), orientation_, + thumb_thickness_, track_start_, + is_left_side_vertical_scrollbar_); } scoped_refptr<SolidColorScrollbarLayer> SolidColorScrollbarLayer::Create( ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - ElementId scroll_element_id) { - return base::WrapRefCounted(new SolidColorScrollbarLayer( - orientation, thumb_thickness, track_start, - is_left_side_vertical_scrollbar, scroll_element_id)); + bool is_left_side_vertical_scrollbar) { + return base::WrapRefCounted( + new SolidColorScrollbarLayer(orientation, thumb_thickness, track_start, + is_left_side_vertical_scrollbar)); } -SolidColorScrollbarLayer::SolidColorScrollbarLayerInputs:: - SolidColorScrollbarLayerInputs(ScrollbarOrientation orientation, - int thumb_thickness, - int track_start, - bool is_left_side_vertical_scrollbar, - ElementId scroll_element_id) - : scroll_element_id(scroll_element_id), - orientation(orientation), - thumb_thickness(thumb_thickness), - track_start(track_start), - is_left_side_vertical_scrollbar(is_left_side_vertical_scrollbar) {} - -SolidColorScrollbarLayer::SolidColorScrollbarLayerInputs:: - ~SolidColorScrollbarLayerInputs() = default; - SolidColorScrollbarLayer::SolidColorScrollbarLayer( ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - ElementId scroll_element_id) - : solid_color_scrollbar_layer_inputs_(orientation, - thumb_thickness, - track_start, - is_left_side_vertical_scrollbar, - scroll_element_id) { + bool is_left_side_vertical_scrollbar) + : orientation_(orientation), + thumb_thickness_(thumb_thickness), + track_start_(track_start), + is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar) { Layer::SetOpacity(0.f); - SetIsScrollbar(true); } SolidColorScrollbarLayer::~SolidColorScrollbarLayer() = default; @@ -71,17 +48,6 @@ void SolidColorScrollbarLayer::SetOpacity(float opacity) { Layer::SetOpacity(opacity); } -void SolidColorScrollbarLayer::PushPropertiesTo(LayerImpl* layer) { - Layer::PushPropertiesTo(layer); - SolidColorScrollbarLayerImpl* scrollbar_layer = - static_cast<SolidColorScrollbarLayerImpl*>(layer); - - DCHECK(!scrollbar_layer->HitTestable()); - - scrollbar_layer->SetScrollElementId( - solid_color_scrollbar_layer_inputs_.scroll_element_id); -} - void SolidColorScrollbarLayer::SetNeedsDisplayRect(const gfx::Rect& rect) { // Never needs repaint. } @@ -90,14 +56,6 @@ bool SolidColorScrollbarLayer::OpacityCanAnimateOnImplThread() const { return true; } -void SolidColorScrollbarLayer::SetScrollElementId(ElementId element_id) { - if (element_id == solid_color_scrollbar_layer_inputs_.scroll_element_id) - return; - - solid_color_scrollbar_layer_inputs_.scroll_element_id = element_id; - SetNeedsCommit(); -} - bool SolidColorScrollbarLayer::HitTestable() const { // Android scrollbars can't be interacted with by user input. They should // avoid hit testing so we don't enter any scrollbar scrolling code paths. diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.h b/chromium/cc/layers/solid_color_scrollbar_layer.h index 0b937b48b09..8aed2f50026 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer.h +++ b/chromium/cc/layers/solid_color_scrollbar_layer.h @@ -7,12 +7,11 @@ #include "cc/cc_export.h" #include "cc/layers/layer.h" -#include "cc/layers/scrollbar_layer_interface.h" +#include "cc/layers/scrollbar_layer_base.h" namespace cc { -class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, - public Layer { +class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerBase { public: std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; @@ -20,53 +19,28 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - ElementId scroll_element_id); + bool is_left_side_vertical_scrollbar); SolidColorScrollbarLayer(const SolidColorScrollbarLayer&) = delete; SolidColorScrollbarLayer& operator=(const SolidColorScrollbarLayer&) = delete; // Layer overrides. bool OpacityCanAnimateOnImplThread() const override; - void SetOpacity(float opacity) override; - void PushPropertiesTo(LayerImpl* layer) override; - void SetNeedsDisplayRect(const gfx::Rect& rect) override; - bool HitTestable() const override; - // ScrollbarLayerInterface - void SetScrollElementId(ElementId element_id) override; - protected: SolidColorScrollbarLayer(ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - ElementId scroll_element_id); + bool is_left_side_vertical_scrollbar); ~SolidColorScrollbarLayer() override; - private: - friend class LayerSerializationTest; - - // Encapsulate all data, callbacks, interfaces received from the embedder. - struct SolidColorScrollbarLayerInputs { - SolidColorScrollbarLayerInputs(ScrollbarOrientation orientation, - int thumb_thickness, - int track_start, - bool is_left_side_vertical_scrollbar, - ElementId scroll_element_id); - ~SolidColorScrollbarLayerInputs(); - - ElementId scroll_element_id; - ScrollbarOrientation orientation; - int thumb_thickness; - int track_start; - bool is_left_side_vertical_scrollbar; - }; - - SolidColorScrollbarLayerInputs solid_color_scrollbar_layer_inputs_; + ScrollbarOrientation orientation_; + int thumb_thickness_; + int track_start_; + bool is_left_side_vertical_scrollbar_; }; } // namespace cc diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc index b96e4bc3b68..e37741cdc5d 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc +++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.cc @@ -18,24 +18,19 @@ SolidColorScrollbarLayerImpl::Create(LayerTreeImpl* tree_impl, ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - bool is_overlay) { + bool is_left_side_vertical_scrollbar) { return base::WrapUnique(new SolidColorScrollbarLayerImpl( tree_impl, id, orientation, thumb_thickness, track_start, - is_left_side_vertical_scrollbar, is_overlay)); + is_left_side_vertical_scrollbar)); } SolidColorScrollbarLayerImpl::~SolidColorScrollbarLayerImpl() = default; std::unique_ptr<LayerImpl> SolidColorScrollbarLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { - return SolidColorScrollbarLayerImpl::Create(tree_impl, - id(), - orientation(), - thumb_thickness_, - track_start_, - is_left_side_vertical_scrollbar(), - is_overlay_scrollbar()); + return SolidColorScrollbarLayerImpl::Create( + tree_impl, id(), orientation(), thumb_thickness_, track_start_, + is_left_side_vertical_scrollbar()); } SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl( @@ -44,17 +39,15 @@ SolidColorScrollbarLayerImpl::SolidColorScrollbarLayerImpl( ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - bool is_overlay) + bool is_left_side_vertical_scrollbar) : ScrollbarLayerImplBase(tree_impl, id, orientation, is_left_side_vertical_scrollbar, - is_overlay), + /*is_overlay*/ true), thumb_thickness_(thumb_thickness), track_start_(track_start), - color_(tree_impl->settings().solid_color_scrollbar_color) { -} + color_(tree_impl->settings().solid_color_scrollbar_color) {} void SolidColorScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { ScrollbarLayerImplBase::PushPropertiesTo(layer); diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl.h b/chromium/cc/layers/solid_color_scrollbar_layer_impl.h index 710b4d603b0..7a3a72de5da 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer_impl.h +++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl.h @@ -18,8 +18,7 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - bool is_overlay); + bool is_left_side_vertical_scrollbar); ~SolidColorScrollbarLayerImpl() override; // LayerImpl overrides. @@ -37,8 +36,7 @@ class CC_EXPORT SolidColorScrollbarLayerImpl : public ScrollbarLayerImplBase { ScrollbarOrientation orientation, int thumb_thickness, int track_start, - bool is_left_side_vertical_scrollbar, - bool is_overlay); + bool is_left_side_vertical_scrollbar); // ScrollbarLayerImplBase implementation. int ThumbLength() const override; diff --git a/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc index a2b24303f23..8544ce1723e 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc +++ b/chromium/cc/layers/solid_color_scrollbar_layer_impl_unittest.cc @@ -6,7 +6,7 @@ #include <stddef.h> -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "testing/gtest/include/gtest/gtest.h" namespace cc { @@ -16,28 +16,25 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) { gfx::Size layer_size(10, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; ScrollbarOrientation orientation = VERTICAL; int thumb_thickness = layer_size.width(); int track_start = 0; bool is_left_side_vertical_scrollbar = false; - bool is_overlay = false; SolidColorScrollbarLayerImpl* scrollbar_layer_impl = - impl.AddChildToRoot<SolidColorScrollbarLayerImpl>( - orientation, - thumb_thickness, - track_start, - is_left_side_vertical_scrollbar, - is_overlay); + impl.AddLayer<SolidColorScrollbarLayerImpl>( + orientation, thumb_thickness, track_start, + is_left_side_vertical_scrollbar); scrollbar_layer_impl->SetBounds(layer_size); scrollbar_layer_impl->SetDrawsContent(true); scrollbar_layer_impl->SetCurrentPos(25.f); scrollbar_layer_impl->SetClipLayerLength(100.f); scrollbar_layer_impl->SetScrollLayerLength(200.f); // SolidColorScrollbarLayers construct with opacity = 0.f, so override. - scrollbar_layer_impl->test_properties()->opacity = 1.f; + CopyProperties(impl.root_layer(), scrollbar_layer_impl); + CreateEffectNode(scrollbar_layer_impl).opacity = 1.f; impl.CalcDrawProps(viewport_size); @@ -50,7 +47,7 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), thumb_rect); + VerifyQuadsExactlyCoverRect(impl.quad_list(), thumb_rect); EXPECT_EQ(1u, impl.quad_list().size()); } @@ -59,7 +56,7 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) { gfx::Rect occluded(scrollbar_layer_impl->visible_layer_rect()); impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -69,8 +66,8 @@ TEST(SolidColorScrollbarLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(scrollbar_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs one quad, which is partially occluded. EXPECT_EQ(1u, impl.quad_list().size()); EXPECT_EQ(1u, partially_occluded_count); diff --git a/chromium/cc/layers/surface_layer_impl_unittest.cc b/chromium/cc/layers/surface_layer_impl_unittest.cc index 50ab0f01570..b5e8b7834ae 100644 --- a/chromium/cc/layers/surface_layer_impl_unittest.cc +++ b/chromium/cc/layers/surface_layer_impl_unittest.cc @@ -7,8 +7,7 @@ #include <stddef.h> #include "cc/layers/append_quads_data.h" -#include "cc/test/layer_test_common.h" -#include "cc/trees/layer_tree_host_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,15 +24,15 @@ TEST(SurfaceLayerImplTest, Occlusion) { const viz::LocalSurfaceId kArbitraryLocalSurfaceId( 9, base::UnguessableToken::Create()); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; - SurfaceLayerImpl* surface_layer_impl = - impl.AddChildToRoot<SurfaceLayerImpl>(); + SurfaceLayerImpl* surface_layer_impl = impl.AddLayer<SurfaceLayerImpl>(); surface_layer_impl->SetBounds(layer_size); surface_layer_impl->SetDrawsContent(true); viz::SurfaceId surface_id(kArbitraryFrameSinkId, kArbitraryLocalSurfaceId); surface_layer_impl->SetRange(viz::SurfaceRange(base::nullopt, surface_id), base::nullopt); + CopyProperties(impl.root_layer(), surface_layer_impl); impl.CalcDrawProps(viewport_size); @@ -42,8 +41,7 @@ TEST(SurfaceLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendQuadsWithOcclusion(surface_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_size)); EXPECT_EQ(1u, impl.quad_list().size()); EXPECT_TRUE(surface_layer_impl->WillDraw(DRAW_MODE_HARDWARE, nullptr)); } @@ -53,7 +51,7 @@ TEST(SurfaceLayerImplTest, Occlusion) { gfx::Rect occluded(surface_layer_impl->visible_layer_rect()); impl.AppendQuadsWithOcclusion(surface_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); EXPECT_FALSE(surface_layer_impl->WillDraw(DRAW_MODE_HARDWARE, nullptr)); } @@ -64,8 +62,8 @@ TEST(SurfaceLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(surface_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs one quad, which is partially occluded. EXPECT_EQ(1u, impl.quad_list().size()); EXPECT_EQ(1u, partially_occluded_count); @@ -76,9 +74,8 @@ TEST(SurfaceLayerImplTest, Occlusion) { // This test verifies that activation_dependencies and the fallback_surface_id // are populated correctly if primary and fallback surfaces differ. TEST(SurfaceLayerImplTest, SurfaceLayerImplWithTwoDifferentSurfaces) { - LayerTestCommon::LayerImplTest impl; - SurfaceLayerImpl* surface_layer_impl = - impl.AddChildToRoot<SurfaceLayerImpl>(); + LayerTreeImplTestBase impl; + SurfaceLayerImpl* surface_layer_impl = impl.AddLayer<SurfaceLayerImpl>(); // Populate the primary viz::SurfaceInfo. const viz::LocalSurfaceId kArbitraryLocalSurfaceId1( @@ -98,6 +95,7 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithTwoDifferentSurfaces) { surface_layer_impl->SetDrawsContent(true); surface_layer_impl->SetRange(viz::SurfaceRange(surface_id2, surface_id1), 2u); surface_layer_impl->SetBackgroundColor(SK_ColorBLUE); + CopyProperties(impl.root_layer(), surface_layer_impl); gfx::Size viewport_size(1000, 1000); impl.CalcDrawProps(viewport_size); @@ -174,12 +172,12 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithTwoDifferentSurfaces) { // and the other uses the default then AppendQuadsData is populated // correctly. TEST(SurfaceLayerImplTest, SurfaceLayerImplsWithDeadlines) { - LayerTestCommon::LayerImplTest impl; - SurfaceLayerImpl* surface_layer_impl = - impl.AddChildToRoot<SurfaceLayerImpl>(); + LayerTreeImplTestBase impl; + SurfaceLayerImpl* surface_layer_impl = impl.AddLayer<SurfaceLayerImpl>(); + CopyProperties(impl.root_layer(), surface_layer_impl); - SurfaceLayerImpl* surface_layer_impl2 = - impl.AddChildToRoot<SurfaceLayerImpl>(); + SurfaceLayerImpl* surface_layer_impl2 = impl.AddLayer<SurfaceLayerImpl>(); + CopyProperties(impl.root_layer(), surface_layer_impl2); const viz::LocalSurfaceId kArbitraryLocalSurfaceId1( 1, base::UnguessableToken::Create()); @@ -218,9 +216,8 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplsWithDeadlines) { // SurfaceLayerImpl holds the same surface ID for both the primary // and fallback viz::SurfaceInfo. TEST(SurfaceLayerImplTest, SurfaceLayerImplWithMatchingPrimaryAndFallback) { - LayerTestCommon::LayerImplTest impl; - SurfaceLayerImpl* surface_layer_impl = - impl.AddChildToRoot<SurfaceLayerImpl>(); + LayerTreeImplTestBase impl; + SurfaceLayerImpl* surface_layer_impl = impl.AddLayer<SurfaceLayerImpl>(); // Populate the primary viz::SurfaceId. const viz::LocalSurfaceId kArbitraryLocalSurfaceId1( @@ -236,6 +233,7 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithMatchingPrimaryAndFallback) { surface_layer_impl->SetRange(viz::SurfaceRange(surface_id1), 1u); surface_layer_impl->SetRange(viz::SurfaceRange(surface_id1), 2u); surface_layer_impl->SetBackgroundColor(SK_ColorBLUE); + CopyProperties(impl.root_layer(), surface_layer_impl); gfx::Size viewport_size(1000, 1000); impl.CalcDrawProps(viewport_size); @@ -259,11 +257,11 @@ TEST(SurfaceLayerImplTest, SurfaceLayerImplWithMatchingPrimaryAndFallback) { TEST(SurfaceLayerImplTest, GetEnclosingRectInTargetSpace) { gfx::Size layer_size(902, 1000); gfx::Size viewport_size(902, 1000); - LayerTestCommon::LayerImplTest impl; - SurfaceLayerImpl* surface_layer_impl = - impl.AddChildToRoot<SurfaceLayerImpl>(); + LayerTreeImplTestBase impl; + SurfaceLayerImpl* surface_layer_impl = impl.AddLayer<SurfaceLayerImpl>(); surface_layer_impl->SetBounds(layer_size); surface_layer_impl->SetDrawsContent(true); + CopyProperties(impl.root_layer(), surface_layer_impl); // A device scale of 1.33 and transform of 1.5 were chosen as they produce // different results when rounding at each stage, vs applying a single diff --git a/chromium/cc/layers/texture_layer_impl_unittest.cc b/chromium/cc/layers/texture_layer_impl_unittest.cc index 13a352cd982..dad52054171 100644 --- a/chromium/cc/layers/texture_layer_impl_unittest.cc +++ b/chromium/cc/layers/texture_layer_impl_unittest.cc @@ -8,7 +8,7 @@ #include "base/bind.h" #include "cc/test/fake_layer_tree_frame_sink.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/layer_tree_frame_sink.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/quads/draw_quad.h" @@ -26,12 +26,13 @@ TEST(TextureLayerImplTest, VisibleOpaqueRegion) { const gfx::Rect layer_rect(layer_bounds); const Region layer_region(layer_rect); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; - TextureLayerImpl* layer = impl.AddChildToRoot<TextureLayerImpl>(); + TextureLayerImpl* layer = impl.AddLayer<TextureLayerImpl>(); layer->SetBounds(layer_bounds); layer->draw_properties().visible_layer_rect = layer_rect; layer->SetBlendBackgroundColor(true); + CopyProperties(impl.root_layer(), layer); // Verify initial conditions. EXPECT_FALSE(layer->contents_opaque()); @@ -51,7 +52,7 @@ TEST(TextureLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; auto resource = viz::TransferableResource::MakeGL( gpu::Mailbox::Generate(), GL_LINEAR, GL_TEXTURE_2D, @@ -59,13 +60,13 @@ TEST(TextureLayerImplTest, Occlusion) { gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456), layer_size, false /* is_overlay_candidate */); - TextureLayerImpl* texture_layer_impl = - impl.AddChildToRoot<TextureLayerImpl>(); + TextureLayerImpl* texture_layer_impl = impl.AddLayer<TextureLayerImpl>(); texture_layer_impl->SetBounds(layer_size); texture_layer_impl->SetDrawsContent(true); texture_layer_impl->SetTransferableResource( resource, viz::SingleReleaseCallback::Create(base::BindOnce(&IgnoreCallback))); + CopyProperties(impl.root_layer(), texture_layer_impl); impl.CalcDrawProps(viewport_size); @@ -74,8 +75,7 @@ TEST(TextureLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendQuadsWithOcclusion(texture_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_size)); EXPECT_EQ(1u, impl.quad_list().size()); } @@ -84,7 +84,7 @@ TEST(TextureLayerImplTest, Occlusion) { gfx::Rect occluded(texture_layer_impl->visible_layer_rect()); impl.AppendQuadsWithOcclusion(texture_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -94,17 +94,17 @@ TEST(TextureLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(texture_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs one quad, which is partially occluded. EXPECT_EQ(1u, impl.quad_list().size()); EXPECT_EQ(1u, partially_occluded_count); } } -TEST(TextureLayerImplTest, ResourceNotFreedOnGpuRasterToggle) { +TEST(TextureLayerImplTest, ResourceNotFreedOnMSAAToggle) { bool released = false; - LayerTestCommon::LayerImplTest impl( + LayerTreeImplTestBase impl( FakeLayerTreeFrameSink::Create3dForGpuRasterization()); impl.host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); @@ -119,8 +119,7 @@ TEST(TextureLayerImplTest, ResourceNotFreedOnGpuRasterToggle) { gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456); resource.mailbox_holder.texture_target = GL_TEXTURE_2D; - TextureLayerImpl* texture_layer_impl = - impl.AddChildToRoot<TextureLayerImpl>(); + TextureLayerImpl* texture_layer_impl = impl.AddLayer<TextureLayerImpl>(); texture_layer_impl->SetBounds(layer_size); texture_layer_impl->SetDrawsContent(true); texture_layer_impl->SetTransferableResource( @@ -128,16 +127,14 @@ TEST(TextureLayerImplTest, ResourceNotFreedOnGpuRasterToggle) { [](bool* released, const gpu::SyncToken& sync_token, bool lost) { *released = true; }, base::Unretained(&released)))); + CopyProperties(impl.root_layer(), texture_layer_impl); impl.CalcDrawProps(viewport_size); - // Gpu rasterization is disabled by default. - EXPECT_FALSE(impl.host_impl()->use_gpu_rasterization()); EXPECT_FALSE(released); - // Toggling the gpu rasterization clears all tilings on both trees. - impl.host_impl()->SetHasGpuRasterizationTrigger(true); + // Toggling MSAA clears all tilings on both trees. + impl.host_impl()->SetContentHasSlowPaths(true); impl.host_impl()->CommitComplete(); - EXPECT_TRUE(impl.host_impl()->use_gpu_rasterization()); EXPECT_FALSE(released); } diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc index 0f5a97da5e6..f47ff407d6c 100644 --- a/chromium/cc/layers/texture_layer_unittest.cc +++ b/chromium/cc/layers/texture_layer_unittest.cc @@ -14,6 +14,7 @@ #include "base/callback.h" #include "base/location.h" #include "base/memory/ptr_util.h" +#include "base/run_loop.h" #include "base/sequenced_task_runner.h" #include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" diff --git a/chromium/cc/layers/tile_size_calculator.cc b/chromium/cc/layers/tile_size_calculator.cc index 6c071ca3708..eacb897a12f 100644 --- a/chromium/cc/layers/tile_size_calculator.cc +++ b/chromium/cc/layers/tile_size_calculator.cc @@ -124,9 +124,9 @@ TileSizeCalculator::AffectingParams TileSizeCalculator::GetAffectingParams() { gfx::Size TileSizeCalculator::CalculateTileSize() { gfx::Size content_bounds = layer_impl()->content_bounds(); - if (layer_impl()->mask_type() == Layer::LayerMaskType::SINGLE_TEXTURE_MASK) { - // Masks are not tiled, so if we can't cover the whole mask with one tile, - // we shouldn't have such a tiling at all. + if (layer_impl()->is_backdrop_filter_mask()) { + // Backdrop filter masks are not tiled, so if we can't cover the whole mask + // with one tile, we shouldn't have such a tiling at all. DCHECK_LE(content_bounds.width(), layer_impl()->layer_tree_impl()->max_texture_size()); DCHECK_LE(content_bounds.height(), diff --git a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc index db2f6d25863..e7337ea871f 100644 --- a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc +++ b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc @@ -12,7 +12,7 @@ #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_ui_resource_layer_tree_host_impl.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/single_thread_proxy.h" #include "components/viz/common/quads/draw_quad.h" @@ -23,7 +23,7 @@ namespace cc { namespace { -std::unique_ptr<UIResourceLayerImpl> GenerateUIResourceLayer( +UIResourceLayerImpl* GenerateUIResourceLayer( FakeUIResourceLayerTreeHostImpl* host_impl, const gfx::Size& bitmap_size, const gfx::Size& layer_size, @@ -34,27 +34,28 @@ std::unique_ptr<UIResourceLayerImpl> GenerateUIResourceLayer( UIResourceLayerImpl::Create(host_impl->active_tree(), 1); layer->draw_properties().visible_layer_rect = visible_layer_rect; layer->SetBounds(layer_size); - layer->test_properties()->force_render_surface = true; UIResourceBitmap bitmap(bitmap_size, opaque); host_impl->CreateUIResource(uid, bitmap); layer->SetUIResourceId(uid); - return layer; + host_impl->active_tree()->property_trees()->clear(); + auto* layer_ptr = layer.get(); + SetupRootProperties(layer_ptr); + host_impl->active_tree()->SetRootLayerForTesting(std::move(layer)); + UpdateDrawProperties(host_impl->active_tree()); + + return layer_ptr; } void QuadSizeTest(FakeUIResourceLayerTreeHostImpl* host_impl, - std::unique_ptr<UIResourceLayerImpl> layer, + UIResourceLayerImpl* layer, size_t expected_quad_size) { - host_impl->active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl->active_tree()->BuildPropertyTreesForTesting(); - std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); AppendQuadsData data; - host_impl->active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + host_impl->active_tree()->root_layer()->AppendQuads(render_pass.get(), &data); // Verify quad rects const viz::QuadList& quads = render_pass->quad_list; @@ -79,9 +80,9 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) { size_t expected_quad_size = 1; bool opaque = true; UIResourceId uid = 1; - std::unique_ptr<UIResourceLayerImpl> layer = + auto* layer = GenerateUIResourceLayer(&host_impl, bitmap_size, layer_size, opaque, uid); - QuadSizeTest(&host_impl, std::move(layer), expected_quad_size); + QuadSizeTest(&host_impl, layer, expected_quad_size); host_impl.DeleteUIResource(uid); // Make sure we're not appending quads when there are invalid values. @@ -92,21 +93,17 @@ TEST(UIResourceLayerImplTest, VerifyDrawQuads) { layer_size, opaque, uid); - QuadSizeTest(&host_impl, std::move(layer), expected_quad_size); + QuadSizeTest(&host_impl, layer, expected_quad_size); host_impl.DeleteUIResource(uid); } void NeedsBlendingTest(FakeUIResourceLayerTreeHostImpl* host_impl, - std::unique_ptr<UIResourceLayerImpl> layer, + UIResourceLayerImpl* layer, bool needs_blending) { - host_impl->active_tree()->SetRootLayerForTesting(std::move(layer)); - host_impl->active_tree()->BuildPropertyTreesForTesting(); - std::unique_ptr<viz::RenderPass> render_pass = viz::RenderPass::Create(); AppendQuadsData data; - host_impl->active_tree()->root_layer_for_testing()->AppendQuads( - render_pass.get(), &data); + host_impl->active_tree()->root_layer()->AppendQuads(render_pass.get(), &data); // Verify needs_blending is set appropriately. const viz::QuadList& quads = render_pass->quad_list; @@ -132,9 +129,9 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) { gfx::Size layer_size(100, 100); bool opaque = false; UIResourceId uid = 1; - std::unique_ptr<UIResourceLayerImpl> layer = + auto* layer = GenerateUIResourceLayer(&host_impl, bitmap_size, layer_size, opaque, uid); - NeedsBlendingTest(&host_impl, std::move(layer), !opaque); + NeedsBlendingTest(&host_impl, layer, !opaque); host_impl.DeleteUIResource(uid); opaque = true; @@ -143,7 +140,7 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) { layer_size, opaque, uid); - NeedsBlendingTest(&host_impl, std::move(layer), !opaque); + NeedsBlendingTest(&host_impl, layer, !opaque); host_impl.DeleteUIResource(uid); } @@ -161,18 +158,18 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) { gfx::Size layer_size(100, 100); bool skbitmap_opaque = false; UIResourceId uid = 1; - std::unique_ptr<UIResourceLayerImpl> layer = GenerateUIResourceLayer( - &host_impl, bitmap_size, layer_size, skbitmap_opaque, uid); + auto* layer = GenerateUIResourceLayer(&host_impl, bitmap_size, layer_size, + skbitmap_opaque, uid); bool opaque = false; layer->SetContentsOpaque(opaque); - NeedsBlendingTest(&host_impl, std::move(layer), !opaque); + NeedsBlendingTest(&host_impl, layer, !opaque); host_impl.DeleteUIResource(uid); opaque = true; layer = GenerateUIResourceLayer( &host_impl, bitmap_size, layer_size, skbitmap_opaque, uid); layer->SetContentsOpaque(true); - NeedsBlendingTest(&host_impl, std::move(layer), !opaque); + NeedsBlendingTest(&host_impl, layer, !opaque); host_impl.DeleteUIResource(uid); } @@ -180,7 +177,7 @@ TEST(UIResourceLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; SkBitmap sk_bitmap; sk_bitmap.allocN32Pixels(10, 10); @@ -190,10 +187,11 @@ TEST(UIResourceLayerImplTest, Occlusion) { impl.host_impl()->CreateUIResource(uid, bitmap); UIResourceLayerImpl* ui_resource_layer_impl = - impl.AddChildToRoot<UIResourceLayerImpl>(); + impl.AddLayer<UIResourceLayerImpl>(); ui_resource_layer_impl->SetBounds(layer_size); ui_resource_layer_impl->SetDrawsContent(true); ui_resource_layer_impl->SetUIResourceId(uid); + CopyProperties(impl.root_layer(), ui_resource_layer_impl); impl.CalcDrawProps(viewport_size); @@ -202,8 +200,7 @@ TEST(UIResourceLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendQuadsWithOcclusion(ui_resource_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_size)); EXPECT_EQ(1u, impl.quad_list().size()); } @@ -212,7 +209,7 @@ TEST(UIResourceLayerImplTest, Occlusion) { gfx::Rect occluded(ui_resource_layer_impl->visible_layer_rect()); impl.AppendQuadsWithOcclusion(ui_resource_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -222,8 +219,8 @@ TEST(UIResourceLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(ui_resource_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); // The layer outputs one quad, which is partially occluded. EXPECT_EQ(1u, impl.quad_list().size()); EXPECT_EQ(1u, partially_occluded_count); diff --git a/chromium/cc/layers/ui_resource_layer_unittest.cc b/chromium/cc/layers/ui_resource_layer_unittest.cc index 17397773b5b..2b627f59cde 100644 --- a/chromium/cc/layers/ui_resource_layer_unittest.cc +++ b/chromium/cc/layers/ui_resource_layer_unittest.cc @@ -9,7 +9,7 @@ #include "cc/resources/scoped_ui_resource.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/test/stub_layer_tree_host_single_thread_client.h" #include "cc/trees/single_thread_proxy.h" #include "testing/gmock/include/gmock/gmock.h" @@ -47,7 +47,7 @@ class UIResourceLayerTest : public testing::Test { FakeLayerTreeHost* layer_tree_host() { return layer_impl_test_.host(); } private: - LayerTestCommon::LayerImplTest layer_impl_test_; + LayerTreeImplTestBase layer_impl_test_; }; TEST_F(UIResourceLayerTest, SetBitmap) { @@ -131,7 +131,7 @@ TEST_F(UIResourceLayerTest, BitmapClearedOnSetUIResourceId) { // Add to a layer tree; now the UIResourceManager holds onto a ref // indefinitely. { - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; impl.host()->SetRootLayer(test_layer); test_layer->SetBitmap(bitmap); @@ -182,7 +182,7 @@ TEST_F(UIResourceLayerTest, SharedBitmap) { // still be the same. We can make sure it's using the same shared bitmap by // verifying that whatever ID it has, it changes away from and back to when we // change the shared bitmap to something else then back to the original. - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; impl.host()->SetRootLayer(layer1); layer1->Update(); EXPECT_TRUE(layer1->DrawsContent()); diff --git a/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc b/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc index 5d03c6700f2..fa4c2e9209e 100644 --- a/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc +++ b/chromium/cc/layers/video_frame_provider_client_impl_unittest.cc @@ -5,7 +5,7 @@ #include "cc/layers/video_frame_provider_client_impl.h" #include "cc/layers/video_layer_impl.h" #include "cc/test/fake_video_frame_provider.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "media/base/video_frame.h" #include "testing/gmock/include/gmock/gmock.h" @@ -79,8 +79,8 @@ class VideoFrameProviderClientImplTest : public testing::Test, void CreateActiveVideoLayer() { gfx::Size layer_size(100, 100); - video_layer_impl_ = impl_.AddChildToRoot<VideoLayerImpl>( - &provider_, media::VIDEO_ROTATION_0); + video_layer_impl_ = + impl_.AddLayer<VideoLayerImpl>(&provider_, media::VIDEO_ROTATION_0); video_layer_impl_->SetBounds(layer_size); video_layer_impl_->SetDrawsContent(true); client_impl_->SetActiveVideoLayer(video_layer_impl_); @@ -92,7 +92,7 @@ class VideoFrameProviderClientImplTest : public testing::Test, protected: FakeVideoFrameProvider provider_; - LayerTestCommon::LayerImplTest impl_; + LayerTreeImplTestBase impl_; scoped_refptr<VideoFrameProviderClientImpl> client_impl_; VideoLayerImpl* video_layer_impl_; scoped_refptr<media::VideoFrame> test_frame_; diff --git a/chromium/cc/layers/video_layer_impl_unittest.cc b/chromium/cc/layers/video_layer_impl_unittest.cc index a84a559f445..8a22f392e56 100644 --- a/chromium/cc/layers/video_layer_impl_unittest.cc +++ b/chromium/cc/layers/video_layer_impl_unittest.cc @@ -9,7 +9,7 @@ #include "base/bind_helpers.h" #include "cc/layers/video_frame_provider_client_impl.h" #include "cc/test/fake_video_frame_provider.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/single_thread_proxy.h" #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/quads/draw_quad.h" @@ -38,7 +38,7 @@ TEST(VideoLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( @@ -48,10 +48,11 @@ TEST(VideoLayerImplTest, Occlusion) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); video_layer_impl->set_visible_layer_rect(gfx::Rect(layer_size)); + CopyProperties(impl.root_layer(), video_layer_impl); impl.CalcDrawProps(viewport_size); @@ -60,10 +61,9 @@ TEST(VideoLayerImplTest, Occlusion) { gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), - gfx::Rect(layer_size)); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect(layer_size)); - LayerTestCommon::VerifyQuadsExactlyCoverRect( + VerifyQuadsExactlyCoverRect( impl.quad_list(), impl.quad_list().cbegin()->shared_quad_state->visible_quad_layer_rect); EXPECT_EQ(1u, impl.quad_list().size()); @@ -74,7 +74,7 @@ TEST(VideoLayerImplTest, Occlusion) { gfx::Rect occluded(video_layer_impl->visible_layer_rect()); impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); - LayerTestCommon::VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); + VerifyQuadsExactlyCoverRect(impl.quad_list(), gfx::Rect()); EXPECT_EQ(impl.quad_list().size(), 0u); } @@ -84,9 +84,9 @@ TEST(VideoLayerImplTest, Occlusion) { impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); size_t partially_occluded_count = 0; - LayerTestCommon::VerifyQuadsAreOccluded( - impl.quad_list(), occluded, &partially_occluded_count); - LayerTestCommon::VerifyQuadsExactlyCoverRect( + VerifyQuadsAreOccluded(impl.quad_list(), occluded, + &partially_occluded_count); + VerifyQuadsExactlyCoverRect( impl.quad_list(), impl.quad_list().cbegin()->shared_quad_state->visible_quad_layer_rect); // The layer outputs one quad, which is partially occluded. @@ -99,31 +99,26 @@ TEST(VideoLayerImplTest, OccludesOtherLayers) { gfx::Size layer_size(1000, 1000); gfx::Rect visible(layer_size); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; impl.host_impl()->active_tree()->SetDeviceViewportRect(visible); DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); auto* active_tree = impl.host_impl()->active_tree(); // Create a video layer with no frame on top of another layer. - std::unique_ptr<LayerImpl> layer_impl = LayerImpl::Create(active_tree, 3); - layer_impl->test_properties()->force_render_surface = true; - layer_impl->SetBounds(layer_size); - layer_impl->SetDrawsContent(true); - const auto& draw_properties = layer_impl->draw_properties(); + LayerImpl* root = impl.root_layer(); + root->SetBounds(layer_size); + root->SetDrawsContent(true); + const auto& draw_properties = root->draw_properties(); FakeVideoFrameProvider provider; - std::unique_ptr<VideoLayerImpl> video_layer_impl = VideoLayerImpl::Create( - active_tree, 4, &provider, media::VIDEO_ROTATION_0); + VideoLayerImpl* video_layer_impl = + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); video_layer_impl->SetContentsOpaque(true); + CopyProperties(root, video_layer_impl); - layer_impl->test_properties()->AddChild(std::move(video_layer_impl)); - active_tree->SetRootLayerForTesting(std::move(layer_impl)); - - active_tree->BuildLayerListAndPropertyTreesForTesting(); - - active_tree->UpdateDrawProperties(); + impl.CalcDrawProps(layer_size); // We don't have a frame yet, so the video doesn't occlude the layer below it. EXPECT_FALSE(draw_properties.occlusion_in_content_space.IsOccluded(visible)); @@ -140,12 +135,13 @@ TEST(VideoLayerImplTest, OccludesOtherLayers) { } TEST(VideoLayerImplTest, DidBecomeActiveShouldSetActiveVideoLayer) { - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); FakeVideoFrameProvider provider; VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + CopyProperties(impl.root_layer(), video_layer_impl); VideoFrameProviderClientImpl* client = static_cast<VideoFrameProviderClientImpl*>(provider.client()); @@ -160,7 +156,7 @@ TEST(VideoLayerImplTest, Rotated0) { gfx::Size layer_size(100, 50); gfx::Size viewport_size(1000, 500); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( @@ -170,9 +166,10 @@ TEST(VideoLayerImplTest, Rotated0) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + CopyProperties(impl.root_layer(), video_layer_impl); impl.CalcDrawProps(viewport_size); gfx::Rect occluded; @@ -196,7 +193,7 @@ TEST(VideoLayerImplTest, Rotated90) { gfx::Size layer_size(100, 50); gfx::Size viewport_size(1000, 500); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( @@ -206,9 +203,10 @@ TEST(VideoLayerImplTest, Rotated90) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_90); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_90); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + CopyProperties(impl.root_layer(), video_layer_impl); impl.CalcDrawProps(viewport_size); gfx::Rect occluded; @@ -232,7 +230,7 @@ TEST(VideoLayerImplTest, Rotated180) { gfx::Size layer_size(100, 50); gfx::Size viewport_size(1000, 500); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( @@ -242,9 +240,10 @@ TEST(VideoLayerImplTest, Rotated180) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_180); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_180); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + CopyProperties(impl.root_layer(), video_layer_impl); impl.CalcDrawProps(viewport_size); gfx::Rect occluded; @@ -268,7 +267,7 @@ TEST(VideoLayerImplTest, Rotated270) { gfx::Size layer_size(100, 50); gfx::Size viewport_size(1000, 500); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); scoped_refptr<media::VideoFrame> video_frame = media::VideoFrame::CreateFrame( @@ -278,9 +277,10 @@ TEST(VideoLayerImplTest, Rotated270) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_270); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_270); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); + CopyProperties(impl.root_layer(), video_layer_impl); impl.CalcDrawProps(viewport_size); gfx::Rect occluded; @@ -303,7 +303,7 @@ TEST(VideoLayerImplTest, Rotated270) { TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) { gfx::Size layer_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); gpu::MailboxHolder mailbox_holder; @@ -317,11 +317,13 @@ TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); video_layer_impl->set_visible_layer_rect(gfx::Rect(layer_size)); - impl.host_impl()->active_tree()->BuildLayerListAndPropertyTreesForTesting(); + CopyProperties(impl.root_layer(), video_layer_impl); + + impl.CalcDrawProps(layer_size); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); @@ -341,7 +343,7 @@ TEST(VideoLayerImplTest, SoftwareVideoFrameGeneratesYUVQuad) { TEST(VideoLayerImplTest, HibitSoftwareVideoFrameGeneratesYUVQuad) { gfx::Size layer_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); gpu::MailboxHolder mailbox_holder; @@ -355,11 +357,13 @@ TEST(VideoLayerImplTest, HibitSoftwareVideoFrameGeneratesYUVQuad) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); video_layer_impl->set_visible_layer_rect(gfx::Rect(layer_size)); - impl.host_impl()->active_tree()->BuildLayerListAndPropertyTreesForTesting(); + CopyProperties(impl.root_layer(), video_layer_impl); + + impl.CalcDrawProps(layer_size); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); @@ -377,7 +381,7 @@ TEST(VideoLayerImplTest, HibitSoftwareVideoFrameGeneratesYUVQuad) { TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) { gfx::Size layer_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes]; @@ -397,11 +401,12 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); video_layer_impl->set_visible_layer_rect(gfx::Rect(layer_size)); - impl.host_impl()->active_tree()->BuildLayerListAndPropertyTreesForTesting(); + CopyProperties(impl.root_layer(), video_layer_impl); + impl.CalcDrawProps(layer_size); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); @@ -421,7 +426,7 @@ TEST(VideoLayerImplTest, NativeYUVFrameGeneratesYUVQuad) { TEST(VideoLayerImplTest, NativeARGBFrameGeneratesTextureQuad) { gfx::Size layer_size(1000, 1000); - LayerTestCommon::LayerImplTest impl; + LayerTreeImplTestBase impl; DebugSetImplThreadAndMainThreadBlocked(impl.task_runner_provider()); gpu::MailboxHolder mailbox_holders[media::VideoFrame::kMaxPlanes]; @@ -440,11 +445,13 @@ TEST(VideoLayerImplTest, NativeARGBFrameGeneratesTextureQuad) { provider.set_frame(video_frame); VideoLayerImpl* video_layer_impl = - impl.AddChildToRoot<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); + impl.AddLayer<VideoLayerImpl>(&provider, media::VIDEO_ROTATION_0); video_layer_impl->SetBounds(layer_size); video_layer_impl->SetDrawsContent(true); video_layer_impl->set_visible_layer_rect(gfx::Rect(layer_size)); - impl.host_impl()->active_tree()->BuildLayerListAndPropertyTreesForTesting(); + CopyProperties(impl.root_layer(), video_layer_impl); + + impl.CalcDrawProps(layer_size); gfx::Rect occluded; impl.AppendQuadsWithOcclusion(video_layer_impl, occluded); diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc index 8bbe7293b32..5a50ee6b010 100644 --- a/chromium/cc/layers/viewport.cc +++ b/chromium/cc/layers/viewport.cc @@ -234,10 +234,6 @@ bool Viewport::ShouldScroll(const ScrollNode& scroll_node) { scroll_node.scrolls_outer_viewport; } -LayerImpl* Viewport::MainScrollLayer() const { - return host_impl_->OuterViewportScrollLayer(); -} - ScrollNode* Viewport::MainScrollNode() const { return host_impl_->OuterViewportScrollNode(); } diff --git a/chromium/cc/layers/viewport.h b/chromium/cc/layers/viewport.h index 9143b58b747..ac17140f513 100644 --- a/chromium/cc/layers/viewport.h +++ b/chromium/cc/layers/viewport.h @@ -74,9 +74,8 @@ class CC_EXPORT Viewport { // false if it should be scrolled directly. bool ShouldScroll(const ScrollNode& scroll_node); - // Returns the "representative" viewport layer/node. That is, the one that's - // set as the currently scrolling layer/node when the viewport scrolls. - LayerImpl* MainScrollLayer() const; + // Returns the "representative" viewport scroll node. That is, the one that's + // set as the currently scrolling node when the viewport scrolls. ScrollNode* MainScrollNode() const; private: diff --git a/chromium/cc/metrics/begin_main_frame_metrics.cc b/chromium/cc/metrics/begin_main_frame_metrics.cc new file mode 100644 index 00000000000..d4e83ead0c0 --- /dev/null +++ b/chromium/cc/metrics/begin_main_frame_metrics.cc @@ -0,0 +1,11 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/metrics/begin_main_frame_metrics.h" + +namespace cc { + +BeginMainFrameMetrics::BeginMainFrameMetrics() = default; + +} // namespace cc diff --git a/chromium/cc/metrics/begin_main_frame_metrics.h b/chromium/cc/metrics/begin_main_frame_metrics.h new file mode 100644 index 00000000000..2927360a849 --- /dev/null +++ b/chromium/cc/metrics/begin_main_frame_metrics.h @@ -0,0 +1,35 @@ +// Copyright 2019 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_METRICS_BEGIN_MAIN_FRAME_METRICS_H_ +#define CC_METRICS_BEGIN_MAIN_FRAME_METRICS_H_ + +#include "base/time/time.h" +#include "cc/cc_export.h" + +namespace cc { + +// Latency timing data for Main Frame lifecycle updates triggered by cc. +// The data is captured in LocalFrameViewUKMAggregator and passed back through +// the proxy when a main frame ends. LayerTreeHost updates the update_layers_ +// value in LayerTreeHost::UpdateLayers. +// TODO(schenney): Include work done in LayerTreeHost::AnimateLayers? +struct CC_EXPORT BeginMainFrameMetrics { + base::TimeDelta handle_input_events; + base::TimeDelta animate; + base::TimeDelta style_update; + base::TimeDelta layout_update; + base::TimeDelta prepaint; + base::TimeDelta composite; + base::TimeDelta paint; + base::TimeDelta scrolling_coordinator; + base::TimeDelta composite_commit; + base::TimeDelta update_layers; + + BeginMainFrameMetrics(); +}; + +} // namespace cc + +#endif // CC_METRICS_BEGIN_MAIN_FRAME_METRICS_H_ diff --git a/chromium/cc/metrics/compositor_frame_reporter.cc b/chromium/cc/metrics/compositor_frame_reporter.cc index 560bc2932fc..cb494e657b7 100644 --- a/chromium/cc/metrics/compositor_frame_reporter.cc +++ b/chromium/cc/metrics/compositor_frame_reporter.cc @@ -15,19 +15,15 @@ namespace cc { namespace { -// When considering if a time is abnormal, compare the stage execution -// time to this percentile from the previous times of the same stage. -constexpr double kAbnormalityPercentile = 95; - -// Use for determining abnormal execution times. If the sample size is less -// than this then don't check for abnormal execution time. -constexpr size_t kMinimumTimeDeltaSampleSize = 20; +using StageType = CompositorFrameReporter::StageType; +using VizBreakdown = CompositorFrameReporter::VizBreakdown; constexpr int kMissedFrameReportTypeCount = static_cast<int>(CompositorFrameReporter::MissedFrameReportTypes:: kMissedFrameReportTypeCount); -constexpr int kStageTypeCount = - static_cast<int>(CompositorFrameReporter::StageType::kStageTypeCount); +constexpr int kStageTypeCount = static_cast<int>(StageType::kStageTypeCount); +constexpr int kAllBreakdownCount = + static_cast<int>(VizBreakdown::kBreakdownCount); // For each possible FrameSequenceTrackerType there will be a UMA histogram // plus one for general case. constexpr int kFrameSequenceTrackerTypeCount = @@ -35,16 +31,37 @@ constexpr int kFrameSequenceTrackerTypeCount = // Names for CompositorFrameReporter::StageType, which should be updated in case // of changes to the enum. -constexpr const char* kStageNames[]{ - "BeginImplFrameToSendBeginMainFrame", - "SendBeginMainFrameToCommit", - "Commit", - "EndCommitToActivation", - "Activation", - "EndActivateToSubmitCompositorFrame", - "SubmitCompositorFrameToPresentationCompositorFrame", - "TotalLatency"}; -static_assert(sizeof(kStageNames) / sizeof(kStageNames[0]) == kStageTypeCount, +constexpr const char* kStageNames[] = { + [static_cast<int>(StageType::kBeginImplFrameToSendBeginMainFrame)] = + "BeginImplFrameToSendBeginMainFrame", + [static_cast<int>(StageType::kSendBeginMainFrameToCommit)] = + "SendBeginMainFrameToCommit", + [static_cast<int>(StageType::kCommit)] = "Commit", + [static_cast<int>(StageType::kEndCommitToActivation)] = + "EndCommitToActivation", + [static_cast<int>(StageType::kActivation)] = "Activation", + [static_cast<int>(StageType::kEndActivateToSubmitCompositorFrame)] = + "EndActivateToSubmitCompositorFrame", + [static_cast<int>( + StageType::kSubmitCompositorFrameToPresentationCompositorFrame)] = + "SubmitCompositorFrameToPresentationCompositorFrame", + [static_cast<int>(StageType::kTotalLatency)] = "TotalLatency", + [static_cast<int>(VizBreakdown::kSubmitToReceiveCompositorFrame) + + kStageTypeCount] = + "SubmitCompositorFrameToPresentationCompositorFrame." + "SubmitToReceiveCompositorFrame", + [static_cast<int>(VizBreakdown::kReceivedCompositorFrameToStartDraw) + + kStageTypeCount] = + "SubmitCompositorFrameToPresentationCompositorFrame." + "ReceivedCompositorFrameToStartDraw", + [static_cast<int>(VizBreakdown::kStartDrawToSwapEnd) + kStageTypeCount] = + "SubmitCompositorFrameToPresentationCompositorFrame.StartDrawToSwapEnd", + [static_cast<int>(VizBreakdown::kSwapEndToPresentationCompositorFrame) + + kStageTypeCount] = + "SubmitCompositorFrameToPresentationCompositorFrame." + "SwapEndToPresentationCompositorFrame"}; +static_assert(sizeof(kStageNames) / sizeof(kStageNames[0]) == + kStageTypeCount + kAllBreakdownCount, "Compositor latency stages has changed."); // Names for CompositorFrameReporter::MissedFrameReportTypes, which should be @@ -59,23 +76,24 @@ static_assert(sizeof(kReportTypeNames) / sizeof(kReportTypeNames[0]) == // This value should be recalculate in case of changes to the number of values // in CompositorFrameReporter::MissedFrameReportTypes or in // CompositorFrameReporter::StageType -constexpr int kMaxHistogramIndex = 2 * kMissedFrameReportTypeCount * +constexpr int kMaxHistogramIndex = kMissedFrameReportTypeCount * kFrameSequenceTrackerTypeCount * - kStageTypeCount; + (kStageTypeCount + kAllBreakdownCount); constexpr int kHistogramMin = 1; constexpr int kHistogramMax = 350000; constexpr int kHistogramBucketCount = 50; -std::string HistogramName(const char* compositor_type, - const int report_type_index, +std::string HistogramName(const int report_type_index, const int frame_sequence_tracker_type_index, const int stage_type_index) { - std::string tracker_type_name = FrameSequenceTracker:: + DCHECK_LE(frame_sequence_tracker_type_index, + FrameSequenceTrackerType::kMaxType); + const char* tracker_type_name = FrameSequenceTracker:: kFrameSequenceTrackerTypeNames[frame_sequence_tracker_type_index]; - if (!tracker_type_name.empty()) - tracker_type_name += "."; - return base::StrCat({compositor_type, "CompositorLatency.", + DCHECK(tracker_type_name); + return base::StrCat({"CompositorLatency.", kReportTypeNames[report_type_index], tracker_type_name, + *tracker_type_name ? "." : "", kStageNames[stage_type_index]}); } } // namespace @@ -93,14 +111,20 @@ CompositorFrameReporter::~CompositorFrameReporter() { TerminateReporter(); } +CompositorFrameReporter::StageData::StageData() = default; +CompositorFrameReporter::StageData::StageData(StageType stage_type, + base::TimeTicks start_time, + base::TimeTicks end_time) + : stage_type(stage_type), start_time(start_time), end_time(end_time) {} +CompositorFrameReporter::StageData::StageData(const StageData&) = default; +CompositorFrameReporter::StageData::~StageData() = default; + void CompositorFrameReporter::StartStage( CompositorFrameReporter::StageType stage_type, - base::TimeTicks start_time, - RollingTimeDeltaHistory* stage_time_delta_history) { + base::TimeTicks start_time) { EndCurrentStage(start_time); current_stage_.stage_type = stage_type; current_stage_.start_time = start_time; - current_stage_.time_delta_history = stage_time_delta_history; int stage_type_index = static_cast<int>(current_stage_.stage_type); CHECK_LT(stage_type_index, static_cast<int>(StageType::kStageTypeCount)); CHECK_GE(stage_type_index, 0); @@ -113,9 +137,8 @@ void CompositorFrameReporter::EndCurrentStage(base::TimeTicks end_time) { if (current_stage_.start_time == base::TimeTicks()) return; current_stage_.end_time = end_time; - stage_history_.emplace_back(current_stage_); + stage_history_.push_back(current_stage_); current_stage_.start_time = base::TimeTicks(); - current_stage_.time_delta_history = nullptr; } void CompositorFrameReporter::MissedSubmittedFrame() { @@ -130,8 +153,27 @@ void CompositorFrameReporter::TerminateFrame( EndCurrentStage(frame_termination_time_); } +void CompositorFrameReporter::OnFinishImplFrame(base::TimeTicks timestamp) { + DCHECK(!did_finish_impl_frame_); + + did_finish_impl_frame_ = true; + impl_frame_finish_time_ = timestamp; +} + +void CompositorFrameReporter::OnAbortBeginMainFrame() { + did_abort_main_frame_ = false; +} + +void CompositorFrameReporter::SetVizBreakdown( + const viz::FrameTimingDetails& viz_breakdown) { + DCHECK(current_stage_.viz_breakdown.received_compositor_frame_timestamp + .is_null()); + current_stage_.viz_breakdown = viz_breakdown; +} + void CompositorFrameReporter::TerminateReporter() { - DCHECK_EQ(current_stage_.start_time, base::TimeTicks()); + if (frame_termination_status_ != FrameTerminationStatus::kUnknown) + DCHECK_EQ(current_stage_.start_time, base::TimeTicks()); bool report_latency = false; const char* termination_status_str = nullptr; switch (frame_termination_status_) { @@ -140,25 +182,27 @@ void CompositorFrameReporter::TerminateReporter() { termination_status_str = "presented_frame"; break; case FrameTerminationStatus::kDidNotPresentFrame: + report_latency = true; + MissedSubmittedFrame(); termination_status_str = "did_not_present_frame"; break; case FrameTerminationStatus::kMainFrameAborted: termination_status_str = "main_frame_aborted"; break; case FrameTerminationStatus::kReplacedByNewReporter: + report_latency = true; + MissedSubmittedFrame(); termination_status_str = "replaced_by_new_reporter_at_same_stage"; break; case FrameTerminationStatus::kDidNotProduceFrame: termination_status_str = "did_not_produce_frame"; break; case FrameTerminationStatus::kUnknown: - NOTREACHED(); + termination_status_str = "terminated_before_ending"; break; } - const char* submission_status_str = submitted_frame_missed_deadline_ ? "missed_frame" : "non_missed_frame"; - TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2( "cc,benchmark", "PipelineReporter", this, frame_termination_time_, "termination_status", TRACE_STR_COPY(termination_status_str), @@ -168,9 +212,9 @@ void CompositorFrameReporter::TerminateReporter() { // Only report histograms if the frame was presented. if (report_latency) { DCHECK(stage_history_.size()); - stage_history_.emplace_back( - StageData{StageType::kTotalLatency, stage_history_.front().start_time, - stage_history_.back().end_time, nullptr}); + stage_history_.emplace_back(StageType::kTotalLatency, + stage_history_.front().start_time, + stage_history_.back().end_time); ReportStageHistograms(submitted_frame_missed_deadline_); } } @@ -182,91 +226,103 @@ void CompositorFrameReporter::ReportStageHistograms(bool missed_frame) const { : CompositorFrameReporter::MissedFrameReportTypes::kNonMissedFrame; for (const StageData& stage : stage_history_) { - base::TimeDelta stage_delta = stage.end_time - stage.start_time; - ReportHistogram(report_type, FrameSequenceTrackerType::kMaxType, - stage.stage_type, stage_delta); + ReportStageHistogramWithBreakdown( + report_type, FrameSequenceTrackerType::kMaxType, stage); for (const auto& frame_sequence_tracker_type : *active_trackers_) { - ReportHistogram(report_type, frame_sequence_tracker_type, - stage.stage_type, stage_delta); + // Report stage breakdowns. + ReportStageHistogramWithBreakdown(report_type, + frame_sequence_tracker_type, stage); } + } +} - if (!stage.time_delta_history) - continue; - - if (!missed_frame) { - stage.time_delta_history->InsertSample(stage_delta); - } else { - // If enough sample data is recorded compare the stage duration with the - // known normal stage duration and if it's higher than normal, report the - // difference. - if (stage.time_delta_history->sample_count() >= - kMinimumTimeDeltaSampleSize) { - base::TimeDelta time_upper_limit = GetStateNormalUpperLimit(stage); - if (stage_delta > time_upper_limit) { - // This ReportHistogram reports the latency of all - // frame_sequence_tracker_types(interactions) combined. - auto current_report_type = CompositorFrameReporter:: - MissedFrameReportTypes::kMissedFrameLatencyIncrease; - ReportHistogram(current_report_type, - FrameSequenceTrackerType::kMaxType, stage.stage_type, - stage_delta - time_upper_limit); - - for (const auto& frame_sequence_tracker_type : *active_trackers_) { - ReportHistogram(current_report_type, frame_sequence_tracker_type, - stage.stage_type, stage_delta - time_upper_limit); - } - } - } - - // In case of a missing frame, remove a sample from the recorded normal - // stages. This invalidates the recorded normal durations if at a point - // all frames start missing for a while. - stage.time_delta_history->RemoveOldestSample(); +void CompositorFrameReporter::ReportStageHistogramWithBreakdown( + CompositorFrameReporter::MissedFrameReportTypes report_type, + FrameSequenceTrackerType frame_sequence_tracker_type, + CompositorFrameReporter::StageData stage) const { + base::TimeDelta stage_delta = stage.end_time - stage.start_time; + ReportHistogram(report_type, frame_sequence_tracker_type, + static_cast<int>(stage.stage_type), stage_delta); + switch (stage.stage_type) { + case StageType::kSubmitCompositorFrameToPresentationCompositorFrame: { + ReportVizBreakdown(report_type, frame_sequence_tracker_type, stage); + break; } + default: + break; } } +void CompositorFrameReporter::ReportVizBreakdown( + CompositorFrameReporter::MissedFrameReportTypes report_type, + FrameSequenceTrackerType frame_sequence_tracker_type, + CompositorFrameReporter::StageData stage) const { + // Check if viz_breakdown is set. + if (stage.viz_breakdown.received_compositor_frame_timestamp.is_null()) + return; + + int index_origin = static_cast<int>(StageType::kStageTypeCount); + base::TimeDelta submit_to_receive_compositor_frame_delta = + stage.viz_breakdown.received_compositor_frame_timestamp - + stage.start_time; + ReportHistogram(report_type, frame_sequence_tracker_type, index_origin, + submit_to_receive_compositor_frame_delta); + + if (stage.viz_breakdown.draw_start_timestamp.is_null()) + return; + base::TimeDelta received_compositor_frame_to_start_draw_delta = + stage.viz_breakdown.draw_start_timestamp - + stage.viz_breakdown.received_compositor_frame_timestamp; + ReportHistogram(report_type, frame_sequence_tracker_type, index_origin + 1, + received_compositor_frame_to_start_draw_delta); + + if (stage.viz_breakdown.swap_timings.is_null()) + return; + base::TimeDelta start_draw_to_swap_end_delta = + stage.viz_breakdown.swap_timings.swap_end - + stage.viz_breakdown.draw_start_timestamp; + + ReportHistogram(report_type, frame_sequence_tracker_type, index_origin + 2, + start_draw_to_swap_end_delta); + + base::TimeDelta swap_end_to_presentation_compositor_frame_delta = + stage.end_time - stage.viz_breakdown.swap_timings.swap_end; + + ReportHistogram(report_type, frame_sequence_tracker_type, index_origin + 3, + swap_end_to_presentation_compositor_frame_delta); +} + void CompositorFrameReporter::ReportHistogram( CompositorFrameReporter::MissedFrameReportTypes report_type, FrameSequenceTrackerType frame_sequence_tracker_type, - CompositorFrameReporter::StageType stage_type, + const int stage_type_index, base::TimeDelta time_delta) const { const int report_type_index = static_cast<int>(report_type); - const int stage_type_index = static_cast<int>(stage_type); const int frame_sequence_tracker_type_index = static_cast<int>(frame_sequence_tracker_type); const int histogram_index = - ((stage_type_index * kFrameSequenceTrackerTypeCount + - frame_sequence_tracker_type_index) * - kMissedFrameReportTypeCount + - report_type_index) * - 2 + - (is_single_threaded_ ? 1 : 0); - - CHECK_LT(stage_type_index, kStageTypeCount); + (stage_type_index * kFrameSequenceTrackerTypeCount + + frame_sequence_tracker_type_index) * + kMissedFrameReportTypeCount + + report_type_index; + + CHECK_LT(stage_type_index, kStageTypeCount + kAllBreakdownCount); CHECK_GE(stage_type_index, 0); CHECK_LT(report_type_index, kMissedFrameReportTypeCount); CHECK_GE(report_type_index, 0); CHECK_LT(histogram_index, kMaxHistogramIndex); CHECK_GE(histogram_index, 0); - const char* compositor_type = is_single_threaded_ ? "SingleThreaded" : ""; - STATIC_HISTOGRAM_POINTER_GROUP( - HistogramName(compositor_type, report_type_index, - frame_sequence_tracker_type_index, stage_type_index), + HistogramName(report_type_index, frame_sequence_tracker_type_index, + stage_type_index), histogram_index, kMaxHistogramIndex, AddTimeMicrosecondsGranularity(time_delta), base::Histogram::FactoryGet( - HistogramName(compositor_type, report_type_index, - frame_sequence_tracker_type_index, stage_type_index), + HistogramName(report_type_index, frame_sequence_tracker_type_index, + stage_type_index), kHistogramMin, kHistogramMax, kHistogramBucketCount, base::HistogramBase::kUmaTargetedHistogramFlag)); } - -base::TimeDelta CompositorFrameReporter::GetStateNormalUpperLimit( - const StageData& stage) const { - return stage.time_delta_history->Percentile(kAbnormalityPercentile); -} } // namespace cc diff --git a/chromium/cc/metrics/compositor_frame_reporter.h b/chromium/cc/metrics/compositor_frame_reporter.h index 297c813f138..79cbd089e46 100644 --- a/chromium/cc/metrics/compositor_frame_reporter.h +++ b/chromium/cc/metrics/compositor_frame_reporter.h @@ -12,6 +12,11 @@ #include "cc/base/base_export.h" #include "cc/cc_export.h" #include "cc/metrics/frame_sequence_tracker.h" +#include "components/viz/common/frame_timing_details.h" + +namespace viz { +struct FrameTimingDetails; +} namespace cc { class RollingTimeDeltaHistory; @@ -55,25 +60,37 @@ class CC_EXPORT CompositorFrameReporter { kUnknown }; + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. enum class MissedFrameReportTypes { - kNonMissedFrame, - kMissedFrame, - kMissedFrameLatencyIncrease, + kNonMissedFrame = 0, + kMissedFrame = 1, + kDeprecatedMissedFrameLatencyIncrease = 2, kMissedFrameReportTypeCount }; + // These values are persisted to logs. Entries should not be renumbered and + // numeric values should never be reused. enum class StageType { - kBeginImplFrameToSendBeginMainFrame, - kSendBeginMainFrameToCommit, - kCommit, - kEndCommitToActivation, - kActivation, - kEndActivateToSubmitCompositorFrame, - kSubmitCompositorFrameToPresentationCompositorFrame, - kTotalLatency, + kBeginImplFrameToSendBeginMainFrame = 0, + kSendBeginMainFrameToCommit = 1, + kCommit = 2, + kEndCommitToActivation = 3, + kActivation = 4, + kEndActivateToSubmitCompositorFrame = 5, + kSubmitCompositorFrameToPresentationCompositorFrame = 6, + kTotalLatency = 7, kStageTypeCount }; + enum class VizBreakdown { + kSubmitToReceiveCompositorFrame = 0, + kReceivedCompositorFrameToStartDraw = 1, + kStartDrawToSwapEnd = 2, + kSwapEndToPresentationCompositorFrame = 3, + kBreakdownCount + }; + CompositorFrameReporter( const base::flat_set<FrameSequenceTrackerType>* active_trackers, bool is_single_threaded = false); @@ -87,20 +104,33 @@ class CC_EXPORT CompositorFrameReporter { // Note that the started stage may be reported to UMA. If the histogram is // intended to be reported then the histograms.xml file must be updated too. - void StartStage(StageType stage_type, - base::TimeTicks start_time, - RollingTimeDeltaHistory* stage_time_delta_history); + void StartStage(StageType stage_type, base::TimeTicks start_time); void TerminateFrame(FrameTerminationStatus termination_status, base::TimeTicks termination_time); + void SetVizBreakdown(const viz::FrameTimingDetails& viz_breakdown); int StageHistorySizeForTesting() { return stage_history_.size(); } + void OnFinishImplFrame(base::TimeTicks timestamp); + void OnAbortBeginMainFrame(); + bool did_finish_impl_frame() const { return did_finish_impl_frame_; } + bool did_abort_main_frame() const { return did_abort_main_frame_; } + base::TimeTicks impl_frame_finish_time() const { + return impl_frame_finish_time_; + } + protected: struct StageData { StageType stage_type; base::TimeTicks start_time; base::TimeTicks end_time; - RollingTimeDeltaHistory* time_delta_history; + viz::FrameTimingDetails viz_breakdown; + StageData(); + StageData(StageType stage_type, + base::TimeTicks start_time, + base::TimeTicks end_time); + StageData(const StageData&); + ~StageData(); }; StageData current_stage_; @@ -114,10 +144,18 @@ class CC_EXPORT CompositorFrameReporter { void TerminateReporter(); void EndCurrentStage(base::TimeTicks end_time); void ReportStageHistograms(bool missed_frame) const; + void ReportStageHistogramWithBreakdown( + CompositorFrameReporter::MissedFrameReportTypes report_type, + FrameSequenceTrackerType frame_sequence_tracker_type, + CompositorFrameReporter::StageData stage) const; + void ReportVizBreakdown( + CompositorFrameReporter::MissedFrameReportTypes report_type, + FrameSequenceTrackerType frame_sequence_tracker_type, + CompositorFrameReporter::StageData stage) const; void ReportHistogram( CompositorFrameReporter::MissedFrameReportTypes report_type, FrameSequenceTrackerType intraction_type, - StageType stage_type, + const int stage_type_index, base::TimeDelta time_delta) const; // Returns true if the stage duration is greater than |kAbnormalityPercentile| @@ -131,6 +169,14 @@ class CC_EXPORT CompositorFrameReporter { FrameTerminationStatus::kUnknown; const base::flat_set<FrameSequenceTrackerType>* active_trackers_; + + // Indicates if work on Impl frame is finished. + bool did_finish_impl_frame_ = false; + // Indicates if main frame is aborted after begin. + bool did_abort_main_frame_ = false; + // The time that work on Impl frame is finished. It's only valid if the + // reporter is in a stage other than begin impl frame. + base::TimeTicks impl_frame_finish_time_; }; } // namespace cc diff --git a/chromium/cc/metrics/compositor_frame_reporter_unittest.cc b/chromium/cc/metrics/compositor_frame_reporter_unittest.cc index 83e23ade478..d11995fa79f 100644 --- a/chromium/cc/metrics/compositor_frame_reporter_unittest.cc +++ b/chromium/cc/metrics/compositor_frame_reporter_unittest.cc @@ -38,13 +38,12 @@ TEST_F(CompositorFrameReporterTest, MainFrameAbortedReportingTest) { pipeline_reporter_->StartStage( CompositorFrameReporter::StageType::kBeginImplFrameToSendBeginMainFrame, - Now(), nullptr); + Now()); EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(3); pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now(), - nullptr); + CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now()); EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(2); @@ -64,13 +63,12 @@ TEST_F(CompositorFrameReporterTest, ReplacedByNewReporterReportingTest) { base::HistogramTester histogram_tester; pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), nullptr); + Now()); EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(3); pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - nullptr); + CompositorFrameReporter::StageType::kEndCommitToActivation, Now()); EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(2); @@ -89,13 +87,13 @@ TEST_F(CompositorFrameReporterTest, SubmittedFrameReportingTest) { base::HistogramTester histogram_tester; pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kActivation, Now(), nullptr); + CompositorFrameReporter::StageType::kActivation, Now()); EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(3); pipeline_reporter_->StartStage( CompositorFrameReporter::StageType::kEndActivateToSubmitCompositorFrame, - Now(), nullptr); + Now()); EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(2); @@ -125,13 +123,12 @@ TEST_F(CompositorFrameReporterTest, SubmittedMissedFrameReportingTest) { base::HistogramTester histogram_tester; pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now(), - nullptr); + CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now()); EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(3); pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), nullptr); + Now()); EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting()); AdvanceNowByMs(2); @@ -158,149 +155,5 @@ TEST_F(CompositorFrameReporterTest, SubmittedMissedFrameReportingTest) { histogram_tester.ExpectBucketCount( "CompositorLatency.MissedFrame.TotalLatency", 5, 1); } - -TEST_F(CompositorFrameReporterTest, MissedFrameLatencyIncreaseReportingTest) { - base::HistogramTester histogram_tester; - RollingTimeDeltaHistory time_delta_history(50); - RollingTimeDeltaHistory time_delta_history2(50); - - // Terminate this frame since it will get destroyed in the for loop. - pipeline_reporter_->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kDidNotProduceFrame, - Now()); - - // Submit 19 non-missed frames. - for (int i = 0; i < 19; ++i) { - pipeline_reporter_ = - std::make_unique<CompositorFrameReporter>(&active_trackers); - pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), &time_delta_history); - AdvanceNowByMs(1); - pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - &time_delta_history2); - pipeline_reporter_->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, - Now()); - } - pipeline_reporter_ = nullptr; - EXPECT_EQ((size_t)19, time_delta_history.sample_count()); - EXPECT_EQ((size_t)19, time_delta_history2.sample_count()); - histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 19); - histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation", - 19); - - // Submit 3 frames missed frames. This will remove 3 sample from the front of - // time delta history. And 16 sample will be in the time delta history. - for (int i = 0; i < 3; ++i) { - pipeline_reporter_ = - std::make_unique<CompositorFrameReporter>(&active_trackers); - pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), &time_delta_history); - AdvanceNowByMs(100); - pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - &time_delta_history2); - pipeline_reporter_->MissedSubmittedFrame(); - pipeline_reporter_->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, - Now()); - } - pipeline_reporter_ = nullptr; - EXPECT_EQ((size_t)16, time_delta_history.sample_count()); - EXPECT_EQ((size_t)16, time_delta_history2.sample_count()); - DCHECK_EQ(time_delta_history.sample_count(), (size_t)16); - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrameLatencyIncrease.Commit", 0); - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrameLatencyIncrease.EndCommitToActivation", 0); - histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 3); - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.EndCommitToActivation", 3); - - // Submit 5 frame so that missed frame duration increases would be reported. - for (int i = 0; i < 5; ++i) { - pipeline_reporter_ = - std::make_unique<CompositorFrameReporter>(&active_trackers); - pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), &time_delta_history); - AdvanceNowByMs(1); - pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - &time_delta_history2); - pipeline_reporter_->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, - Now()); - } - pipeline_reporter_ = nullptr; - EXPECT_EQ((size_t)21, time_delta_history.sample_count()); - EXPECT_EQ((size_t)21, time_delta_history2.sample_count()); - - histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 24); - histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation", - 24); - - // Submit missed frame that is not abnormal (more than 95 percentile of the - // frame history). This brings down the time delta history count to 20. - pipeline_reporter_ = - std::make_unique<CompositorFrameReporter>(&active_trackers); - pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), &time_delta_history); - AdvanceNowByMs(1); - pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - &time_delta_history2); - pipeline_reporter_->MissedSubmittedFrame(); - pipeline_reporter_->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now()); - pipeline_reporter_ = nullptr; - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrameLatencyIncrease.Commit", 0); - histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 4); - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.EndCommitToActivation", 4); - - EXPECT_EQ((size_t)20, time_delta_history.sample_count()); - EXPECT_EQ((size_t)20, time_delta_history2.sample_count()); - - // Submit missed frame that is abnormal (more than 95 percentile of the - // frame history). - pipeline_reporter_ = - std::make_unique<CompositorFrameReporter>(&active_trackers); - pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), &time_delta_history); - AdvanceNowByMs(3); - pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - &time_delta_history2); - pipeline_reporter_->MissedSubmittedFrame(); - pipeline_reporter_->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now()); - pipeline_reporter_ = nullptr; - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrameLatencyIncrease.Commit", 1); - histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 5); - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.EndCommitToActivation", 5); - - // Submit not-missed frame with abnormal times. - pipeline_reporter_ = - std::make_unique<CompositorFrameReporter>(&active_trackers); - pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit, - Now(), &time_delta_history); - AdvanceNowByMs(3); - pipeline_reporter_->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - &time_delta_history2); - pipeline_reporter_->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now()); - pipeline_reporter_ = nullptr; - histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrameLatencyIncrease.Commit", 1); - histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 25); - histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation", - 25); -} - } // namespace } // namespace cc diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller.cc b/chromium/cc/metrics/compositor_frame_reporting_controller.cc index f996975f2d3..760207b87f0 100644 --- a/chromium/cc/metrics/compositor_frame_reporting_controller.cc +++ b/chromium/cc/metrics/compositor_frame_reporting_controller.cc @@ -5,30 +5,17 @@ #include "cc/metrics/compositor_frame_reporting_controller.h" #include "cc/metrics/compositor_frame_reporter.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/quads/compositor_frame_metadata.h" namespace cc { namespace { using StageType = CompositorFrameReporter::StageType; -RollingTimeDeltaHistory* GetStageHistory( - std::unique_ptr<RollingTimeDeltaHistory> stage_history_[], - StageType stage_type) { - return stage_history_[static_cast<int>(stage_type)].get(); -} - -static constexpr size_t kMaxHistorySize = 50; } // namespace CompositorFrameReportingController::CompositorFrameReportingController( bool is_single_threaded) - : is_single_threaded_(is_single_threaded) { - for (int i = 0; i < static_cast<int>( - CompositorFrameReporter::StageType::kStageTypeCount); - ++i) { - stage_history_[i] = - std::make_unique<RollingTimeDeltaHistory>(kMaxHistorySize); - } -} + : is_single_threaded_(is_single_threaded) {} CompositorFrameReportingController::~CompositorFrameReportingController() { base::TimeTicks now = Now(); @@ -72,53 +59,60 @@ void CompositorFrameReportingController::WillBeginImplFrame() { std::unique_ptr<CompositorFrameReporter> reporter = std::make_unique<CompositorFrameReporter>(&active_trackers_, is_single_threaded_); - reporter->StartStage( - CompositorFrameReporter::StageType::kBeginImplFrameToSendBeginMainFrame, - begin_time, - GetStageHistory(stage_history_, CompositorFrameReporter::StageType:: - kBeginImplFrameToSendBeginMainFrame)); + reporter->StartStage(StageType::kBeginImplFrameToSendBeginMainFrame, + begin_time); reporters_[PipelineStage::kBeginImplFrame] = std::move(reporter); } void CompositorFrameReportingController::WillBeginMainFrame() { - DCHECK(reporters_[PipelineStage::kBeginImplFrame]); - // We need to use .get() below because operator<< in std::unique_ptr is a - // C++20 feature. - DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame].get(), - reporters_[PipelineStage::kBeginImplFrame].get()); - reporters_[PipelineStage::kBeginImplFrame]->StartStage( - CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now(), - GetStageHistory( - stage_history_, - CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit)); - AdvanceReporterStage(PipelineStage::kBeginImplFrame, - PipelineStage::kBeginMainFrame); + if (reporters_[PipelineStage::kBeginImplFrame]) { + // We need to use .get() below because operator<< in std::unique_ptr is a + // C++20 feature. + DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame].get(), + reporters_[PipelineStage::kBeginImplFrame].get()); + reporters_[PipelineStage::kBeginImplFrame]->StartStage( + StageType::kSendBeginMainFrameToCommit, Now()); + AdvanceReporterStage(PipelineStage::kBeginImplFrame, + PipelineStage::kBeginMainFrame); + } else { + // In this case we have already submitted the ImplFrame, but we received + // beginMain frame before next BeginImplFrame (Not reached the ImplFrame + // deadline yet). So will start a new reporter at BeginMainFrame. + std::unique_ptr<CompositorFrameReporter> reporter = + std::make_unique<CompositorFrameReporter>(&active_trackers_, + is_single_threaded_); + reporter->StartStage(StageType::kSendBeginMainFrameToCommit, Now()); + reporters_[PipelineStage::kBeginMainFrame] = std::move(reporter); + } } void CompositorFrameReportingController::BeginMainFrameAborted() { DCHECK(reporters_[PipelineStage::kBeginMainFrame]); - std::unique_ptr<CompositorFrameReporter> aborted_frame_reporter = - std::move(reporters_[PipelineStage::kBeginMainFrame]); - aborted_frame_reporter->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kMainFrameAborted, - Now()); + + auto& begin_main_reporter = reporters_[PipelineStage::kBeginMainFrame]; + begin_main_reporter->OnAbortBeginMainFrame(); + + // If the main-frame was aborted (e.g. there was no visible update), then + // advance to activate stage if the compositor has already made changes to + // the active tree (i.e. if impl-frame has finished). + if (begin_main_reporter->did_finish_impl_frame()) { + begin_main_reporter->StartStage( + StageType::kEndActivateToSubmitCompositorFrame, Now()); + AdvanceReporterStage(PipelineStage::kBeginMainFrame, + PipelineStage::kActivate); + } } void CompositorFrameReportingController::WillCommit() { DCHECK(reporters_[PipelineStage::kBeginMainFrame]); - reporters_[PipelineStage::kBeginMainFrame]->StartStage( - CompositorFrameReporter::StageType::kCommit, Now(), - GetStageHistory(stage_history_, - CompositorFrameReporter::StageType::kCommit)); + reporters_[PipelineStage::kBeginMainFrame]->StartStage(StageType::kCommit, + Now()); } void CompositorFrameReportingController::DidCommit() { DCHECK(reporters_[PipelineStage::kBeginMainFrame]); reporters_[PipelineStage::kBeginMainFrame]->StartStage( - CompositorFrameReporter::StageType::kEndCommitToActivation, Now(), - GetStageHistory( - stage_history_, - CompositorFrameReporter::StageType::kEndCommitToActivation)); + StageType::kEndCommitToActivation, Now()); AdvanceReporterStage(PipelineStage::kBeginMainFrame, PipelineStage::kCommit); } @@ -132,10 +126,7 @@ void CompositorFrameReportingController::WillActivate() { DCHECK(reporters_[PipelineStage::kCommit] || next_activate_has_invalidation_); if (!reporters_[PipelineStage::kCommit]) return; - reporters_[PipelineStage::kCommit]->StartStage( - CompositorFrameReporter::StageType::kActivation, Now(), - GetStageHistory(stage_history_, - CompositorFrameReporter::StageType::kActivation)); + reporters_[PipelineStage::kCommit]->StartStage(StageType::kActivation, Now()); } void CompositorFrameReportingController::DidActivate() { @@ -144,50 +135,60 @@ void CompositorFrameReportingController::DidActivate() { if (!reporters_[PipelineStage::kCommit]) return; reporters_[PipelineStage::kCommit]->StartStage( - CompositorFrameReporter::StageType::kEndActivateToSubmitCompositorFrame, - Now(), - GetStageHistory(stage_history_, CompositorFrameReporter::StageType:: - kEndActivateToSubmitCompositorFrame)); + StageType::kEndActivateToSubmitCompositorFrame, Now()); AdvanceReporterStage(PipelineStage::kCommit, PipelineStage::kActivate); } void CompositorFrameReportingController::DidSubmitCompositorFrame( uint32_t frame_token) { + // If there is no reporter in active stage and there exists a finished + // BeginImplFrame reporter (i.e. if impl-frame has finished), then advance it + // to the activate stage. + if (!reporters_[PipelineStage::kActivate] && + reporters_[PipelineStage::kBeginImplFrame]) { + auto& begin_impl_frame = reporters_[PipelineStage::kBeginImplFrame]; + if (begin_impl_frame->did_finish_impl_frame()) { + begin_impl_frame->StartStage( + StageType::kEndActivateToSubmitCompositorFrame, + begin_impl_frame->impl_frame_finish_time()); + AdvanceReporterStage(PipelineStage::kBeginImplFrame, + PipelineStage::kActivate); + } + } + if (!reporters_[PipelineStage::kActivate]) return; + std::unique_ptr<CompositorFrameReporter> submitted_reporter = std::move(reporters_[PipelineStage::kActivate]); - // If there are any other reporters active on the other stages of the - // pipeline then that means a new frame was started during the duration of - // this reporter and therefore the frame being tracked missed the deadline. - if (reporters_[PipelineStage::kBeginImplFrame] || - reporters_[PipelineStage::kBeginMainFrame] || - reporters_[PipelineStage::kCommit]) { - submitted_reporter->MissedSubmittedFrame(); - } submitted_reporter->StartStage( - CompositorFrameReporter::StageType:: - kSubmitCompositorFrameToPresentationCompositorFrame, - Now(), - GetStageHistory(stage_history_, - CompositorFrameReporter::StageType:: - kSubmitCompositorFrameToPresentationCompositorFrame)); + StageType::kSubmitCompositorFrameToPresentationCompositorFrame, Now()); submitted_compositor_frames_.emplace_back(frame_token, std::move(submitted_reporter)); } -void CompositorFrameReportingController::DidNotProduceFrame() { - if (!reporters_[PipelineStage::kActivate]) - return; - reporters_[PipelineStage::kActivate]->TerminateFrame( - CompositorFrameReporter::FrameTerminationStatus::kDidNotProduceFrame, - Now()); - reporters_[PipelineStage::kActivate] = nullptr; +void CompositorFrameReportingController::OnFinishImplFrame() { + if (reporters_[PipelineStage::kBeginImplFrame]) { + reporters_[PipelineStage::kBeginImplFrame]->OnFinishImplFrame(Now()); + } else if (reporters_[PipelineStage::kBeginMainFrame]) { + auto& begin_main_reporter = reporters_[PipelineStage::kBeginMainFrame]; + begin_main_reporter->OnFinishImplFrame(Now()); + + // If the main-frame was aborted (e.g. there was no visible update), then + // advance to activate stage if the compositor has already made changes to + // the active tree (i.e. if impl-frame has finished). + if (begin_main_reporter->did_abort_main_frame()) { + begin_main_reporter->StartStage( + StageType::kEndActivateToSubmitCompositorFrame, Now()); + AdvanceReporterStage(PipelineStage::kBeginMainFrame, + PipelineStage::kActivate); + } + } } void CompositorFrameReportingController::DidPresentCompositorFrame( uint32_t frame_token, - base::TimeTicks presentation_time) { + const viz::FrameTimingDetails& details) { while (!submitted_compositor_frames_.empty()) { auto submitted_frame = submitted_compositor_frames_.begin(); if (viz::FrameTokenGT(submitted_frame->frame_token, frame_token)) @@ -199,8 +200,9 @@ void CompositorFrameReportingController::DidPresentCompositorFrame( termination_status = CompositorFrameReporter::FrameTerminationStatus::kDidNotPresentFrame; - submitted_frame->reporter->TerminateFrame(termination_status, - presentation_time); + submitted_frame->reporter->SetVizBreakdown(details); + submitted_frame->reporter->TerminateFrame( + termination_status, details.presentation_feedback.timestamp); submitted_compositor_frames_.erase(submitted_frame); } } diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller.h b/chromium/cc/metrics/compositor_frame_reporting_controller.h index ef37fcda7e9..80254c1dc64 100644 --- a/chromium/cc/metrics/compositor_frame_reporting_controller.h +++ b/chromium/cc/metrics/compositor_frame_reporting_controller.h @@ -15,6 +15,10 @@ #include "cc/metrics/compositor_frame_reporter.h" #include "cc/metrics/frame_sequence_tracker.h" +namespace viz { +struct FrameTimingDetails; +} + namespace cc { class RollingTimeDeltaHistory; @@ -53,9 +57,10 @@ class CC_EXPORT CompositorFrameReportingController { virtual void WillActivate(); virtual void DidActivate(); virtual void DidSubmitCompositorFrame(uint32_t frame_token); - virtual void DidNotProduceFrame(); - virtual void DidPresentCompositorFrame(uint32_t frame_token, - base::TimeTicks presentation_time); + virtual void OnFinishImplFrame(); + virtual void DidPresentCompositorFrame( + uint32_t frame_token, + const viz::FrameTimingDetails& details); virtual void AddActiveTracker(FrameSequenceTrackerType type); virtual void RemoveActiveTracker(FrameSequenceTrackerType type); diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc b/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc index e12ba768f17..6fd89c4a30a 100644 --- a/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc +++ b/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc @@ -6,6 +6,7 @@ #include "base/macros.h" #include "base/test/metrics/histogram_tester.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/quads/compositor_frame_metadata.h" #include "testing/gtest/include/gtest/gtest.h" @@ -93,8 +94,9 @@ class CompositorFrameReportingControllerTest : public testing::Test { void SimulatePresentCompositorFrame() { ++next_token_; SimulateSubmitCompositorFrame(*next_token_); - reporting_controller_.DidPresentCompositorFrame(*next_token_, - base::TimeTicks::Now()); + viz::FrameTimingDetails details = {}; + details.presentation_feedback.timestamp = base::TimeTicks::Now(); + reporting_controller_.DidPresentCompositorFrame(*next_token_, details); } protected: @@ -171,41 +173,37 @@ TEST_F(CompositorFrameReportingControllerTest, // 2 reporters active. SimulateActivate(); - SimulateBeginImplFrame(); + SimulateCommit(); - // Submitting and Presenting the next reporter should be a missed. + // Submitting and Presenting the next reporter which will be a normal frame. SimulatePresentCompositorFrame(); histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.BeginImplFrameToSendBeginMainFrame", 1); + "CompositorLatency.MissedFrame.BeginImplFrameToSendBeginMainFrame", 0); histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.SendBeginMainFrameToCommit", 1); - histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 1); + "CompositorLatency.MissedFrame.SendBeginMainFrameToCommit", 0); + histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 0); histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.EndCommitToActivation", 1); + "CompositorLatency.MissedFrame.EndCommitToActivation", 0); histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Activation", - 1); + 0); histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 1); - - // Other histograms should not be reported. + "CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 0); histogram_tester.ExpectTotalCount( - "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 0); + "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1); histogram_tester.ExpectTotalCount( - "CompositorLatency.SendBeginMainFrameToCommit", 0); - histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 0); + "CompositorLatency.SendBeginMainFrameToCommit", 1); + histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1); histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation", - 0); - histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 0); + 1); + histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1); histogram_tester.ExpectTotalCount( - "CompositorLatency.EndActivateToSubmitCompositorFrame", 0); + "CompositorLatency.EndActivateToSubmitCompositorFrame", 1); - // Submitting the next reporter will not be counted as missed. - // In practice this submitted frame should be considered as missed because a - // new BeginFrame would have been issued, which is the cause for this frame - // submission. - SimulatePresentCompositorFrame(); - // Other histograms should not be reported. + // Submitting the next reporter will be replaced as a result of a new commit. + // And this will be reported for all stage before activate as a missed frame. + SimulateCommit(); + // Non Missed frame histogram counts should not change. histogram_tester.ExpectTotalCount( "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1); histogram_tester.ExpectTotalCount( @@ -217,7 +215,7 @@ TEST_F(CompositorFrameReportingControllerTest, histogram_tester.ExpectTotalCount( "CompositorLatency.EndActivateToSubmitCompositorFrame", 1); - // Missed frame histogram counts should not change. + // Other histograms should be reported updated. histogram_tester.ExpectTotalCount( "CompositorLatency.MissedFrame.BeginImplFrameToSendBeginMainFrame", 1); histogram_tester.ExpectTotalCount( @@ -226,9 +224,9 @@ TEST_F(CompositorFrameReportingControllerTest, histogram_tester.ExpectTotalCount( "CompositorLatency.MissedFrame.EndCommitToActivation", 1); histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Activation", - 1); + 0); histogram_tester.ExpectTotalCount( - "CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 1); + "CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 0); } } // namespace } // namespace cc diff --git a/chromium/cc/metrics/compositor_timing_history.cc b/chromium/cc/metrics/compositor_timing_history.cc index 0e478f818db..d244237b7e9 100644 --- a/chromium/cc/metrics/compositor_timing_history.cc +++ b/chromium/cc/metrics/compositor_timing_history.cc @@ -48,13 +48,15 @@ class CompositorTimingHistory::UMAReporter { virtual void AddDrawDuration(base::TimeDelta duration) = 0; virtual void AddSubmitToAckLatency(base::TimeDelta duration) = 0; - // crbug.com/758439: the following 3 functions are used to report timing in + // crbug.com/758439: the following functions are used to report timing in // certain conditions targeting blink / compositor animations. // Only the renderer would get the meaningful data. virtual void AddDrawIntervalWithCompositedAnimations( base::TimeDelta duration) = 0; virtual void AddDrawIntervalWithMainThreadAnimations( base::TimeDelta duration) = 0; + virtual void AddDrawIntervalWithCustomPropertyAnimations( + base::TimeDelta duration) = 0; // Synchronization measurements virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0; @@ -329,6 +331,13 @@ class RendererUMAReporter : public CompositorTimingHistory::UMAReporter { "Scheduling.Renderer.DrawIntervalWithMainThreadAnimations", interval); } + void AddDrawIntervalWithCustomPropertyAnimations( + base::TimeDelta interval) override { + UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED( + "Scheduling.Renderer.DrawIntervalWithCustomPropertyAnimations", + interval); + } + void AddBeginImplFrameLatency(base::TimeDelta delta) override { UMA_HISTOGRAM_CUSTOM_TIMES_DURATION( "Scheduling.Renderer.BeginImplFrameLatency", delta); @@ -432,6 +441,9 @@ class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { void AddDrawIntervalWithMainThreadAnimations( base::TimeDelta interval) override {} + void AddDrawIntervalWithCustomPropertyAnimations( + base::TimeDelta interval) override {} + void AddBeginImplFrameLatency(base::TimeDelta delta) override { UMA_HISTOGRAM_CUSTOM_TIMES_DURATION( "Scheduling.Browser.BeginImplFrameLatency", delta); @@ -507,6 +519,8 @@ class NullUMAReporter : public CompositorTimingHistory::UMAReporter { base::TimeDelta inverval) override {} void AddDrawIntervalWithMainThreadAnimations( base::TimeDelta inverval) override {} + void AddDrawIntervalWithCustomPropertyAnimations( + base::TimeDelta inverval) override {} void AddBeginImplFrameLatency(base::TimeDelta delta) override {} void AddBeginMainFrameQueueDurationCriticalDuration( base::TimeDelta duration) override {} @@ -721,6 +735,8 @@ void CompositorTimingHistory::WillBeginImplFrame( void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) { if (!needs_redraw) SetCompositorDrawingContinuously(false); + + compositor_frame_reporting_controller_->OnFinishImplFrame(); } void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() { @@ -964,7 +980,8 @@ void CompositorTimingHistory::DidDraw(bool used_new_active_tree, size_t composited_animations_count, size_t main_thread_animations_count, bool current_frame_had_raf, - bool next_frame_has_pending_raf) { + bool next_frame_has_pending_raf, + bool has_custom_property_animations) { DCHECK_NE(base::TimeTicks(), draw_start_time_); base::TimeTicks draw_end_time = Now(); base::TimeDelta draw_duration = draw_end_time - draw_start_time_; @@ -989,8 +1006,13 @@ void CompositorTimingHistory::DidDraw(bool used_new_active_tree, if (composited_animations_count > 0 && previous_frame_had_composited_animations_) uma_reporter_->AddDrawIntervalWithCompositedAnimations(draw_interval); + if (has_custom_property_animations && + previous_frame_had_custom_property_animations_) + uma_reporter_->AddDrawIntervalWithCustomPropertyAnimations(draw_interval); } previous_frame_had_composited_animations_ = composited_animations_count > 0; + previous_frame_had_custom_property_animations_ = + has_custom_property_animations; draw_end_time_prev_ = draw_end_time; if (used_new_active_tree) { @@ -1049,10 +1071,6 @@ void CompositorTimingHistory::DidSubmitCompositorFrame(uint32_t frame_token) { submit_start_time_ = Now(); } -void CompositorTimingHistory::DidNotProduceFrame() { - compositor_frame_reporting_controller_->DidNotProduceFrame(); -} - void CompositorTimingHistory::DidReceiveCompositorFrameAck() { DCHECK_NE(base::TimeTicks(), submit_start_time_); base::TimeDelta submit_to_ack_duration = Now() - submit_start_time_; @@ -1062,9 +1080,9 @@ void CompositorTimingHistory::DidReceiveCompositorFrameAck() { void CompositorTimingHistory::DidPresentCompositorFrame( uint32_t frame_token, - base::TimeTicks presentation_time) { - compositor_frame_reporting_controller_->DidPresentCompositorFrame( - frame_token, presentation_time); + const viz::FrameTimingDetails& details) { + compositor_frame_reporting_controller_->DidPresentCompositorFrame(frame_token, + details); } void CompositorTimingHistory::SetTreePriority(TreePriority priority) { diff --git a/chromium/cc/metrics/compositor_timing_history.h b/chromium/cc/metrics/compositor_timing_history.h index 8f83b3be7fa..c39f69ad071 100644 --- a/chromium/cc/metrics/compositor_timing_history.h +++ b/chromium/cc/metrics/compositor_timing_history.h @@ -18,6 +18,10 @@ class TracedValue; } // namespace trace_event } // namespace base +namespace viz { +struct FrameTimingDetails; +} + namespace cc { class CompositorFrameReportingController; @@ -87,12 +91,12 @@ class CC_EXPORT CompositorTimingHistory { size_t composited_animations_count, size_t main_thread_animations_count, bool current_frame_had_raf, - bool next_frame_has_pending_raf); + bool next_frame_has_pending_raf, + bool has_custom_property_animations); void DidSubmitCompositorFrame(uint32_t frame_token); - void DidNotProduceFrame(); void DidReceiveCompositorFrameAck(); void DidPresentCompositorFrame(uint32_t frame_token, - base::TimeTicks presentation_time); + const viz::FrameTimingDetails& details); void WillInvalidateOnImplSide(); void SetTreePriority(TreePriority priority); @@ -173,6 +177,7 @@ class CC_EXPORT CompositorTimingHistory { // Used only for reporting animation targeted UMA. bool previous_frame_had_composited_animations_ = false; bool previous_frame_had_main_thread_animations_ = false; + bool previous_frame_had_custom_property_animations_ = false; bool previous_frame_had_raf_ = false; TreePriority tree_priority_ = SAME_PRIORITY_FOR_BOTH_TREES; diff --git a/chromium/cc/metrics/compositor_timing_history_unittest.cc b/chromium/cc/metrics/compositor_timing_history_unittest.cc index c0fba798c2e..81f72e61733 100644 --- a/chromium/cc/metrics/compositor_timing_history_unittest.cc +++ b/chromium/cc/metrics/compositor_timing_history_unittest.cc @@ -53,6 +53,7 @@ class CompositorTimingHistoryTest : public testing::Test { base::TimeTicks Now() { return now_; } + // TODO(xidachen): the composited_animations_count should just be 0. void DrawMainFrame(int advance_ms, int composited_animations_count, int main_thread_animations_count, @@ -69,12 +70,13 @@ class CompositorTimingHistoryTest : public testing::Test { AdvanceNowBy(base::TimeDelta::FromMicroseconds(advance_ms)); timing_history_.DidDraw(true, Now(), composited_animations_count, main_thread_animations_count, current_frame_had_raf, - next_frame_has_pending_raf); + next_frame_has_pending_raf, false); } void DrawImplFrame(int advance_ms, int composited_animations_count, - int main_thread_animations_count) { + int main_thread_animations_count, + bool has_custom_property_animation) { timing_history_.WillBeginMainFrame(true, Now()); timing_history_.BeginMainFrameStarted(Now()); timing_history_.BeginMainFrameAborted(); @@ -83,7 +85,8 @@ class CompositorTimingHistoryTest : public testing::Test { timing_history_.WillDraw(); AdvanceNowBy(base::TimeDelta::FromMicroseconds(advance_ms)); timing_history_.DidDraw(false, Now(), composited_animations_count, - main_thread_animations_count, false, false); + main_thread_animations_count, false, false, + has_custom_property_animation); } protected: @@ -137,7 +140,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_Commit) { AdvanceNowBy(one_second); timing_history_.WillDraw(); AdvanceNowBy(draw_duration); - timing_history_.DidDraw(true, Now(), 0, 0, false, false); + timing_history_.DidDraw(true, Now(), 0, 0, false, false, false); EXPECT_EQ(begin_main_frame_queue_duration, timing_history_.BeginMainFrameQueueDurationCriticalEstimate()); @@ -188,7 +191,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_BeginMainFrameAborted) { AdvanceNowBy(one_second); timing_history_.WillDraw(); AdvanceNowBy(draw_duration); - timing_history_.DidDraw(false, Now(), 0, 0, false, false); + timing_history_.DidDraw(false, Now(), 0, 0, false, false, false); EXPECT_EQ(base::TimeDelta(), timing_history_.BeginMainFrameQueueDurationCriticalEstimate()); @@ -417,10 +420,10 @@ TEST_F(CompositorTimingHistoryTest, InterFrameAnimationsNotReported) { TEST_F(CompositorTimingHistoryTest, AnimationsWithNewActiveTreeNotUsed) { base::HistogramTester histogram_tester; - DrawImplFrame(123, 1, 1); + DrawImplFrame(123, 1, 1, false); TestAnimationUMA(histogram_tester, 0, 0); - DrawImplFrame(456, 1, 0); + DrawImplFrame(456, 1, 0, false); TestAnimationUMA(histogram_tester, 1, 0); histogram_tester.ExpectBucketCount( "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 456, 1); @@ -430,7 +433,7 @@ TEST_F(CompositorTimingHistoryTest, AnimationsWithNewActiveTreeNotUsed) { // This frame verifies that we record that there is a composited animation, // so in the next frame when there is a composited animation, we report it. - DrawImplFrame(234, 1, 1); + DrawImplFrame(234, 1, 1, false); TestAnimationUMA(histogram_tester, 1, 0); // Even though the previous frame had no main thread animation, we report it @@ -445,11 +448,36 @@ TEST_F(CompositorTimingHistoryTest, AnimationsWithNewActiveTreeNotUsed) { histogram_tester.ExpectBucketCount( "Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2", 888, 1); - DrawImplFrame(123, 1, 0); + DrawImplFrame(123, 1, 0, false); TestAnimationUMA(histogram_tester, 3, 1); histogram_tester.ExpectBucketCount( "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 123, 1); } +TEST_F(CompositorTimingHistoryTest, CustomPropertyAnimations) { + base::HistogramTester histogram_tester; + + DrawImplFrame(123, 1, 0, true); + TestAnimationUMA(histogram_tester, 0, 0); + + DrawImplFrame(456, 1, 0, true); + TestAnimationUMA(histogram_tester, 1, 0); + + histogram_tester.ExpectBucketCount( + "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 456, 1); + histogram_tester.ExpectBucketCount( + "Scheduling.Renderer.DrawIntervalWithCustomPropertyAnimations2", 456, 1); + + DrawImplFrame(1234, 1, 0, false); + DrawImplFrame(2345, 1, 0, true); + TestAnimationUMA(histogram_tester, 3, 0); + histogram_tester.ExpectBucketCount( + "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 2345, 1); + // This impl frame does have custom property animation, but the previous impl + // frame doesn't, so we won't report it. + histogram_tester.ExpectBucketCount( + "Scheduling.Renderer.DrawIntervalWithCustomPropertyAnimations2", 2345, 0); +} + } // namespace } // namespace cc diff --git a/chromium/cc/metrics/frame_sequence_tracker.cc b/chromium/cc/metrics/frame_sequence_tracker.cc index 51bc0374cd9..5ba4bf9f95b 100644 --- a/chromium/cc/metrics/frame_sequence_tracker.cc +++ b/chromium/cc/metrics/frame_sequence_tracker.cc @@ -23,6 +23,7 @@ constexpr const char* FrameSequenceTracker::kFrameSequenceTrackerTypeNames[] = { [FrameSequenceTrackerType::kPinchZoom] = "PinchZoom", [FrameSequenceTrackerType::kRAF] = "RAF", [FrameSequenceTrackerType::kTouchScroll] = "TouchScroll", + [FrameSequenceTrackerType::kUniversal] = "Universal", [FrameSequenceTrackerType::kVideo] = "Video", [FrameSequenceTrackerType::kWheelScroll] = "WheelScroll", [FrameSequenceTrackerType::kMaxType] = "", @@ -37,16 +38,38 @@ constexpr int kMinFramesForThroughputMetric = 4; enum class ThreadType { kMain, kCompositor, + kSlower, }; constexpr int kBuiltinSequenceNum = base::size(FrameSequenceTracker::kFrameSequenceTrackerTypeNames); -constexpr int kMaximumHistogramIndex = 2 * kBuiltinSequenceNum; +constexpr int kMaximumHistogramIndex = 3 * kBuiltinSequenceNum; int GetIndexForMetric(ThreadType thread_type, FrameSequenceTrackerType type) { - return thread_type == ThreadType::kMain - ? static_cast<int>(type) - : static_cast<int>(type + kBuiltinSequenceNum); + if (thread_type == ThreadType::kMain) + return static_cast<int>(type); + if (thread_type == ThreadType::kCompositor) + return static_cast<int>(type + kBuiltinSequenceNum); + return static_cast<int>(type + 2 * kBuiltinSequenceNum); +} + +std::string GetCheckerboardingHistogramName(FrameSequenceTrackerType type) { + return base::StrCat( + {"Graphics.Smoothness.Checkerboarding.", + FrameSequenceTracker::kFrameSequenceTrackerTypeNames[type]}); +} + +std::string GetThroughputHistogramName(FrameSequenceTrackerType type, + const char* thread_name) { + return base::StrCat( + {"Graphics.Smoothness.Throughput.", thread_name, ".", + FrameSequenceTracker::kFrameSequenceTrackerTypeNames[type]}); +} + +std::string GetFrameSequenceLengthHistogramName(FrameSequenceTrackerType type) { + return base::StrCat( + {"Graphics.Smoothness.FrameSequenceLength.", + FrameSequenceTracker::kFrameSequenceTrackerTypeNames[type]}); } } // namespace @@ -55,8 +78,10 @@ int GetIndexForMetric(ThreadType thread_type, FrameSequenceTrackerType type) { // FrameSequenceTrackerCollection FrameSequenceTrackerCollection::FrameSequenceTrackerCollection( + bool is_single_threaded, CompositorFrameReportingController* compositor_frame_reporting_controller) - : compositor_frame_reporting_controller_( + : is_single_threaded_(is_single_threaded), + compositor_frame_reporting_controller_( compositor_frame_reporting_controller) {} FrameSequenceTrackerCollection::~FrameSequenceTrackerCollection() { @@ -66,6 +91,8 @@ FrameSequenceTrackerCollection::~FrameSequenceTrackerCollection() { void FrameSequenceTrackerCollection::StartSequence( FrameSequenceTrackerType type) { + if (is_single_threaded_) + return; if (frame_trackers_.contains(type)) return; auto tracker = base::WrapUnique(new FrameSequenceTracker(type)); @@ -98,16 +125,15 @@ void FrameSequenceTrackerCollection::ClearAll() { void FrameSequenceTrackerCollection::NotifyBeginImplFrame( const viz::BeginFrameArgs& args) { - for (auto& tracker : frame_trackers_) { + RecreateTrackers(args); + for (auto& tracker : frame_trackers_) tracker.second->ReportBeginImplFrame(args); - } } void FrameSequenceTrackerCollection::NotifyBeginMainFrame( const viz::BeginFrameArgs& args) { - for (auto& tracker : frame_trackers_) { + for (auto& tracker : frame_trackers_) tracker.second->ReportBeginMainFrame(args); - } } void FrameSequenceTrackerCollection::NotifyImplFrameCausedNoDamage( @@ -158,6 +184,24 @@ void FrameSequenceTrackerCollection::NotifyFramePresented( }); } +void FrameSequenceTrackerCollection::RecreateTrackers( + const viz::BeginFrameArgs& args) { + std::vector<FrameSequenceTrackerType> recreate_trackers; + for (const auto& tracker : frame_trackers_) { + if (tracker.second->ShouldReportMetricsNow(args)) + recreate_trackers.push_back(tracker.first); + } + + for (const auto& tracker_type : recreate_trackers) { + // StopSequence put the tracker in the |removal_trackers_|, which will + // report its throughput data when its frame is presented. + StopSequence(tracker_type); + // The frame sequence is still active, so create a new tracker to keep + // tracking this sequence. + StartSequence(tracker_type); + } +} + FrameSequenceTracker* FrameSequenceTrackerCollection::GetTrackerForTesting( FrameSequenceTrackerType type) { if (!frame_trackers_.contains(type)) @@ -185,28 +229,45 @@ FrameSequenceTracker::~FrameSequenceTracker() { "cc,benchmark", "FrameSequenceTracker", this, "args", ThroughputData::ToTracedValue(impl_throughput_, main_throughput_), "checkerboard", checkerboarding_.frames_checkerboarded); + ReportMetrics(); +} +void FrameSequenceTracker::ReportMetrics() { // Report the throughput metrics. - ThroughputData::ReportHistogram( + base::Optional<int> impl_throughput_percent = ThroughputData::ReportHistogram( type_, "CompositorThread", GetIndexForMetric(ThreadType::kCompositor, type_), impl_throughput_); - ThroughputData::ReportHistogram(type_, "MainThread", - GetIndexForMetric(ThreadType::kMain, type_), - main_throughput_); + base::Optional<int> main_throughput_percent = ThroughputData::ReportHistogram( + type_, "MainThread", GetIndexForMetric(ThreadType::kMain, type_), + main_throughput_); + + base::Optional<ThroughputData> slower_throughput; + if (impl_throughput_percent && + (!main_throughput_percent || + impl_throughput_percent.value() <= main_throughput_percent.value())) { + slower_throughput = impl_throughput_; + } + if (main_throughput_percent && + (!impl_throughput_percent || + main_throughput_percent.value() < impl_throughput_percent.value())) { + slower_throughput = main_throughput_; + } + if (slower_throughput.has_value()) { + ThroughputData::ReportHistogram( + type_, "SlowerThread", GetIndexForMetric(ThreadType::kSlower, type_), + slower_throughput.value()); + } // Report the checkerboarding metrics. if (impl_throughput_.frames_expected >= kMinFramesForThroughputMetric) { - const std::string checkerboarding_name = - base::StrCat({"Graphics.Smoothness.Checkerboarding.", - kFrameSequenceTrackerTypeNames[type_]}); const int checkerboarding_percent = static_cast<int>(100 * checkerboarding_.frames_checkerboarded / impl_throughput_.frames_expected); STATIC_HISTOGRAM_POINTER_GROUP( - checkerboarding_name, type_, FrameSequenceTrackerType::kMaxType, - Add(checkerboarding_percent), + GetCheckerboardingHistogramName(type_), type_, + FrameSequenceTrackerType::kMaxType, Add(checkerboarding_percent), base::LinearHistogram::FactoryGet( - checkerboarding_name, 1, 100, 101, + GetCheckerboardingHistogramName(type_), 1, 100, 101, base::HistogramBase::kUmaTargetedHistogramFlag)); } } @@ -223,6 +284,9 @@ void FrameSequenceTracker::ReportBeginImplFrame( args.sequence_number); impl_throughput_.frames_expected += begin_impl_frame_data_.previous_sequence_delta; + + if (first_frame_timestamp_.is_null()) + first_frame_timestamp_ = args.frame_time; } void FrameSequenceTracker::ReportBeginMainFrame( @@ -442,35 +506,40 @@ FrameSequenceTracker::ThroughputData::ToTracedValue( return dict; } -void FrameSequenceTracker::ThroughputData::ReportHistogram( +bool FrameSequenceTracker::ShouldReportMetricsNow( + const viz::BeginFrameArgs& args) const { + if (!first_frame_timestamp_.is_null() && + args.frame_time - first_frame_timestamp_ >= time_delta_to_report_) + return true; + return false; +} + +base::Optional<int> FrameSequenceTracker::ThroughputData::ReportHistogram( FrameSequenceTrackerType sequence_type, const char* thread_name, int metric_index, const ThroughputData& data) { DCHECK_LT(sequence_type, FrameSequenceTrackerType::kMaxType); - const std::string sequence_length_name = base::StrCat( - {"Graphics.Smoothness.FrameSequenceLength.", - FrameSequenceTracker::kFrameSequenceTrackerTypeNames[sequence_type]}); STATIC_HISTOGRAM_POINTER_GROUP( - sequence_length_name, sequence_type, FrameSequenceTrackerType::kMaxType, - Add(data.frames_expected), + GetFrameSequenceLengthHistogramName(sequence_type), sequence_type, + FrameSequenceTrackerType::kMaxType, Add(data.frames_expected), base::Histogram::FactoryGet( - sequence_length_name, 1, 1000, 50, + GetFrameSequenceLengthHistogramName(sequence_type), 1, 1000, 50, base::HistogramBase::kUmaTargetedHistogramFlag)); if (data.frames_expected < kMinFramesForThroughputMetric) - return; + return base::nullopt; - const std::string name = base::StrCat( - {"Graphics.Smoothness.Throughput.", thread_name, ".", - FrameSequenceTracker::kFrameSequenceTrackerTypeNames[sequence_type]}); const int percent = static_cast<int>(100 * data.frames_produced / data.frames_expected); STATIC_HISTOGRAM_POINTER_GROUP( - name, metric_index, kMaximumHistogramIndex, Add(percent), + GetThroughputHistogramName(sequence_type, thread_name), metric_index, + kMaximumHistogramIndex, Add(percent), base::LinearHistogram::FactoryGet( - name, 1, 100, 101, base::HistogramBase::kUmaTargetedHistogramFlag)); + GetThroughputHistogramName(sequence_type, thread_name), 1, 100, 101, + base::HistogramBase::kUmaTargetedHistogramFlag)); + return percent; } FrameSequenceTracker::CheckerboardingData::CheckerboardingData() = default; diff --git a/chromium/cc/metrics/frame_sequence_tracker.h b/chromium/cc/metrics/frame_sequence_tracker.h index bea4723f4f2..5004aa001c5 100644 --- a/chromium/cc/metrics/frame_sequence_tracker.h +++ b/chromium/cc/metrics/frame_sequence_tracker.h @@ -15,6 +15,7 @@ #include "base/containers/circular_deque.h" #include "base/containers/flat_map.h" #include "base/macros.h" +#include "base/optional.h" #include "base/trace_event/traced_value.h" #include "cc/cc_export.h" @@ -33,12 +34,13 @@ class CompositorFrameReportingController; enum FrameSequenceTrackerType { kCompositorAnimation = 0, - kMainThreadAnimation, - kPinchZoom, - kRAF, - kTouchScroll, - kVideo, - kWheelScroll, + kMainThreadAnimation = 1, + kPinchZoom = 2, + kRAF = 3, + kTouchScroll = 4, + kUniversal = 5, + kVideo = 6, + kWheelScroll = 7, kMaxType }; @@ -46,8 +48,9 @@ enum FrameSequenceTrackerType { // submitted frames. class CC_EXPORT FrameSequenceTrackerCollection { public: - explicit FrameSequenceTrackerCollection( - CompositorFrameReportingController* = nullptr); + FrameSequenceTrackerCollection( + bool is_single_threaded, + CompositorFrameReportingController* frame_reporting_controller); ~FrameSequenceTrackerCollection(); FrameSequenceTrackerCollection(const FrameSequenceTrackerCollection&) = @@ -93,6 +96,9 @@ class CC_EXPORT FrameSequenceTrackerCollection { private: friend class FrameSequenceTrackerTest; + void RecreateTrackers(const viz::BeginFrameArgs& args); + + const bool is_single_threaded_; // The callsite can use the type to manipulate the tracker. base::flat_map<FrameSequenceTrackerType, std::unique_ptr<FrameSequenceTracker>> @@ -163,6 +169,9 @@ class CC_EXPORT FrameSequenceTracker { TerminationStatus termination_status() const { return termination_status_; } + // Returns true if we should ask this tracker to report its throughput data. + bool ShouldReportMetricsNow(const viz::BeginFrameArgs& args) const; + private: friend class FrameSequenceTrackerCollection; friend class FrameSequenceTrackerTest; @@ -189,10 +198,13 @@ class CC_EXPORT FrameSequenceTracker { static std::unique_ptr<base::trace_event::TracedValue> ToTracedValue( const ThroughputData& impl, const ThroughputData& main); - static void ReportHistogram(FrameSequenceTrackerType sequence_type, - const char* thread_name, - int metric_index, - const ThroughputData& data); + // Returns the throughput in percent, a return value of base::nullopt + // indicates that no throughput metric is reported. + static base::Optional<int> ReportHistogram( + FrameSequenceTrackerType sequence_type, + const char* thread_name, + int metric_index, + const ThroughputData& data); // Tracks the number of frames that were expected to be shown during this // frame-sequence. uint32_t frames_expected = 0; @@ -226,6 +238,9 @@ class CC_EXPORT FrameSequenceTracker { bool ShouldIgnoreBeginFrameSource(uint64_t source_id) const; + // Report related metrics: throughput, checkboarding... + void ReportMetrics(); + const FrameSequenceTrackerType type_; TerminationStatus termination_status_ = TerminationStatus::kActive; @@ -262,6 +277,13 @@ class CC_EXPORT FrameSequenceTracker { // Keeps track of the last sequence-number that produced a frame from the // main-thread. uint64_t last_submitted_main_sequence_ = 0; + + // The time when this tracker is created, or the time when it was previously + // scheduled to report histogram. + base::TimeTicks first_frame_timestamp_; + + // Report the throughput metrics every 5 seconds. + const base::TimeDelta time_delta_to_report_ = base::TimeDelta::FromSeconds(5); }; } // namespace cc diff --git a/chromium/cc/metrics/frame_sequence_tracker_unittest.cc b/chromium/cc/metrics/frame_sequence_tracker_unittest.cc index 41fa3361591..53d9b62a8d3 100644 --- a/chromium/cc/metrics/frame_sequence_tracker_unittest.cc +++ b/chromium/cc/metrics/frame_sequence_tracker_unittest.cc @@ -7,6 +7,7 @@ #include <vector> #include "base/macros.h" +#include "base/test/metrics/histogram_tester.h" #include "cc/metrics/compositor_frame_reporting_controller.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,7 +23,8 @@ class FrameSequenceTrackerTest : public testing::Test { FrameSequenceTrackerTest() : compositor_frame_reporting_controller_( std::make_unique<CompositorFrameReportingController>()), - collection_(compositor_frame_reporting_controller_.get()) { + collection_(/* is_single_threaded=*/false, + compositor_frame_reporting_controller_.get()) { collection_.StartSequence(FrameSequenceTrackerType::kTouchScroll); tracker_ = collection_.GetTrackerForTesting( FrameSequenceTrackerType::kTouchScroll); @@ -35,9 +37,10 @@ class FrameSequenceTrackerTest : public testing::Test { FrameSequenceTrackerType::kTouchScroll); } - viz::BeginFrameArgs CreateBeginFrameArgs(uint64_t source_id, - uint64_t sequence_number) { - auto now = base::TimeTicks::Now(); + viz::BeginFrameArgs CreateBeginFrameArgs( + uint64_t source_id, + uint64_t sequence_number, + base::TimeTicks now = base::TimeTicks::Now()) { auto interval = base::TimeDelta::FromMilliseconds(16); auto deadline = now + interval; return viz::BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, source_id, @@ -76,13 +79,23 @@ class FrameSequenceTrackerTest : public testing::Test { return ++frame_token; } + // Check whether a type of tracker exists in |frame_trackers_| or not. + bool TrackerExists(FrameSequenceTrackerType type) const { + return collection_.frame_trackers_.contains(type); + } + void TestNotifyFramePresented() { collection_.StartSequence(FrameSequenceTrackerType::kCompositorAnimation); collection_.StartSequence(FrameSequenceTrackerType::kMainThreadAnimation); + // The kTouchScroll tracker is created in the test constructor, and the + // kUniversal tracker is created in the FrameSequenceTrackerCollection + // constructor. EXPECT_EQ(collection_.frame_trackers_.size(), 3u); + collection_.StartSequence(FrameSequenceTrackerType::kUniversal); + EXPECT_EQ(collection_.frame_trackers_.size(), 4u); collection_.StopSequence(kCompositorAnimation); - EXPECT_EQ(collection_.frame_trackers_.size(), 2u); + EXPECT_EQ(collection_.frame_trackers_.size(), 3u); EXPECT_TRUE(collection_.frame_trackers_.contains( FrameSequenceTrackerType::kMainThreadAnimation)); EXPECT_TRUE(collection_.frame_trackers_.contains( @@ -100,6 +113,69 @@ class FrameSequenceTrackerTest : public testing::Test { EXPECT_TRUE(collection_.removal_trackers_.empty()); } + void ReportMetrics() { + base::HistogramTester histogram_tester; + + // Test that there is no main thread frames expected. + tracker_->impl_throughput_.frames_expected = 100u; + tracker_->impl_throughput_.frames_produced = 85u; + tracker_->ReportMetrics(); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 1u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.MainThread.TouchScroll", 0u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 1u); + + // Test that both are reported. + tracker_->main_throughput_.frames_expected = 50u; + tracker_->main_throughput_.frames_produced = 25u; + tracker_->ReportMetrics(); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 2u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.MainThread.TouchScroll", 1u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 2u); + + // Test that none is reported. + tracker_->main_throughput_.frames_expected = 2u; + tracker_->main_throughput_.frames_produced = 1u; + tracker_->impl_throughput_.frames_expected = 2u; + tracker_->impl_throughput_.frames_produced = 1u; + tracker_->ReportMetrics(); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 2u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.MainThread.TouchScroll", 1u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 2u); + + // Test the case where compositor and main thread have the same throughput. + tracker_->impl_throughput_.frames_expected = 20u; + tracker_->impl_throughput_.frames_produced = 18u; + tracker_->main_throughput_.frames_expected = 20u; + tracker_->main_throughput_.frames_produced = 18u; + tracker_->ReportMetrics(); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 3u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.MainThread.TouchScroll", 2u); + histogram_tester.ExpectTotalCount( + "Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 3u); + } + + base::TimeDelta TimeDeltaToReort() const { + return tracker_->time_delta_to_report_; + } + + unsigned NumberOfTrackers() const { + return collection_.frame_trackers_.size(); + } + unsigned NumberOfRemovalTrackers() const { + return collection_.removal_trackers_.size(); + } + protected: uint32_t number_of_frames_checkerboarded() const { return tracker_->checkerboarding_.frames_checkerboarded; @@ -142,6 +218,23 @@ TEST_F(FrameSequenceTrackerTest, SourceIdChangeDuringSequence) { viz::BeginFrameAck(args_2, true), args_1); } +TEST_F(FrameSequenceTrackerTest, UniversalTrackerCreation) { + // The universal tracker should be explicitly created by the object that + // manages the |collection_| + EXPECT_FALSE(TrackerExists(FrameSequenceTrackerType::kUniversal)); +} + +TEST_F(FrameSequenceTrackerTest, UniversalTrackerRestartableAfterClearAll) { + collection_.StartSequence(FrameSequenceTrackerType::kUniversal); + EXPECT_TRUE(TrackerExists(FrameSequenceTrackerType::kUniversal)); + + collection_.ClearAll(); + EXPECT_FALSE(TrackerExists(FrameSequenceTrackerType::kUniversal)); + + collection_.StartSequence(FrameSequenceTrackerType::kUniversal); + EXPECT_TRUE(TrackerExists(FrameSequenceTrackerType::kUniversal)); +} + TEST_F(FrameSequenceTrackerTest, TestNotifyFramePresented) { TestNotifyFramePresented(); } @@ -246,4 +339,30 @@ TEST_F(FrameSequenceTrackerTest, MultipleCheckerboardingFrames) { EXPECT_EQ(kFrames, number_of_frames_checkerboarded()); } +TEST_F(FrameSequenceTrackerTest, ReportMetrics) { + ReportMetrics(); +} + +TEST_F(FrameSequenceTrackerTest, ReportMetricsAtFixedInterval) { + const uint64_t source = 1; + uint64_t sequence = 0; + base::TimeDelta first_time_delta = base::TimeDelta::FromSeconds(1); + auto args = CreateBeginFrameArgs(source, ++sequence, + base::TimeTicks::Now() + first_time_delta); + + // args.frame_time is less than 5s of the tracker creation time, so won't + // schedule this tracker to report its throughput. + collection_.NotifyBeginImplFrame(args); + EXPECT_EQ(NumberOfTrackers(), 1u); + EXPECT_EQ(NumberOfRemovalTrackers(), 0u); + + // Now args.frame_time is 5s since the tracker creation time, so this tracker + // should be scheduled to report its throughput. + args = CreateBeginFrameArgs(source, ++sequence, + args.frame_time + TimeDeltaToReort()); + collection_.NotifyBeginImplFrame(args); + EXPECT_EQ(NumberOfTrackers(), 1u); + EXPECT_EQ(NumberOfRemovalTrackers(), 1u); +} + } // namespace cc diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc index c66fe89ba21..72c13d9231f 100644 --- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc +++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc @@ -66,9 +66,9 @@ AsyncLayerTreeFrameSink::UnboundMessagePipes::UnboundMessagePipes() = default; AsyncLayerTreeFrameSink::UnboundMessagePipes::~UnboundMessagePipes() = default; bool AsyncLayerTreeFrameSink::UnboundMessagePipes::HasUnbound() const { - return client_request.is_pending() && - (compositor_frame_sink_info.is_valid() ^ - compositor_frame_sink_associated_info.is_valid()); + return client_receiver.is_valid() && + (compositor_frame_sink_remote.is_valid() ^ + compositor_frame_sink_associated_remote.is_valid()); } AsyncLayerTreeFrameSink::UnboundMessagePipes::UnboundMessagePipes( @@ -86,7 +86,6 @@ AsyncLayerTreeFrameSink::AsyncLayerTreeFrameSink( synthetic_begin_frame_source_( std::move(params->synthetic_begin_frame_source)), pipes_(std::move(params->pipes)), - client_binding_(this), wants_animate_only_begin_frames_(params->wants_animate_only_begin_frames), receive_begin_frame_histogram_( GetHistogramNamed("GraphicsPipeline.%s.ReceivedBeginFrame", @@ -110,22 +109,22 @@ bool AsyncLayerTreeFrameSink::BindToClient(LayerTreeFrameSinkClient* client) { return false; DCHECK(pipes_.HasUnbound()); - if (pipes_.compositor_frame_sink_info.is_valid()) { - compositor_frame_sink_.Bind(std::move(pipes_.compositor_frame_sink_info)); - compositor_frame_sink_.set_connection_error_with_reason_handler( + if (pipes_.compositor_frame_sink_remote.is_valid()) { + compositor_frame_sink_.Bind(std::move(pipes_.compositor_frame_sink_remote)); + compositor_frame_sink_.set_disconnect_with_reason_handler( base::BindOnce(&AsyncLayerTreeFrameSink::OnMojoConnectionError, weak_factory_.GetWeakPtr())); compositor_frame_sink_ptr_ = compositor_frame_sink_.get(); - } else if (pipes_.compositor_frame_sink_associated_info.is_valid()) { + } else if (pipes_.compositor_frame_sink_associated_remote.is_valid()) { compositor_frame_sink_associated_.Bind( - std::move(pipes_.compositor_frame_sink_associated_info)); - compositor_frame_sink_associated_.set_connection_error_with_reason_handler( + std::move(pipes_.compositor_frame_sink_associated_remote)); + compositor_frame_sink_associated_.set_disconnect_with_reason_handler( base::BindOnce(&AsyncLayerTreeFrameSink::OnMojoConnectionError, weak_factory_.GetWeakPtr())); compositor_frame_sink_ptr_ = compositor_frame_sink_associated_.get(); } - client_binding_.Bind(std::move(pipes_.client_request), - compositor_task_runner_); + client_receiver_.Bind(std::move(pipes_.client_receiver), + compositor_task_runner_); if (synthetic_begin_frame_source_) { client->SetBeginFrameSource(synthetic_begin_frame_source_.get()); @@ -146,7 +145,7 @@ void AsyncLayerTreeFrameSink::DetachFromClient() { client_->SetBeginFrameSource(nullptr); begin_frame_source_.reset(); synthetic_begin_frame_source_.reset(); - client_binding_.Close(); + client_receiver_.reset(); compositor_frame_sink_.reset(); compositor_frame_sink_associated_.reset(); compositor_frame_sink_ptr_ = nullptr; @@ -292,8 +291,7 @@ void AsyncLayerTreeFrameSink::OnBeginFrame( const viz::BeginFrameArgs& args, const viz::FrameTimingDetailsMap& timing_details) { for (const auto& pair : timing_details) { - client_->DidPresentCompositorFrame(pair.first, - pair.second.presentation_feedback); + client_->DidPresentCompositorFrame(pair.first, pair.second); } DCHECK_LE(pipeline_reporting_frame_times_.size(), 25u); diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h index d32489d3f19..236d792b4b0 100644 --- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h +++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h @@ -19,7 +19,12 @@ #include "components/viz/common/gpu/context_provider.h" #include "components/viz/common/surfaces/parent_local_surface_id_allocator.h" #include "components/viz/common/surfaces/surface_id.h" -#include "mojo/public/cpp/bindings/binding.h" +#include "mojo/public/cpp/bindings/associated_remote.h" +#include "mojo/public/cpp/bindings/pending_associated_remote.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" +#include "mojo/public/cpp/bindings/receiver.h" +#include "mojo/public/cpp/bindings/remote.h" #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" namespace base { @@ -74,12 +79,14 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink bool HasUnbound() const; - // Only one of |compositor_frame_sink_info| or - // |compositor_frame_sink_associated_info| should be set. - viz::mojom::CompositorFrameSinkPtrInfo compositor_frame_sink_info; - viz::mojom::CompositorFrameSinkAssociatedPtrInfo - compositor_frame_sink_associated_info; - viz::mojom::CompositorFrameSinkClientRequest client_request; + // Only one of |compositor_frame_sink_remote| or + // |compositor_frame_sink_associated_remote| should be set. + mojo::PendingRemote<viz::mojom::CompositorFrameSink> + compositor_frame_sink_remote; + mojo::PendingAssociatedRemote<viz::mojom::CompositorFrameSink> + compositor_frame_sink_associated_remote; + mojo::PendingReceiver<viz::mojom::CompositorFrameSinkClient> + client_receiver; }; struct CC_MOJO_EMBEDDER_EXPORT InitParams { @@ -159,10 +166,10 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink // be bound after calling BindToClient(). |compositor_frame_sink_ptr_| will // point to message pipe we want to use. viz::mojom::CompositorFrameSink* compositor_frame_sink_ptr_ = nullptr; - viz::mojom::CompositorFrameSinkPtr compositor_frame_sink_; - viz::mojom::CompositorFrameSinkAssociatedPtr + mojo::Remote<viz::mojom::CompositorFrameSink> compositor_frame_sink_; + mojo::AssociatedRemote<viz::mojom::CompositorFrameSink> compositor_frame_sink_associated_; - mojo::Binding<viz::mojom::CompositorFrameSinkClient> client_binding_; + mojo::Receiver<viz::mojom::CompositorFrameSinkClient> client_receiver_{this}; THREAD_CHECKER(thread_checker_); const bool wants_animate_only_begin_frames_; diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc index 48ec028118b..82984c11006 100644 --- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc +++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc @@ -21,7 +21,8 @@ #include "components/viz/test/compositor_frame_helpers.h" #include "components/viz/test/test_context_provider.h" #include "components/viz/test/test_gpu_memory_buffer_manager.h" -#include "mojo/public/cpp/bindings/interface_request.h" +#include "mojo/public/cpp/bindings/pending_receiver.h" +#include "mojo/public/cpp/bindings/pending_remote.h" #include "services/viz/public/mojom/compositing/compositor_frame_sink.mojom.h" #include "testing/gtest/include/gtest/gtest.h" @@ -67,18 +68,16 @@ TEST(AsyncLayerTreeFrameSinkTest, viz::TestContextProvider::Create(); viz::TestGpuMemoryBufferManager test_gpu_memory_buffer_manager; - viz::mojom::CompositorFrameSinkPtrInfo sink_info; - viz::mojom::CompositorFrameSinkRequest sink_request = - mojo::MakeRequest(&sink_info); - viz::mojom::CompositorFrameSinkClientPtr client; - viz::mojom::CompositorFrameSinkClientRequest client_request = - mojo::MakeRequest(&client); + mojo::PendingRemote<viz::mojom::CompositorFrameSink> sink_remote; + mojo::PendingReceiver<viz::mojom::CompositorFrameSink> sink_receiver = + sink_remote.InitWithNewPipeAndPassReceiver(); + mojo::PendingRemote<viz::mojom::CompositorFrameSinkClient> client; AsyncLayerTreeFrameSink::InitParams init_params; init_params.compositor_task_runner = bg_thread.task_runner(); init_params.gpu_memory_buffer_manager = &test_gpu_memory_buffer_manager; - init_params.pipes.compositor_frame_sink_info = std::move(sink_info); - init_params.pipes.client_request = std::move(client_request); + init_params.pipes.compositor_frame_sink_remote = std::move(sink_remote); + init_params.pipes.client_receiver = client.InitWithNewPipeAndPassReceiver(); auto layer_tree_frame_sink = std::make_unique<AsyncLayerTreeFrameSink>( std::move(provider), nullptr, &init_params); @@ -99,7 +98,7 @@ TEST(AsyncLayerTreeFrameSinkTest, // Closes the pipe, which should trigger calling DidLoseLayerTreeFrameSink() // (and quitting the RunLoop). There is no need to wait for BindToClient() // to complete as mojo::Binding error callbacks are processed asynchronously. - sink_request = viz::mojom::CompositorFrameSinkRequest(); + sink_receiver.reset(); close_run_loop.Run(); EXPECT_NE(base::kInvalidThreadId, called_thread_id); @@ -132,17 +131,16 @@ class AsyncLayerTreeFrameSinkSimpleTest : public testing::Test { display_rect_(1, 1) { auto context_provider = viz::TestContextProvider::Create(); - viz::mojom::CompositorFrameSinkPtrInfo sink_info; - viz::mojom::CompositorFrameSinkRequest sink_request = - mojo::MakeRequest(&sink_info); - viz::mojom::CompositorFrameSinkClientPtr client; - viz::mojom::CompositorFrameSinkClientRequest client_request = - mojo::MakeRequest(&client); + mojo::PendingRemote<viz::mojom::CompositorFrameSink> sink_remote; + mojo::PendingReceiver<viz::mojom::CompositorFrameSink> sink_receiver = + sink_remote.InitWithNewPipeAndPassReceiver(); + mojo::PendingRemote<viz::mojom::CompositorFrameSinkClient> client; init_params_.compositor_task_runner = task_runner_; init_params_.gpu_memory_buffer_manager = &test_gpu_memory_buffer_manager_; - init_params_.pipes.compositor_frame_sink_info = std::move(sink_info); - init_params_.pipes.client_request = std::move(client_request); + init_params_.pipes.compositor_frame_sink_remote = std::move(sink_remote); + init_params_.pipes.client_receiver = + client.InitWithNewPipeAndPassReceiver(); init_params_.hit_test_data_provider = std::make_unique<viz::HitTestDataProviderDrawQuad>( /*should_ask_for_child_region=*/true, /*root_accepts_events=*/true); @@ -289,15 +287,15 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) { quad3_root_1->SetNew(shared_quad_state3_root, /*rect=*/rect3_root, /*visible_rect=*/rect3_root, /*render_pass_id=*/3, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad3_root_2 = pass3_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>(); quad3_root_2->SetNew(shared_quad_state3_root, /*rect=*/rect3_root, /*visible_rect=*/rect3_root, /*render_pass_id=*/4, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); pass_list.push_back(std::move(pass3_root)); SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false); @@ -393,15 +391,15 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, quad2_root_1->SetNew(shared_quad_state2_root, /*rect=*/rect2_root, /*visible_rect=*/rect2_root, /*render_pass_id=*/2, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); auto* quad2_root_2 = pass2_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>(); quad2_root_2->SetNew(shared_quad_state2_root, /*rect=*/rect2_root, /*visible_rect=*/rect2_root, /*render_pass_id=*/3, /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(), - /*mask_applies_to_backdrop=*/false, gfx::Vector2dF(1, 1), - gfx::PointF(), gfx::RectF(), false, 1.0f); + gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false, + 1.0f); pass_list.push_back(std::move(pass2_root)); SendRenderPassList(&pass_list, /*hit_test_data_changed=*/true); diff --git a/chromium/cc/paint/element_id.cc b/chromium/cc/paint/element_id.cc index 15d78835bca..69d3237012b 100644 --- a/chromium/cc/paint/element_id.cc +++ b/chromium/cc/paint/element_id.cc @@ -26,7 +26,7 @@ void ElementId::AddToTracedValue(base::trace_event::TracedValue* res) const { res->EndDictionary(); } -ElementIdType ElementId::GetInternalValue() const { +ElementIdType ElementId::GetStableId() const { return id_; } diff --git a/chromium/cc/paint/element_id.h b/chromium/cc/paint/element_id.h index 59e01582126..05ecd232dba 100644 --- a/chromium/cc/paint/element_id.h +++ b/chromium/cc/paint/element_id.h @@ -61,7 +61,7 @@ struct CC_PAINT_EXPORT ElementId { void AddToTracedValue(base::trace_event::TracedValue* res) const; std::unique_ptr<base::Value> AsValue() const; - ElementIdType GetInternalValue() const; + ElementIdType GetStableId() const; std::string ToString() const; diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc index fe86b36039a..5939e789bb8 100644 --- a/chromium/cc/paint/image_transfer_cache_entry.cc +++ b/chromium/cc/paint/image_transfer_cache_entry.cc @@ -429,10 +429,6 @@ bool ServiceImageTransferCacheEntry::Deserialize( if (!reader.valid()) return false; DCHECK(SkIsAlign4(reinterpret_cast<uintptr_t>(plane_pixel_data))); - const size_t plane_size = GrContext::ComputeTextureSize( - yuv_plane_color_type, plane_width, plane_height, gr_mips); - size_ += plane_size; - plane_sizes_.push_back(plane_size); // Const-cast away the "volatile" on |pixel_data|. We specifically // understand that a malicious caller may change our pixels under us, and @@ -449,6 +445,11 @@ bool ServiceImageTransferCacheEntry::Deserialize( if (!plane) return false; DCHECK(plane->isTextureBacked()); + + const size_t plane_size = GrContext::ComputeImageSize(plane, gr_mips); + size_ += plane_size; + plane_sizes_.push_back(plane_size); + // |plane_images_| must be set for use in EnsureMips(), memory dumps, and // unit tests. plane_images_.push_back(std::move(plane)); @@ -501,16 +502,19 @@ bool ServiceImageTransferCacheEntry::Deserialize( if (width == 0 || height == 0) return false; - // Match GrTexture::onGpuMemorySize so that memory traces agree. - auto gr_mips = has_mips_ ? GrMipMapped::kYes : GrMipMapped::kNo; - size_ = GrContext::ComputeTextureSize(color_type, width, height, gr_mips); - // Const-cast away the "volatile" on |pixel_data|. We specifically understand // that a malicious caller may change our pixels under us, and are OK with // this as the worst case scenario is visual corruption. SkPixmap pixmap(image_info, const_cast<const void*>(pixel_data), image_info.minRowBytes()); image_ = MakeSkImage(pixmap, width, height, target_color_space); + + if (image_) { + // Match GrTexture::onGpuMemorySize so that memory traces agree. + auto gr_mips = has_mips_ ? GrMipMapped::kYes : GrMipMapped::kNo; + size_ = GrContext::ComputeImageSize(image_, gr_mips); + } + return !!image_; } diff --git a/chromium/cc/paint/paint_canvas.h b/chromium/cc/paint/paint_canvas.h index a8201032901..32918efd58a 100644 --- a/chromium/cc/paint/paint_canvas.h +++ b/chromium/cc/paint/paint_canvas.h @@ -50,6 +50,10 @@ class CC_PAINT_EXPORT PaintCanvas { // recording or not, so could be simplified or removed. virtual SkImageInfo imageInfo() const = 0; + virtual void* accessTopLayerPixels(SkImageInfo* info, + size_t* rowBytes, + SkIPoint* origin = nullptr) = 0; + // TODO(enne): It would be nice to get rid of flush() entirely, as it // doesn't really make sense for recording. However, this gets used by // PaintCanvasVideoRenderer which takes a PaintCanvas to paint both @@ -172,7 +176,6 @@ class CC_PAINT_EXPORT PaintCanvas { virtual void drawPicture(sk_sp<const PaintRecord> record) = 0; virtual bool isClipEmpty() const = 0; - virtual bool isClipRect() const = 0; virtual const SkMatrix& getTotalMatrix() const = 0; // Used for printing diff --git a/chromium/cc/paint/paint_image.cc b/chromium/cc/paint/paint_image.cc index 0331bfc1ca3..c601c016c78 100644 --- a/chromium/cc/paint/paint_image.cc +++ b/chromium/cc/paint/paint_image.cc @@ -28,6 +28,13 @@ const PaintImage::Id PaintImage::kInvalidId = -2; const PaintImage::ContentId PaintImage::kInvalidContentId = -1; const PaintImage::GeneratorClientId PaintImage::kDefaultGeneratorClientId = 0; +ImageHeaderMetadata::ImageHeaderMetadata() = default; +ImageHeaderMetadata::ImageHeaderMetadata(const ImageHeaderMetadata& other) = + default; +ImageHeaderMetadata& ImageHeaderMetadata::operator=( + const ImageHeaderMetadata& other) = default; +ImageHeaderMetadata::ImageHeaderMetadata::~ImageHeaderMetadata() = default; + PaintImage::PaintImage() = default; PaintImage::PaintImage(const PaintImage& other) = default; PaintImage::PaintImage(PaintImage&& other) = default; @@ -153,13 +160,6 @@ void PaintImage::CreateSkImage() { } } -bool PaintImage::IsEligibleForAcceleratedDecoding() const { - if (!CanDecodeFromGenerator()) - return false; - DCHECK(paint_image_generator_); - return paint_image_generator_->IsEligibleForAcceleratedDecoding(); -} - SkISize PaintImage::GetSupportedDecodeSize( const SkISize& requested_size) const { // TODO(vmpstr): In some cases we do not support decoding to any other @@ -292,10 +292,10 @@ int PaintImage::height() const { : GetSkImage()->height(); } -PaintImage::ImageType PaintImage::GetImageType() const { +const ImageHeaderMetadata* PaintImage::GetImageHeaderMetadata() const { if (paint_image_generator_) - return paint_image_generator_->GetImageType(); - return PaintImage::ImageType::kInvalid; + return paint_image_generator_->GetMetadataForDecodeAcceleration(); + return nullptr; } bool PaintImage::IsYuv(SkYUVASizeInfo* yuva_size_info, diff --git a/chromium/cc/paint/paint_image.h b/chromium/cc/paint/paint_image.h index 0967fde3d09..df01c1086f9 100644 --- a/chromium/cc/paint/paint_image.h +++ b/chromium/cc/paint/paint_image.h @@ -10,6 +10,7 @@ #include "base/gtest_prod_util.h" #include "base/logging.h" #include "base/memory/scoped_refptr.h" +#include "base/optional.h" #include "cc/paint/frame_metadata.h" #include "cc/paint/image_animation_count.h" #include "cc/paint/paint_export.h" @@ -17,6 +18,7 @@ #include "third_party/skia/include/core/SkYUVAIndex.h" #include "third_party/skia/include/core/SkYUVASizeInfo.h" #include "ui/gfx/geometry/rect.h" +#include "ui/gfx/geometry/size.h" namespace cc { @@ -25,6 +27,46 @@ class PaintOpBuffer; class PaintWorkletInput; using PaintRecord = PaintOpBuffer; +enum class ImageType { kPNG, kJPEG, kWEBP, kGIF, kICO, kBMP, kInvalid }; + +enum class YUVSubsampling { k410, k411, k420, k422, k440, k444, kUnknown }; + +struct CC_PAINT_EXPORT ImageHeaderMetadata { + public: + ImageHeaderMetadata(); + ImageHeaderMetadata(const ImageHeaderMetadata& other); + ImageHeaderMetadata& operator=(const ImageHeaderMetadata& other); + ~ImageHeaderMetadata(); + + // The image type, e.g., JPEG or WebP. + ImageType image_type = ImageType::kInvalid; + + // The subsampling format used for the chroma planes, e.g., YUV 4:2:0. + YUVSubsampling yuv_subsampling = YUVSubsampling::kUnknown; + + // The visible size of the image (i.e., the area that contains meaningful + // pixels). + gfx::Size image_size; + + // The size of the area containing coded data, if known. For example, if the + // |image_size| for a 4:2:0 JPEG is 12x31, its coded size should be 16x32 + // because the size of a minimum-coded unit for 4:2:0 is 16x16. + base::Optional<gfx::Size> coded_size; + + // Whether the image embeds an ICC color profile. + bool has_embedded_color_profile = false; + + // Whether all the data was received prior to starting decoding work. + bool all_data_received_prior_to_decode = false; + + // For JPEGs only: whether the image is progressive (as opposed to baseline). + base::Optional<bool> jpeg_is_progressive; + + // For WebPs only: whether this is a simple-format lossy image. See + // https://developers.google.com/speed/webp/docs/riff_container#simple_file_format_lossy. + base::Optional<bool> webp_is_non_extended_lossy; +}; + // A representation of an image for the compositor. This is the most abstract // form of images, and represents what is known at paint time. Note that aside // from default construction, it can only be constructed using a @@ -117,7 +159,6 @@ class CC_PAINT_EXPORT PaintImage { // CheckerImageTracker for all heuristics used. kAsync }; - enum class ImageType { kPNG, kJPEG, kWEBP, kGIF, kICO, kBMP, kInvalid }; // Returns the more conservative mode out of the two given ones. static DecodingMode GetConservative(DecodingMode one, DecodingMode two); @@ -141,18 +182,6 @@ class CC_PAINT_EXPORT PaintImage { bool operator==(const PaintImage& other) const; bool operator!=(const PaintImage& other) const { return !(*this == other); } - // Returns true if the image is eligible for decoding using a hardware - // accelerator (which would require at least that all the encoded data has - // been received). Returns false otherwise or if the image cannot be decoded - // from a PaintImageGenerator. Notice that a return value of true does not - // guarantee that the hardware accelerator supports the image. It only - // indicates that the software decoder hasn't done any work with the image, so - // sending it to a hardware decoder is appropriate. - // - // TODO(andrescj): consider supporting the non-PaintImageGenerator path which - // is expected to be rare. - bool IsEligibleForAcceleratedDecoding() const; - // Returns the smallest size that is at least as big as the requested_size // such that we can decode to exactly that scale. If the requested size is // larger than the image, this returns the image size. Any returned value is @@ -227,6 +256,7 @@ class CC_PAINT_EXPORT PaintImage { SkColorSpace* color_space() const { return paint_worklet_input_ ? nullptr : GetSkImage()->colorSpace(); } + const gfx::Rect subset_rect() const { return subset_rect_; } // Returns whether this image will be decoded and rendered from YUV data // and fills out plane size info, plane index info, and the matrix for @@ -239,8 +269,9 @@ class CC_PAINT_EXPORT PaintImage { // Returns the color type of this image. SkColorType GetColorType() const; - // Returns the image type (e.g. PNG, WEBP) of this image. - ImageType GetImageType() const; + // Returns general information about the underlying image. Returns nullptr if + // there is no available |paint_image_generator_|. + const ImageHeaderMetadata* GetImageHeaderMetadata() const; // Returns a unique id for the pixel data for the frame at |frame_index|. FrameKey GetKeyForFrame(size_t frame_index) const; diff --git a/chromium/cc/paint/paint_image_generator.cc b/chromium/cc/paint/paint_image_generator.cc index 41483faec12..740808e21e1 100644 --- a/chromium/cc/paint/paint_image_generator.cc +++ b/chromium/cc/paint/paint_image_generator.cc @@ -33,8 +33,9 @@ SkISize PaintImageGenerator::GetSupportedDecodeSize( return info_.dimensions(); } -PaintImage::ImageType PaintImageGenerator::GetImageType() const { - return PaintImage::ImageType::kInvalid; +const ImageHeaderMetadata* +PaintImageGenerator::GetMetadataForDecodeAcceleration() const { + return nullptr; } } // namespace cc diff --git a/chromium/cc/paint/paint_image_generator.h b/chromium/cc/paint/paint_image_generator.h index 1ff7515f855..6481c7a5d7b 100644 --- a/chromium/cc/paint/paint_image_generator.h +++ b/chromium/cc/paint/paint_image_generator.h @@ -29,14 +29,6 @@ class CC_PAINT_EXPORT PaintImageGenerator : public SkRefCnt { PaintImageGenerator& operator=(const PaintImageGenerator&) = delete; - // Returns true if we can guarantee that the software decoder hasn't done work - // on the image, so it's appropriate to send the encoded image to a hardware - // accelerator. False if we can't guarantee this or if not applicable. For - // example, if the encoded data comes incrementally, and the software decoder - // starts working with partial data, the image shouldn't later be sent to a - // hardware decoder. - virtual bool IsEligibleForAcceleratedDecoding() const = 0; - // Returns a reference to the encoded content of this image. virtual sk_sp<SkData> GetEncodedData() const = 0; @@ -88,7 +80,9 @@ class CC_PAINT_EXPORT PaintImageGenerator : public SkRefCnt { const SkImageInfo& GetSkImageInfo() const { return info_; } const std::vector<FrameMetadata>& GetFrameMetadata() const { return frames_; } - virtual PaintImage::ImageType GetImageType() const; + // Returns the information required to decide whether or not hardware + // acceleration can be used to decode this image. + virtual const ImageHeaderMetadata* GetMetadataForDecodeAcceleration() const; protected: // |info| is the info for this paint image generator. diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc index 6ac1a1e1fcb..02915f75f95 100644 --- a/chromium/cc/paint/paint_op_buffer.cc +++ b/chromium/cc/paint/paint_op_buffer.cc @@ -1256,7 +1256,11 @@ void DrawImageRectOp::RasterWithFlags(const DrawImageRectOp* op, // TODO(crbug.com/931704): make sure to support the case where paint worklet // generated images are used in other raster work such as canvas2d. if (op->image.IsPaintWorklet()) { - DCHECK(params.image_provider); + // When rasterizing on the main thread (e.g. paint invalidation checking, + // see https://crbug.com/990382), an image provider may not be available, so + // we should draw nothing. + if (!params.image_provider) + return; ImageProvider::ScopedResult result = params.image_provider->GetRasterContent(DrawImage(op->image)); @@ -2373,7 +2377,11 @@ void PaintOpBuffer::PlaybackFoldingIterator::FindNextOp() { third = NextUnfoldedOp(); if (third && third->GetType() == PaintOpType::Restore) { auto* save_op = static_cast<const SaveLayerAlphaOp*>(current_op_); - if (draw_op->IsPaintOpWithFlags()) { + if (draw_op->IsPaintOpWithFlags() && + // SkPaint::drawTextBlob() applies alpha on each glyph so we don't + // fold SaveLayerAlpha into DrwaTextBlob to ensure correct alpha + // even if some glyphs overlap. + draw_op->GetType() != PaintOpType::DrawTextBlob) { auto* flags_op = static_cast<const PaintOpWithFlags*>(draw_op); if (flags_op->flags.SupportsFoldingAlpha()) { current_alpha_ = save_op->alpha; diff --git a/chromium/cc/paint/paint_op_buffer_unittest.cc b/chromium/cc/paint/paint_op_buffer_unittest.cc index 8ccd0abb75a..2d35d90ad84 100644 --- a/chromium/cc/paint/paint_op_buffer_unittest.cc +++ b/chromium/cc/paint/paint_op_buffer_unittest.cc @@ -48,7 +48,6 @@ void ValidateOps(PaintOpBuffer* buffer) { for (auto* op : PaintOpBuffer::Iterator(buffer)) EXPECT_TRUE(static_cast<T*>(op)->IsValid()); } - } // namespace class PaintOpSerializationTestUtils { @@ -240,6 +239,26 @@ TEST(PaintOpBufferTest, SaveDrawRestore) { EXPECT_LE(std::abs(expected_alpha - canvas.paint_.getAlpha()), 1.f); } +// Verify that we don't optimize SaveLayerAlpha / DrawTextBlob / Restore. +TEST(PaintOpBufferTest, SaveDrawTextBlobRestore) { + PaintOpBuffer buffer; + + uint8_t alpha = 100; + buffer.push<SaveLayerAlphaOp>(nullptr, alpha); + + PaintFlags paint_flags; + EXPECT_TRUE(paint_flags.SupportsFoldingAlpha()); + buffer.push<DrawTextBlobOp>(SkTextBlob::MakeFromString("abc", SkFont()), 0, 0, + paint_flags); + buffer.push<RestoreOp>(); + + SaveCountingCanvas canvas; + buffer.Playback(&canvas); + + EXPECT_EQ(1, canvas.save_count_); + EXPECT_EQ(1, canvas.restore_count_); +} + // The same as SaveDrawRestore, but test that the optimization doesn't apply // when the drawing op's flags are not compatible with being folded into the // save layer with opacity. @@ -1393,8 +1412,8 @@ void PushDrawDRRectOps(PaintOpBuffer* buffer) { } void PushDrawImageOps(PaintOpBuffer* buffer) { - size_t len = std::min(std::min(test_images.size(), test_flags.size()), - test_floats.size() - 1); + size_t len = + std::min({test_images.size(), test_flags.size(), test_floats.size() - 1}); for (size_t i = 0; i < len; ++i) { buffer->push<DrawImageOp>(test_images[i], test_floats[i], test_floats[i + 1], &test_flags[i]); @@ -1408,8 +1427,8 @@ void PushDrawImageOps(PaintOpBuffer* buffer) { } void PushDrawImageRectOps(PaintOpBuffer* buffer) { - size_t len = std::min(std::min(test_images.size(), test_flags.size()), - test_rects.size() - 1); + size_t len = + std::min({test_images.size(), test_flags.size(), test_rects.size() - 1}); for (size_t i = 0; i < len; ++i) { PaintCanvas::SrcRectConstraint constraint = i % 2 ? PaintCanvas::kStrict_SrcRectConstraint @@ -1529,8 +1548,8 @@ void PushDrawTextBlobOps(PaintOpBuffer* buffer) { return builder.make(); }(), }; - size_t len = std::min(std::min(test_paint_blobs.size(), test_flags.size()), - test_floats.size() - 1); + size_t len = std::min( + {test_paint_blobs.size(), test_flags.size(), test_floats.size() - 1}); for (size_t i = 0; i < len; ++i) { buffer->push<DrawTextBlobOp>(test_paint_blobs[i], test_floats[i], test_floats[i + 1], test_flags[i]); diff --git a/chromium/cc/paint/paint_op_perftest.cc b/chromium/cc/paint/paint_op_perftest.cc index 6dacf3ebadf..e3cd6cb58a4 100644 --- a/chromium/cc/paint/paint_op_perftest.cc +++ b/chromium/cc/paint/paint_op_perftest.cc @@ -10,7 +10,7 @@ #include "cc/paint/paint_op_buffer.h" #include "cc/paint/paint_op_buffer_serializer.h" #include "cc/test/test_options_provider.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" #include "third_party/skia/include/core/SkMaskFilter.h" #include "third_party/skia/include/effects/SkColorMatrixFilter.h" #include "third_party/skia/include/effects/SkDashPathEffect.h" @@ -67,9 +67,9 @@ class PaintOpPerfTest : public testing::Test { } while (!timer_.HasTimeLimitExpired()); CHECK_GT(bytes_written, 0u); - perf_test::PrintResult(name.c_str(), "", " serialize", - buffer.size() * timer_.LapsPerSecond(), "ops/s", - true); + perf_test::PerfResultReporter reporter(name, " serialize"); + reporter.RegisterImportantMetric("", "runs/s"); + reporter.AddResult("", timer_.LapsPerSecond()); size_t bytes_read = 0; timer_.Reset(); @@ -98,9 +98,9 @@ class PaintOpPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult(name.c_str(), "", "deserialize", - buffer.size() * timer_.LapsPerSecond(), "ops/s", - true); + reporter = perf_test::PerfResultReporter(name, "deserialize"); + reporter.RegisterImportantMetric("", "runs/s"); + reporter.AddResult("", timer_.LapsPerSecond()); } protected: diff --git a/chromium/cc/paint/record_paint_canvas.cc b/chromium/cc/paint/record_paint_canvas.cc index 3b1c6108092..b6c58cb06f3 100644 --- a/chromium/cc/paint/record_paint_canvas.cc +++ b/chromium/cc/paint/record_paint_canvas.cc @@ -28,6 +28,13 @@ SkImageInfo RecordPaintCanvas::imageInfo() const { return GetCanvas()->imageInfo(); } +void* RecordPaintCanvas::accessTopLayerPixels(SkImageInfo* info, + size_t* rowBytes, + SkIPoint* origin) { + // Modifications to the underlying pixels cannot be saved. + return nullptr; +} + void RecordPaintCanvas::flush() { // This is a noop when recording. } @@ -289,11 +296,6 @@ bool RecordPaintCanvas::isClipEmpty() const { return GetCanvas()->isClipEmpty(); } -bool RecordPaintCanvas::isClipRect() const { - DCHECK(InitializedWithRecordingBounds()); - return GetCanvas()->isClipRect(); -} - const SkMatrix& RecordPaintCanvas::getTotalMatrix() const { return GetCanvas()->getTotalMatrix(); } diff --git a/chromium/cc/paint/record_paint_canvas.h b/chromium/cc/paint/record_paint_canvas.h index 68ad78ab315..27256f52193 100644 --- a/chromium/cc/paint/record_paint_canvas.h +++ b/chromium/cc/paint/record_paint_canvas.h @@ -31,6 +31,10 @@ class CC_PAINT_EXPORT RecordPaintCanvas final : public PaintCanvas { SkImageInfo imageInfo() const override; + void* accessTopLayerPixels(SkImageInfo* info, + size_t* rowBytes, + SkIPoint* origin = nullptr) override; + void flush() override; int save() override; @@ -98,7 +102,6 @@ class CC_PAINT_EXPORT RecordPaintCanvas final : public PaintCanvas { void drawPicture(sk_sp<const PaintRecord> record) override; bool isClipEmpty() const override; - bool isClipRect() const override; const SkMatrix& getTotalMatrix() const override; void Annotate(AnnotationType type, diff --git a/chromium/cc/paint/render_surface_filters.cc b/chromium/cc/paint/render_surface_filters.cc index 0a9cb8bca72..913cd402028 100644 --- a/chromium/cc/paint/render_surface_filters.cc +++ b/chromium/cc/paint/render_surface_filters.cc @@ -147,7 +147,11 @@ void GetSepiaMatrix(float amount, float matrix[20]) { sk_sp<PaintFilter> CreateMatrixImageFilter(const float matrix[20], sk_sp<PaintFilter> input) { - return sk_make_sp<ColorFilterPaintFilter>(SkColorFilters::Matrix(matrix), + auto color_filter = SkColorFilters::Matrix(matrix); + if (!color_filter) + return nullptr; + + return sk_make_sp<ColorFilterPaintFilter>(std::move(color_filter), std::move(input)); } diff --git a/chromium/cc/paint/skia_paint_canvas.cc b/chromium/cc/paint/skia_paint_canvas.cc index 3a6dfbbf907..72d34e97c58 100644 --- a/chromium/cc/paint/skia_paint_canvas.cc +++ b/chromium/cc/paint/skia_paint_canvas.cc @@ -24,12 +24,13 @@ SkiaPaintCanvas::SkiaPaintCanvas(SkCanvas* canvas, SkiaPaintCanvas::SkiaPaintCanvas(const SkBitmap& bitmap, ImageProvider* image_provider) : canvas_(new SkCanvas(bitmap)), + bitmap_(bitmap), owned_(canvas_), image_provider_(image_provider) {} SkiaPaintCanvas::SkiaPaintCanvas(const SkBitmap& bitmap, const SkSurfaceProps& props) - : canvas_(new SkCanvas(bitmap, props)), owned_(canvas_) {} + : canvas_(new SkCanvas(bitmap, props)), bitmap_(bitmap), owned_(canvas_) {} SkiaPaintCanvas::~SkiaPaintCanvas() = default; @@ -37,6 +38,14 @@ SkImageInfo SkiaPaintCanvas::imageInfo() const { return canvas_->imageInfo(); } +void* SkiaPaintCanvas::accessTopLayerPixels(SkImageInfo* info, + size_t* rowBytes, + SkIPoint* origin) { + if (bitmap_.isNull() || bitmap_.isImmutable()) + return nullptr; + return canvas_->accessTopLayerPixels(info, rowBytes, origin); +} + void SkiaPaintCanvas::flush() { canvas_->flush(); } @@ -319,10 +328,6 @@ bool SkiaPaintCanvas::isClipEmpty() const { return canvas_->isClipEmpty(); } -bool SkiaPaintCanvas::isClipRect() const { - return canvas_->isClipRect(); -} - const SkMatrix& SkiaPaintCanvas::getTotalMatrix() const { return canvas_->getTotalMatrix(); } diff --git a/chromium/cc/paint/skia_paint_canvas.h b/chromium/cc/paint/skia_paint_canvas.h index 6ba29a621d1..3dc125172fa 100644 --- a/chromium/cc/paint/skia_paint_canvas.h +++ b/chromium/cc/paint/skia_paint_canvas.h @@ -53,6 +53,10 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas { SkImageInfo imageInfo() const override; + void* accessTopLayerPixels(SkImageInfo* info, + size_t* rowBytes, + SkIPoint* origin = nullptr) override; + void flush() override; int save() override; @@ -122,7 +126,6 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas { void drawPicture(sk_sp<const PaintRecord> record) override; bool isClipEmpty() const override; - bool isClipRect() const override; const SkMatrix& getTotalMatrix() const override; void Annotate(AnnotationType type, @@ -130,9 +133,9 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas { sk_sp<SkData> data) override; // Don't shadow non-virtual helper functions. + using PaintCanvas::clipPath; using PaintCanvas::clipRect; using PaintCanvas::clipRRect; - using PaintCanvas::clipPath; using PaintCanvas::drawColor; using PaintCanvas::drawImage; using PaintCanvas::drawPicture; @@ -152,6 +155,7 @@ class CC_PAINT_EXPORT SkiaPaintCanvas final : public PaintCanvas { } SkCanvas* canvas_; + SkBitmap bitmap_; std::unique_ptr<SkCanvas> owned_; ImageProvider* image_provider_ = nullptr; diff --git a/chromium/cc/raster/raster_buffer_provider.cc b/chromium/cc/raster/raster_buffer_provider.cc index c4fa5a9be41..86bd980aba1 100644 --- a/chromium/cc/raster/raster_buffer_provider.cc +++ b/chromium/cc/raster/raster_buffer_provider.cc @@ -45,7 +45,6 @@ bool IsSupportedPlaybackToMemoryFormat(viz::ResourceFormat format) { case viz::BGRX_1010102: case viz::YVU_420: case viz::YUV_420_BIPLANAR: - case viz::UYVY_422: case viz::P010: return false; } @@ -145,7 +144,6 @@ void RasterBufferProvider::PlaybackToMemory( case viz::BGRX_1010102: case viz::YVU_420: case viz::YUV_420_BIPLANAR: - case viz::UYVY_422: case viz::P010: NOTREACHED(); return; diff --git a/chromium/cc/raster/raster_buffer_provider_perftest.cc b/chromium/cc/raster/raster_buffer_provider_perftest.cc index 541b22df9a8..66391be769d 100644 --- a/chromium/cc/raster/raster_buffer_provider_perftest.cc +++ b/chromium/cc/raster/raster_buffer_provider_perftest.cc @@ -29,7 +29,7 @@ #include "gpu/command_buffer/common/sync_token.h" #include "gpu/config/gpu_feature_info.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" #include "third_party/khronos/GLES2/gl2.h" #include "third_party/skia/include/gpu/GrContext.h" @@ -435,8 +435,8 @@ class RasterBufferProviderPerfTest RunMessageLoopUntilAllTasksHaveCompleted(); tile_task_manager_->CheckForCompletedTasks(); - perf_test::PrintResult("schedule_tasks", TestModifierString(), test_name, - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_tasks" + TestModifierString(), timer_.LapsPerSecond()); } void RunScheduleAlternateTasksTest(const std::string& test_name, @@ -472,8 +472,9 @@ class RasterBufferProviderPerfTest RunMessageLoopUntilAllTasksHaveCompleted(); tile_task_manager_->CheckForCompletedTasks(); - perf_test::PrintResult("schedule_alternate_tasks", TestModifierString(), - test_name, timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_alternate_tasks" + TestModifierString(), + timer_.LapsPerSecond()); } void RunScheduleAndExecuteTasksTest(const std::string& test_name, @@ -501,8 +502,20 @@ class RasterBufferProviderPerfTest tile_task_manager_->ScheduleTasks(&empty); RunMessageLoopUntilAllTasksHaveCompleted(); - perf_test::PrintResult("schedule_and_execute_tasks", TestModifierString(), - test_name, timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_and_execute_tasks" + TestModifierString(), + timer_.LapsPerSecond()); + } + + protected: + perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { + perf_test::PerfResultReporter reporter("schedule", story_name); + reporter.RegisterImportantMetric("_tasks" + TestModifierString(), "runs/s"); + reporter.RegisterImportantMetric("_alternate_tasks" + TestModifierString(), + "runs/s"); + reporter.RegisterImportantMetric( + "_and_execute_tasks" + TestModifierString(), "runs/s"); + return reporter; } private: @@ -606,8 +619,16 @@ class RasterBufferProviderCommonPerfTest for (auto& task : raster_tasks) task->OnTaskCompleted(); - perf_test::PrintResult("build_raster_task_graph", "", test_name, - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("", timer_.LapsPerSecond()); + } + + protected: + perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { + perf_test::PerfResultReporter reporter("build_raster_test_graph", + story_name); + reporter.RegisterImportantMetric("", "runs/s"); + return reporter; } }; diff --git a/chromium/cc/raster/task_graph_runner_perftest.cc b/chromium/cc/raster/task_graph_runner_perftest.cc index d7f35a0b738..c6119f0f29f 100644 --- a/chromium/cc/raster/task_graph_runner_perftest.cc +++ b/chromium/cc/raster/task_graph_runner_perftest.cc @@ -14,7 +14,7 @@ #include "cc/base/completion_event.h" #include "cc/raster/synchronous_task_graph_runner.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -79,12 +79,9 @@ class TaskGraphRunnerPerfTest : public testing::Test { CancelTasks(tasks); CancelTasks(top_level_tasks); - perf_test::PrintResult("build_task_graph", - TestModifierString(), - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("build_task_graph" + TestModifierString(), + timer_.LapsPerSecond()); } void RunScheduleTasksTest(const std::string& test_name, @@ -118,12 +115,9 @@ class TaskGraphRunnerPerfTest : public testing::Test { task_graph_runner_->ScheduleTasks(namespace_token_, &empty); CollectCompletedTasks(&completed_tasks); - perf_test::PrintResult("schedule_tasks", - TestModifierString(), - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("schedule_tasks" + TestModifierString(), + timer_.LapsPerSecond()); } void RunScheduleAlternateTasksTest(const std::string& test_name, @@ -168,12 +162,9 @@ class TaskGraphRunnerPerfTest : public testing::Test { task_graph_runner_->ScheduleTasks(namespace_token_, &empty); CollectCompletedTasks(&completed_tasks); - perf_test::PrintResult("schedule_alternate_tasks", - TestModifierString(), - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("schedule_alternate_tasks" + TestModifierString(), + timer_.LapsPerSecond()); } void RunScheduleAndExecuteTasksTest(const std::string& test_name, @@ -208,12 +199,9 @@ class TaskGraphRunnerPerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("execute_tasks", - TestModifierString(), - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("execute_tasks" + TestModifierString(), + timer_.LapsPerSecond()); } private: @@ -269,6 +257,19 @@ class TaskGraphRunnerPerfTest : public testing::Test { return completed_tasks->size(); } + perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { + perf_test::PerfResultReporter reporter("", story_name); + reporter.RegisterImportantMetric("build_task_graph" + TestModifierString(), + "runs/s"); + reporter.RegisterImportantMetric("schedule_tasks" + TestModifierString(), + "runs/s"); + reporter.RegisterImportantMetric( + "schedule_alternate_tasks" + TestModifierString(), "runs/s"); + reporter.RegisterImportantMetric("execute_tasks" + TestModifierString(), + "runs/s"); + return reporter; + } + // Test uses SynchronousTaskGraphRunner, as this implementation introduces // minimal additional complexity over the TaskGraphWorkQueue helpers. std::unique_ptr<SynchronousTaskGraphRunner> task_graph_runner_; diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc index 6a14640dcbb..523b09c2e4f 100644 --- a/chromium/cc/scheduler/scheduler.cc +++ b/chromium/cc/scheduler/scheduler.cc @@ -196,10 +196,10 @@ void Scheduler::DidPrepareTiles() { state_machine_.DidPrepareTiles(); } -void Scheduler::DidPresentCompositorFrame(uint32_t frame_token, - base::TimeTicks presentation_time) { - compositor_timing_history_->DidPresentCompositorFrame(frame_token, - presentation_time); +void Scheduler::DidPresentCompositorFrame( + uint32_t frame_token, + const viz::FrameTimingDetails& details) { + compositor_timing_history_->DidPresentCompositorFrame(frame_token, details); } void Scheduler::DidLoseLayerTreeFrameSink() { @@ -589,7 +589,6 @@ void Scheduler::SendDidNotProduceFrame(const viz::BeginFrameArgs& args) { if (last_begin_frame_ack_.source_id == args.source_id && last_begin_frame_ack_.sequence_number == args.sequence_number) return; - compositor_timing_history_->DidNotProduceFrame(); last_begin_frame_ack_ = viz::BeginFrameAck(args, false /* has_damage */); client_->DidNotProduceFrame(last_begin_frame_ack_); } @@ -732,8 +731,9 @@ void Scheduler::DrawIfPossible() { drawing_with_new_active_tree, begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time, client_->CompositedAnimationsCount(), - client_->MainThreadAnimationsCount(), - client_->CurrentFrameHadRAF(), client_->NextFrameHasPendingRAF()); + client_->MainThreadAnimationsCount(), client_->CurrentFrameHadRAF(), + client_->NextFrameHasPendingRAF(), + client_->HasCustomPropertyAnimations()); } void Scheduler::DrawForced() { @@ -750,8 +750,9 @@ void Scheduler::DrawForced() { drawing_with_new_active_tree, begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time, client_->CompositedAnimationsCount(), - client_->MainThreadAnimationsCount(), - client_->CurrentFrameHadRAF(), client_->NextFrameHasPendingRAF()); + client_->MainThreadAnimationsCount(), client_->CurrentFrameHadRAF(), + client_->NextFrameHasPendingRAF(), + client_->HasCustomPropertyAnimations()); } void Scheduler::SetDeferBeginMainFrame(bool defer_begin_main_frame) { diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h index 6168d88768c..23571c15023 100644 --- a/chromium/cc/scheduler/scheduler.h +++ b/chromium/cc/scheduler/scheduler.h @@ -27,6 +27,10 @@ class ConvertableToTraceFormat; class SingleThreadTaskRunner; } +namespace viz { +struct FrameTimingDetails; +} + namespace cc { class CompositorTimingHistory; @@ -63,6 +67,7 @@ class SchedulerClient { // Functions used for reporting animation targeting UMA, crbug.com/758439. virtual size_t CompositedAnimationsCount() const = 0; virtual size_t MainThreadAnimationsCount() const = 0; + virtual bool HasCustomPropertyAnimations() const = 0; virtual bool CurrentFrameHadRAF() const = 0; virtual bool NextFrameHasPendingRAF() const = 0; @@ -182,7 +187,7 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase { // |DidPresentCompositorFrame| is called when the renderer receives // presentation feedback. void DidPresentCompositorFrame(uint32_t frame_token, - base::TimeTicks presentation_time); + const viz::FrameTimingDetails& details); void DidLoseLayerTreeFrameSink(); void DidCreateAndInitializeLayerTreeFrameSink(); diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc index 5f9a7223698..5437a540cd1 100644 --- a/chromium/cc/scheduler/scheduler_unittest.cc +++ b/chromium/cc/scheduler/scheduler_unittest.cc @@ -259,6 +259,7 @@ class FakeSchedulerClient : public SchedulerClient, size_t CompositedAnimationsCount() const override { return 0; } size_t MainThreadAnimationsCount() const override { return 0; } + bool HasCustomPropertyAnimations() const override { return false; } bool CurrentFrameHadRAF() const override { return false; } bool NextFrameHasPendingRAF() const override { return false; } diff --git a/chromium/cc/tiles/checker_image_tracker.cc b/chromium/cc/tiles/checker_image_tracker.cc index c31c7b5e3e9..ebaf3d0f1d5 100644 --- a/chromium/cc/tiles/checker_image_tracker.cc +++ b/chromium/cc/tiles/checker_image_tracker.cc @@ -209,6 +209,7 @@ void CheckerImageTracker::ClearTracker(bool can_clear_decode_policy_tracking) { image_id_to_decode_.clear(); if (can_clear_decode_policy_tracking) { + decoding_mode_map_.clear(); image_async_decode_state_.clear(); } else { // If we can't clear the decode policy, we need to make sure we still diff --git a/chromium/cc/tiles/checker_image_tracker_unittest.cc b/chromium/cc/tiles/checker_image_tracker_unittest.cc index 47dc8ab1306..57984cc8d00 100644 --- a/chromium/cc/tiles/checker_image_tracker_unittest.cc +++ b/chromium/cc/tiles/checker_image_tracker_unittest.cc @@ -381,6 +381,11 @@ TEST_F(CheckerImageTrackerTest, ClearsTracker) { // Now clear the decode tracking as well. The image will be re-checkered. can_clear_decode_policy_tracking = true; checker_image_tracker_->ClearTracker(can_clear_decode_policy_tracking); + // Re-initialize the decoding hint state. The decode policy tracking should + // only be done when all image state will be re-created, so is safe to purge. + checker_image_tracker_->UpdateImageDecodingHints( + {{checkerable_image.paint_image().stable_id(), + PaintImage::DecodingMode::kAsync}}); image_decode_queue = BuildImageDecodeQueue({checkerable_image}, WhichTree::PENDING_TREE); EXPECT_EQ(image_decode_queue.size(), 1U); diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc index 461927bb58f..198f910967d 100644 --- a/chromium/cc/tiles/gpu_image_decode_cache.cc +++ b/chromium/cc/tiles/gpu_image_decode_cache.cc @@ -30,6 +30,7 @@ #include "gpu/command_buffer/common/sync_token.h" #include "gpu/config/gpu_finch_features.h" #include "third_party/skia/include/core/SkCanvas.h" +#include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkSurface.h" #include "third_party/skia/include/core/SkYUVAIndex.h" @@ -486,8 +487,7 @@ sk_sp<SkImage> MakeTextureImage(viz::RasterContextProvider* context, size_t GetUploadedTextureSizeFromSkImage(const sk_sp<SkImage>& plane, const GrMipMapped mipped) { - const size_t plane_size = GrContext::ComputeTextureSize( - plane->colorType(), plane->width(), plane->height(), mipped); + const size_t plane_size = GrContext::ComputeImageSize(plane, mipped); return plane_size; } @@ -557,12 +557,15 @@ class GpuImageDecodeTaskImpl : public TileTask { TRACE_EVENT2("cc", "GpuImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu", "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); + + const auto* image_metadata = image_.paint_image().GetImageHeaderMetadata(); + const ImageType image_type = + image_metadata ? image_metadata->image_type : ImageType::kInvalid; devtools_instrumentation::ScopedImageDecodeTask image_decode_task( &image_.paint_image(), devtools_instrumentation::ScopedImageDecodeTask::kGpu, ImageDecodeCache::ToScopedTaskType(tracing_info_.task_type), - ImageDecodeCache::ToScopedImageType( - image_.paint_image().GetImageType())); + ImageDecodeCache::ToScopedImageType(image_type)); cache_->DecodeImageInTask(image_, tracing_info_.task_type); } @@ -589,12 +592,10 @@ class ImageUploadTaskImpl : public TileTask { ImageUploadTaskImpl(GpuImageDecodeCache* cache, const DrawImage& draw_image, scoped_refptr<TileTask> decode_dependency, - sk_sp<SkData> encoded_data, const ImageDecodeCache::TracingInfo& tracing_info) : TileTask(false), cache_(cache), image_(draw_image), - encoded_data_(std::move(encoded_data)), tracing_info_(tracing_info) { DCHECK(!SkipImage(draw_image)); // If an image is already decoded and locked, we will not generate a @@ -610,7 +611,7 @@ class ImageUploadTaskImpl : public TileTask { void RunOnWorkerThread() override { TRACE_EVENT2("cc", "ImageUploadTaskImpl::RunOnWorkerThread", "mode", "gpu", "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); - cache_->UploadImageInTask(image_, std::move(encoded_data_)); + cache_->UploadImageInTask(image_); } // Overridden from TileTask: @@ -624,7 +625,6 @@ class ImageUploadTaskImpl : public TileTask { private: GpuImageDecodeCache* cache_; DrawImage image_; - sk_sp<SkData> encoded_data_; const ImageDecodeCache::TracingInfo tracing_info_; }; @@ -961,6 +961,20 @@ GpuImageDecodeCache::GpuImageDecodeCache( persistent_cache_(PersistentCache::NO_AUTO_EVICT), max_working_set_bytes_(max_working_set_bytes), max_working_set_items_(kMaxItemsInWorkingSet) { + // Note that to compute |allow_accelerated_jpeg_decodes_| and + // |allow_accelerated_webp_decodes_|, the last thing we check is the feature + // flag. That's because we want to ensure that we're in OOP-R mode and the + // hardware decoder supports the image type so that finch experiments + // involving hardware decode acceleration only count users in that + // population (both in the 'control' and the 'enabled' groups). + allow_accelerated_jpeg_decodes_ = + use_transfer_cache && + context_->ContextSupport()->IsJpegDecodeAccelerationSupported() && + base::FeatureList::IsEnabled(features::kVaapiJpegImageDecodeAcceleration); + allow_accelerated_webp_decodes_ = + use_transfer_cache && + context_->ContextSupport()->IsWebPDecodeAccelerationSupported() && + base::FeatureList::IsEnabled(features::kVaapiWebPImageDecodeAcceleration); // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). // Don't register a dump provider in these cases. if (base::ThreadTaskRunnerHandle::IsSet()) { @@ -1015,7 +1029,6 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal( const InUseCacheKey cache_key = InUseCacheKey::FromDrawImage(draw_image); ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key); scoped_refptr<ImageData> new_data; - sk_sp<SkData> encoded_data; if (!image_data) { // We need an ImageData, create one now. Note that hardware decode // acceleration is allowed only in the DecodeTaskType::kPartOfUploadTask @@ -1024,8 +1037,7 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal( new_data = CreateImageData( draw_image, task_type == - DecodeTaskType::kPartOfUploadTask /* allow_hardware_decode */, - &encoded_data); + DecodeTaskType::kPartOfUploadTask /* allow_hardware_decode */); image_data = new_data.get(); } else if (image_data->decode.decode_failure) { // We have already tried and failed to decode this image, so just return. @@ -1076,7 +1088,7 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal( task = base::MakeRefCounted<ImageUploadTaskImpl>( this, draw_image, GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type), - std::move(encoded_data), tracing_info); + tracing_info); image_data->upload.task = task; } else { task = GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type); @@ -1115,11 +1127,9 @@ DecodedDrawImage GpuImageDecodeCache::GetDecodedImageForDraw( base::AutoLock lock(lock_); const InUseCacheKey cache_key = InUseCacheKey::FromDrawImage(draw_image); ImageData* image_data = GetImageDataForDrawImage(draw_image, cache_key); - sk_sp<SkData> encoded_data; if (!image_data) { // We didn't find the image, create a new entry. - auto data = CreateImageData(draw_image, true /* allow_hardware_decode */, - &encoded_data); + auto data = CreateImageData(draw_image, true /* allow_hardware_decode */); image_data = data.get(); AddToPersistentCache(draw_image, std::move(data)); } @@ -1134,7 +1144,7 @@ DecodedDrawImage GpuImageDecodeCache::GetDecodedImageForDraw( // We may or may not need to decode and upload the image we've found, the // following functions early-out to if we already decoded. DecodeImageIfNecessary(draw_image, image_data, TaskType::kInRaster); - UploadImageIfNecessary(draw_image, image_data, std::move(encoded_data)); + UploadImageIfNecessary(draw_image, image_data); // Unref the image decode, but not the image. The image ref will be released // in DrawWithImageFinished. UnrefImageDecode(draw_image, cache_key); @@ -1458,8 +1468,7 @@ void GpuImageDecodeCache::DecodeImageInTask(const DrawImage& draw_image, DecodeImageIfNecessary(draw_image, image_data, task_type); } -void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image, - sk_sp<SkData> encoded_data) { +void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeCache::UploadImage"); base::Optional<viz::RasterContextProvider::ScopedRasterContextLock> @@ -1479,7 +1488,7 @@ void GpuImageDecodeCache::UploadImageInTask(const DrawImage& draw_image, if (image_data->is_bitmap_backed) DecodeImageIfNecessary(draw_image, image_data, TaskType::kInRaster); - UploadImageIfNecessary(draw_image, image_data, std::move(encoded_data)); + UploadImageIfNecessary(draw_image, image_data); } void GpuImageDecodeCache::OnImageDecodeTaskCompleted( @@ -1935,8 +1944,7 @@ void GpuImageDecodeCache::DecodeImageIfNecessary(const DrawImage& draw_image, } void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image, - ImageData* image_data, - sk_sp<SkData> encoded_data) { + ImageData* image_data) { CheckContextLockAcquiredIfNecessary(); lock_.AssertAcquired(); @@ -1998,14 +2006,11 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image, DCHECK_EQ(0, image_data->upload_scale_mip_level); const gfx::Size output_size(draw_image.paint_image().width(), draw_image.paint_image().height()); - // Try to get the encoded data if we don't have it already: this can - // happen, e.g., if we create an upload task using a pre-existing - // ImageData. In that case, we previously decided to do hardware decode - // acceleration but we didn't cache the encoded data. - if (!encoded_data) { - encoded_data = draw_image.paint_image().GetSkImage()->refEncodedData(); - DCHECK(encoded_data); - } + + // Get the encoded data in a contiguous form. + sk_sp<SkData> encoded_data = + draw_image.paint_image().GetSkImage()->refEncodedData(); + DCHECK(encoded_data); const uint32_t transfer_cache_id = ClientImageTransferCacheEntry::GetNextId(); const gpu::SyncToken decode_sync_token = @@ -2202,8 +2207,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image, scoped_refptr<GpuImageDecodeCache::ImageData> GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image, - bool allow_hardware_decode, - sk_sp<SkData>* encoded_data) { + bool allow_hardware_decode) { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeCache::CreateImageData"); lock_.AssertAcquired(); @@ -2249,24 +2253,12 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image, // Figure out if we will do hardware accelerated decoding. The criteria is as // follows: // - // - Either the kVaapiJpegImageDecodeAcceleration or - // kVaapiWebPImageDecodeAcceleration features are enabled. // - The caller allows hardware decodes. // - We are using the transfer cache (OOP-R). // - The image does not require downscaling for uploading (see TODO below). - // - All the encoded data was received prior to any decoding work. Otherwise, - // it means that the software decoder has already started decoding the - // image, so we just let it finish. - // - The image's color space is sRGB. This is because we don't currently - // support detecting embedded color profiles. + // - The image does not require subsetting. // - The image is supported according to the profiles advertised by the GPU - // service. Checking this involves obtaining the contiguous encoded data - // which may require a copy if the data is not already contiguous. Because - // of this, we return a pointer to the contiguous data (as |encoded_data|) - // so that we can re-use it later (when requesting the image decode). - // - // TODO(crbug.com/953363): ideally, we can make the hardware decoder support - // decision without requiring contiguous data. + // service. // // TODO(crbug.com/953367): currently, we don't support scaling with hardware // decode acceleration. Note that it's still okay for the image to be @@ -2275,33 +2267,28 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image, // TODO(crbug.com/981208): |data_size| needs to be set to the size of the // decoded data, but for accelerated decodes we won't know until the driver // gives us the result in the GPU process. Figure out what to do. + const ImageHeaderMetadata* image_metadata = + draw_image.paint_image().GetImageHeaderMetadata(); bool do_hardware_accelerated_decode = false; - if ((base::FeatureList::IsEnabled( - features::kVaapiJpegImageDecodeAcceleration) || - base::FeatureList::IsEnabled( - features::kVaapiWebPImageDecodeAcceleration)) && - allow_hardware_decode && mode == DecodedDataMode::kTransferCache && + if (allow_hardware_decode && mode == DecodedDataMode::kTransferCache && upload_scale_mip_level == 0 && - draw_image.paint_image().IsEligibleForAcceleratedDecoding() && - draw_image.paint_image().color_space() && - draw_image.paint_image().color_space()->isSRGB()) { - sk_sp<SkData> tmp_encoded_data = - draw_image.paint_image().GetSkImage() - ? draw_image.paint_image().GetSkImage()->refEncodedData() - : nullptr; - if (tmp_encoded_data && - context_->ContextSupport()->CanDecodeWithHardwareAcceleration( - base::make_span<const uint8_t>(tmp_encoded_data->bytes(), - tmp_encoded_data->size()))) { - do_hardware_accelerated_decode = true; - DCHECK(encoded_data); - *encoded_data = std::move(tmp_encoded_data); - } + draw_image.paint_image().subset_rect().IsEmpty() && + context_->ContextSupport()->CanDecodeWithHardwareAcceleration( + image_metadata)) { + DCHECK(image_metadata); + DCHECK_EQ(image_metadata->image_size.width(), + draw_image.paint_image().width()); + DCHECK_EQ(image_metadata->image_size.height(), + draw_image.paint_image().height()); + + const bool is_jpeg = (image_metadata->image_type == ImageType::kJPEG); + const bool is_webp = (image_metadata->image_type == ImageType::kWEBP); + do_hardware_accelerated_decode = + (is_jpeg && allow_accelerated_jpeg_decodes_) || + (is_webp && allow_accelerated_webp_decodes_); + DCHECK(!do_hardware_accelerated_decode || !is_bitmap_backed); } - // If draw_image.paint_image().IsEligibleForAcceleratedDecoding() returns - // true, the image should not be backed by a bitmap. - DCHECK(!do_hardware_accelerated_decode || !is_bitmap_backed); SkYUVASizeInfo target_yuva_size_info; // We fill out a default value for |yuv_color_space| but only fill out the // base::Optional member in ImageData if it is YUV. @@ -2659,8 +2646,8 @@ bool GpuImageDecodeCache::IsCompatible(const ImageData* image_data, size_t GpuImageDecodeCache::GetDrawImageSizeForTesting(const DrawImage& image) { base::AutoLock lock(lock_); - scoped_refptr<ImageData> data = CreateImageData( - image, false /* allow_hardware_decode */, nullptr /* encoded_data */); + scoped_refptr<ImageData> data = + CreateImageData(image, false /* allow_hardware_decode */); return data->size; } diff --git a/chromium/cc/tiles/gpu_image_decode_cache.h b/chromium/cc/tiles/gpu_image_decode_cache.h index 466ee2d107b..fdfd11497a1 100644 --- a/chromium/cc/tiles/gpu_image_decode_cache.h +++ b/chromium/cc/tiles/gpu_image_decode_cache.h @@ -19,7 +19,6 @@ #include "cc/cc_export.h" #include "cc/paint/image_transfer_cache_entry.h" #include "cc/tiles/image_decode_cache.h" -#include "third_party/skia/include/core/SkData.h" #include "third_party/skia/include/core/SkRefCnt.h" #include "third_party/skia/include/core/SkYUVAIndex.h" #include "third_party/skia/include/gpu/gl/GrGLTypes.h" @@ -177,7 +176,7 @@ class CC_EXPORT GpuImageDecodeCache // Called by Decode / Upload tasks. void DecodeImageInTask(const DrawImage& image, TaskType task_type); - void UploadImageInTask(const DrawImage& image, sk_sp<SkData> encoded_data); + void UploadImageInTask(const DrawImage& image); // Called by Decode / Upload tasks when tasks are finished. void OnImageDecodeTaskCompleted(const DrawImage& image, @@ -611,8 +610,7 @@ class CC_EXPORT GpuImageDecodeCache scoped_refptr<GpuImageDecodeCache::ImageData> CreateImageData( const DrawImage& image, - bool allow_hardware_decode, - sk_sp<SkData>* encoded_data); + bool allow_hardware_decode); void WillAddCacheEntry(const DrawImage& draw_image); SkImageInfo CreateImageInfoForDrawImage(const DrawImage& draw_image, int upload_scale_mip_level) const; @@ -646,8 +644,7 @@ class CC_EXPORT GpuImageDecodeCache // Requires that the |context_| lock be held when calling. void UploadImageIfNecessary(const DrawImage& draw_image, - ImageData* image_data, - sk_sp<SkData> encoded_data); + ImageData* image_data); // Flush pending operations on context_->GrContext() for each element of // |yuv_images| and then clear the vector. @@ -701,6 +698,8 @@ class CC_EXPORT GpuImageDecodeCache viz::RasterContextProvider* context_; int max_texture_size_ = 0; const PaintImage::GeneratorClientId generator_client_id_; + bool allow_accelerated_jpeg_decodes_ = false; + bool allow_accelerated_webp_decodes_ = false; // All members below this point must only be accessed while holding |lock_|. // The exception are const members like |normal_max_cache_bytes_| that can diff --git a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc index b201c58b0af..8b1d4239d40 100644 --- a/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc +++ b/chromium/cc/tiles/gpu_image_decode_cache_perftest.cc @@ -2,6 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <memory> #include <vector> #include "base/timer/lap_timer.h" @@ -12,7 +13,7 @@ #include "components/viz/test/test_in_process_context_provider.h" #include "gpu/command_buffer/client/raster_interface.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" #include "third_party/skia/include/core/SkSurface.h" namespace cc { @@ -48,17 +49,14 @@ class GpuImageDecodeCachePerfTest context_provider_( base::MakeRefCounted<viz::TestInProcessContextProvider>( UseTransferCache(), - false /* support_locking */)), - cache_(context_provider_.get(), - UseTransferCache(), - kRGBA_8888_SkColorType, - kCacheSize, - MaxTextureSize(), - PaintImage::kDefaultGeneratorClientId) { - // Initializing context here is ok because image decode cache does not use - // context provider in its constructor. + false /* support_locking */)) {} + + void SetUp() override { gpu::ContextResult result = context_provider_->BindToCurrentThread(); - DCHECK_EQ(result, gpu::ContextResult::kSuccess); + ASSERT_EQ(result, gpu::ContextResult::kSuccess); + cache_ = std::make_unique<GpuImageDecodeCache>( + context_provider_.get(), UseTransferCache(), kRGBA_8888_SkColorType, + kCacheSize, MaxTextureSize(), PaintImage::kDefaultGeneratorClientId); } protected: @@ -87,9 +85,17 @@ class GpuImageDecodeCachePerfTest } } + perf_test::PerfResultReporter SetUpReporter( + const std::string& metric_suffix) { + perf_test::PerfResultReporter reporter("gpu_image_decode_cache", + ParamName()); + reporter.RegisterImportantMetric(metric_suffix, "runs/s"); + return reporter; + } + base::LapTimer timer_; scoped_refptr<viz::TestInProcessContextProvider> context_provider_; - GpuImageDecodeCache cache_; + std::unique_ptr<GpuImageDecodeCache> cache_; }; INSTANTIATE_TEST_SUITE_P(P, @@ -110,14 +116,14 @@ TEST_P(GpuImageDecodeCachePerfTest, DecodeWithColorConversion) { CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u, gfx::ColorSpace::CreateXYZD50()); - DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image); - cache_.DrawWithImageFinished(image, decoded_image); + DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image); + cache_->DrawWithImageFinished(image, decoded_image); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("gpu_image_decode_cache_decode_with_color_conversion", - ParamName(), "result", timer_.LapsPerSecond(), - "runs/s", true); + perf_test::PerfResultReporter reporter = + SetUpReporter("_with_color_conversion"); + reporter.AddResult("_with_color_conversion", timer_.LapsPerSecond()); } using GpuImageDecodeCachePerfTestNoSw = GpuImageDecodeCachePerfTest; @@ -142,7 +148,7 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) { SkIRect::MakeWH(1024, 2048), kMedium_SkFilterQuality, CreateMatrix(SkSize::Make(0.6f, 0.6f)), 0u, gfx::ColorSpace()); - DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image); + DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image); if (GetParam() == TestMode::kGpu) { SkPaint paint; @@ -153,12 +159,12 @@ TEST_P(GpuImageDecodeCachePerfTestNoSw, DecodeWithMips) { surface->flush(); } - cache_.DrawWithImageFinished(image, decoded_image); + cache_->DrawWithImageFinished(image, decoded_image); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("gpu_image_decode_cache_decode_with_mips", ParamName(), - "result", timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter = SetUpReporter("_with_mips"); + reporter.AddResult("_with_mips", timer_.LapsPerSecond()); } TEST_P(GpuImageDecodeCachePerfTest, AcquireExistingImages) { @@ -172,18 +178,18 @@ TEST_P(GpuImageDecodeCachePerfTest, AcquireExistingImages) { CreateMatrix(SkSize::Make(1.0f, 1.0f)), 0u, gfx::ColorSpace::CreateXYZD50()); - DecodedDrawImage decoded_image = cache_.GetDecodedImageForDraw(image); - cache_.DrawWithImageFinished(image, decoded_image); + DecodedDrawImage decoded_image = cache_->GetDecodedImageForDraw(image); + cache_->DrawWithImageFinished(image, decoded_image); do { - decoded_image = cache_.GetDecodedImageForDraw(image); - cache_.DrawWithImageFinished(image, decoded_image); + decoded_image = cache_->GetDecodedImageForDraw(image); + cache_->DrawWithImageFinished(image, decoded_image); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("gpu_image_decode_cache_acquire_existing_images", - ParamName(), "result", timer_.LapsPerSecond(), - "runs/s", true); + perf_test::PerfResultReporter reporter = + SetUpReporter("_acquire_existing_images"); + reporter.AddResult("_acquire_existing_images", timer_.LapsPerSecond()); } } // namespace diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc index 0c64190327f..329edf9d239 100644 --- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc +++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc @@ -5,7 +5,9 @@ #include "cc/tiles/gpu_image_decode_cache.h" #include <memory> +#include <vector> +#include "base/feature_list.h" #include "base/test/scoped_feature_list.h" #include "cc/paint/draw_image.h" #include "cc/paint/image_transfer_cache_entry.h" @@ -172,8 +174,16 @@ class FakeGPUImageDecodeTestGLES2Interface : public viz::TestGLES2Interface, transfer_cache_helper_->DeleteEntryDirect(MakeEntryKey(type, id)); } + bool IsJpegDecodeAccelerationSupported() const override { + return advertise_accelerated_decoding_; + } + + bool IsWebPDecodeAccelerationSupported() const override { + return advertise_accelerated_decoding_; + } + bool CanDecodeWithHardwareAcceleration( - base::span<const uint8_t> encoded_data) const override { + const ImageHeaderMetadata* image_metadata) const override { return advertise_accelerated_decoding_; } @@ -319,14 +329,21 @@ class GpuImageDecodeCacheTest std::tuple<SkColorType, bool /* use_transfer_cache */, bool /* do_yuv_decode */, + bool /* allow_accelerated_jpeg_decoding */, + bool /* allow_accelerated_webp_decoding */, bool /* advertise_accelerated_decoding */>> { public: void SetUp() override { - advertise_accelerated_decoding_ = std::get<3>(GetParam()); - if (advertise_accelerated_decoding_) { - feature_list_.InitAndEnableFeature( - features::kVaapiJpegImageDecodeAcceleration); - } + std::vector<base::Feature> enabled_features; + allow_accelerated_jpeg_decoding_ = std::get<3>(GetParam()); + if (allow_accelerated_jpeg_decoding_) + enabled_features.push_back(features::kVaapiJpegImageDecodeAcceleration); + allow_accelerated_webp_decoding_ = std::get<4>(GetParam()); + if (allow_accelerated_webp_decoding_) + enabled_features.push_back(features::kVaapiWebPImageDecodeAcceleration); + feature_list_.InitWithFeatures(enabled_features, + {} /* disabled_features */); + advertise_accelerated_decoding_ = std::get<5>(GetParam()); context_provider_ = GPUImageDecodeTestMockContextProvider::Create( &discardable_manager_, &transfer_cache_helper_, advertise_accelerated_decoding_); @@ -556,6 +573,8 @@ class GpuImageDecodeCacheTest bool use_transfer_cache_; SkColorType color_type_; bool do_yuv_decode_; + bool allow_accelerated_jpeg_decoding_; + bool allow_accelerated_webp_decoding_; bool advertise_accelerated_decoding_; int max_texture_size_ = 0; }; @@ -2912,6 +2931,8 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(test_color_types), testing::ValuesIn(false_array) /* use_transfer_cache */, testing::Bool() /* do_yuv_decode */, + testing::ValuesIn(false_array) /* allow_accelerated_jpeg_decoding */, + testing::ValuesIn(false_array) /* allow_accelerated_webp_decoding */, testing::ValuesIn(false_array) /* advertise_accelerated_decoding */)); INSTANTIATE_TEST_SUITE_P( @@ -2921,27 +2942,35 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(test_color_types), testing::ValuesIn(true_array) /* use_transfer_cache */, testing::Bool() /* do_yuv_decode */, + testing::ValuesIn(false_array) /* allow_accelerated_jpeg_decoding */, + testing::ValuesIn(false_array) /* allow_accelerated_webp_decoding */, testing::ValuesIn(false_array) /* advertise_accelerated_decoding */)); class GpuImageDecodeCacheWithAcceleratedDecodesTest : public GpuImageDecodeCacheTest { public: PaintImage CreatePaintImageForDecodeAcceleration( - const gfx::Size& size, - sk_sp<SkColorSpace> color_space = nullptr, - bool is_eligible_for_accelerated_decoding = true) { - SkImageInfo info = - SkImageInfo::Make(size.width(), size.height(), color_type_, - kPremul_SkAlphaType, color_space); + ImageType image_type = ImageType::kJPEG) { + // Create a valid image metadata for hardware acceleration. + ImageHeaderMetadata image_data{}; + image_data.image_size = GetNormalImageSize(); + image_data.image_type = image_type; + image_data.all_data_received_prior_to_decode = true; + image_data.has_embedded_color_profile = false; + image_data.jpeg_is_progressive = false; + image_data.webp_is_non_extended_lossy = true; + + SkImageInfo info = SkImageInfo::Make( + image_data.image_size.width(), image_data.image_size.height(), + color_type_, kPremul_SkAlphaType, SkColorSpace::MakeSRGB()); sk_sp<FakePaintImageGenerator> generator; if (do_yuv_decode_) { - generator = - sk_make_sp<FakePaintImageGenerator>(info, GetYUV420SizeInfo(size)); + generator = sk_make_sp<FakePaintImageGenerator>( + info, GetYUV420SizeInfo(image_data.image_size)); } else { generator = sk_make_sp<FakePaintImageGenerator>(info); } - if (is_eligible_for_accelerated_decoding) - generator->SetEligibleForAcceleratedDecoding(); + generator->SetImageHeaderMetadata(image_data); PaintImage image = PaintImageBuilder::WithDefault() .set_id(PaintImage::GetNextId()) .set_paint_image_generator(generator) @@ -2958,12 +2987,9 @@ class GpuImageDecodeCacheWithAcceleratedDecodesTest TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, RequestAcceleratedDecodeSuccessfully) { auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB(); - const gfx::ColorSpace target_color_space(*image_color_space); + const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB(); ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = - CreatePaintImageForDecodeAcceleration(image_size, image_color_space); + const PaintImage image = CreatePaintImageForDecodeAcceleration(); const SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)), @@ -2975,8 +3001,10 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, // Accelerated decodes should not produce decode tasks. ASSERT_TRUE(result.task->dependencies().empty()); + ASSERT_TRUE(image.GetImageHeaderMetadata()); EXPECT_CALL(*raster_implementation(), - DoScheduleImageDecode(image_size, _, gfx::ColorSpace(), _)) + DoScheduleImageDecode(image.GetImageHeaderMetadata()->image_size, + _, gfx::ColorSpace(), _)) .Times(1); TestTileTaskRunner::ProcessTask(result.task.get()); @@ -2993,12 +3021,9 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, RequestAcceleratedDecodeSuccessfullyWithColorSpaceConversion) { auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB(); const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50(); ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = - CreatePaintImageForDecodeAcceleration(image_size, image_color_space); + const PaintImage image = CreatePaintImageForDecodeAcceleration(); const SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)), @@ -3010,12 +3035,13 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, // Accelerated decodes should not produce decode tasks. ASSERT_TRUE(result.task->dependencies().empty()); + ASSERT_TRUE(image.GetImageHeaderMetadata()); EXPECT_CALL(*raster_implementation(), - DoScheduleImageDecode(image_size, _, - cache->SupportsColorSpaceConversion() - ? target_color_space - : gfx::ColorSpace(), - _)) + DoScheduleImageDecode( + image.GetImageHeaderMetadata()->image_size, _, + cache->SupportsColorSpaceConversion() ? target_color_space + : gfx::ColorSpace(), + _)) .Times(1); TestTileTaskRunner::ProcessTask(result.task.get()); @@ -3032,12 +3058,9 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, AcceleratedDecodeRequestFails) { auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB(); const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateXYZD50(); ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = - CreatePaintImageForDecodeAcceleration(image_size, image_color_space); + const PaintImage image = CreatePaintImageForDecodeAcceleration(); const SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)), @@ -3050,12 +3073,13 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, // Accelerated decodes should not produce decode tasks. ASSERT_TRUE(result.task->dependencies().empty()); raster_implementation()->SetAcceleratedDecodingFailed(); + ASSERT_TRUE(image.GetImageHeaderMetadata()); EXPECT_CALL(*raster_implementation(), - DoScheduleImageDecode(image_size, _, - cache->SupportsColorSpaceConversion() - ? target_color_space - : gfx::ColorSpace(), - _)) + DoScheduleImageDecode( + image.GetImageHeaderMetadata()->image_size, _, + cache->SupportsColorSpaceConversion() ? target_color_space + : gfx::ColorSpace(), + _)) .Times(1); TestTileTaskRunner::ProcessTask(result.task.get()); @@ -3072,12 +3096,9 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, CannotRequestAcceleratedDecodeBecauseOfStandAloneDecode) { auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB(); - const gfx::ColorSpace target_color_space(*image_color_space); + const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB(); ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = - CreatePaintImageForDecodeAcceleration(image_size, image_color_space); + const PaintImage image = CreatePaintImageForDecodeAcceleration(); const SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(1.0f, 1.0f)), @@ -3096,12 +3117,9 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, CannotRequestAcceleratedDecodeBecauseOfNonZeroUploadMipLevel) { auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB(); - const gfx::ColorSpace target_color_space(*image_color_space); + const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB(); ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = - CreatePaintImageForDecodeAcceleration(image_size, image_color_space); + const PaintImage image = CreatePaintImageForDecodeAcceleration(); const SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(0.5f, 0.5f)), @@ -3120,68 +3138,11 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, } TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, - CannotRequestAcceleratedDecodeBecauseOfIneligiblePaintImage) { - auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB(); - const gfx::ColorSpace target_color_space(*image_color_space); - ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = CreatePaintImageForDecodeAcceleration( - image_size, image_color_space, - false /* is_eligible_for_accelerated_decoding */); - const SkFilterQuality quality = kHigh_SkFilterQuality; - DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), - quality, CreateMatrix(SkSize::Make(1.0f, 1.0f)), - PaintImage::kDefaultFrameIndex, target_color_space); - ImageDecodeCache::TaskResult result = - cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo()); - EXPECT_TRUE(result.need_unref); - ASSERT_TRUE(result.task); - - // A non-accelerated normal decode should produce a decode dependency. - ASSERT_EQ(result.task->dependencies().size(), 1u); - ASSERT_TRUE(result.task->dependencies()[0]); - TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get()); - TestTileTaskRunner::ProcessTask(result.task.get()); - cache->UnrefImage(draw_image); -} - -TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, - CannotRequestAcceleratedDecodeBecauseOfNonSRGBColorSpace) { - auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = - SkColorSpace::MakeRGB(SkNamedTransferFn::k2Dot2, SkNamedGamut::kAdobeRGB); - const gfx::ColorSpace target_color_space(*image_color_space); - ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = - CreatePaintImageForDecodeAcceleration(image_size, image_color_space); - const SkFilterQuality quality = kHigh_SkFilterQuality; - DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), - quality, CreateMatrix(SkSize::Make(1.0f, 1.0f)), - PaintImage::kDefaultFrameIndex, target_color_space); - ImageDecodeCache::TaskResult result = - cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo()); - EXPECT_TRUE(result.need_unref); - ASSERT_TRUE(result.task); - - // A non-accelerated normal decode should produce a decode dependency. - ASSERT_EQ(result.task->dependencies().size(), 1u); - ASSERT_TRUE(result.task->dependencies()[0]); - TestTileTaskRunner::ProcessTask(result.task->dependencies()[0].get()); - TestTileTaskRunner::ProcessTask(result.task.get()); - cache->UnrefImage(draw_image); -} - -TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, RequestAcceleratedDecodeSuccessfullyAfterCancellation) { auto cache = CreateCache(); - const gfx::Size image_size = GetNormalImageSize(); - const sk_sp<SkColorSpace> image_color_space = SkColorSpace::MakeSRGB(); - const gfx::ColorSpace target_color_space(*image_color_space); + const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB(); ASSERT_TRUE(target_color_space.IsValid()); - const PaintImage image = - CreatePaintImageForDecodeAcceleration(image_size, image_color_space); + const PaintImage image = CreatePaintImageForDecodeAcceleration(); const SkFilterQuality quality = kHigh_SkFilterQuality; DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()), quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)), @@ -3204,8 +3165,10 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest, EXPECT_TRUE(another_result.need_unref); ASSERT_TRUE(another_result.task); EXPECT_EQ(another_result.task->dependencies().size(), 0u); + ASSERT_TRUE(image.GetImageHeaderMetadata()); EXPECT_CALL(*raster_implementation(), - DoScheduleImageDecode(image_size, _, gfx::ColorSpace(), _)) + DoScheduleImageDecode(image.GetImageHeaderMetadata()->image_size, + _, gfx::ColorSpace(), _)) .Times(1); TestTileTaskRunner::ProcessTask(another_result.task.get()); @@ -3227,8 +3190,111 @@ INSTANTIATE_TEST_SUITE_P( testing::ValuesIn(test_color_types), testing::ValuesIn(true_array) /* use_transfer_cache */, testing::Bool() /* do_yuv_decode */, + testing::ValuesIn(true_array) /* allow_accelerated_jpeg_decoding */, + testing::ValuesIn(true_array) /* allow_accelerated_webp_decoding */, testing::ValuesIn(true_array) /* advertise_accelerated_decoding */)); +class GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest + : public GpuImageDecodeCacheWithAcceleratedDecodesTest {}; + +TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest, + RequestAcceleratedDecodeSuccessfully) { + auto cache = CreateCache(); + const SkFilterQuality quality = kHigh_SkFilterQuality; + const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB(); + ASSERT_TRUE(target_color_space.IsValid()); + + // Try a JPEG image. + const PaintImage jpeg_image = + CreatePaintImageForDecodeAcceleration(ImageType::kJPEG); + DrawImage jpeg_draw_image( + jpeg_image, SkIRect::MakeWH(jpeg_image.width(), jpeg_image.height()), + quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)), + PaintImage::kDefaultFrameIndex, target_color_space); + ImageDecodeCache::TaskResult jpeg_task = cache->GetTaskForImageAndRef( + jpeg_draw_image, ImageDecodeCache::TracingInfo()); + EXPECT_TRUE(jpeg_task.need_unref); + ASSERT_TRUE(jpeg_task.task); + // If the hardware decoder claims support for the image (i.e., + // |advertise_accelerated_decoding_| is true) and the feature flag for the + // image type is on (i.e., |allow_accelerated_jpeg_decoding_| is true), we + // should expect hardware acceleration. In that path, there is only an upload + // task without a decode dependency since the decode will be done in the GPU + // process. In the alternative path (software decoding), the upload task + // depends on a decode task that runs in the renderer. + if (advertise_accelerated_decoding_ && allow_accelerated_jpeg_decoding_) { + ASSERT_TRUE(jpeg_task.task->dependencies().empty()); + ASSERT_TRUE(jpeg_image.GetImageHeaderMetadata()); + EXPECT_CALL( + *raster_implementation(), + DoScheduleImageDecode(jpeg_image.GetImageHeaderMetadata()->image_size, + _, gfx::ColorSpace(), _)) + .Times(1); + } else { + ASSERT_EQ(jpeg_task.task->dependencies().size(), 1u); + ASSERT_TRUE(jpeg_task.task->dependencies()[0]); + TestTileTaskRunner::ProcessTask(jpeg_task.task->dependencies()[0].get()); + } + TestTileTaskRunner::ProcessTask(jpeg_task.task.get()); + testing::Mock::VerifyAndClearExpectations(raster_implementation()); + cache->UnrefImage(jpeg_draw_image); + + // Try a WebP image. + const PaintImage webp_image = + CreatePaintImageForDecodeAcceleration(ImageType::kWEBP); + DrawImage webp_draw_image( + webp_image, SkIRect::MakeWH(webp_image.width(), webp_image.height()), + quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)), + PaintImage::kDefaultFrameIndex, target_color_space); + ImageDecodeCache::TaskResult webp_task = cache->GetTaskForImageAndRef( + webp_draw_image, ImageDecodeCache::TracingInfo()); + EXPECT_TRUE(webp_task.need_unref); + ASSERT_TRUE(webp_task.task); + if (advertise_accelerated_decoding_ && allow_accelerated_webp_decoding_) { + ASSERT_TRUE(webp_task.task->dependencies().empty()); + ASSERT_TRUE(webp_image.GetImageHeaderMetadata()); + EXPECT_CALL( + *raster_implementation(), + DoScheduleImageDecode(webp_image.GetImageHeaderMetadata()->image_size, + _, gfx::ColorSpace(), _)) + .Times(1); + } else { + ASSERT_EQ(webp_task.task->dependencies().size(), 1u); + ASSERT_TRUE(webp_task.task->dependencies()[0]); + TestTileTaskRunner::ProcessTask(webp_task.task->dependencies()[0].get()); + } + TestTileTaskRunner::ProcessTask(webp_task.task.get()); + testing::Mock::VerifyAndClearExpectations(raster_implementation()); + cache->UnrefImage(webp_draw_image); + + // Try a PNG image (which should not be hardware accelerated). + const PaintImage png_image = + CreatePaintImageForDecodeAcceleration(ImageType::kPNG); + DrawImage png_draw_image( + png_image, SkIRect::MakeWH(jpeg_image.width(), jpeg_image.height()), + quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)), + PaintImage::kDefaultFrameIndex, target_color_space); + ImageDecodeCache::TaskResult png_task = cache->GetTaskForImageAndRef( + png_draw_image, ImageDecodeCache::TracingInfo()); + EXPECT_TRUE(png_task.need_unref); + ASSERT_TRUE(png_task.task); + ASSERT_EQ(png_task.task->dependencies().size(), 1u); + ASSERT_TRUE(png_task.task->dependencies()[0]); + TestTileTaskRunner::ProcessTask(png_task.task->dependencies()[0].get()); + TestTileTaskRunner::ProcessTask(png_task.task.get()); + cache->UnrefImage(png_draw_image); +} + +INSTANTIATE_TEST_SUITE_P( + GpuImageDecodeCacheTestsOOPR, + GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest, + testing::Combine(testing::Values(kN32_SkColorType), + testing::ValuesIn(true_array) /* use_transfer_cache */, + testing::Bool() /* do_yuv_decode */, + testing::Bool() /* allow_accelerated_jpeg_decoding */, + testing::Bool() /* allow_accelerated_webp_decoding */, + testing::Bool() /* advertise_accelerated_decoding */)); + #undef EXPECT_TRUE_IF_NOT_USING_TRANSFER_CACHE #undef EXPECT_FALSE_IF_NOT_USING_TRANSFER_CACHE diff --git a/chromium/cc/tiles/image_decode_cache.h b/chromium/cc/tiles/image_decode_cache.h index 54b13164211..f2451ca7e5a 100644 --- a/chromium/cc/tiles/image_decode_cache.h +++ b/chromium/cc/tiles/image_decode_cache.h @@ -74,12 +74,12 @@ class CC_EXPORT ImageDecodeCache { } static devtools_instrumentation::ScopedImageDecodeTask::ImageType - ToScopedImageType(PaintImage::ImageType image_type) { + ToScopedImageType(ImageType image_type) { using ScopedImageType = devtools_instrumentation::ScopedImageDecodeTask::ImageType; - if (image_type == PaintImage::ImageType::kWEBP) + if (image_type == ImageType::kWEBP) return ScopedImageType::kWebP; - if (image_type == PaintImage::ImageType::kJPEG) + if (image_type == ImageType::kJPEG) return ScopedImageType::kJpeg; return ScopedImageType::kOther; } diff --git a/chromium/cc/tiles/picture_layer_tiling.cc b/chromium/cc/tiles/picture_layer_tiling.cc index d8347eb17ec..116f3c4db58 100644 --- a/chromium/cc/tiles/picture_layer_tiling.cc +++ b/chromium/cc/tiles/picture_layer_tiling.cc @@ -626,12 +626,11 @@ void PictureLayerTiling::SetTilePriorityRects( // since skewport.Contains(visible_rect) is always true. max_skewport_extent_in_screen_space_ = current_content_to_screen_scale_ * - std::max(std::max(current_visible_rect_.x() - current_skewport_rect_.x(), - current_skewport_rect_.right() - - current_visible_rect_.right()), - std::max(current_visible_rect_.y() - current_skewport_rect_.y(), - current_skewport_rect_.bottom() - - current_visible_rect_.bottom())); + std::max( + {current_visible_rect_.x() - current_skewport_rect_.x(), + current_skewport_rect_.right() - current_visible_rect_.right(), + current_visible_rect_.y() - current_skewport_rect_.y(), + current_skewport_rect_.bottom() - current_visible_rect_.bottom()}); } void PictureLayerTiling::SetLiveTilesRect( diff --git a/chromium/cc/tiles/software_image_decode_cache.cc b/chromium/cc/tiles/software_image_decode_cache.cc index 9a2a8e905a8..cbe8511f196 100644 --- a/chromium/cc/tiles/software_image_decode_cache.cc +++ b/chromium/cc/tiles/software_image_decode_cache.cc @@ -72,11 +72,15 @@ class SoftwareImageDecodeTaskImpl : public TileTask { TRACE_EVENT2("cc", "SoftwareImageDecodeTaskImpl::RunOnWorkerThread", "mode", "software", "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); + + const auto* image_metadata = paint_image_.GetImageHeaderMetadata(); + const ImageType image_type = + image_metadata ? image_metadata->image_type : ImageType::kInvalid; devtools_instrumentation::ScopedImageDecodeTask image_decode_task( paint_image_.GetSkImage().get(), devtools_instrumentation::ScopedImageDecodeTask::kSoftware, ImageDecodeCache::ToScopedTaskType(tracing_info_.task_type), - ImageDecodeCache::ToScopedImageType(paint_image_.GetImageType())); + ImageDecodeCache::ToScopedImageType(image_type)); SoftwareImageDecodeCache::TaskProcessingResult result = cache_->DecodeImageInTask(image_key_, paint_image_, task_type_); diff --git a/chromium/cc/tiles/software_image_decode_cache_perftest.cc b/chromium/cc/tiles/software_image_decode_cache_perftest.cc index fb99fb7c3f6..5d729ac8587 100644 --- a/chromium/cc/tiles/software_image_decode_cache_perftest.cc +++ b/chromium/cc/tiles/software_image_decode_cache_perftest.cc @@ -10,7 +10,7 @@ #include "cc/raster/tile_task.h" #include "cc/tiles/software_image_decode_cache.h" #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -78,8 +78,10 @@ class SoftwareImageDecodeCachePerfTest : public testing::Test { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("software_image_decode_cache_fromdrawimage", "", - "result", timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter("software_image_decode_cache", + "fromdrawimage"); + reporter.RegisterImportantMetric("", "runs/s"); + reporter.AddResult("", timer_.LapsPerSecond()); } private: diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc index e6d77b6aedc..5ec8b2642fe 100644 --- a/chromium/cc/tiles/tile_manager.cc +++ b/chromium/cc/tiles/tile_manager.cc @@ -17,7 +17,6 @@ #include "base/metrics/histogram.h" #include "base/numerics/safe_conversions.h" #include "base/optional.h" -#include "base/system/sys_info.h" #include "base/threading/thread_checker.h" #include "base/trace_event/traced_value.h" #include "cc/base/devtools_instrumentation.h" @@ -702,8 +701,6 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { tile->use_picture_analysis() && kUseColorEstimator) { // We analyze for solid color here, to decide to continue // or drop the tile for scheduling and raster. - // TODO(sohanjg): Check if we could use a shared analysis - // canvas which is reset between tiles. tile->set_solid_color_analysis_performed(true); SkColor color = SK_ColorTRANSPARENT; bool is_solid_color = @@ -848,13 +845,10 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { } } - // The hard_limit for low-end devices is 8MB, so we set the max_value for the - // histogram to be 8200KB. - if (had_enough_memory_to_schedule_tiles_needed_now && - base::SysInfo::AmountOfPhysicalMemoryMB() <= 512) { + if (had_enough_memory_to_schedule_tiles_needed_now) { int64_t tiles_gpu_memory_kb = memory_usage.memory_bytes() / 1024; - UMA_HISTOGRAM_CUSTOM_COUNTS("TileManager.TilesGPUMemoryUsage", - tiles_gpu_memory_kb, 1, 8200, 100); + UMA_HISTOGRAM_MEMORY_KB("TileManager.TilesGPUMemoryUsage2", + tiles_gpu_memory_kb); } UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget", diff --git a/chromium/cc/tiles/tile_manager_perftest.cc b/chromium/cc/tiles/tile_manager_perftest.cc index a683a74f0ab..07cd2aa57f2 100644 --- a/chromium/cc/tiles/tile_manager_perftest.cc +++ b/chromium/cc/tiles/tile_manager_perftest.cc @@ -21,6 +21,7 @@ #include "cc/test/fake_tile_manager.h" #include "cc/test/fake_tile_manager_client.h" #include "cc/test/fake_tile_task_manager.h" +#include "cc/test/layer_test_common.h" #include "cc/test/test_layer_tree_host_base.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_tile_priorities.h" @@ -28,9 +29,8 @@ #include "cc/tiles/tile_priority.h" #include "cc/trees/layer_tree_impl.h" #include "components/viz/test/begin_frame_args_test.h" - #include "testing/gtest/include/gtest/gtest.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -65,6 +65,18 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { SetupPendingTree(std::move(pending_raster_source), tile_size, Region()); } + perf_test::PerfResultReporter SetUpReporter(const std::string& story_name) { + perf_test::PerfResultReporter reporter("tile_manager", story_name); + reporter.RegisterImportantMetric("_raster_tile_queue_construct", "runs/s"); + reporter.RegisterImportantMetric("_raster_tile_queue_construct_and_iterate", + "runs/s"); + reporter.RegisterImportantMetric("_eviction_tile_queue_construct", + "runs/s"); + reporter.RegisterImportantMetric( + "_eviction_tile_queue_construct_and_iterate", "runs/s"); + return reporter; + } + void RunRasterQueueConstructTest(const std::string& test_name, int layer_count) { TreePriority priorities[] = {SAME_PRIORITY_FOR_BOTH_TREES, @@ -85,12 +97,8 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("tile_manager_raster_tile_queue_construct", - "", - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_raster_tile_queue_construct", timer_.LapsPerSecond()); } void RunRasterQueueConstructAndIterateTest(const std::string& test_name, @@ -120,13 +128,9 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult( - "tile_manager_raster_tile_queue_construct_and_iterate", - "", - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_raster_tile_queue_construct_and_iterate", + timer_.LapsPerSecond()); } void RunEvictionQueueConstructTest(const std::string& test_name, @@ -153,12 +157,9 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("tile_manager_eviction_tile_queue_construct", - "", - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_eviction_tile_queue_construct", + timer_.LapsPerSecond()); } void RunEvictionQueueConstructAndIterateTest(const std::string& test_name, @@ -193,13 +194,9 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult( - "tile_manager_eviction_tile_queue_construct_and_iterate", - "", - test_name, - timer_.LapsPerSecond(), - "runs/s", - true); + perf_test::PerfResultReporter reporter = SetUpReporter(test_name); + reporter.AddResult("_eviction_tile_queue_construct_and_iterate", + timer_.LapsPerSecond()); } std::vector<FakePictureLayerImpl*> CreateLayers(int layer_count, @@ -211,12 +208,12 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { // Adjust the width and height to account for the fact that tiles // are bigger than 1x1. - LayerTreeSettings settings; + LayerListSettings settings; width *= settings.default_tile_size.width(); height *= settings.default_tile_size.height(); // Ensure that we start with blank trees and no tiles. - host_impl()->ResetTreesForTesting(); + ResetTrees(); gfx::Size layer_bounds(width, height); gfx::Rect viewport(width / 5, height / 5); @@ -228,26 +225,22 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { // Pending layer counts as one layer. layers.push_back(pending_layer()); - int next_id = layer_id() + 1; // Create the rest of the layers as children of the root layer. scoped_refptr<FakeRasterSource> raster_source = FakeRasterSource::CreateFilledWithImages(layer_bounds); while (static_cast<int>(layers.size()) < layer_count) { - std::unique_ptr<FakePictureLayerImpl> child_layer = - FakePictureLayerImpl::CreateWithRasterSource( - host_impl()->pending_tree(), next_id, raster_source); + auto* child_layer = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), raster_source); child_layer->SetBounds(layer_bounds); child_layer->SetDrawsContent(true); - layers.push_back(child_layer.get()); - pending_layer()->test_properties()->AddChild(std::move(child_layer)); - ++next_id; + layers.push_back(child_layer); + CopyProperties(pending_layer(), child_layer); } // Property trees need to be rebuilt because layers were added above. - host_impl()->pending_tree()->property_trees()->needs_rebuild = true; - host_impl()->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl()->pending_tree()->UpdateDrawProperties(); + host_impl()->pending_tree()->set_needs_update_draw_properties(); + UpdateDrawProperties(host_impl()->pending_tree()); for (FakePictureLayerImpl* layer : layers) layer->CreateAllTiles(); @@ -285,8 +278,9 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); - perf_test::PrintResult("prepare_tiles", "", test_name, - timer_.LapsPerSecond(), "runs/s", true); + perf_test::PerfResultReporter reporter("prepare_tiles", test_name); + reporter.RegisterImportantMetric("", "runs/s"); + reporter.AddResult("", timer_.LapsPerSecond()); } TileManager* tile_manager() { return host_impl()->tile_manager(); } diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc index df7e2d838a2..56410fea4fc 100644 --- a/chromium/cc/tiles/tile_manager_unittest.cc +++ b/chromium/cc/tiles/tile_manager_unittest.cc @@ -30,6 +30,7 @@ #include "cc/test/fake_recording_source.h" #include "cc/test/fake_tile_manager.h" #include "cc/test/fake_tile_task_manager.h" +#include "cc/test/layer_test_common.h" #include "cc/test/skia_common.h" #include "cc/test/test_layer_tree_host_base.h" #include "cc/test/test_task_graph_runner.h" @@ -88,7 +89,7 @@ class SynchronousSimpleTaskRunner : public base::TestSimpleTaskRunner { class TileManagerTilePriorityQueueTest : public TestLayerTreeHostBase { public: LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings; + auto settings = TestLayerTreeHostBase::CreateSettings(); settings.create_low_res_tiling = true; return settings; } @@ -616,19 +617,15 @@ TEST_F(TileManagerTilePriorityQueueTest, ActivationComesBeforeSoon) { // Create a pending child layer. scoped_refptr<FakeRasterSource> pending_raster_source = FakeRasterSource::CreateFilled(layer_bounds); - std::unique_ptr<FakePictureLayerImpl> pending_child = - FakePictureLayerImpl::CreateWithRasterSource( - host_impl()->pending_tree(), layer_id() + 1, pending_raster_source); - FakePictureLayerImpl* pending_child_raw = pending_child.get(); - pending_child_raw->SetDrawsContent(true); - pending_layer()->test_properties()->AddChild(std::move(pending_child)); + auto* pending_child = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), pending_raster_source); + pending_child->SetDrawsContent(true); + CopyProperties(pending_layer(), pending_child); // Set a small viewport, so we have soon and eventually tiles. host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(200, 200)); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->property_trees()->needs_rebuild = true; - host_impl()->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); host_impl()->SetRequiresHighResToDraw(); std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( @@ -836,21 +833,14 @@ TEST_F(TileManagerTilePriorityQueueTest, FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - std::unique_ptr<FakePictureLayerImpl> pending_child = - FakePictureLayerImpl::CreateWithRasterSource(host_impl()->pending_tree(), - 2, pending_raster_source); - int child_id = pending_child->id(); - pending_layer()->test_properties()->AddChild(std::move(pending_child)); - - FakePictureLayerImpl* pending_child_layer = - static_cast<FakePictureLayerImpl*>( - pending_layer()->test_properties()->children[0]); + auto* pending_child_layer = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), pending_raster_source); + int child_id = pending_child_layer->id(); pending_child_layer->SetDrawsContent(true); + CopyProperties(pending_layer(), pending_child_layer); host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->property_trees()->needs_rebuild = true; - host_impl()->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); ActivateTree(); SetupPendingTree(pending_raster_source); @@ -950,21 +940,20 @@ TEST_F(TileManagerTilePriorityQueueTest, FakeRasterSource::CreateFilled(layer_bounds); SetupPendingTree(pending_raster_source); - std::unique_ptr<FakePictureLayerImpl> pending_child = - FakePictureLayerImpl::CreateWithRasterSource(host_impl()->pending_tree(), - 2, pending_raster_source); - FakePictureLayerImpl* pending_child_layer = pending_child.get(); - pending_layer()->test_properties()->AddChild(std::move(pending_child)); + auto* pending_child_layer = AddLayer<FakePictureLayerImpl>( + host_impl()->pending_tree(), pending_raster_source); + pending_child_layer->SetElementId( + LayerIdToElementIdForTesting(pending_child_layer->id())); + CopyProperties(pending_layer(), pending_child_layer); // Create a fully transparent child layer so that its tile priorities are not // considered to be valid. pending_child_layer->SetDrawsContent(true); - pending_child_layer->test_properties()->force_render_surface = true; + CreateEffectNode(pending_child_layer).render_surface_reason = + RenderSurfaceReason::kTest; host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1)); - host_impl()->pending_tree()->property_trees()->needs_rebuild = true; - host_impl()->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); host_impl()->pending_tree()->SetOpacityMutated( pending_child_layer->element_id(), 0.0f); @@ -1052,13 +1041,11 @@ TEST_F(TileManagerTilePriorityQueueTest, RasterTilePriorityQueueEmptyLayers) { EXPECT_EQ(16u, tile_count); for (int i = 1; i < 10; ++i) { - std::unique_ptr<FakePictureLayerImpl> pending_child_layer = - FakePictureLayerImpl::Create(host_impl()->pending_tree(), - layer_id() + i); + auto* pending_child_layer = + AddLayer<FakePictureLayerImpl>(host_impl()->pending_tree()); pending_child_layer->SetDrawsContent(true); pending_child_layer->set_has_valid_tile_priorities(true); - pending_layer()->test_properties()->AddChild( - std::move(pending_child_layer)); + CopyProperties(pending_layer(), pending_child_layer); } queue = host_impl()->BuildRasterQueue(SAME_PRIORITY_FOR_BOTH_TREES, @@ -1102,13 +1089,11 @@ TEST_F(TileManagerTilePriorityQueueTest, EvictionTilePriorityQueueEmptyLayers) { host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting(tiles); for (int i = 1; i < 10; ++i) { - std::unique_ptr<FakePictureLayerImpl> pending_child_layer = - FakePictureLayerImpl::Create(host_impl()->pending_tree(), - layer_id() + i); + auto* pending_child_layer = + AddLayer<FakePictureLayerImpl>(host_impl()->pending_tree()); pending_child_layer->SetDrawsContent(true); pending_child_layer->set_has_valid_tile_priorities(true); - pending_layer()->test_properties()->AddChild( - std::move(pending_child_layer)); + CopyProperties(pending_layer(), pending_child_layer); } std::unique_ptr<EvictionTilePriorityQueue> queue( @@ -1491,8 +1476,8 @@ TEST_F(TileManagerTilePriorityQueueTest, NoRasterTasksforSolidColorTiles) { FakePictureLayerTilingClient tiling_client; tiling_client.SetTileSize(size); - std::unique_ptr<PictureLayerImpl> layer_impl = PictureLayerImpl::Create( - host_impl()->active_tree(), 1, Layer::LayerMaskType::NOT_MASK); + std::unique_ptr<PictureLayerImpl> layer_impl = + PictureLayerImpl::Create(host_impl()->active_tree(), 1); layer_impl->set_contributes_to_drawn_render_surface(true); PictureLayerTilingSet* tiling_set = layer_impl->picture_layer_tiling_set(); @@ -1775,8 +1760,8 @@ TEST_F(PixelInspectTileManagerTest, LowResHasNoImage) { FakePictureLayerTilingClient tiling_client; tiling_client.SetTileSize(size); - std::unique_ptr<PictureLayerImpl> layer = PictureLayerImpl::Create( - host_impl()->active_tree(), 1, Layer::LayerMaskType::NOT_MASK); + std::unique_ptr<PictureLayerImpl> layer = + PictureLayerImpl::Create(host_impl()->active_tree(), 1); PictureLayerTilingSet* tiling_set = layer->picture_layer_tiling_set(); layer->set_contributes_to_drawn_render_surface(true); @@ -1850,7 +1835,7 @@ class ActivationTasksDoNotBlockReadyToDrawTest : public TileManagerTest { } LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings = TileManagerTest::CreateSettings(); + auto settings = TileManagerTest::CreateSettings(); settings.gpu_rasterization_forced = true; return settings; } @@ -1906,7 +1891,7 @@ TEST_F(ActivationTasksDoNotBlockReadyToDrawTest, class PartialRasterTileManagerTest : public TileManagerTest { public: LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings = TileManagerTest::CreateSettings(); + auto settings = TileManagerTest::CreateSettings(); settings.use_partial_raster = true; return settings; } @@ -1935,17 +1920,17 @@ TEST_F(PartialRasterTileManagerTest, CancelledTasksHaveNoContentId) { // Steal from the recycled tree. std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, kLayerId, - pending_raster_source); + FakePictureLayerImpl::Create(pending_tree, kLayerId, + pending_raster_source); pending_layer->SetDrawsContent(true); // The bounds() just mirror the raster source size. pending_layer->SetBounds(pending_layer->raster_source()->GetSize()); + SetupRootProperties(pending_layer.get()); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); // Add tilings/tiles for the layer. - host_impl()->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); // Build the raster queue and invalidate the top tile. std::unique_ptr<RasterTilePriorityQueue> queue(host_impl()->BuildRasterQueue( @@ -2033,17 +2018,17 @@ void RunPartialRasterCheck(std::unique_ptr<LayerTreeHostImpl> host_impl, host_impl->active_tree()->GetDeviceViewport()); std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, kLayerId, - pending_raster_source); + FakePictureLayerImpl::Create(pending_tree, kLayerId, + pending_raster_source); pending_layer->SetDrawsContent(true); // The bounds() just mirror the raster source size. pending_layer->SetBounds(pending_layer->raster_source()->GetSize()); + SetupRootProperties(pending_layer.get()); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); // Add tilings/tiles for the layer. - host_impl->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(pending_tree); // Build the raster queue and invalidate the top tile. std::unique_ptr<RasterTilePriorityQueue> queue(host_impl->BuildRasterQueue( @@ -2118,17 +2103,17 @@ void RunPartialTileDecodeCheck(std::unique_ptr<LayerTreeHostImpl> host_impl, // Steal from the recycled tree. std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, kLayerId, - pending_raster_source); + FakePictureLayerImpl::Create(pending_tree, kLayerId, + pending_raster_source); pending_layer->SetDrawsContent(true); // The bounds() just mirror the raster source size. pending_layer->SetBounds(pending_layer->raster_source()->GetSize()); + SetupRootProperties(pending_layer.get()); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); // Add tilings/tiles for the layer. - host_impl->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(pending_tree); // Build the raster queue and invalidate the top tile if partial raster is // enabled. @@ -2230,8 +2215,8 @@ TEST_F(InvalidResourceTileManagerTest, InvalidResource) { FakePictureLayerTilingClient tiling_client; tiling_client.SetTileSize(size); - std::unique_ptr<PictureLayerImpl> layer = PictureLayerImpl::Create( - host_impl()->active_tree(), 1, Layer::LayerMaskType::NOT_MASK); + std::unique_ptr<PictureLayerImpl> layer = + PictureLayerImpl::Create(host_impl()->active_tree(), 1); layer->set_contributes_to_drawn_render_surface(true); auto* tiling = layer->picture_layer_tiling_set()->AddTiling( @@ -2337,11 +2322,6 @@ class TileManagerReadyToDrawTest : public TileManagerTest { recording_source_->Rerecord(); } - LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings; - return settings; - } - void SetupTreesWithActiveTreeTiles() { scoped_refptr<RasterSource> active_tree_raster_source = recording_source_->CreateRasterSource(); @@ -2561,8 +2541,8 @@ TEST_F(TileManagerReadyToDrawTest, TilePrioritiesUpdated) { EXPECT_GT(orig_num_required, 0u); host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds)); - host_impl()->active_tree()->UpdateDrawProperties(); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->active_tree()); + UpdateDrawProperties(host_impl()->pending_tree()); // Rerun prepare tiles. { @@ -2711,7 +2691,7 @@ class CheckerImagingTileManagerTest : public TestLayerTreeHostBase { } LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings; + auto settings = TestLayerTreeHostBase::CreateSettings(); settings.commit_to_active_tree = false; settings.enable_checker_imaging = true; settings.min_image_bytes_to_checker = 512 * 1024; @@ -2797,7 +2777,7 @@ TEST_F(CheckerImagingTileManagerTest, class EmptyCacheTileManagerTest : public TileManagerTest { public: LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings; + auto settings = TileManagerTest::CreateSettings(); settings.decoded_image_working_set_budget_bytes = 0; return settings; } @@ -3325,7 +3305,7 @@ class DecodedImageTrackerTileManagerTest : public TestLayerTreeHostBase { } LayerTreeSettings CreateSettings() override { - LayerTreeSettings settings = TestLayerTreeHostBase::CreateSettings(); + auto settings = TestLayerTreeHostBase::CreateSettings(); settings.max_preraster_distance_in_screen_pixels = 100; return settings; } @@ -3403,18 +3383,18 @@ TEST_F(DecodedImageTrackerTileManagerTest, DecodedImageTrackerDropsLocksOnUse) { // Steal from the recycled tree. std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, kLayerId, - pending_raster_source); + FakePictureLayerImpl::Create(pending_tree, kLayerId, + pending_raster_source); pending_layer->SetDrawsContent(true); // The bounds() are half the recording source size, allowing for prepaint // images. pending_layer->SetBounds(gfx::Size(500, 500)); + SetupRootProperties(pending_layer.get()); pending_tree->SetRootLayerForTesting(std::move(pending_layer)); // Add tilings/tiles for the layer. - host_impl()->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl()->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl()->pending_tree()); // Build the raster queue and invalidate the top tile if partial raster is // enabled. diff --git a/chromium/cc/trees/damage_tracker.cc b/chromium/cc/trees/damage_tracker.cc index 743b681dc6a..e56e3311013 100644 --- a/chromium/cc/trees/damage_tracker.cc +++ b/chromium/cc/trees/damage_tracker.cc @@ -15,7 +15,6 @@ #include "cc/layers/render_surface_impl.h" #include "cc/paint/filter_operations.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -25,13 +24,10 @@ std::unique_ptr<DamageTracker> DamageTracker::Create() { return base::WrapUnique(new DamageTracker()); } -DamageTracker::DamageTracker() : mailboxId_(0) {} - +DamageTracker::DamageTracker() = default; DamageTracker::~DamageTracker() = default; -void DamageTracker::UpdateDamageTracking( - LayerTreeImpl* layer_tree_impl, - const RenderSurfaceList& render_surface_list) { +void DamageTracker::UpdateDamageTracking(LayerTreeImpl* layer_tree_impl) { // // This function computes the "damage rect" of each target surface, and // updates the state that is used to correctly track damage across frames. The @@ -105,7 +101,7 @@ void DamageTracker::UpdateDamageTracking( // erased from map. // - for (RenderSurfaceImpl* render_surface : render_surface_list) { + for (auto* render_surface : layer_tree_impl->GetRenderSurfaceList()) { render_surface->damage_tracker()->PrepareForUpdate(); } @@ -171,8 +167,6 @@ void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) { // These functions cannot be bypassed with early-exits, even if we know what // the damage will be for this frame, because we need to update the damage // tracker state to correctly track the next frame. - DamageAccumulator damage_from_surface_mask = - TrackDamageFromSurfaceMask(render_surface->MaskLayer()); DamageAccumulator damage_from_leftover_rects = TrackDamageFromLeftoverRects(); // True if any layer is removed. has_damage_from_contributing_content_ |= @@ -186,7 +180,6 @@ void DamageTracker::ComputeSurfaceDamage(RenderSurfaceImpl* render_surface) { } else { // TODO(shawnsingh): can we clamp this damage to the surface's content rect? // (affects performance, but not correctness) - damage_for_this_update_.Union(damage_from_surface_mask); damage_for_this_update_.Union(damage_from_leftover_rects); gfx::Rect damage_rect; @@ -240,24 +233,6 @@ DamageTracker::SurfaceRectMapData& DamageTracker::RectDataForSurface( return *it; } -DamageTracker::DamageAccumulator DamageTracker::TrackDamageFromSurfaceMask( - LayerImpl* target_surface_mask_layer) { - DamageAccumulator damage; - - if (!target_surface_mask_layer) - return damage; - - // Currently, if there is any change to the mask, we choose to damage the - // entire surface. This could potentially be optimized later, but it is not - // expected to be a common case. - if (target_surface_mask_layer->LayerPropertyChanged() || - !target_surface_mask_layer->update_rect().IsEmpty()) { - damage.Union(gfx::Rect(target_surface_mask_layer->bounds())); - } - - return damage; -} - void DamageTracker::PrepareForUpdate() { mailboxId_++; damage_for_this_update_ = DamageAccumulator(); diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h index bda7579c9d9..2515a563f04 100644 --- a/chromium/cc/trees/damage_tracker.h +++ b/chromium/cc/trees/damage_tracker.h @@ -34,9 +34,7 @@ class CC_EXPORT DamageTracker { DamageTracker& operator=(const DamageTracker&) = delete; - static void UpdateDamageTracking( - LayerTreeImpl* layer_tree_impl, - const RenderSurfaceList& render_surface_list); + static void UpdateDamageTracking(LayerTreeImpl* layer_tree_impl); void DidDrawDamagedArea() { current_damage_ = DamageAccumulator(); @@ -91,8 +89,6 @@ class CC_EXPORT DamageTracker { int bottom_ = 0; }; - DamageAccumulator TrackDamageFromSurfaceMask( - LayerImpl* target_surface_mask_layer); DamageAccumulator TrackDamageFromLeftoverRects(); // These helper functions are used only during UpdateDamageTracking(). @@ -148,10 +144,10 @@ class CC_EXPORT DamageTracker { SortedRectMapForLayers rect_history_for_layers_; SortedRectMapForSurfaces rect_history_for_surfaces_; - unsigned int mailboxId_; + unsigned int mailboxId_ = 0; DamageAccumulator current_damage_; // Damage from contributing render surface and layer - bool has_damage_from_contributing_content_; + bool has_damage_from_contributing_content_ = false; // Damage accumulated since the last call to PrepareForUpdate(). DamageAccumulator damage_for_this_update_; diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index f5bb60b229d..d2636625dfb 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -10,12 +10,10 @@ #include "cc/layers/layer_impl.h" #include "cc/paint/filter_operation.h" #include "cc/paint/filter_operations.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_host_impl.h" +#include "cc/test/fake_picture_layer_impl.h" +#include "cc/test/fake_raster_source.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" -#include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" @@ -28,7 +26,10 @@ namespace { class TestLayerImpl : public LayerImpl { public: - TestLayerImpl(LayerTreeImpl* tree_impl, int id); + static std::unique_ptr<TestLayerImpl> Create(LayerTreeImpl* tree_impl, + int id) { + return base::WrapUnique(new TestLayerImpl(tree_impl, id)); + } void AddDamageRect(const gfx::Rect& damage_rect); @@ -37,6 +38,8 @@ class TestLayerImpl : public LayerImpl { void ResetChangeTracking() override; private: + TestLayerImpl(LayerTreeImpl* tree_impl, int id); + gfx::Rect damage_rect_; }; @@ -56,21 +59,6 @@ void TestLayerImpl::ResetChangeTracking() { damage_rect_.SetRect(0, 0, 0, 0); } -void ExecuteCalculateDrawProperties(LayerImpl* root, - float device_scale_factor, - RenderSurfaceList* render_surface_list) { - // Sanity check: The test itself should create the root layer's render - // surface, so that the surface (and its damage tracker) can - // persist across multiple calls to this function. - ASSERT_FALSE(render_surface_list->size()); - - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(root->bounds()), device_scale_factor, - render_surface_list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); - ASSERT_TRUE(GetRenderSurface(root)); -} - void ClearDamageForAllSurfaces(LayerImpl* root) { for (auto* layer : *root->layer_tree_impl()) { if (GetRenderSurface(layer)) @@ -78,48 +66,29 @@ void ClearDamageForAllSurfaces(LayerImpl* root) { } } -void EmulateDrawingOneFrame(LayerImpl* root, float device_scale_factor = 1.f) { - // This emulates only steps that are relevant to testing the damage tracker: - // 1. computing the render passes and layerlists - // 2. updating all damage trackers in the correct order - // 3. resetting all update_rects and property_changed flags for all layers - // and surfaces. - - RenderSurfaceList render_surface_list; - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); - - DamageTracker::UpdateDamageTracking(root->layer_tree_impl(), - render_surface_list); - - root->layer_tree_impl()->ResetAllChangeTracking(); -} - -class DamageTrackerTest : public testing::Test { +class DamageTrackerTest : public LayerTreeImplTestBase, public testing::Test { public: - DamageTrackerTest() - : host_impl_(&task_runner_provider_, &task_graph_runner_) {} - LayerImpl* CreateTestTreeWithOneSurface(int number_of_children) { - host_impl_.active_tree()->DetachLayers(); - auto root = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 1); + ClearLayersAndProperties(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(500, 500)); + root->layer_tree_impl()->SetDeviceViewportRect(gfx::Rect(root->bounds())); root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; + SetupRootProperties(root); + child_layers_.resize(number_of_children); for (int i = 0; i < number_of_children; ++i) { - auto child = - std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 2 + i); - child->test_properties()->position = gfx::PointF(100.f, 100.f); + auto* child = AddLayer<TestLayerImpl>(); child->SetBounds(gfx::Size(30, 30)); child->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child)); + child_layers_[i] = child; + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); } - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_.active_tree()->SetElementIdsForTesting(); + SetElementIdsForTesting(); - return host_impl_.active_tree()->root_layer_for_testing(); + return root; } LayerImpl* CreateTestTreeWithTwoSurfaces() { @@ -127,47 +96,47 @@ class DamageTrackerTest : public testing::Test { // child1. Additionally, the root has a second child layer, and child1 has // two children of its own. - host_impl_.active_tree()->DetachLayers(); - auto root = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 1); - auto child1 = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 2); - auto child2 = std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 3); - auto grand_child1 = - std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 4); - auto grand_child2 = - std::make_unique<TestLayerImpl>(host_impl_.active_tree(), 5); + ClearLayersAndProperties(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(500, 500)); + root->layer_tree_impl()->SetDeviceViewportRect(gfx::Rect(root->bounds())); root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; + SetupRootProperties(root); - child1->test_properties()->position = gfx::PointF(100.f, 100.f); - child1->SetBounds(gfx::Size(30, 30)); + child1_ = AddLayer<TestLayerImpl>(); + grand_child1_ = AddLayer<TestLayerImpl>(); + grand_child2_ = AddLayer<TestLayerImpl>(); + child2_ = AddLayer<TestLayerImpl>(); + SetElementIdsForTesting(); + + child1_->SetBounds(gfx::Size(30, 30)); // With a child that draws_content, opacity will cause the layer to create // its own RenderSurface. This layer does not draw, but is intended to // create its own RenderSurface. - child1->SetDrawsContent(false); - child1->test_properties()->force_render_surface = true; - - child2->test_properties()->position = gfx::PointF(11.f, 11.f); - child2->SetBounds(gfx::Size(18, 18)); - child2->SetDrawsContent(true); - - grand_child1->test_properties()->position = gfx::PointF(200.f, 200.f); - grand_child1->SetBounds(gfx::Size(6, 8)); - grand_child1->SetDrawsContent(true); - - grand_child2->test_properties()->position = gfx::PointF(190.f, 190.f); - grand_child2->SetBounds(gfx::Size(6, 8)); - grand_child2->SetDrawsContent(true); + child1_->SetDrawsContent(false); + CopyProperties(root, child1_); + CreateTransformNode(child1_).post_translation = + gfx::Vector2dF(100.f, 100.f); + CreateEffectNode(child1_).render_surface_reason = + RenderSurfaceReason::kTest; + + grand_child1_->SetBounds(gfx::Size(6, 8)); + grand_child1_->SetDrawsContent(true); + CopyProperties(child1_, grand_child1_); + grand_child1_->SetOffsetToTransformParent(gfx::Vector2dF(200.f, 200.f)); + + grand_child2_->SetBounds(gfx::Size(6, 8)); + grand_child2_->SetDrawsContent(true); + CopyProperties(child1_, grand_child2_); + grand_child2_->SetOffsetToTransformParent(gfx::Vector2dF(190.f, 190.f)); + + child2_->SetBounds(gfx::Size(18, 18)); + child2_->SetDrawsContent(true); + CopyProperties(root, child2_); + child2_->SetOffsetToTransformParent(gfx::Vector2dF(11.f, 11.f)); - child1->test_properties()->AddChild(std::move(grand_child1)); - child1->test_properties()->AddChild(std::move(grand_child2)); - root->test_properties()->AddChild(std::move(child1)); - root->test_properties()->AddChild(std::move(child2)); - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_.active_tree()->SetElementIdsForTesting(); - - return host_impl_.active_tree()->root_layer_for_testing(); + return root; } LayerImpl* CreateAndSetUpTestTreeWithOneSurface(int number_of_children = 1) { @@ -175,7 +144,6 @@ class DamageTrackerTest : public testing::Test { // Setup includes going past the first frame which always damages // everything, so that we can actually perform specific tests. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); return root; @@ -186,16 +154,44 @@ class DamageTrackerTest : public testing::Test { // Setup includes going past the first frame which always damages // everything, so that we can actually perform specific tests. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); return root; } + void EmulateDrawingOneFrame(LayerImpl* root, + float device_scale_factor = 1.f) { + // This emulates only steps that are relevant to testing the damage tracker: + // 1. computing the render passes and layerlists + // 2. updating all damage trackers in the correct order + // 3. resetting all update_rects and property_changed flags for all layers + // and surfaces. + + root->layer_tree_impl()->SetDeviceScaleFactor(device_scale_factor); + root->layer_tree_impl()->set_needs_update_draw_properties(); + UpdateDrawProperties(root->layer_tree_impl()); + + DamageTracker::UpdateDamageTracking(root->layer_tree_impl()); + + root->layer_tree_impl()->ResetAllChangeTracking(); + } + protected: - FakeImplTaskRunnerProvider task_runner_provider_; - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostImpl host_impl_; + void ClearLayersAndProperties() { + host_impl()->active_tree()->DetachLayersKeepingRootLayerForTesting(); + host_impl()->active_tree()->property_trees()->clear(); + child_layers_.clear(); + child1_ = child2_ = grand_child1_ = grand_child2_ = nullptr; + } + + // Stores result of CreateTestTreeWithOneSurface(). + std::vector<TestLayerImpl*> child_layers_; + + // Store result of CreateTestTreeWithTwoSurfaces(). + TestLayerImpl* child1_ = nullptr; + TestLayerImpl* child2_ = nullptr; + TestLayerImpl* grand_child1_ = nullptr; + TestLayerImpl* grand_child2_ = nullptr; }; TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { @@ -203,7 +199,7 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithOneSurface) { // render surfaces. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; EXPECT_EQ(2, GetRenderSurface(root)->num_contributors()); EXPECT_TRUE(root->contributes_to_drawn_render_surface()); @@ -225,23 +221,20 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - gfx::Rect child_damage_rect; - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_NE(GetRenderSurface(child1), GetRenderSurface(root)); - EXPECT_EQ(GetRenderSurface(child2), GetRenderSurface(root)); + EXPECT_NE(GetRenderSurface(child1_), GetRenderSurface(root)); + EXPECT_EQ(GetRenderSurface(child2_), GetRenderSurface(root)); EXPECT_EQ(3, GetRenderSurface(root)->num_contributors()); - EXPECT_EQ(2, GetRenderSurface(child1)->num_contributors()); + EXPECT_EQ(2, GetRenderSurface(child1_)->num_contributors()); - // The render surface for child1 only has a content_rect that encloses - // grand_child1 and grand_child2, because child1 does not draw content. + // The render surface for child1_ only has a content_rect that encloses + // grand_child1_ and grand_child2_, because child1_ does not draw content. EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), child_damage_rect.ToString()); EXPECT_EQ(gfx::Rect(500, 500).ToString(), root_damage_rect.ToString()); @@ -249,20 +242,19 @@ TEST_F(DamageTrackerTest, SanityCheckTestTreeWithTwoSurfaces) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // CASE 1: Setting the update rect should cause the corresponding damage to // the surface. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of update_rect (10, 11) @@ -277,7 +269,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // damage. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -288,7 +279,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { // update region, but no additional exposed old region. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(20, 25, 1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of update_rect (20, 25) @@ -303,14 +293,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) { TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - auto* child = - static_cast<TestLayerImpl*>(root->test_properties()->children[0]); + TestLayerImpl* child = child_layers_[0]; // CASE 1: Adding the layer damage rect should cause the corresponding damage // to the surface. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of layer damage_rect @@ -324,7 +312,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { // damage. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(10, 11, 12, 13)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -334,7 +321,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { // new damaged region, but no additional exposed old region. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(20, 25, 1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of layer damage_rect @@ -348,7 +334,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(20, 25, 1, 2)); child->AddDamageRect(gfx::Rect(10, 15, 3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of layer damage_rect @@ -364,15 +349,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerDamageRects) { TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - auto* child = - static_cast<TestLayerImpl*>(root->test_properties()->children[0]); + TestLayerImpl* child = child_layers_[0]; // CASE 1: Adding the layer damage rect and update rect should cause the // corresponding damage to the surface. ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(5, 6, 12, 13)); child->SetUpdateRect(gfx::Rect(15, 16, 14, 10)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of unified layer @@ -388,7 +371,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(10, 11, 12, 13)); child->SetUpdateRect(gfx::Rect(10, 11, 14, 15)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -399,7 +381,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { ClearDamageForAllSurfaces(root); child->AddDamageRect(gfx::Rect(20, 25, 2, 3)); child->SetUpdateRect(gfx::Rect(5, 10, 7, 8)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of unified layer damage @@ -414,12 +395,11 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) { TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // CASE 1: The layer's property changed flag takes priority over update rect. // - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); @@ -448,7 +428,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // Cycle one frame of no change, just to sanity check that the next rect is // not because of the old damage state. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -456,6 +435,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { // Then, test the actual layer movement. ClearDamageForAllSurfaces(root); + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); gfx::Transform translation; translation.Translate(100.f, 130.f); root->layer_tree_impl()->SetTransformMutated(child->element_id(), @@ -470,57 +452,53 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - // Transform from browser animation should not be considered as damage from - // contributing layer since it is applied to the whole layer which has a - // render surface. - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + // TODO(crbug.com/1001882): Transform from browser animation should not be + // considered as damage from contributing layer since it is applied to the + // whole layer which has a render surface. + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForPropertyChangesFromContributingContents) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - LayerImpl* grandchild1 = child1->test_properties()->children[0]; - // CASE 1: The child1's opacity changed. + // CASE 1: child1_'s opacity changed. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(child1->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(child1_->element_id(), 0.5f); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 2: The layer2's opacity changed. - child2->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + // CASE 2: layer2_'s opacity changed. + CreateEffectNode(child2_).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(child2->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(child2_->element_id(), 0.5f); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 3: The grandchild1's opacity changed. - grandchild1->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + // CASE 3: grand_child1_'s opacity changed. + CreateEffectNode(grand_child1_).render_surface_reason = + RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(grandchild1->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(grand_child1_->element_id(), 0.5f); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -528,11 +506,12 @@ TEST_F(DamageTrackerTest, // Regression test for http://crbug.com/923794 TEST_F(DamageTrackerTest, EffectPropertyChangeNoSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // Create a separate effect node for the child, but no render surface. - child->test_properties()->opacity = 0.5; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto& effect_node = CreateEffectNode(child); + effect_node.opacity = 0.5; + effect_node.has_potential_opacity_animation = true; EmulateDrawingOneFrame(root); EXPECT_EQ(root->transform_tree_index(), child->transform_tree_index()); @@ -550,13 +529,12 @@ TEST_F(DamageTrackerTest, EffectPropertyChangeNoSurface) { // Regression test for http://crbug.com/923794 TEST_F(DamageTrackerTest, TransformPropertyChangeNoSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // Create a separate transform node for the child, but no render surface. gfx::Transform trans1; trans1.Scale(2, 1); - child->test_properties()->transform = trans1; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateTransformNode(child).local = trans1; EmulateDrawingOneFrame(root); EXPECT_NE(root->transform_tree_index(), child->transform_tree_index()); @@ -576,66 +554,58 @@ TEST_F(DamageTrackerTest, TransformPropertyChangeNoSurface) { TEST_F(DamageTrackerTest, VerifyDamageForUpdateAndDamageRectsFromContributingContents) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - auto* child1 = - static_cast<TestLayerImpl*>(root->test_properties()->children[0]); - auto* child2 = - static_cast<TestLayerImpl*>(root->test_properties()->children[1]); - auto* grandchild1 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[0]); - - // CASE 1: Adding the layer1's damage rect and update rect should cause the + + // CASE 1: Adding child1_'s damage rect and update rect should cause the // corresponding damage to the surface. - child1->SetDrawsContent(true); + child1_->SetDrawsContent(true); ClearDamageForAllSurfaces(root); - child1->AddDamageRect(gfx::Rect(105, 106, 12, 15)); - child1->SetUpdateRect(gfx::Rect(115, 116, 12, 15)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child1_->AddDamageRect(gfx::Rect(105, 106, 12, 15)); + child1_->SetUpdateRect(gfx::Rect(115, 116, 12, 15)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 2: Adding the layer2's damage rect and update rect should cause the + // CASE 2: Adding child2_'s damage rect and update rect should cause the // corresponding damage to the surface. ClearDamageForAllSurfaces(root); - child2->AddDamageRect(gfx::Rect(11, 11, 12, 15)); - child2->SetUpdateRect(gfx::Rect(12, 12, 12, 15)); + child2_->AddDamageRect(gfx::Rect(11, 11, 12, 15)); + child2_->SetUpdateRect(gfx::Rect(12, 12, 12, 15)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - // CASE 3: Adding the grandchild1's damage rect and update rect should cause + // CASE 3: Adding grand_child1_'s damage rect and update rect should cause // the corresponding damage to the surface. ClearDamageForAllSurfaces(root); - grandchild1->AddDamageRect(gfx::Rect(1, 0, 2, 5)); - grandchild1->SetUpdateRect(gfx::Rect(2, 1, 2, 5)); + grand_child1_->AddDamageRect(gfx::Rect(1, 0, 2, 5)); + grand_child1_->SetUpdateRect(gfx::Rect(2, 1, 2, 5)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageWhenSurfaceRemoved) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* surface = root->test_properties()->children[0]; - LayerImpl* child = surface->test_properties()->children[0]; + LayerImpl* surface = child1_; + LayerImpl* child = grand_child1_; child->SetDrawsContent(true); EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); - surface->test_properties()->force_render_surface = false; + SetRenderSurfaceReason(surface, RenderSurfaceReason::kNone); child->SetDrawsContent(false); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -652,18 +622,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedLayer) { // transformed layer. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; - child->test_properties()->force_render_surface = true; + LayerImpl* child = child_layers_[0]; gfx::Transform rotation; rotation.Rotate(45.0); ClearDamageForAllSurfaces(root); - child->test_properties()->transform_origin = gfx::Point3F( - child->bounds().width() * 0.5f, child->bounds().height() * 0.5f, 0.f); - child->test_properties()->position = gfx::PointF(85.f, 85.f); + auto& transform_node = CreateTransformNode(child); + transform_node.origin = gfx::Point3F(child->bounds().width() * 0.5f, + child->bounds().height() * 0.5f, 0.f); + transform_node.post_translation = gfx::Vector2dF(85.f, 85.f); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + child->NoteLayerPropertyChanged(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Sanity check that the layer actually moved to (85, 85), damaging its old @@ -723,7 +695,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { // LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Transform transform; transform.Translate3d(550.0, 500.0, 0.0); @@ -732,23 +704,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { transform.Translate3d(-50.0, -50.0, 0.0); // Set up the child - child->test_properties()->position = gfx::PointF(0.f, 0.f); child->SetBounds(gfx::Size(100, 100)); - child->test_properties()->transform = transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateTransformNode(child).local = transform; + child->SetOffsetToTransformParent(gfx::Vector2dF()); EmulateDrawingOneFrame(root); // Sanity check that the child layer's bounds would actually get clipped by // w < 0, otherwise this test is not actually testing the intended scenario. - gfx::RectF test_rect(child->test_properties()->position, - gfx::SizeF(child->bounds())); + gfx::RectF test_rect(gfx::SizeF(child->bounds())); bool clipped = false; MathUtil::MapQuad(transform, gfx::QuadF(test_rect), &clipped); EXPECT_TRUE(clipped); // Damage the child without moving it. - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); root->layer_tree_impl()->SetOpacityMutated(child->element_id(), 0.5f); @@ -772,20 +741,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForPerspectiveClippedLayer) { TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* surface = root->test_properties()->children[0]; - LayerImpl* child = surface->test_properties()->children[0]; + LayerImpl* surface = child1_; + LayerImpl* child = grand_child1_; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(5.f)); - // Setting the filter should not damage the conrresponding render surface. + // TODO(crbug.com/1001882): Setting the filter on an existing render surface + // should not damage the conrresponding render surface. ClearDamageForAllSurfaces(root); - surface->test_properties()->filters = filters; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetFilter(surface, filters); EmulateDrawingOneFrame(root); - EXPECT_FALSE(GetRenderSurface(root) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(root) + ->damage_tracker() + ->has_damage_from_contributing_content()); EXPECT_FALSE(GetRenderSurface(surface) ->damage_tracker() ->has_damage_from_contributing_content()); @@ -794,7 +763,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { // surface, blurred based on the size of the blur filter. ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(1, 2, 3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Damage position on the surface should be: position of update_rect (1, 2) @@ -814,7 +782,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) { TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Rect root_damage_rect, child_damage_rect; // Allow us to set damage on child too. @@ -826,8 +794,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { 2, 2, BlurPaintFilter::TileMode::kClampToBlack_TileMode, nullptr))); // Setting the filter will damage the whole surface. - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); ClearDamageForAllSurfaces(root); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); @@ -896,7 +866,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) { TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Rect root_damage_rect, child_damage_rect; // Allow us to set damage on child too. @@ -911,9 +881,14 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { gfx::Transform transform; transform.RotateAboutYAxis(60); ClearDamageForAllSurfaces(root); - child->test_properties()->force_render_surface = true; - child->test_properties()->transform = transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto& transform_node = CreateTransformNode(child); + transform_node.local = transform; + transform_node.post_translation = child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + auto& effect_node = CreateEffectNode(child); + effect_node.render_surface_reason = RenderSurfaceReason::kFilter; + effect_node.has_potential_filter_animation = true; + EmulateDrawingOneFrame(root); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root); @@ -955,21 +930,27 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) { TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Rect root_damage_rect, child_damage_rect; + ClearDamageForAllSurfaces(root); + int device_scale_factor = 2; + EmulateDrawingOneFrame(root, device_scale_factor); + // Allow us to set damage on child too. child->SetDrawsContent(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - // Setting the filter will damage the whole surface. + // Setting the filter and creating a new render surface will damage the whole + // surface. + ClearDamageForAllSurfaces(root); + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; ClearDamageForAllSurfaces(root); - child->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - int device_scale_factor = 2; - EmulateDrawingOneFrame(root, device_scale_factor); child->layer_tree_impl()->SetFilterMutated(child->element_id(), filters); EmulateDrawingOneFrame(root, device_scale_factor); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -979,14 +960,11 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { // Blur outset is 9px for a 3px blur, scaled up by DSF. int blur_outset = 9 * device_scale_factor; - gfx::Rect original_rect(100, 100, 100, 100); gfx::Rect expected_child_damage_rect(60, 60); expected_child_damage_rect.Inset(-blur_outset, -blur_outset); gfx::Rect expected_root_damage_rect(child_damage_rect); expected_root_damage_rect.Offset(200, 200); - gfx::Rect expected_total_damage_rect = expected_root_damage_rect; - expected_total_damage_rect.Union(original_rect); - EXPECT_EQ(expected_total_damage_rect, root_damage_rect); + EXPECT_EQ(expected_root_damage_rect, root_damage_rect); EXPECT_EQ(expected_child_damage_rect, child_damage_rect); // Setting the update rect should damage only the affected area (original, @@ -1006,36 +984,32 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) { TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - // Allow us to set damage on child1 too. - child1->SetDrawsContent(true); + // Allow us to set damage on child1_ too. + child1_->SetDrawsContent(true); FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(2.f)); // Setting the filter will damage the whole surface. ClearDamageForAllSurfaces(root); - child1->test_properties()->backdrop_filters = filters; - child1->NoteLayerPropertyChanged(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetBackdropFilter(child1_, filters); + child1_->NoteLayerPropertyChanged(); EmulateDrawingOneFrame(root); // CASE 1: Setting the update rect should cause the corresponding damage to // the surface, blurred based on the size of the child's backdrop - // blur filter. Note that child1's render surface has a size of - // 206x208 due to contributions from grand_child1 and grand_child2. + // blur filter. Note that child1_'s render surface has a size of + // 206x208 due to contributions from grand_child1_ and grand_child2_. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(297, 297, 2, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage position on the surface should be a composition of the damage on - // the root and on child2. Damage on the root should be: position of + // the root and on child2_. Damage on the root should be: position of // update_rect (297, 297), but expanded by the blur outsets. gfx::Rect expected_damage_rect = gfx::Rect(297, 297, 2, 2); @@ -1049,13 +1023,12 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { // of the blurred layer, only the left/top should end up expanded. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(297, 297, 30, 30)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); // Damage position on the surface should be a composition of the damage on - // the root and on child2. Damage on the root should be: position of + // the root and on child2_. Damage on the root should be: position of // update_rect (297, 297), but expanded on the left/top by the blur outsets. expected_damage_rect = gfx::Rect(297, 297, 30, 30); @@ -1064,10 +1037,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 3: Setting this update rect outside the blurred content_bounds of the - // blurred child1 will not cause it to be expanded. + // blurred child1_ will not cause it to be expanded. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(30, 30, 2, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1079,11 +1051,10 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); // CASE 4: Setting this update rect inside the blurred content_bounds but - // outside the original content_bounds of the blurred child1 will + // outside the original content_bounds of the blurred child1_ will // cause it to be expanded. ClearDamageForAllSurfaces(root); root->SetUpdateRect(gfx::Rect(99, 99, 1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1096,37 +1067,35 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { expected_damage_rect = gfx::Rect(99, 99, 7, 7); EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); - // CASE 5: Setting the update rect on child2, which is above child1, will - // not get blurred by child1, so it does not need to get expanded. + // CASE 5: Setting the update rect on child2_, which is above child1_, will + // not get blurred by child1_, so it does not need to get expanded. ClearDamageForAllSurfaces(root); - child2->SetUpdateRect(gfx::Rect(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child2_->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - // Damage on child2 should be: position of update_rect offset by the child's + // Damage on child2_ should be: position of update_rect offset by the child's // position (11, 11), and not expanded by anything. expected_damage_rect = gfx::Rect(11, 11, 1, 1); EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); - // CASE 6: Setting the update rect on child1 will also blur the damage, so + // CASE 6: Setting the update rect on child1_ will also blur the damage, so // that any pixels needed for the blur are redrawn in the current // frame. ClearDamageForAllSurfaces(root); - child1->SetUpdateRect(gfx::Rect(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child1_->SetUpdateRect(gfx::Rect(1, 1)); EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - // Damage on child1 should be: position of update_rect offset by the child's + // Damage on child1_ should be: position of update_rect offset by the child's // position (100, 100), and expanded by the damage. - // Damage should be (0,0 1x1), offset by the 100,100 offset of child1 in + // Damage should be (0,0 1x1), offset by the 100,100 offset of child1_ in // root, and expanded 6px for the 2px blur (i.e., 94,94 13x13), but there - // should be no damage outside child1 (i.e. none above or to the left of + // should be no damage outside child1_ (i.e. none above or to the left of // 100,100. expected_damage_rect = gfx::Rect(100, 100, 7, 7); EXPECT_EQ(expected_damage_rect.ToString(), root_damage_rect.ToString()); @@ -1134,17 +1103,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { // CASE 7: No changes, so should not damage the surface. ClearDamageForAllSurfaces(root); // We want to make sure that the backdrop filter doesn't cause empty damage - // to get expanded. We position child1 so that an expansion of the empty rect - // would have non-empty intersection with child1 in its target space (root + // to get expanded. We position child1_ so that an expansion of the empty rect + // would have non-empty intersection with child1_ in its target space (root // space). - child1->test_properties()->position = gfx::PointF(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetPostTranslation(child1_, gfx::Vector2dF()); + child1_->NoteLayerPropertyChanged(); + // The first call clears the damage caused by the movement. + EmulateDrawingOneFrame(root); + ClearDamageForAllSurfaces(root); EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); // Should not be expanded by the blur filter. @@ -1154,20 +1126,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) { TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child1 = root->test_properties()->children[0]; + LayerImpl* child1 = child_layers_[0]; // CASE 1: Adding a new layer should cause the appropriate damage. // ClearDamageForAllSurfaces(root); - { - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); - child2->test_properties()->position = gfx::PointF(400.f, 380.f); - child2->SetBounds(gfx::Size(6, 8)); - child2->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child2)); - } - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(6, 8)); + child2->SetDrawsContent(true); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(400.f, 380.f)); EmulateDrawingOneFrame(root); // Sanity check - all 3 layers should be on the same render surface; render @@ -1188,17 +1157,20 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { // Advance one frame without damage so that we know the damage rect is not // leftover from the previous case. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); EXPECT_TRUE(root_damage_rect.IsEmpty()); - // Then, test removing child1. - root->test_properties()->RemoveChild(child1); - child1 = nullptr; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + // Then, test removing child1_. + { + OwnedLayerImplList layers = + host_impl()->active_tree()->DetachLayersKeepingRootLayerForTesting(); + ASSERT_EQ(3u, layers.size()); + ASSERT_EQ(child1, layers[1].get()); + host_impl()->active_tree()->AddLayer(std::move(layers[2])); + } EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1211,29 +1183,25 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingLayer) { } TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { - // If child2 is added to the layer tree, but it doesn't have any explicit + // If child2_ is added to the layer tree, but it doesn't have any explicit // damage of its own, it should still indeed damage the target surface. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); ClearDamageForAllSurfaces(root); - { - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); - child2->test_properties()->position = gfx::PointF(400.f, 380.f); - child2->SetBounds(gfx::Size(6, 8)); - child2->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child2)); - root->layer_tree_impl()->BuildLayerListForTesting(); - host_impl_.active_tree()->ResetAllChangeTracking(); - LayerImpl* child2_ptr = host_impl_.active_tree()->LayerById(3); - // Sanity check the initial conditions of the test, if these asserts - // trigger, it means the test no longer actually covers the intended - // scenario. - ASSERT_FALSE(child2_ptr->LayerPropertyChanged()); - ASSERT_TRUE(child2_ptr->update_rect().IsEmpty()); - } - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(6, 8)); + child2->SetDrawsContent(true); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(400.f, 380.f)); + host_impl()->active_tree()->ResetAllChangeTracking(); + // Sanity check the initial conditions of the test, if these asserts + // trigger, it means the test no longer actually covers the intended + // scenario. + ASSERT_FALSE(child2->LayerPropertyChanged()); + ASSERT_TRUE(child2->update_rect().IsEmpty()); + EmulateDrawingOneFrame(root); // Sanity check - all 3 layers should be on the same render surface; render @@ -1251,30 +1219,24 @@ TEST_F(DamageTrackerTest, VerifyDamageForNewUnchangedLayer) { TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child1 = root->test_properties()->children[0]; + LayerImpl* child1 = child_layers_[0]; // In this test we don't want the above tree manipulation to be considered // part of the same frame. ClearDamageForAllSurfaces(root); - { - std::unique_ptr<LayerImpl> child2 = - LayerImpl::Create(host_impl_.active_tree(), 3); - child2->test_properties()->position = gfx::PointF(400.f, 380.f); - child2->SetBounds(gfx::Size(6, 8)); - child2->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child2)); - } - LayerImpl* child2 = root->test_properties()->children[1]; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + LayerImpl* child2 = AddLayer<LayerImpl>(); + child2->SetBounds(gfx::Size(6, 8)); + child2->SetDrawsContent(true); + CopyProperties(root, child2); + child2->SetOffsetToTransformParent(gfx::Vector2dF(400.f, 380.f)); EmulateDrawingOneFrame(root); // Damaging two layers simultaneously should cause combined damage. - // - child1 update rect in surface space: gfx::Rect(100, 100, 1, 2); - // - child2 update rect in surface space: gfx::Rect(400, 380, 3, 4); + // - child1_ update rect in surface space: gfx::Rect(100, 100, 1, 2); + // - child2_ update rect in surface space: gfx::Rect(400, 380, 3, 4); ClearDamageForAllSurfaces(root); child1->SetUpdateRect(gfx::Rect(1, 2)); child2->SetUpdateRect(gfx::Rect(3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1288,13 +1250,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) { TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; - LayerImpl* grand_child1 = - root->test_properties()->children[0]->test_properties()->children[0]; - child2->test_properties()->force_render_surface = true; - grand_child1->test_properties()->force_render_surface = true; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + CreateEffectNode(child2_).render_surface_reason = RenderSurfaceReason::kTest; + CreateEffectNode(grand_child1_).render_surface_reason = + RenderSurfaceReason::kTest; EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; @@ -1302,9 +1260,9 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { // CASE 1: Damage to a descendant surface should propagate properly to // ancestor surface. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(grand_child1->element_id(), 0.5f); + root->layer_tree_impl()->SetOpacityMutated(grand_child1_->element_id(), 0.5f); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1313,27 +1271,27 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child2) + EXPECT_FALSE(GetRenderSurface(child2_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(grand_child1) + EXPECT_FALSE(GetRenderSurface(grand_child1_) ->damage_tracker() ->has_damage_from_contributing_content()); // CASE 2: Same as previous case, but with additional damage elsewhere that // should be properly unioned. - // - child1 surface damage in root surface space: + // - child1_ surface damage in root surface space: // gfx::Rect(300, 300, 6, 8); - // - child2 damage in root surface space: + // - child2_ damage in root surface space: // gfx::Rect(11, 11, 18, 18); ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->SetOpacityMutated(grand_child1->element_id(), 0.7f); - root->layer_tree_impl()->SetOpacityMutated(child2->element_id(), 0.7f); + root->layer_tree_impl()->SetOpacityMutated(grand_child1_->element_id(), 0.7f); + root->layer_tree_impl()->SetOpacityMutated(child2_->element_id(), 0.7f); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1343,13 +1301,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForNestedSurfaces) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child2) + EXPECT_FALSE(GetRenderSurface(child2_) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(grand_child1) + EXPECT_FALSE(GetRenderSurface(grand_child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -1363,17 +1321,13 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { // entire surface should be marked dirty. LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* grand_child1 = - root->test_properties()->children[0]->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root); - grand_child1->test_properties()->position = gfx::PointF(195.f, 205.f); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + grand_child1_->SetOffsetToTransformParent(gfx::Vector2dF(195.f, 205.f)); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1383,7 +1337,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { EXPECT_EQ(gfx::Rect(190, 190, 11, 23).ToString(), child_damage_rect.ToString()); - // Damage to the root surface should be the union of child1's *entire* render + // Damage to the root surface should be the union of child1_'s *entire* render // surface (in target space), and its old exposed area (also in target // space). EXPECT_EQ(gfx::Rect(290, 290, 16, 23).ToString(), @@ -1392,7 +1346,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantLayer) { EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -1402,37 +1356,34 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromDescendantSurface) { // damaged with the old and new descendant surface regions. LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - child1->SetDrawsContent(true); + child1_->SetDrawsContent(true); EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root); - child1->test_properties()->position = gfx::PointF(105.f, 107.f); - child1->NoteLayerPropertyChanged(); - TransformNode* child1_transform = - root->layer_tree_impl()->property_trees()->transform_tree.Node( - child1->transform_tree_index()); - child1_transform->transform_changed = true; + SetPostTranslation(child1_, gfx::Vector2dF(105.f, 107.f)); + child1_->NoteLayerPropertyChanged(); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); - // Damage to the root surface should be the union of child1's *entire* render + // Damage to the root surface should be the union of child1_'s *entire* render // surface (in target space), and its old exposed area (also in target // space). - EXPECT_EQ(gfx::Rect(100, 100, 206, 208).ToString(), + EXPECT_EQ(gfx::UnionRects(gfx::Rect(100, 100, 206, 208), + gfx::Rect(105, 107, 206, 208)) + .ToString(), root_damage_rect.ToString()); // The child surface should also be damaged. EXPECT_EQ(gfx::Rect(0, 0, 206, 208).ToString(), child_damage_rect.ToString()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } @@ -1441,26 +1392,25 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { // An ancestor/owning layer changes that affects the position/transform of // the render surface. Note that in this case, the layer_property_changed flag // already propagates to the subtree (tested in LayerImpltest), which damages - // the entire child1 surface, but the damage tracker still needs the correct + // the entire child1_ surface, but the damage tracker still needs the correct // logic to compute the exposed region on the root surface. // TODO(shawnsingh): the expectations of this test case should change when we // add support for a unique scissor_rect per RenderSurface. In that case, the - // child1 surface should be completely unchanged, since we are only + // child1_ surface should be completely unchanged, since we are only // transforming it, while the root surface would be damaged appropriately. LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; ClearDamageForAllSurfaces(root); gfx::Transform translation; translation.Translate(-50.f, -50.f); - root->layer_tree_impl()->SetTransformMutated(child1->element_id(), + root->layer_tree_impl()->SetTransformMutated(child1_->element_id(), translation); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1469,36 +1419,34 @@ TEST_F(DamageTrackerTest, VerifyDamageForSurfaceChangeFromAncestorLayer) { EXPECT_EQ(gfx::Rect(190, 190, 16, 18).ToString(), child_damage_rect.ToString()); - // The entire child1 surface and the old exposed child1 surface should damage - // the root surface. - // - old child1 surface in target space: gfx::Rect(290, 290, 16, 18) - // - new child1 surface in target space: gfx::Rect(240, 240, 16, 18) + // The entire child1_ surface and the old exposed child1_ surface should + // damage the root surface. + // - old child1_ surface in target space: gfx::Rect(290, 290, 16, 18) + // - new child1_ surface in target space: gfx::Rect(240, 240, 16, 18) EXPECT_EQ(gfx::Rect(240, 240, 66, 68).ToString(), root_damage_rect.ToString()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child1) + EXPECT_FALSE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; // CASE 1: If a descendant surface disappears, its entire old area becomes // exposed. ClearDamageForAllSurfaces(root); - child1->test_properties()->force_render_surface = false; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + SetRenderSurfaceReason(child1_, RenderSurfaceReason::kNone); EmulateDrawingOneFrame(root); // Sanity check that there is only one surface now. - ASSERT_EQ(GetRenderSurface(child1), GetRenderSurface(root)); + ASSERT_EQ(GetRenderSurface(child1_), GetRenderSurface(root)); ASSERT_EQ(4, GetRenderSurface(root)->num_contributors()); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1516,7 +1464,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // Cycle one frame of no change, just to sanity check that the next rect is // not because of the old damage state. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1524,17 +1471,16 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { // Then change the tree so that the render surface is added back. ClearDamageForAllSurfaces(root); - child1->test_properties()->force_render_surface = true; + SetRenderSurfaceReason(child1_, RenderSurfaceReason::kTest); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Sanity check that there is a new surface now. - ASSERT_TRUE(GetRenderSurface(child1)); + ASSERT_TRUE(GetRenderSurface(child1_)); EXPECT_EQ(3, GetRenderSurface(root)->num_contributors()); - EXPECT_EQ(2, GetRenderSurface(child1)->num_contributors()); + EXPECT_EQ(2, GetRenderSurface(child1_)->num_contributors()); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1549,16 +1495,14 @@ TEST_F(DamageTrackerTest, VerifyDamageForAddingAndRemovingRenderSurfaces) { TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; // CASE 1: If nothing changes, the damage rect should be empty. // ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1572,9 +1516,8 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { // empty. // ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1587,17 +1530,15 @@ TEST_F(DamageTrackerTest, VerifyNoDamageWhenNothingChanged) { TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; gfx::Rect child_damage_rect; gfx::Rect root_damage_rect; - // In our specific tree, the update rect of child1 should not cause any + // In our specific tree, the update rect of child1_ should not cause any // damage to any surface because it does not actually draw content. ClearDamageForAllSurfaces(root); - child1->SetUpdateRect(gfx::Rect(1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + child1_->SetUpdateRect(gfx::Rect(1, 2)); EmulateDrawingOneFrame(root); - EXPECT_TRUE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( + EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1610,55 +1551,57 @@ TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) { TEST_F(DamageTrackerTest, VerifyDamageForMask) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // In the current implementation of the damage tracker, changes to mask // layers should damage the entire corresponding surface. ClearDamageForAllSurfaces(root); + CreateTransformNode(child).post_translation = + child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + // Set up the mask layer. - { - std::unique_ptr<LayerImpl> mask_layer = - LayerImpl::Create(host_impl_.active_tree(), 3); - mask_layer->test_properties()->position = - child->test_properties()->position; - mask_layer->SetBounds(child->bounds()); - child->test_properties()->SetMaskLayer(std::move(mask_layer)); - child->test_properties()->force_render_surface = true; - } - LayerImpl* mask_layer = child->test_properties()->mask_layer; + CreateEffectNode(child); + auto* mask_layer = AddLayer<FakePictureLayerImpl>(); + SetupMaskProperties(child, mask_layer); + Region empty_invalidation; + mask_layer->UpdateRasterSource( + FakeRasterSource::CreateFilled(child->bounds()), &empty_invalidation, + nullptr, nullptr); // Add opacity and a grand_child so that the render surface persists even // after we remove the mask. - { - std::unique_ptr<LayerImpl> grand_child = - LayerImpl::Create(host_impl_.active_tree(), 4); - grand_child->test_properties()->position = gfx::PointF(2.f, 2.f); - grand_child->SetBounds(gfx::Size(2, 2)); - grand_child->SetDrawsContent(true); - child->test_properties()->AddChild(std::move(grand_child)); - } - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + LayerImpl* grand_child = AddLayer<LayerImpl>(); + grand_child->SetBounds(gfx::Size(2, 2)); + grand_child->SetDrawsContent(true); + CopyProperties(child, grand_child); + grand_child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); EmulateDrawingOneFrame(root); - // CASE 1: the update_rect on a mask layer should damage the entire target - // surface. + EXPECT_EQ(2, GetRenderSurface(root)->num_contributors()); + EXPECT_TRUE(root->contributes_to_drawn_render_surface()); + EXPECT_EQ(3, GetRenderSurface(child)->num_contributors()); + EXPECT_TRUE(child->contributes_to_drawn_render_surface()); + EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(mask_layer)); + EXPECT_TRUE(mask_layer->contributes_to_drawn_render_surface()); + + // CASE 1: the update_rect on a mask layer should damage the rect. ClearDamageForAllSurfaces(root); mask_layer->SetUpdateRect(gfx::Rect(1, 2, 3, 4)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect child_damage_rect; EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(1, 2, 3, 4), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 2: a property change on the mask layer should damage the entire // target surface. @@ -1666,7 +1609,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Advance one frame without damage so that we know the damage rect is not // leftover from the previous case. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); @@ -1676,18 +1618,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { ClearDamageForAllSurfaces(root); mask_layer->NoteLayerPropertyChanged(); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30, 30), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_FALSE(GetRenderSurface(child) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_TRUE(GetRenderSurface(child) + ->damage_tracker() + ->has_damage_from_contributing_content()); // CASE 3: removing the mask also damages the entire target surface. // @@ -1695,7 +1636,6 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Advance one frame without damage so that we know the damage rect is not // leftover from the previous case. ClearDamageForAllSurfaces(root); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); @@ -1703,10 +1643,17 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { // Then test mask removal. ClearDamageForAllSurfaces(root); - child->test_properties()->SetMaskLayer(nullptr); - child->NoteLayerPropertyChanged(); - ASSERT_TRUE(child->LayerPropertyChanged()); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto layers = + root->layer_tree_impl()->DetachLayersKeepingRootLayerForTesting(); + ASSERT_EQ(layers[1].get(), child); + root->layer_tree_impl()->AddLayer(std::move(layers[1])); + ASSERT_EQ(layers[2].get(), mask_layer); + ASSERT_EQ(layers[3].get(), grand_child); + root->layer_tree_impl()->AddLayer(std::move(layers[3])); + CopyProperties(root, child); + CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(child, grand_child); + EmulateDrawingOneFrame(root); // Sanity check that a render surface still exists. @@ -1714,7 +1661,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid( &child_damage_rect)); - EXPECT_EQ(gfx::Rect(30, 30).ToString(), child_damage_rect.ToString()); + EXPECT_EQ(gfx::Rect(30, 30), child_damage_rect); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() @@ -1723,7 +1670,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) { TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; // Case 1: This test ensures that when the tracker is given damage, that // it is included with any other partial damage. @@ -1732,7 +1679,6 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { child->SetUpdateRect(gfx::Rect(10, 11, 12, 13)); GetRenderSurface(root)->damage_tracker()->AddDamageNextUpdate( gfx::Rect(15, 16, 32, 33)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); gfx::Rect root_damage_rect; EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( @@ -1750,7 +1696,6 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { ClearDamageForAllSurfaces(root); GetRenderSurface(root)->damage_tracker()->AddDamageNextUpdate( gfx::Rect(30, 31, 14, 15)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1761,34 +1706,33 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) { } TEST_F(DamageTrackerTest, VerifyDamageWithNoContributingLayers) { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_.active_tree(), 1); - root->test_properties()->force_render_surface = true; - host_impl_.active_tree()->SetRootLayerForTesting(std::move(root)); - LayerImpl* root_ptr = host_impl_.active_tree()->root_layer_for_testing(); - root_ptr->layer_tree_impl()->property_trees()->needs_rebuild = true; - EmulateDrawingOneFrame(root_ptr); - - DCHECK_EQ(GetRenderSurface(root_ptr), root_ptr->render_target()); - RenderSurfaceImpl* target_surface = GetRenderSurface(root_ptr); + LayerImpl* root = root_layer(); + ClearDamageForAllSurfaces(root); + + LayerImpl* empty_surface = AddLayer<LayerImpl>(); + CopyProperties(root, empty_surface); + CreateEffectNode(empty_surface).render_surface_reason = + RenderSurfaceReason::kTest; + EmulateDrawingOneFrame(root); + + DCHECK_EQ(GetRenderSurface(empty_surface), empty_surface->render_target()); + RenderSurfaceImpl* target_surface = GetRenderSurface(empty_surface); gfx::Rect damage_rect; EXPECT_TRUE( target_surface->damage_tracker()->GetDamageRectIfValid(&damage_rect)); EXPECT_TRUE(damage_rect.IsEmpty()); - EXPECT_FALSE(GetRenderSurface(root_ptr) - ->damage_tracker() - ->has_damage_from_contributing_content()); + EXPECT_FALSE( + target_surface->damage_tracker()->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // If damage is not cleared, it should accumulate. LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; ClearDamageForAllSurfaces(root); child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); // Sanity check damage after the first frame; this isnt the actual test yet. @@ -1803,7 +1747,6 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // New damage, without having cleared the previous damage, should be unioned // to the previous one. child->SetUpdateRect(gfx::Rect(20, 25, 1, 2)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1825,7 +1768,6 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) { // Damage should remain empty even after one frame, since there's yet no new // damage. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; EmulateDrawingOneFrame(root); EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &root_damage_rect)); @@ -1844,7 +1786,7 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { for (int i = 0; i < kRange; ++i) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = child_layers_[0]; gfx::Transform transform; transform.Translate(-kBigNumber, -kBigNumber); @@ -1852,8 +1794,11 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { // The child layer covers (0, 0, i, i) of the viewport, // but has a huge negative position. child->SetBounds(gfx::Size(kBigNumber + i, kBigNumber + i)); - child->test_properties()->transform = transform; - root->layer_tree_impl()->property_trees()->needs_rebuild = true; + auto& transform_node = CreateTransformNode(child); + transform_node.local = transform; + transform_node.post_translation = child->offset_to_transform_parent(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + float device_scale_factor = 1.f; // Visible rects computed from combining clips in target space and root // space don't match because of the loss in floating point accuracy. So, we @@ -1876,20 +1821,19 @@ TEST_F(DamageTrackerTest, HugeDamageRect) { TEST_F(DamageTrackerTest, DamageRectTooBig) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(2); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; + LayerImpl* child1 = child_layers_[0]; + LayerImpl* child2 = child_layers_[1]; // Really far left. - child1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 100, 0); + child1->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 100, 0)); child1->SetBounds(gfx::Size(1, 1)); // Really far right. - child2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 100, 0); + child2->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 100, 0)); child2->SetBounds(gfx::Size(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; float device_scale_factor = 1.f; EmulateDrawingOneFrame(root, device_scale_factor); @@ -1907,25 +1851,24 @@ TEST_F(DamageTrackerTest, DamageRectTooBig) { TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithOneSurface(2); - LayerImpl* child1 = root->test_properties()->children[0]; - LayerImpl* child2 = root->test_properties()->children[1]; + LayerImpl* child1 = child_layers_[0]; + LayerImpl* child2 = child_layers_[1]; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(5.f)); root->SetDrawsContent(true); - root->test_properties()->backdrop_filters = filters; + SetBackdropFilter(root, filters); // Really far left. - child1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 100, 0); + child1->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 100, 0)); child1->SetBounds(gfx::Size(1, 1)); // Really far right. - child2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 100, 0); + child2->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 100, 0)); child2->SetBounds(gfx::Size(1, 1)); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; float device_scale_factor = 1.f; EmulateDrawingOneFrame(root, device_scale_factor); @@ -1943,190 +1886,168 @@ TEST_F(DamageTrackerTest, DamageRectTooBigWithFilter) { TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurface) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - auto* grandchild1 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[0]); - auto* grandchild2 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[1]); // Really far left. - grandchild1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 500, 0); - grandchild1->SetBounds(gfx::Size(1, 1)); - grandchild1->SetDrawsContent(true); + grand_child1_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 500, 0)); + grand_child1_->SetBounds(gfx::Size(1, 1)); + grand_child1_->SetDrawsContent(true); // Really far right. - grandchild2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 500, 0); - grandchild2->SetBounds(gfx::Size(1, 1)); - grandchild2->SetDrawsContent(true); + grand_child2_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 500, 0)); + grand_child2_->SetBounds(gfx::Size(1, 1)); + grand_child2_->SetDrawsContent(true); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - float device_scale_factor = 1.f; - RenderSurfaceList render_surface_list; - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); // Avoid the descendant-only property change path that skips unioning damage // from descendant layers. - GetRenderSurface(child1)->NoteAncestorPropertyChanged(); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + GetRenderSurface(child1_)->NoteAncestorPropertyChanged(); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // The expected damage would be too large to store in a gfx::Rect, so we - // should damage everything on child1. + // should damage everything on child1_. gfx::Rect damage_rect; - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); - // However, the root should just use the child1 render surface's content rect + // However, the root should just use the child1_ render surface's content rect // as damage. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); // Add new damage, without changing properties, which goes down a different // path in the damage tracker. root->layer_tree_impl()->ResetAllChangeTracking(); - grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); - grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); + grand_child1_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); + grand_child2_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); // Recompute all damage / properties. - render_surface_list.clear(); - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // Child1 should still not have a valid rect, since the union of the damage of // its children is not representable by a single rect. - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); // Root should have valid damage and contain both its content rect and the - // drawable content rect of child1. + // drawable content rect of child1_. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } TEST_F(DamageTrackerTest, DamageRectTooBigInRenderSurfaceWithFilter) { LayerImpl* root = CreateAndSetUpTestTreeWithTwoSurfaces(); - LayerImpl* child1 = root->test_properties()->children[0]; - auto* grandchild1 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[0]); - auto* grandchild2 = - static_cast<TestLayerImpl*>(child1->test_properties()->children[1]); // Set up a moving pixels filter on the child. FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(5.f)); - child1->SetDrawsContent(true); - child1->test_properties()->backdrop_filters = filters; + child1_->SetDrawsContent(true); + SetBackdropFilter(child1_, filters); // Really far left. - grandchild1->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::min() + 500, 0); - grandchild1->SetBounds(gfx::Size(1, 1)); - grandchild1->SetDrawsContent(true); + grand_child1_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::min() + 500, 0)); + grand_child1_->SetBounds(gfx::Size(1, 1)); + grand_child1_->SetDrawsContent(true); // Really far right. - grandchild2->test_properties()->position = - gfx::PointF(std::numeric_limits<int>::max() - 500, 0); - grandchild2->SetBounds(gfx::Size(1, 1)); - grandchild2->SetDrawsContent(true); + grand_child2_->SetOffsetToTransformParent( + gfx::Vector2dF(std::numeric_limits<int>::max() - 500, 0)); + grand_child2_->SetBounds(gfx::Size(1, 1)); + grand_child2_->SetDrawsContent(true); - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - float device_scale_factor = 1.f; - RenderSurfaceList render_surface_list; - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); // Avoid the descendant-only property change path that skips unioning damage // from descendant layers. - GetRenderSurface(child1)->NoteAncestorPropertyChanged(); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + GetRenderSurface(child1_)->NoteAncestorPropertyChanged(); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // The expected damage would be too large to store in a gfx::Rect, so we - // should damage everything on child1. + // should damage everything on child1_. gfx::Rect damage_rect; - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); - // However, the root should just use the child1 render surface's content rect + // However, the root should just use the child1_ render surface's content rect // as damage. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); // Add new damage, without changing properties, which goes down a different // path in the damage tracker. root->layer_tree_impl()->ResetAllChangeTracking(); - grandchild1->AddDamageRect(gfx::Rect(grandchild1->bounds())); - grandchild2->AddDamageRect(gfx::Rect(grandchild1->bounds())); + grand_child1_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); + grand_child2_->AddDamageRect(gfx::Rect(grand_child1_->bounds())); // Recompute all damage / properties. - render_surface_list.clear(); - ExecuteCalculateDrawProperties(root, device_scale_factor, - &render_surface_list); - DamageTracker::UpdateDamageTracking(host_impl_.active_tree(), - render_surface_list); + UpdateDrawProperties(host_impl()->active_tree()); + DamageTracker::UpdateDamageTracking(host_impl()->active_tree()); // Child1 should still not have a valid rect, since the union of the damage of // its children is not representable by a single rect. - EXPECT_FALSE(GetRenderSurface(child1)->damage_tracker()->GetDamageRectIfValid( - &damage_rect)); - EXPECT_EQ(GetRenderSurface(child1)->content_rect(), - GetRenderSurface(child1)->GetDamageRect()); + EXPECT_FALSE( + GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid( + &damage_rect)); + EXPECT_EQ(GetRenderSurface(child1_)->content_rect(), + GetRenderSurface(child1_)->GetDamageRect()); // Root should have valid damage and contain both its content rect and the - // drawable content rect of child1. + // drawable content rect of child1_. ASSERT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid( &damage_rect)); EXPECT_TRUE(damage_rect.Contains(GetRenderSurface(root)->content_rect())); EXPECT_TRUE(damage_rect.Contains( - gfx::ToEnclosingRect(GetRenderSurface(child1)->DrawableContentRect()))); + gfx::ToEnclosingRect(GetRenderSurface(child1_)->DrawableContentRect()))); EXPECT_EQ(damage_rect, GetRenderSurface(root)->GetDamageRect()); EXPECT_TRUE(GetRenderSurface(root) ->damage_tracker() ->has_damage_from_contributing_content()); - EXPECT_TRUE(GetRenderSurface(child1) + EXPECT_TRUE(GetRenderSurface(child1_) ->damage_tracker() ->has_damage_from_contributing_content()); } diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc index 07e6bd172b0..ca985285ffb 100644 --- a/chromium/cc/trees/debug_rect_history.cc +++ b/chromium/cc/trees/debug_rect_history.cc @@ -14,8 +14,8 @@ #include "cc/layers/render_surface_impl.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/scroll_node.h" #include "ui/gfx/geometry/rect_conversions.h" namespace cc { @@ -137,9 +137,8 @@ void DebugRectHistory::SaveScreenSpaceRects( } void DebugRectHistory::SaveTouchEventHandlerRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveTouchEventHandlerRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveTouchEventHandlerRectsCallback(layer); } void DebugRectHistory::SaveTouchEventHandlerRectsCallback(LayerImpl* layer) { @@ -167,19 +166,20 @@ void DebugRectHistory::SaveWheelEventHandlerRects(LayerTreeImpl* tree_impl) { // Since the wheel event handlers property is on the entire layer tree just // mark inner viewport if have listeners. - LayerImpl* inner_viewport = tree_impl->InnerViewportScrollLayer(); - if (!inner_viewport) + ScrollNode* inner_scroll = tree_impl->InnerViewportScrollNode(); + if (!inner_scroll) return; - debug_rects_.push_back(DebugRect( - WHEEL_EVENT_HANDLER_RECT_TYPE, - MathUtil::MapEnclosingClippedRect(inner_viewport->ScreenSpaceTransform(), - gfx::Rect(inner_viewport->bounds())))); + debug_rects_.push_back( + DebugRect(WHEEL_EVENT_HANDLER_RECT_TYPE, + MathUtil::MapEnclosingClippedRect( + tree_impl->property_trees()->transform_tree.ToScreen( + inner_scroll->transform_id), + gfx::Rect(inner_scroll->bounds)))); } void DebugRectHistory::SaveScrollEventHandlerRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveScrollEventHandlerRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveScrollEventHandlerRectsCallback(layer); } void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { @@ -193,9 +193,8 @@ void DebugRectHistory::SaveScrollEventHandlerRectsCallback(LayerImpl* layer) { } void DebugRectHistory::SaveNonFastScrollableRects(LayerTreeImpl* tree_impl) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - tree_impl, - [this](LayerImpl* layer) { SaveNonFastScrollableRectsCallback(layer); }); + for (auto* layer : *tree_impl) + SaveNonFastScrollableRectsCallback(layer); } void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) { diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/draw_properties_unittest.cc index 6a511ff0898..93acf2883ce 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/draw_properties_unittest.cc @@ -2,8 +2,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/trees/layer_tree_host_common.h" - #include <stddef.h> #include <algorithm> @@ -20,33 +18,22 @@ #include "cc/animation/single_keyframe_effect_animation.h" #include "cc/animation/transform_operations.h" #include "cc/base/math_util.h" -#include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/content_layer_client.h" #include "cc/layers/effect_tree_layer_list_iterator.h" #include "cc/layers/layer.h" #include "cc/layers/layer_client.h" #include "cc/layers/layer_impl.h" #include "cc/layers/render_surface_impl.h" -#include "cc/layers/texture_layer.h" -#include "cc/layers/texture_layer_client.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_content_layer_client.h" -#include "cc/test/fake_impl_task_runner_provider.h" -#include "cc/test/fake_layer_tree_frame_sink.h" -#include "cc/test/fake_layer_tree_host.h" -#include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" -#include "cc/test/test_task_graph_runner.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" -#include "cc/trees/property_tree_builder.h" #include "cc/trees/scroll_node.h" -#include "cc/trees/single_thread_proxy.h" -#include "cc/trees/task_runner_provider.h" #include "cc/trees/transform_node.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" @@ -64,12 +51,11 @@ bool LayerSubtreeHasCopyRequest(Layer* layer) { return GetEffectNode(layer)->subtree_has_copy_request; } -class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { +class DrawPropertiesTestBase : public LayerTreeImplTestBase { public: - LayerTreeHostCommonTestBase() - : LayerTestCommon::LayerImplTest(LayerListSettings()) {} - explicit LayerTreeHostCommonTestBase(const LayerTreeSettings& settings) - : LayerTestCommon::LayerImplTest(settings) {} + DrawPropertiesTestBase() = default; + explicit DrawPropertiesTestBase(const LayerTreeSettings& settings) + : LayerTreeImplTestBase(settings) {} static void SetScrollOffsetDelta(LayerImpl* layer_impl, const gfx::Vector2dF& delta) { @@ -97,40 +83,9 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { .starting_animation_scale; } - // Inherits the impl version from LayerImplTest. - using LayerImplTest::ExecuteCalculateDrawProperties; - - // This is the main version. - void ExecuteCalculateDrawProperties(Layer* root_layer, - float device_scale_factor = 1.0f, - float page_scale_factor = 1.0f, - Layer* page_scale_layer = nullptr) { - if (!host()->IsUsingLayerLists()) { - if (device_scale_factor != host()->device_scale_factor() || - page_scale_factor != host()->page_scale_factor()) { - host()->property_trees()->needs_rebuild = true; - } - } - - EXPECT_TRUE(page_scale_layer || (page_scale_factor == 1.f)); - gfx::Rect device_viewport_rect = - gfx::Rect(root_layer->bounds().width() * device_scale_factor, - root_layer->bounds().height() * device_scale_factor); - - root_layer->layer_tree_host()->SetViewportRectAndScale( - device_viewport_rect, device_scale_factor, - viz::LocalSurfaceIdAllocation()); - - // We are probably not testing what is intended if the root_layer bounds are - // empty. - DCHECK(!root_layer->bounds().IsEmpty()); - LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( - root_layer, device_viewport_rect); - inputs.device_scale_factor = device_scale_factor; - inputs.page_scale_factor = page_scale_factor; - inputs.page_scale_layer = page_scale_layer; - inputs.update_layer_list = &update_layer_list_; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + void UpdateMainDrawProperties(float device_scale_factor = 1.0f) { + SetDeviceScaleAndUpdateViewportRect(host(), device_scale_factor); + UpdateDrawProperties(host(), &update_layer_list_); } LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) { @@ -146,11 +101,8 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { // Updates main thread draw properties, commits main thread tree to // impl-side pending tree, and updates pending tree draw properties. - void Commit(float device_scale_factor = 1.0f, - float page_scale_factor = 1.0f, - Layer* page_scale_layer = nullptr) { - ExecuteCalculateDrawProperties(host()->root_layer(), device_scale_factor, - page_scale_factor, page_scale_layer); + void Commit(float device_scale_factor = 1.0f) { + UpdateMainDrawProperties(device_scale_factor); if (!host_impl()->pending_tree()) host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); @@ -158,22 +110,18 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { // FakeLayerTreeHost instead of manually pushing the properties from the // layer tree host to the pending tree. host()->PushLayerTreePropertiesTo(host_impl()->pending_tree()); - ExecuteCalculateDrawProperties( - host_impl()->pending_tree()->root_layer_for_testing(), - device_scale_factor, gfx::Transform(), page_scale_factor, - PendingImplOf(page_scale_layer)); + + UpdateDrawProperties(host_impl()->pending_tree()); } // Calls Commit(), then activates the pending tree, and updates active tree // draw properties. - void CommitAndActivate(float device_scale_factor = 1.0f, - float page_scale_factor = 1.0f, - Layer* page_scale_layer = nullptr) { - Commit(device_scale_factor, page_scale_factor, page_scale_layer); + void CommitAndActivate(float device_scale_factor = 1.0f) { + Commit(device_scale_factor); host_impl()->ActivateSyncTree(); - ExecuteCalculateDrawProperties(root_layer_for_testing(), - device_scale_factor, gfx::Transform(), - page_scale_factor, ImplOf(page_scale_layer)); + DCHECK_EQ(device_scale_factor, + host_impl()->active_tree()->device_scale_factor()); + UpdateActiveTreeDrawProperties(device_scale_factor); } bool UpdateLayerListContains(int id) const { @@ -186,36 +134,44 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { const LayerList& update_layer_list() const { return update_layer_list_; } + const RenderSurfaceList& GetRenderSurfaceList() { + return host_impl()->active_tree()->GetRenderSurfaceList(); + } + + void SetDeviceTransform(const gfx::Transform& device_transform) { + host_impl()->OnDraw(device_transform, host_impl()->external_viewport(), + false, false); + } + private: LayerList update_layer_list_; }; -class LayerTreeHostCommonTest : public LayerTreeHostCommonTestBase, - public testing::Test {}; +class DrawPropertiesTest : public DrawPropertiesTestBase, + public testing::Test {}; -class LayerTreeHostCommonTestWithLayerTree : public LayerTreeHostCommonTestBase, - public testing::Test { +class DrawPropertiesTestWithLayerTree : public DrawPropertiesTestBase, + public testing::Test { public: - LayerTreeHostCommonTestWithLayerTree() - : LayerTreeHostCommonTestBase(LayerTreeSettings()) {} + DrawPropertiesTestWithLayerTree() + : DrawPropertiesTestBase(LayerTreeSettings()) {} }; -class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { +class DrawPropertiesDrawRectsTest : public DrawPropertiesTest { public: - LayerTreeHostCommonDrawRectsTest() : LayerTreeHostCommonTest() {} + DrawPropertiesDrawRectsTest() : DrawPropertiesTest() {} void SetUp() override { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetDrawsContent(true); root->SetBounds(gfx::Size(500, 500)); - SetupRootProperties(root); } LayerImpl* TestVisibleRectAndDrawableContentRect( const gfx::Rect& target_rect, const gfx::Transform& layer_transform, const gfx::Rect& layer_rect) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* target = AddLayer<LayerImpl>(); LayerImpl* drawing_layer = AddLayer<LayerImpl>(); @@ -238,7 +194,7 @@ class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { gfx::PointF(layer_rect.origin()).OffsetFromOrigin(); drawing_layer_transform_node.flattens_inherited_transform = false; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); return drawing_layer; } @@ -248,18 +204,17 @@ class LayerTreeHostCommonDrawRectsTest : public LayerTreeHostCommonTest { // and with identity transforms, then the draw transform, // screen space transform, and the hierarchy passed on to children // layers should also be identity transforms. -TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { - LayerImpl* parent = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForNoOpLayer) { + LayerImpl* parent = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(parent); CopyProperties(parent, child); CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(parent); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), child->DrawTransform()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), @@ -270,29 +225,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForNoOpLayer) { grand_child->ScreenSpaceTransform()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, EffectTreeTransformIdTest) { - // Tests that effect tree node gets a valid transform id when a layer - // has opacity but doesn't create a render surface. - auto parent = Layer::Create(); - host()->SetRootLayer(parent); - auto child = Layer::Create(); - parent->AddChild(child); - child->SetIsDrawable(true); - - parent->SetBounds(gfx::Size(100, 100)); - child->SetPosition(gfx::PointF(10, 10)); - child->SetBounds(gfx::Size(100, 100)); - child->SetOpacity(0.f); - ExecuteCalculateDrawProperties(parent.get()); - EffectNode* node = GetEffectNode(child.get()); - const int transform_tree_size = - GetPropertyTrees(parent.get())->transform_tree.next_available_id(); - EXPECT_LT(node->transform_id, transform_tree_size); -} - -TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForSingleLayer) { + LayerImpl* root = root_layer(); LayerImpl* layer = AddLayer<LayerImpl>(); TransformTree& transform_tree = @@ -301,13 +235,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { host_impl()->active_tree()->property_trees()->effect_tree; root->SetBounds(gfx::Size(1, 2)); - SetupRootProperties(root); CopyProperties(root, layer); // Case 1: Setting the bounds of the layer should not affect either the draw // transform or the screenspace transform. layer->SetBounds(gfx::Size(10, 12)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( gfx::Transform(), draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -319,7 +252,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { // no effect on the transforms. CreateTransformNode(layer).origin = gfx::Point3F(2.5f, 3.0f, 0.f); layer->SetBounds(gfx::Size(10, 12)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( gfx::Transform(), draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -332,7 +265,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { gfx::Transform position_transform; position_transform.Translate(0.f, 1.2f); SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( position_transform, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -348,7 +281,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { SetTransform(layer, layer_transform); SetTransformOrigin(layer, gfx::Point3F()); SetPostTranslation(layer, gfx::Vector2dF()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( layer_transform, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -362,7 +295,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { gfx::Transform expected_result = translation_to_anchor * layer_transform * Inverse(translation_to_anchor); SetTransformOrigin(layer, gfx::Point3F(5.f, 0.f, 0.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_result, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -376,7 +309,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { expected_result = position_transform * translation_to_anchor * layer_transform * Inverse(translation_to_anchor); SetPostTranslation(layer, gfx::Vector2dF(0.f, 1.2f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( expected_result, draw_property_utils::DrawTransform(layer, transform_tree, effect_tree)); @@ -385,7 +318,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleLayer) { draw_property_utils::ScreenSpaceTransform(layer, transform_tree)); } -TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { +TEST_F(DrawPropertiesTest, TransformsAboutScrollOffset) { const gfx::ScrollOffset kScrollOffset(50, 100); const gfx::Vector2dF kScrollDelta(2.34f, 5.67f); const gfx::Vector2d kMaxScrollOffset(200, 200); @@ -406,16 +339,11 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { gfx::Size(scroll_layer->bounds().width() + kMaxScrollOffset.x(), scroll_layer->bounds().height() + kMaxScrollOffset.y())); - LayerImpl* page_scale_layer = AddLayer<LayerImpl>(); - page_scale_layer->SetBounds(gfx::Size(3, 4)); + LayerImpl* root = root_layer(); + root->SetBounds(gfx::Size(3, 4)); + SetupViewport(root, gfx::Size(3, 4), gfx::Size(500, 500)); - LayerImpl* root_layer = root_layer_for_testing(); - root_layer->SetBounds(gfx::Size(3, 4)); - - SetupRootProperties(root_layer); - CopyProperties(root_layer, page_scale_layer); - CreateTransformNode(page_scale_layer); - CopyProperties(page_scale_layer, scroll_layer); + CopyProperties(OuterViewportScrollLayer(), scroll_layer); CreateTransformNode(scroll_layer); CreateScrollNode(scroll_layer); CopyProperties(scroll_layer, sublayer); @@ -424,10 +352,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), kScrollOffset); SetScrollOffsetDelta(scroll_layer, kScrollDelta); + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale); + UpdateActiveTreeDrawProperties(kDeviceScale); - const gfx::Transform kDeviceTransform; - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, - page_scale, page_scale_layer); gfx::Transform expected_transform; gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta; expected_transform.Translate( @@ -445,8 +372,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { const float kTranslateY = 20.6f; arbitrary_translate.Translate(kTranslateX, kTranslateY); SetTransform(scroll_layer, arbitrary_translate); - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, - page_scale, page_scale_layer); + UpdateActiveTreeDrawProperties(kDeviceScale); expected_transform.MakeIdentity(); expected_transform.Translate( std::round(kTranslateX * page_scale * kDeviceScale + @@ -461,13 +387,9 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { // Test that page scale is updated even when we don't rebuild property trees. page_scale = 1.888f; - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale_layer->id(); - root_layer->layer_tree_impl()->SetViewportLayersFromIds(viewport_ids); - root_layer->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale); - EXPECT_FALSE(root_layer->layer_tree_impl()->property_trees()->needs_rebuild); - ExecuteCalculateDrawProperties(root_layer, kDeviceScale, kDeviceTransform, - page_scale, page_scale_layer); + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale); + EXPECT_FALSE(host_impl()->active_tree()->property_trees()->needs_rebuild); + UpdateActiveTreeDrawProperties(kDeviceScale); expected_transform.MakeIdentity(); expected_transform.Translate( @@ -481,8 +403,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { sublayer->DrawTransform()); } -TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForSimpleHierarchy) { + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -500,13 +422,12 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { child->SetBounds(gfx::Size(16, 18)); grand_child->SetBounds(gfx::Size(76, 78)); - SetupRootProperties(root); CopyProperties(root, parent); CreateTransformNode(parent).origin = gfx::Point3F(2.5f, 3.0f, 0.f); CopyProperties(parent, child); CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( gfx::Transform(), @@ -525,7 +446,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { gfx::Transform parent_position_transform; parent_position_transform.Translate(0.f, 1.2f); SetPostTranslation(parent, gfx::Vector2dF(0.f, 1.2f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( parent_position_transform, draw_property_utils::DrawTransform(child, transform_tree, effect_tree)); @@ -549,7 +470,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { Inverse(parent_translation_to_anchor); SetTransform(parent, parent_layer_transform); SetPostTranslation(parent, gfx::Vector2dF()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( parent_composite_transform, draw_property_utils::DrawTransform(child, transform_tree, effect_tree)); @@ -565,8 +486,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSimpleHierarchy) { draw_property_utils::ScreenSpaceTransform(grand_child, transform_tree)); } -TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformsForSingleRenderSurface) { + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -594,7 +515,6 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { grand_child->SetBounds(gfx::Size(8, 10)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); auto& parent_transform_node = CreateTransformNode(parent); parent_transform_node.origin = gfx::Point3F(2.5f, 30.f, 0.f); @@ -603,7 +523,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Render surface should have been created now. ASSERT_TRUE(GetRenderSurface(child)); @@ -629,7 +549,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForSingleRenderSurface) { child->render_target()->screen_space_transform()); } -TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { +TEST_F(DrawPropertiesTest, TransformsForRenderSurfaceHierarchy) { // This test creates a more complex tree and verifies it all at once. This // covers the following cases: // - layers that are described w.r.t. a render surface: should have draw @@ -641,7 +561,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { // - verifying that each layer has a reference to the correct render surface // and render target values. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetDrawsContent(true); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); @@ -706,7 +626,6 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { grand_child_of_rs1->SetBounds(gfx::Size(10, 10)); grand_child_of_rs2->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, parent); auto& parent_transform_node = CreateTransformNode(parent); parent_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); @@ -755,7 +674,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { grand_child_of_rs2_transform_node.origin = gfx::Point3F(2.5f, 0.f, 0.f); grand_child_of_rs2_transform_node.local = layer_transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Only layers that are associated with render surfaces should have an actual // RenderSurface() value. @@ -868,83 +787,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForRenderSurfaceHierarchy) { 5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3)); } -// Needs layer tree mode: testing PropertyTreeBuilder (forcing flattening on -// surface). -TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformsForFlatteningLayer) { - // For layers that flatten their subtree, there should be an orthographic - // projection (for x and y values) in the middle of the transform sequence. - // Note that the way the code is currently implemented, it is not expected to - // use a canonical orthographic projection. - - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - child->SetIsDrawable(true); - auto grand_child = Layer::Create(); - child->AddChild(grand_child); - grand_child->SetIsDrawable(true); - auto great_grand_child = Layer::Create(); - grand_child->AddChild(great_grand_child); - great_grand_child->SetIsDrawable(true); - - gfx::Transform rotation_about_y_axis; - rotation_about_y_axis.RotateAboutYAxis(30.0); - - root->SetBounds(gfx::Size(100, 100)); - child->SetTransform(rotation_about_y_axis); - child->SetBounds(gfx::Size(10, 10)); - child->SetForceRenderSurfaceForTesting(true); - grand_child->SetTransform(rotation_about_y_axis); - grand_child->SetBounds(gfx::Size(10, 10)); - great_grand_child->SetBounds(gfx::Size(10, 10)); - - // No layers in this test should preserve 3d. - ASSERT_TRUE(root->should_flatten_transform()); - ASSERT_TRUE(child->should_flatten_transform()); - ASSERT_TRUE(grand_child->should_flatten_transform()); - ASSERT_TRUE(great_grand_child->should_flatten_transform()); - - gfx::Transform expected_child_draw_transform = rotation_about_y_axis; - gfx::Transform expected_child_screen_space_transform = rotation_about_y_axis; - gfx::Transform expected_grand_child_draw_transform = - rotation_about_y_axis; // draws onto child's render surface - gfx::Transform flattened_rotation_about_y = rotation_about_y_axis; - flattened_rotation_about_y.FlattenTo2d(); - gfx::Transform expected_grand_child_screen_space_transform = - flattened_rotation_about_y * rotation_about_y_axis; - gfx::Transform expected_great_grand_child_draw_transform = - flattened_rotation_about_y; - gfx::Transform expected_great_grand_child_screen_space_transform = - flattened_rotation_about_y * flattened_rotation_about_y; - - CommitAndActivate(); - - // The child's draw transform should have been taken by its surface. - ASSERT_TRUE(GetRenderSurfaceImpl(child)); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_child_draw_transform, - GetRenderSurfaceImpl(child)->draw_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_child_screen_space_transform, - GetRenderSurfaceImpl(child)->screen_space_transform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - ImplOf(child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_child_screen_space_transform, - ImplOf(child)->ScreenSpaceTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_draw_transform, - ImplOf(grand_child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_grand_child_screen_space_transform, - ImplOf(grand_child)->ScreenSpaceTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected_great_grand_child_draw_transform, - ImplOf(great_grand_child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_great_grand_child_screen_space_transform, - ImplOf(great_grand_child)->ScreenSpaceTransform()); -} - -TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LayerFullyContainedWithinClipInTargetSpace) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -960,7 +804,6 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = child_transform; CopyProperties(child, grand_child); @@ -968,7 +811,7 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { grand_child_transform_node.flattens_inherited_transform = false; grand_child_transform_node.local = grand_child_transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Mapping grand_child's bounds to screen space produces an empty rect, but // only because it is turned sideways. The entire rect is contained inside @@ -980,7 +823,7 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { grand_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { +TEST_F(DrawPropertiesTest, TransformsForDegenerateIntermediateLayer) { // A layer that is empty in one axis, but not the other, was accidentally // skipping a necessary translation. Without that translation, the coordinate // space of the layer's draw transform is incorrect. @@ -990,7 +833,7 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { // implicitly inherited by the rest of the subtree, which then is positioned // incorrectly as a result. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); grand_child->SetDrawsContent(true); @@ -1001,12 +844,11 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { child->SetBounds(gfx::Size(10, 0)); grand_child->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(child)); // This is the real test, the rest are sanity checks. @@ -1017,8 +859,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsForDegenerateIntermediateLayer) { grand_child->DrawTransform()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceWithSublayerScale) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -1032,7 +874,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateTransformNode(render_surface).local = translate; CreateEffectNode(render_surface).render_surface_reason = @@ -1044,7 +885,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { // render_surface will have a sublayer scale because of device scale factor. float device_scale_factor = 2.0f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // Between grand_child and render_surface, we translate by (10, 10) and scale // by a factor of 2. @@ -1053,10 +894,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { expected_translation); } -TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { +TEST_F(DrawPropertiesTest, TransformAboveRootLayer) { // Transformations applied at the root of the tree should be forwarded // to child layers instead of applied to the root RenderSurface. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetDrawsContent(true); @@ -1065,7 +906,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { child->SetBounds(gfx::Size(100, 100)); child->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, child); CreateClipNode(child); @@ -1073,7 +913,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform translate; translate.Translate(50, 50); { - ExecuteCalculateDrawProperties(root, device_scale_factor, translate); + SetDeviceTransform(translate); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( translate, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1087,7 +928,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform scale; scale.Scale(2, 2); { - ExecuteCalculateDrawProperties(root, device_scale_factor, scale); + SetDeviceTransform(scale); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( scale, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1101,7 +943,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { gfx::Transform rotate; rotate.Rotate(2); { - ExecuteCalculateDrawProperties(root, device_scale_factor, rotate); + SetDeviceTransform(rotate); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( rotate, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1117,7 +960,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { composite.ConcatTransform(scale); composite.ConcatTransform(rotate); { - ExecuteCalculateDrawProperties(root, device_scale_factor, composite); + SetDeviceTransform(composite); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( composite, root->draw_properties().target_space_transform); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1132,7 +976,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { device_scale_factor = 1.5f; { - ExecuteCalculateDrawProperties(root, device_scale_factor, translate); + SetDeviceTransform(translate); + UpdateActiveTreeDrawProperties(device_scale_factor); gfx::Transform device_scaled_translate = translate; device_scaled_translate.Scale(device_scale_factor, device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ( @@ -1149,216 +994,8 @@ TEST_F(LayerTreeHostCommonTest, TransformAboveRootLayer) { } } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceForNonAxisAlignedClipping) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto rotated_and_transparent = Layer::Create(); - root->AddChild(rotated_and_transparent); - auto clips_subtree = Layer::Create(); - rotated_and_transparent->AddChild(clips_subtree); - auto draws_content = Layer::Create(); - clips_subtree->AddChild(draws_content); - - root->SetBounds(gfx::Size(10, 10)); - rotated_and_transparent->SetBounds(gfx::Size(10, 10)); - rotated_and_transparent->SetOpacity(0.5f); - gfx::Transform rotate; - rotate.Rotate(2); - rotated_and_transparent->SetTransform(rotate); - clips_subtree->SetBounds(gfx::Size(10, 10)); - clips_subtree->SetMasksToBounds(true); - draws_content->SetBounds(gfx::Size(10, 10)); - draws_content->SetIsDrawable(true); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_TRUE(GetEffectNode(clips_subtree.get())->HasRenderSurface()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - EffectNodesForNonAxisAlignedClips) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto rotate_and_clip = Layer::Create(); - root->AddChild(rotate_and_clip); - auto only_clip = Layer::Create(); - rotate_and_clip->AddChild(only_clip); - auto rotate_and_clip2 = Layer::Create(); - only_clip->AddChild(rotate_and_clip2); - - gfx::Transform rotate; - rotate.Rotate(2); - root->SetBounds(gfx::Size(10, 10)); - rotate_and_clip->SetBounds(gfx::Size(10, 10)); - rotate_and_clip->SetTransform(rotate); - rotate_and_clip->SetMasksToBounds(true); - only_clip->SetBounds(gfx::Size(10, 10)); - only_clip->SetMasksToBounds(true); - rotate_and_clip2->SetBounds(gfx::Size(10, 10)); - rotate_and_clip2->SetTransform(rotate); - rotate_and_clip2->SetMasksToBounds(true); - - ExecuteCalculateDrawProperties(root.get()); - // non-axis aligned clip should create an effect node - EXPECT_NE(root->effect_tree_index(), rotate_and_clip->effect_tree_index()); - // Since only_clip's clip is in the same non-axis aligned space as - // rotate_and_clip's clip, no new effect node should be created. - EXPECT_EQ(rotate_and_clip->effect_tree_index(), - only_clip->effect_tree_index()); - // rotate_and_clip2's clip and only_clip's clip are in different non-axis - // aligned spaces. So, new effect node should be created. - EXPECT_NE(rotate_and_clip2->effect_tree_index(), - only_clip->effect_tree_index()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForRenderSurfaceWithClippedLayer) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - root->SetMasksToBounds(true); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - child->SetIsDrawable(true); - child->SetPosition(gfx::PointF(30.f, 30.f)); - child->SetBounds(gfx::Size(10, 10)); - - CommitAndActivate(); - - // The child layer's content is entirely outside the root's clip rect, so - // the intermediate render surface should not be listed here, even if it was - // forced to be created. Render surfaces without children or visible content - // are unexpected at draw time (e.g. we might try to create a content texture - // of size 0). - ASSERT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(1U, render_surface_list_impl()->size()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForTransparentChild) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - render_surface1->SetOpacity(0.f); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - - CommitAndActivate(); - - // Since the layer is transparent, render_surface1_impl->GetRenderSurface() - // should not have gotten added anywhere. Also, the drawable content rect - // should not have been extended by the children. - ASSERT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(0, GetRenderSurfaceImpl(root)->num_contributors()); - EXPECT_EQ(1U, render_surface_list_impl()->size()); - EXPECT_EQ(static_cast<viz::RenderPassId>(root->id()), - render_surface_list_impl()->at(0)->id()); - EXPECT_EQ(gfx::Rect(), ImplOf(root)->drawable_content_rect()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForTransparentChildWithBackdropFilter) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - render_surface1->SetOpacity(0.f); - render_surface1->SetIsDrawable(true); - FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(1.5f)); - render_surface1->SetBackdropFilters(filters); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - host()->SetElementIdsForTesting(); - - CommitAndActivate(); - EXPECT_EQ(2U, render_surface_list_impl()->size()); - - // The layer is fully transparent, but has a backdrop filter, so it - // shouldn't be skipped and should be drawn. - ASSERT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); - EXPECT_EQ(gfx::RectF(0, 0, 10, 10), - GetRenderSurfaceImpl(root)->DrawableContentRect()); - EXPECT_TRUE(GetEffectNode(ImplOf(render_surface1))->is_drawn); - - // When root is transparent, the layer should not be drawn. - host_impl()->active_tree()->SetOpacityMutated(root->element_id(), 0.f); - host_impl()->active_tree()->SetOpacityMutated(render_surface1->element_id(), - 1.f); - ImplOf(render_surface1)->set_visible_layer_rect(gfx::Rect()); - ExecuteCalculateDrawProperties(ImplOf(root)); - - EXPECT_FALSE(GetEffectNode(ImplOf(render_surface1))->is_drawn); - EXPECT_EQ(gfx::Rect(), ImplOf(render_surface1)->visible_layer_rect()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceListForFilter) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto parent = Layer::Create(); - root->AddChild(parent); - auto child1 = Layer::Create(); - parent->AddChild(child1); - auto child2 = Layer::Create(); - parent->AddChild(child2); - - gfx::Transform scale_matrix; - scale_matrix.Scale(2.0f, 2.0f); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetTransform(scale_matrix); - FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter(10.0f)); - parent->SetFilters(filters); - parent->SetForceRenderSurfaceForTesting(true); - child1->SetBounds(gfx::Size(25, 25)); - child1->SetIsDrawable(true); - child1->SetForceRenderSurfaceForTesting(true); - child2->SetPosition(gfx::PointF(25, 25)); - child2->SetBounds(gfx::Size(25, 25)); - child2->SetIsDrawable(true); - child2->SetForceRenderSurfaceForTesting(true); - - CommitAndActivate(); - - ASSERT_TRUE(GetRenderSurfaceImpl(parent)); - EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); - EXPECT_EQ(4U, render_surface_list_impl()->size()); - - // The rectangle enclosing child1 and child2 (0,0 50x50), expanded for the - // blur (-30,-30 110x110), and then scaled by the scale matrix - // (-60,-60 220x220). - EXPECT_EQ(gfx::RectF(-60, -60, 220, 220), - GetRenderSurfaceImpl(parent)->DrawableContentRect()); -} - -TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilter) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); @@ -1368,13 +1005,12 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { filters.Append(FilterOperation::CreateReferenceFilter( sk_make_sp<OffsetPaintFilter>(50, 50, nullptr))); - SetupRootProperties(root); CopyProperties(root, child); auto& child_effect_node = CreateEffectNode(child); child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; child_effect_node.filters = filters; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // The render surface's size should be unaffected by the offset image filter; // it need only have a drawable content rect large enough to contain the @@ -1384,10 +1020,10 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilter) { GetRenderSurface(child)->DrawableContentRect()); } -TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { +TEST_F(DrawPropertiesTest, DrawableContentRectForReferenceFilterHighDpi) { const float device_scale_factor = 2.0f; - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); @@ -1398,13 +1034,12 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { filters.Append(FilterOperation::CreateReferenceFilter( sk_make_sp<OffsetPaintFilter>(50, 50, nullptr))); - SetupRootProperties(root); CopyProperties(root, child); auto& child_effect_node = CreateEffectNode(child); child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; child_effect_node.filters = filters; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // The render surface's size should be unaffected by the offset image filter; // it need only have a drawable content rect large enough to contain the @@ -1415,22 +1050,21 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForReferenceFilterHighDpi) { GetRenderSurface(child)->DrawableContentRect()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceForBlendMode) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(10, 10)); child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); auto& child_effect_node = CreateEffectNode(child); child_effect_node.render_surface_reason = RenderSurfaceReason::kTest; child_effect_node.blend_mode = SkBlendMode::kMultiply; child_effect_node.opacity = 0.5f; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Since the child layer has a blend mode other than normal, it should get // its own render surface. @@ -1440,8 +1074,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceForBlendMode) { EXPECT_EQ(SkBlendMode::kMultiply, GetRenderSurface(child)->BlendMode()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceDrawOpacity) { + LayerImpl* root = root_layer(); LayerImpl* surface1 = AddLayer<LayerImpl>(); LayerImpl* not_surface = AddLayer<LayerImpl>(); LayerImpl* surface2 = AddLayer<LayerImpl>(); @@ -1453,7 +1087,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { surface2->SetBounds(gfx::Size(10, 10)); surface2->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, surface1); auto& surface1_effect_node = CreateEffectNode(surface1); surface1_effect_node.render_surface_reason = RenderSurfaceReason::kTest; @@ -1465,7 +1098,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { surface2_effect_node.render_surface_reason = RenderSurfaceReason::kTest; surface2_effect_node.opacity = 0.5f; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(surface1)); ASSERT_EQ(GetRenderSurface(not_surface), GetRenderSurface(surface1)); @@ -1476,88 +1109,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceDrawOpacity) { EXPECT_EQ(0.25f, GetRenderSurface(surface2)->draw_opacity()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, ForceRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto render_surface1 = Layer::Create(); - root->AddChild(render_surface1); - auto child = Layer::Create(); - render_surface1->AddChild(child); - - root->SetBounds(gfx::Size(10, 10)); - render_surface1->SetBounds(gfx::Size(10, 10)); - render_surface1->SetForceRenderSurfaceForTesting(true); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - - CommitAndActivate(); - - // The root layer always creates a render surface - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); - - render_surface1->SetForceRenderSurfaceForTesting(false); - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); -} - -// Needs layer tree mode: testing PropertyTreeBuilder (force flattening on -// surface). -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfacesFlattenScreenSpaceTransform) { - // Render surfaces act as a flattening point for their subtree, so should - // always flatten the target-to-screen space transform seen by descendants. - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto parent = Layer::Create(); - root->AddChild(parent); - auto child = Layer::Create(); - parent->AddChild(child); - auto grand_child = Layer::Create(); - child->AddChild(grand_child); - - gfx::Transform rotation_about_y_axis; - rotation_about_y_axis.RotateAboutYAxis(30.0); - - root->SetBounds(gfx::Size(100, 100)); - parent->SetTransform(rotation_about_y_axis); - parent->SetBounds(gfx::Size(10, 10)); - parent->SetForceRenderSurfaceForTesting(true); - child->SetBounds(gfx::Size(10, 10)); - child->SetIsDrawable(true); - grand_child->SetBounds(gfx::Size(10, 10)); - grand_child->SetIsDrawable(true); - grand_child->SetShouldFlattenTransform(false); - - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(parent)); - EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(parent)); - EXPECT_EQ(GetRenderSurfaceImpl(grand_child), GetRenderSurfaceImpl(parent)); - - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - ImplOf(child)->DrawTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), - ImplOf(grand_child)->DrawTransform()); - - // The screen-space transform inherited by |child| and |grand_child| - // should have been flattened at their render target. In particular, the fact - // that |grand_child| happens to preserve 3d shouldn't affect this - // flattening. - gfx::Transform flattened_rotation_about_y = rotation_about_y_axis; - flattened_rotation_about_y.FlattenTo2d(); - EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_y, - ImplOf(child)->ScreenSpaceTransform()); - EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_y, - ImplOf(grand_child)->ScreenSpaceTransform()); -} - -TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { +TEST_F(DrawPropertiesTest, ClipRectCullsRenderSurfaces) { // The entire subtree of layers that are outside the clip rect should be - // culled away, and should not affect the render_surface_list. + // culled away, and should not affect the GetRenderSurfaceList. // // The test tree is set up as follows: // - all layers except the leaf_nodes are forced to be a new render surface @@ -1571,13 +1125,14 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { // outside the clip rect, and they should never get scheduled on the list of // render surfaces. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* great_grand_child = AddLayer<LayerImpl>(); - // leaf_node1 ensures that root and child are kept on the render_surface_list, - // even though grand_child and great_grand_child should be clipped. + // leaf_node1 ensures that root and child are kept on the + // GetRenderSurfaceList, even though grand_child and great_grand_child should + // be clipped. LayerImpl* leaf_node1 = AddLayer<LayerImpl>(); LayerImpl* leaf_node2 = AddLayer<LayerImpl>(); @@ -1591,7 +1146,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { leaf_node1->SetBounds(gfx::Size(20, 20)); leaf_node2->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateClipNode(child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -1605,16 +1159,16 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsRenderSurfaces) { leaf_node2->SetOffsetToTransformParent( great_grand_child->offset_to_transform_parent()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - ASSERT_EQ(2U, render_surface_list_impl()->size()); + ASSERT_EQ(2U, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); EXPECT_EQ(static_cast<uint64_t>(child->id()), - render_surface_list_impl()->at(1)->id()); + GetRenderSurfaceList().at(1)->id()); } -TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { +TEST_F(DrawPropertiesTest, ClipRectCullsSurfaceWithoutVisibleContent) { // When a render surface has a clip rect, it is used to clip the content rect // of the surface. @@ -1627,9 +1181,9 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { // In this configuration, grand_child should be outside the clipped // content rect of the child, making grand_child not appear in the - // render_surface_list. + // GetRenderSurfaceList. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* leaf_node = AddLayer<LayerImpl>(); @@ -1641,7 +1195,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { leaf_node->SetBounds(gfx::Size(10, 10)); leaf_node->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -1653,15 +1206,15 @@ TEST_F(LayerTreeHostCommonTest, ClipRectCullsSurfaceWithoutVisibleContent) { leaf_node->SetOffsetToTransformParent( grand_child->offset_to_transform_parent()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - // We should cull child and grand_child from the render_surface_list. - ASSERT_EQ(1U, render_surface_list_impl()->size()); + // We should cull child and grand_child from the GetRenderSurfaceList. + ASSERT_EQ(1U, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); } -TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { +TEST_F(DrawPropertiesTest, IsClippedIsSetCorrectlyLayerImpl) { // Tests that LayerImpl's IsClipped() property is set to true when: // - the layer clips its subtree, e.g. masks to bounds, // - the layer is clipped by an ancestor that contributes to the same @@ -1675,7 +1228,7 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { // - but if the layer itself masks to bounds, it is considered clipped // and propagates the clip to the subtree. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -1697,7 +1250,6 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { leaf_node2->SetBounds(gfx::Size(100, 100)); leaf_node2->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); CopyProperties(parent, child1); CopyProperties(child1, grand_child); @@ -1708,7 +1260,7 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { CopyProperties(child2, leaf_node2); // Case 1: nothing is clipped except the root render surface. - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(child2)); @@ -1736,7 +1288,8 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { GetEffectNode(child2)->clip_id = parent->clip_tree_index(); leaf_node2->SetClipTreeIndex(parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(child2)); @@ -1766,7 +1319,8 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { CreateClipNode(child2); leaf_node2->SetClipTreeIndex(child2->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(child2)); @@ -1782,10 +1336,10 @@ TEST_F(LayerTreeHostCommonTest, IsClippedIsSetCorrectlyLayerImpl) { EXPECT_TRUE(leaf_node2->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { +TEST_F(DrawPropertiesTest, UpdateClipRectCorrectly) { // Tests that when as long as layer is clipped, it's clip rect is set to // correct value. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -1797,12 +1351,11 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { child->SetDrawsContent(true); child->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, parent); CopyProperties(parent, child); CreateClipNode(child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(root->is_clipped()); EXPECT_FALSE(parent->is_clipped()); @@ -1815,7 +1368,8 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { child->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); GetClipNode(child)->clip += gfx::Vector2dF(100.f, 100.f); - ExecuteCalculateDrawProperties(root); + host_impl()->active_tree()->set_needs_update_draw_properties(); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(root->is_clipped()); EXPECT_TRUE(parent->is_clipped()); @@ -1823,7 +1377,7 @@ TEST_F(LayerTreeHostCommonTest, UpdateClipRectCorrectly) { EXPECT_EQ(gfx::Rect(), child->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { +TEST_F(DrawPropertiesTest, DrawableContentRectForLayers) { // Verify that layers get the appropriate DrawableContentRect when their // parent MasksToBounds is true. // @@ -1837,7 +1391,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { // grand_child4 - outside parent's clip rect; the DrawableContentRect should // be empty. - LayerImpl* parent = root_layer_for_testing(); + LayerImpl* parent = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child1 = AddLayer<LayerImpl>(); LayerImpl* grand_child2 = AddLayer<LayerImpl>(); @@ -1857,7 +1411,6 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { grand_child4->SetBounds(gfx::Size(10, 10)); grand_child4->SetDrawsContent(true); - SetupRootProperties(parent); CopyProperties(parent, child); CreateTransformNode(child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -1872,7 +1425,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { CopyProperties(child, grand_child4); grand_child4->SetOffsetToTransformParent(gfx::Vector2dF(45.f, 45.f)); - ExecuteCalculateDrawProperties(parent); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(5, 5, 10, 10), grand_child1->drawable_content_rect()); EXPECT_EQ(gfx::Rect(15, 15, 5, 5), grand_child3->drawable_content_rect()); @@ -1880,7 +1433,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableContentRectForLayers) { EXPECT_TRUE(grand_child4->drawable_content_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { +TEST_F(DrawPropertiesTest, ClipRectIsPropagatedCorrectlyToSurfaces) { // Verify that render surfaces (and their layers) get the appropriate // clip rects when their parent MasksToBounds is true. // @@ -1888,7 +1441,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { // clipping; instead the surface will enforce the clip for the entire subtree. // They may still have a clip rect of their own layer bounds, however, if // MasksToBounds was true. - LayerImpl* parent = root_layer_for_testing(); + LayerImpl* parent = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child1 = AddLayer<LayerImpl>(); LayerImpl* grand_child2 = AddLayer<LayerImpl>(); @@ -1919,7 +1472,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { leaf_node4->SetBounds(gfx::Size(10, 10)); leaf_node4->SetDrawsContent(true); - SetupRootProperties(parent); CopyProperties(parent, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; CreateClipNode(child); @@ -1949,7 +1501,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { CreateClipNode(grand_child4); CopyProperties(grand_child4, leaf_node4); - ExecuteCalculateDrawProperties(parent); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(grand_child1)); ASSERT_TRUE(GetRenderSurface(grand_child2)); @@ -1965,8 +1517,8 @@ TEST_F(LayerTreeHostCommonTest, ClipRectIsPropagatedCorrectlyToSurfaces) { GetRenderSurface(grand_child3)->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, AnimationsForRenderSurfaceHierarchy) { + LayerImpl* root = root_layer(); LayerImpl* top = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* child_of_rs1 = AddLayer<LayerImpl>(); @@ -2002,7 +1554,6 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { grand_child_of_rs1->SetBounds(gfx::Size(10, 10)); grand_child_of_rs2->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, top); CreateTransformNode(top).local = layer_transform; CopyProperties(top, render_surface1); @@ -2075,7 +1626,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { AddAnimatedTransformToElementWithAnimation(grand_child_of_rs2->element_id(), timeline_impl(), 10.0, 30, 0); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Only layers that are associated with render surfaces should have an actual // RenderSurface() value. @@ -2146,8 +1697,8 @@ TEST_F(LayerTreeHostCommonTest, AnimationsForRenderSurfaceHierarchy) { 5.0, grand_child_of_rs2->ScreenSpaceTransform().matrix().get(1, 3)); } -TEST_F(LayerTreeHostCommonTest, LargeTransforms) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LargeTransforms) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -2159,13 +1710,12 @@ TEST_F(LayerTreeHostCommonTest, LargeTransforms) { grand_child->SetBounds(gfx::Size(10, 10)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = large_transform; CopyProperties(child, grand_child); CreateTransformNode(grand_child).local = large_transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); } @@ -2182,9 +1732,9 @@ static bool HasPotentiallyRunningTransformAnimation(LayerImpl* layer) { layer->element_id(), layer->GetElementTypeForAnimation()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, ScreenSpaceTransformIsAnimatingWithDelayedAnimation) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* great_grand_child = AddLayer<LayerImpl>(); @@ -2201,7 +1751,6 @@ TEST_F(LayerTreeHostCommonTest, SetElementIdsForTesting(); - SetupRootProperties(root); CopyProperties(root, child); CopyProperties(child, grand_child); CreateTransformNode(grand_child); // for animation. @@ -2216,7 +1765,7 @@ TEST_F(LayerTreeHostCommonTest, AddKeyframeModelToElementWithAnimation( grand_child->element_id(), timeline_impl(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(root->screen_space_transform_is_animating()); EXPECT_FALSE(child->screen_space_transform_is_animating()); @@ -2229,7 +1778,7 @@ TEST_F(LayerTreeHostCommonTest, // Test visible layer rect and drawable content rect are calculated correctly // for identity transforms. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForIdentityTransform) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForIdentityTransform) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; @@ -2266,7 +1815,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForIdentityTransform) { // Test visible layer rect and drawable content rect are calculated correctly // for rotations about z-axis (i.e. 2D rotations). -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor2DRotations) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor2DRotations) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 30, 30); gfx::Transform layer_to_surface_transform; @@ -2330,7 +1879,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor2DRotations) { // Test visible layer rect and drawable content rect are calculated correctly // for 3d transforms. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicTransform) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dOrthographicTransform) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); gfx::Transform layer_to_surface_transform; @@ -2370,7 +1919,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dOrthographicTransform) { // Test visible layer rect and drawable content rect are calculated correctly // when the layer has a perspective projection onto the target surface. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(-50, -50, 200, 200); gfx::Transform layer_to_surface_transform; @@ -2424,7 +1973,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsFor3dPerspectiveTransform) { // in our code (nor in the CSS spec to my knowledge). Therefore, layers that // are technically behind the surface in an orthographic world should not be // clipped when they are flattened to the surface. -TEST_F(LayerTreeHostCommonDrawRectsTest, +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dOrthographicIsNotClippedBehindSurface) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 100, 100); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 100, 100); @@ -2456,8 +2005,7 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, // coordinates before converting to cartesian coordinates. The drawable // content rect would be entire surface rect because layer is rotated at the // camera position. -TEST_F(LayerTreeHostCommonDrawRectsTest, - DrawRectsFor3dPerspectiveWhenClippedByW) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsFor3dPerspectiveWhenClippedByW) { gfx::Rect target_surface_rect = gfx::Rect(0, 0, 200, 200); gfx::Rect layer_content_rect = gfx::Rect(0, 0, 20, 2); gfx::Transform layer_to_surface_transform; @@ -2508,7 +2056,7 @@ static bool ProjectionClips(const gfx::Transform& map_transform, // transform was a perspective projection that was clipped, it returns a rect // that encloses the clipped bounds. Un-projecting this new rect may require // clipping again. -TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) { +TEST_F(DrawPropertiesDrawRectsTest, DrawRectsForPerspectiveUnprojection) { // This sequence of transforms causes one corner of the layer to protrude // across the w = 0 plane, and should be clipped. gfx::Rect target_surface_rect = gfx::Rect(0, 0, 150, 150); @@ -2540,8 +2088,8 @@ TEST_F(LayerTreeHostCommonDrawRectsTest, DrawRectsForPerspectiveUnprojection) { drawing_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSimpleLayers) { + LayerImpl* root = root_layer(); LayerImpl* child1_layer = AddLayer<LayerImpl>(); LayerImpl* child2_layer = AddLayer<LayerImpl>(); LayerImpl* child3_layer = AddLayer<LayerImpl>(); @@ -2554,14 +2102,13 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { child3_layer->SetBounds(gfx::Size(50, 50)); child3_layer->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child1_layer); CopyProperties(root, child2_layer); child2_layer->SetOffsetToTransformParent(gfx::Vector2dF(75.f, 75.f)); CopyProperties(root, child3_layer); child3_layer->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::RectF(100.f, 100.f), GetRenderSurface(root)->DrawableContentRect()); @@ -2580,9 +2127,9 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsForSimpleLayers) { EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersClippedByLayer) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child1 = AddLayer<LayerImpl>(); LayerImpl* grand_child2 = AddLayer<LayerImpl>(); @@ -2598,7 +2145,6 @@ TEST_F(LayerTreeHostCommonTest, grand_child3->SetBounds(gfx::Size(50, 50)); grand_child3->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateClipNode(child); CopyProperties(child, grand_child1); @@ -2608,7 +2154,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(child, grand_child3); grand_child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::RectF(100.f, 100.f), GetRenderSurface(root)->DrawableContentRect()); @@ -2628,8 +2174,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_TRUE(grand_child3->drawable_content_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleContentRectWithClippingAndScaling) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -2644,147 +2190,25 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectWithClippingAndScaling) { grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = child_scale_matrix; CreateClipNode(child); CopyProperties(child, grand_child); CreateTransformNode(grand_child).local = grand_child_scale_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // The visible rect is expanded to integer coordinates. EXPECT_EQ(gfx::Rect(41, 41), grand_child->visible_layer_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder (creating expanding clip -// node for pixel-moving filter). -TEST_F(LayerTreeHostCommonTestWithLayerTree, - VisibleRectWithClippingAndFilters) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto clip = Layer::Create(); - root->AddChild(clip); - auto filter = Layer::Create(); - clip->AddChild(filter); - auto filter_child = Layer::Create(); - filter->AddChild(filter_child); - - root->SetBounds(gfx::Size(100, 100)); - clip->SetBounds(gfx::Size(10, 10)); - filter->SetForceRenderSurfaceForTesting(true); - filter_child->SetBounds(gfx::Size(2000, 2000)); - filter_child->SetPosition(gfx::PointF(-50, -50)); - filter_child->SetIsDrawable(true); - - clip->SetMasksToBounds(true); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(50, 50, 10, 10), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurfaceImpl(filter)->content_rect()); - - FilterOperations blur_filter; - blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->SetFilters(blur_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(38, 38, 34, 34), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-12, -12, 34, 34), - GetRenderSurfaceImpl(filter)->content_rect()); - - gfx::Transform vertical_flip; - vertical_flip.Scale(1, -1); - sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( - vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); - FilterOperations reflection_filter; - reflection_filter.Append( - FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( - SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); - filter->SetFilters(reflection_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(49, 39, 12, 21), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-1, -11, 12, 21), - GetRenderSurfaceImpl(filter)->content_rect()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder (creating expanding clip -// node for pixel-moving filter). -TEST_F(LayerTreeHostCommonTestWithLayerTree, - VisibleRectWithScalingClippingAndFilters) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto scale = Layer::Create(); - root->AddChild(scale); - auto clip = Layer::Create(); - scale->AddChild(clip); - auto filter = Layer::Create(); - clip->AddChild(filter); - auto filter_child = Layer::Create(); - filter->AddChild(filter_child); - - root->SetBounds(gfx::Size(100, 100)); - clip->SetBounds(gfx::Size(10, 10)); - filter->SetForceRenderSurfaceForTesting(true); - filter_child->SetBounds(gfx::Size(2000, 2000)); - filter_child->SetPosition(gfx::PointF(-50, -50)); - filter_child->SetIsDrawable(true); - - clip->SetMasksToBounds(true); - - gfx::Transform scale_transform; - scale_transform.Scale(3, 3); - scale->SetTransform(scale_transform); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(50, 50, 10, 10), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurfaceImpl(filter)->content_rect()); - - FilterOperations blur_filter; - blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); - filter->SetFilters(blur_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(38, 38, 34, 34), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-36, -36, 102, 102), - GetRenderSurfaceImpl(filter)->content_rect()); - - gfx::Transform vertical_flip; - vertical_flip.Scale(1, -1); - sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( - vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); - FilterOperations reflection_filter; - reflection_filter.Append( - FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( - SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); - filter->SetFilters(reflection_filter); - - CommitAndActivate(); - - EXPECT_EQ(gfx::Rect(49, 39, 12, 21), - ImplOf(filter_child)->visible_layer_rect()); - EXPECT_EQ(gfx::Rect(-1, -31, 32, 61), - GetRenderSurfaceImpl(filter)->content_rect()); -} - -TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParent) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipRectWithClipParent) { + LayerImpl* root = root_layer(); LayerImpl* clip = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(root); CreateClipNode(root); clip->SetBounds(gfx::Size(10, 10)); @@ -2800,7 +2224,7 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParent) { child2->SetDrawsContent(true); CopyProperties(clip, child2); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child1->is_clipped()); EXPECT_TRUE(child2->is_clipped()); @@ -2808,8 +2232,8 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClipParent) { EXPECT_EQ(gfx::Rect(10, 10), child2->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipRectWithClippedDescendantOfFilter) { + LayerImpl* root = root_layer(); LayerImpl* filter = AddLayer<LayerImpl>(); LayerImpl* clip = AddLayer<LayerImpl>(); LayerImpl* filter_grand_child = AddLayer<LayerImpl>(); @@ -2820,14 +2244,13 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { filter_grand_child->SetBounds(gfx::Size(20, 20)); filter_grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, filter); CreateEffectNode(filter).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(filter, clip); CreateClipNode(clip); CopyProperties(clip, filter_grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(filter_grand_child->is_clipped()); EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect()); @@ -2835,15 +2258,15 @@ TEST_F(LayerTreeHostCommonTest, ClipRectWithClippedDescendantOfFilter) { blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); SetFilter(filter, blur_filter); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(filter_grand_child->is_clipped()); EXPECT_EQ(gfx::Rect(10, 10), filter_grand_child->clip_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersInUnclippedRenderSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -2858,7 +2281,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -2869,7 +2291,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -2896,9 +2318,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, - VisibleContentRectsForClippedSurfaceWithEmptyClip) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleContentRectsForClippedSurfaceWithEmptyClip) { + LayerImpl* root = root_layer(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); LayerImpl* child3 = AddLayer<LayerImpl>(); @@ -2911,7 +2332,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child1); child1->SetOffsetToTransformParent(gfx::Vector2dF(5.f, 5.f)); CopyProperties(root, child2); @@ -2919,12 +2339,12 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(root, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - RenderSurfaceList render_surface_list_impl; // Now set the root render surface an empty clip. - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(), &render_surface_list_impl); + // Not using UpdateActiveTreeDrawProperties() because we want a special + // device viewport rect. + host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect()); + UpdateDrawProperties(host_impl()->active_tree()); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); ASSERT_TRUE(GetRenderSurface(root)); EXPECT_FALSE(root->is_clipped()); @@ -2940,9 +2360,9 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(empty, child3->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersWithUninvertibleTransform) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); root->SetBounds(gfx::Size(100, 100)); @@ -2953,11 +2373,10 @@ TEST_F(LayerTreeHostCommonTest, gfx::Transform uninvertible_matrix(0.0, 0.0, 0.0, 0.0, 0.0, 0.0); ASSERT_FALSE(uninvertible_matrix.IsInvertible()); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = uninvertible_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); EXPECT_TRUE(child->drawable_content_rect().IsEmpty()); @@ -2969,7 +2388,7 @@ TEST_F(LayerTreeHostCommonTest, ASSERT_FALSE(uninvertible_matrix.IsInvertible()); SetTransform(child, uninvertible_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); EXPECT_TRUE(child->drawable_content_rect().IsEmpty()); @@ -2981,15 +2400,15 @@ TEST_F(LayerTreeHostCommonTest, ASSERT_FALSE(uninvertible_matrix.IsInvertible()); SetTransform(child, uninvertible_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(child->visible_layer_rect().IsEmpty()); EXPECT_TRUE(child->drawable_content_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleContentRectForLayerWithUninvertibleDrawTransform) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -3005,7 +2424,6 @@ TEST_F(LayerTreeHostCommonTest, grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); auto& child_transform_node = CreateTransformNode(child); child_transform_node.flattens_inherited_transform = false; @@ -3018,7 +2436,7 @@ TEST_F(LayerTreeHostCommonTest, grand_child_transform_node.sorting_context_id = 1; grand_child_transform_node.local = rotation; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Though all layers have invertible transforms, matrix multiplication using // floating-point math makes the draw transform uninvertible. @@ -3030,7 +2448,7 @@ TEST_F(LayerTreeHostCommonTest, } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, OcclusionBySiblingOfTarget) { +TEST_F(DrawPropertiesTestWithLayerTree, OcclusionBySiblingOfTarget) { auto root = Layer::Create(); auto child = Layer::Create(); FakeContentLayerClient client; @@ -3069,7 +2487,6 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OcclusionBySiblingOfTarget) { host()->SetRootLayer(root); CommitAndActivate(); - host_impl()->active_tree()->UpdateDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ( GetRenderSurfaceImpl(surface)->draw_transform(), translate); @@ -3077,46 +2494,22 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OcclusionBySiblingOfTarget) { // surface_child's contents. Occlusion actual_occlusion = GetRenderSurfaceImpl(surface_child)->occlusion_in_content_space(); - Occlusion expected_occlusion(translate, SimpleEnclosedRegion(gfx::Rect()), + Occlusion expected_occlusion(translate, SimpleEnclosedRegion(), SimpleEnclosedRegion(gfx::Rect(200, 200))); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); - // Mask layer should have the same occlusion. + // Mask layer's occlusion is different because we create transform and render + // surface for it in layer tree mode. actual_occlusion = ImplOf(surface_child_mask)->draw_properties().occlusion_in_content_space; + expected_occlusion = Occlusion( + gfx::Transform(), SimpleEnclosedRegion(gfx::Rect(-20, -20, 200, 200)), + SimpleEnclosedRegion()); EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); } -// Needs layer tree mode: testing PropertyTreeBuilder (snapping transform for -// texture layer). -TEST_F(LayerTreeHostCommonTestWithLayerTree, TextureLayerSnapping) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = TextureLayer::CreateForMailbox(nullptr); - root->AddChild(child); - - root->SetBounds(gfx::Size(100, 100)); - child->SetBounds(gfx::Size(100, 100)); - child->SetIsDrawable(true); - gfx::Transform fractional_translate; - fractional_translate.Translate(10.5f, 20.3f); - child->SetTransform(fractional_translate); - - CommitAndActivate(); - - auto child_screen_space_transform = ImplOf(child)->ScreenSpaceTransform(); - EXPECT_NE(child_screen_space_transform, fractional_translate); - fractional_translate.RoundTranslationComponents(); - EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform, - fractional_translate); - gfx::RectF layer_bounds_in_screen_space = MathUtil::MapClippedRect( - child_screen_space_transform, gfx::RectF(gfx::SizeF(child->bounds()))); - EXPECT_EQ(layer_bounds_in_screen_space, gfx::RectF(11.f, 20.f, 100.f, 100.f)); -} - -TEST_F(LayerTreeHostCommonTest, - OcclusionForLayerWithUninvertibleDrawTransform) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, OcclusionForLayerWithUninvertibleDrawTransform) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); LayerImpl* occluding_child = AddLayer<LayerImpl>(); @@ -3137,7 +2530,6 @@ TEST_F(LayerTreeHostCommonTest, occluding_child->SetDrawsContent(true); occluding_child->SetContentsOpaque(true); - SetupRootProperties(root); CopyProperties(root, child); auto& child_transform_node = CreateTransformNode(child); child_transform_node.flattens_inherited_transform = false; @@ -3152,7 +2544,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(root, occluding_child); CreateTransformNode(occluding_child).flattens_inherited_transform = false; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Though all layers have invertible transforms, matrix multiplication using // floating-point math makes the draw transform uninvertible. @@ -3168,9 +2560,9 @@ TEST_F(LayerTreeHostCommonTest, .occlusion_in_content_space.GetUnoccludedContentRect(layer_bounds)); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForLayersInClippedRenderSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -3186,7 +2578,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -3198,7 +2589,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -3227,9 +2618,8 @@ TEST_F(LayerTreeHostCommonTest, } // Check that clipping does not propagate down surfaces. -TEST_F(LayerTreeHostCommonTest, - DrawableAndVisibleContentRectsForSurfaceHierarchy) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsForSurfaceHierarchy) { + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); @@ -3247,7 +2637,6 @@ TEST_F(LayerTreeHostCommonTest, child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface1); CreateEffectNode(render_surface1).render_surface_reason = @@ -3262,7 +2651,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface2, child3); child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface1)); ASSERT_TRUE(GetRenderSurface(render_surface2)); @@ -3298,9 +2687,9 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(125, 125, 50, 50), child3->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleRectsForClippedDescendantsOfUnclippedSurfaces) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); LayerImpl* child2 = AddLayer<LayerImpl>(); @@ -3318,7 +2707,6 @@ TEST_F(LayerTreeHostCommonTest, child1->SetMasksToBounds(true); child2->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, render_surface1); CreateEffectNode(render_surface1).render_surface_reason = RenderSurfaceReason::kTest; @@ -3330,14 +2718,14 @@ TEST_F(LayerTreeHostCommonTest, CreateEffectNode(render_surface2).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(100, 100), child1->visible_layer_rect()); EXPECT_EQ(gfx::Rect(100, 100), render_surface2->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleRectsWhenClipChildIsBetweenTwoRenderSurfaces) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -3346,7 +2734,6 @@ TEST_F(LayerTreeHostCommonTest, root->SetBounds(gfx::Size(100, 100)); clip_parent->SetBounds(gfx::Size(50, 50)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -3368,14 +2755,14 @@ TEST_F(LayerTreeHostCommonTest, CreateEffectNode(render_surface2).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(20, 20), render_surface1->visible_layer_rect()); EXPECT_EQ(gfx::Rect(50, 50), clip_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(50, 50), render_surface2->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); @@ -3386,7 +2773,6 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { clip_parent->SetBounds(gfx::Size(50, 50)); clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(2, 2)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -3416,18 +2802,19 @@ TEST_F(LayerTreeHostCommonTest, ClipRectOfSurfaceWhoseParentIsAClipChild) { RenderSurfaceReason::kTest; float device_scale_factor = 1.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(render_surface2)->clip_rect()); device_scale_factor = 2.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); + EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(render_surface2)->clip_rect()); } // Test that only drawn layers contribute to render surface content rect. -TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWhenLayerNotDrawn) { + LayerImpl* root = root_layer(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -3436,16 +2823,15 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { surface->SetDrawsContent(true); test_layer->SetBounds(gfx::Size(150, 150)); - SetupRootProperties(root); CopyProperties(root, surface); CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; CopyProperties(surface, test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(100, 100), GetRenderSurface(surface)->content_rect()); test_layer->SetDrawsContent(true); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(150, 150), GetRenderSurface(surface)->content_rect()); } @@ -3453,8 +2839,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWhenLayerNotDrawn) { // surface_with_unclipped_descendants->clipped_surface, checks that the bounds // of surface_with_unclipped_descendants doesn't propagate to the // clipped_surface below it. -TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleRectsMultipleSurfaces) { + LayerImpl* root = root_layer(); LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); @@ -3472,7 +2858,6 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { clipped_surface->SetBounds(gfx::Size(60, 60)); clipped_surface->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, unclipped_surface); CreateEffectNode(unclipped_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -3486,7 +2871,7 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { CreateEffectNode(clipped_surface).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), unclipped_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(20, 20), unclipped_desc_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(50, 50), clipped_surface->visible_layer_rect()); @@ -3495,8 +2880,8 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectsMultipleSurfaces) { // Tests visible rects computation when we have unclipped_surface-> // surface_with_unclipped_descendants->clipped_surface, checks that the bounds // of root propagate to the clipped_surface. -TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RootClipPropagationToClippedSurface) { + LayerImpl* root = root_layer(); LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* unclipped_desc_surface = AddLayer<LayerImpl>(); @@ -3512,9 +2897,7 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { clip_child->SetBounds(gfx::Size(100, 100)); clipped_surface->SetBounds(gfx::Size(50, 50)); clipped_surface->SetDrawsContent(true); - clipped_surface->test_properties()->force_render_surface = true; - SetupRootProperties(root); CopyProperties(root, unclipped_surface); CreateEffectNode(unclipped_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -3530,7 +2913,7 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { CreateEffectNode(clipped_surface).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), unclipped_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(10, 10), unclipped_desc_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(10, 10), clipped_surface->visible_layer_rect()); @@ -3538,9 +2921,9 @@ TEST_F(LayerTreeHostCommonTest, RootClipPropagationToClippedSurface) { // Layers that have non-axis aligned bounds (due to transforms) have an // expanded, axis-aligned DrawableContentRect and visible content rect. -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsWithTransformOnUnclippedSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); @@ -3552,7 +2935,6 @@ TEST_F(LayerTreeHostCommonTest, child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -3562,7 +2944,7 @@ TEST_F(LayerTreeHostCommonTest, child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f); child1_transform_node.local = child_rotation; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -3577,9 +2959,7 @@ TEST_F(LayerTreeHostCommonTest, // regions of the subtree. int diagonal_radius = ceil(sqrt(2.0) * 25.0); gfx::Rect expected_surface_drawable_content = - gfx::Rect(50 - diagonal_radius, - 50 - diagonal_radius, - diagonal_radius * 2, + gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2, diagonal_radius * 2); EXPECT_EQ(gfx::RectF(expected_surface_drawable_content), GetRenderSurface(render_surface)->DrawableContentRect()); @@ -3591,9 +2971,9 @@ TEST_F(LayerTreeHostCommonTest, // Layers that have non-axis aligned bounds (due to transforms) have an // expanded, axis-aligned DrawableContentRect and visible content rect. -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsWithTransformOnClippedSurface) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* child1 = AddLayer<LayerImpl>(); @@ -3606,7 +2986,6 @@ TEST_F(LayerTreeHostCommonTest, child1->SetBounds(gfx::Size(50, 50)); child1->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -3617,17 +2996,16 @@ TEST_F(LayerTreeHostCommonTest, child1_transform_node.post_translation = gfx::Vector2dF(25.f, 25.f); child1_transform_node.local = child_rotation; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(render_surface)); // The clipped surface clamps the DrawableContentRect that encloses the // rotated layer. int diagonal_radius = ceil(sqrt(2.0) * 25.0); - gfx::Rect unclipped_surface_content = gfx::Rect(50 - diagonal_radius, - 50 - diagonal_radius, - diagonal_radius * 2, - diagonal_radius * 2); + gfx::Rect unclipped_surface_content = + gfx::Rect(50 - diagonal_radius, 50 - diagonal_radius, diagonal_radius * 2, + diagonal_radius * 2); gfx::RectF expected_surface_drawable_content( gfx::IntersectRects(unclipped_surface_content, gfx::Rect(50, 50))); EXPECT_EQ(expected_surface_drawable_content, @@ -3642,8 +3020,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(unclipped_surface_content, child1->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, DrawableAndVisibleContentRectsInHighDPI) { + LayerImpl* root = root_layer(); FakePictureLayerImpl* render_surface1 = AddLayer<FakePictureLayerImpl>(); FakePictureLayerImpl* render_surface2 = AddLayer<FakePictureLayerImpl>(); FakePictureLayerImpl* child1 = AddLayer<FakePictureLayerImpl>(); @@ -3663,7 +3041,6 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { child3->SetBounds(gfx::Size(50, 50)); child3->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface1); CreateTransformNode(render_surface1).post_translation = @@ -3683,7 +3060,7 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { child3->SetOffsetToTransformParent(gfx::Vector2dF(125.f, 125.f)); float device_scale_factor = 2.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); ASSERT_TRUE(GetRenderSurface(render_surface1)); ASSERT_TRUE(GetRenderSurface(render_surface2)); @@ -3716,375 +3093,11 @@ TEST_F(LayerTreeHostCommonTest, DrawableAndVisibleContentRectsInHighDPI) { EXPECT_EQ(gfx::Rect(0, 0, 0, 0), child3->visible_layer_rect()); } -// Verify the behavior of back-face culling when there are no preserve-3d -// layers. Note that 3d transforms still apply in this case, but they are -// "flattened" to each parent layer according to current W3C spec. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - BackFaceCullingWithoutPreserves3d) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto front_facing_child = Layer::Create(); - root->AddChild(front_facing_child); - auto back_facing_child = Layer::Create(); - root->AddChild(back_facing_child); - auto front_facing_surface = Layer::Create(); - root->AddChild(front_facing_surface); - auto back_facing_surface = Layer::Create(); - root->AddChild(back_facing_surface); - auto front_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); - auto back_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); - auto front_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); - auto back_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - - // Nothing is double-sided - front_facing_child->SetDoubleSided(false); - back_facing_child->SetDoubleSided(false); - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - front_facing_child_of_front_facing_surface->SetDoubleSided(false); - back_facing_child_of_front_facing_surface->SetDoubleSided(false); - front_facing_child_of_back_facing_surface->SetDoubleSided(false); - back_facing_child_of_back_facing_surface->SetDoubleSided(false); - - // Everything draws content. - front_facing_child->SetIsDrawable(true); - back_facing_child->SetIsDrawable(true); - front_facing_surface->SetIsDrawable(true); - back_facing_surface->SetIsDrawable(true); - front_facing_child_of_front_facing_surface->SetIsDrawable(true); - back_facing_child_of_front_facing_surface->SetIsDrawable(true); - front_facing_child_of_back_facing_surface->SetIsDrawable(true); - back_facing_child_of_back_facing_surface->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - root->SetBounds(gfx::Size(100, 100)); - front_facing_child->SetBounds(gfx::Size(100, 100)); - back_facing_child->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - - front_facing_surface->SetForceRenderSurfaceForTesting(true); - back_facing_surface->SetForceRenderSurfaceForTesting(true); - - back_facing_child->SetTransform(backface_matrix); - back_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); - - // Note: No layers preserve 3d. According to current W3C CSS gfx::Transforms - // spec, these layers should blindly use their own local transforms to - // determine back-face culling. - CommitAndActivate(); - - // Verify which render surfaces were created. - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - - EXPECT_EQ(3u, update_layer_impl_list().size()); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerImplListContains( - front_facing_child_of_front_facing_surface->id())); -} - -// Verify the behavior of back-face culling when preserves-3d transform style -// is used. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, BackFaceCullingWithPreserves3d) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto front_facing_child = Layer::Create(); - root->AddChild(front_facing_child); - auto back_facing_child = Layer::Create(); - root->AddChild(back_facing_child); - auto front_facing_surface = Layer::Create(); - root->AddChild(front_facing_surface); - auto back_facing_surface = Layer::Create(); - root->AddChild(back_facing_surface); - auto front_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); - auto back_facing_child_of_front_facing_surface = Layer::Create(); - front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); - auto front_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); - auto back_facing_child_of_back_facing_surface = Layer::Create(); - back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); - // Opacity will not force creation of render surfaces in this case because of - // the preserve-3d transform style. Instead, an example of when a surface - // would be created with preserve-3d is when there is a mask layer. - FakeContentLayerClient client; - auto dummy_mask_layer1 = PictureLayer::Create(&client); - front_facing_surface->SetMaskLayer(dummy_mask_layer1); - auto dummy_mask_layer2 = PictureLayer::Create(&client); - back_facing_surface->SetMaskLayer(dummy_mask_layer2); - - // Nothing is double-sided - front_facing_child->SetDoubleSided(false); - back_facing_child->SetDoubleSided(false); - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - front_facing_child_of_front_facing_surface->SetDoubleSided(false); - back_facing_child_of_front_facing_surface->SetDoubleSided(false); - front_facing_child_of_back_facing_surface->SetDoubleSided(false); - back_facing_child_of_back_facing_surface->SetDoubleSided(false); - - // Everything draws content. - front_facing_child->SetIsDrawable(true); - back_facing_child->SetIsDrawable(true); - front_facing_surface->SetIsDrawable(true); - back_facing_surface->SetIsDrawable(true); - front_facing_child_of_front_facing_surface->SetIsDrawable(true); - back_facing_child_of_front_facing_surface->SetIsDrawable(true); - front_facing_child_of_back_facing_surface->SetIsDrawable(true); - back_facing_child_of_back_facing_surface->SetIsDrawable(true); - dummy_mask_layer1->SetIsDrawable(true); - dummy_mask_layer2->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - root->SetBounds(gfx::Size(100, 100)); - front_facing_child->SetBounds(gfx::Size(100, 100)); - back_facing_child->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); - dummy_mask_layer1->SetBounds(gfx::Size(100, 100)); - dummy_mask_layer2->SetBounds(gfx::Size(100, 100)); - - back_facing_child->SetTransform(backface_matrix); - back_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); - back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); - - // Each surface creates its own new 3d rendering context (as defined by W3C - // spec). According to current W3C CSS gfx::Transforms spec, layers in a 3d - // rendering context should use the transform with respect to that context. - // This 3d rendering context occurs when (a) parent's transform style is flat - // and (b) the layer's transform style is preserve-3d. - front_facing_surface->SetShouldFlattenTransform(false); - front_facing_surface->Set3dSortingContextId(1); - back_facing_surface->SetShouldFlattenTransform(false); - back_facing_surface->Set3dSortingContextId(1); - front_facing_child_of_front_facing_surface->Set3dSortingContextId(1); - back_facing_child_of_front_facing_surface->Set3dSortingContextId(1); - front_facing_child_of_back_facing_surface->Set3dSortingContextId(1); - back_facing_child_of_back_facing_surface->Set3dSortingContextId(1); - - CommitAndActivate(); - - // Verify which render surfaces were created and used. - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), - GetRenderSurfaceImpl(root)); - // We expect that a render surface was created but not used. - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), - GetRenderSurfaceImpl(back_facing_surface)); - - EXPECT_EQ(3u, update_layer_impl_list().size()); - - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerImplListContains( - front_facing_child_of_front_facing_surface->id())); -} - -// Verify that layers are appropriately culled when their back face is showing -// and they are not double sided, while animations are going on. -// Even layers that are animating get culled if their back face is showing and -// they are not double sided. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - BackFaceCullingWithAnimatingTransforms) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto animating_surface = Layer::Create(); - root->AddChild(animating_surface); - auto child_of_animating_surface = Layer::Create(); - animating_surface->AddChild(child_of_animating_surface); - auto animating_child = Layer::Create(); - root->AddChild(animating_child); - auto child2 = Layer::Create(); - root->AddChild(child2); - - // Nothing is double-sided - child->SetDoubleSided(false); - child2->SetDoubleSided(false); - animating_surface->SetDoubleSided(false); - child_of_animating_surface->SetDoubleSided(false); - animating_child->SetDoubleSided(false); - - // Everything draws content. - child->SetIsDrawable(true); - child2->SetIsDrawable(true); - animating_surface->SetIsDrawable(true); - child_of_animating_surface->SetIsDrawable(true); - animating_child->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - host()->SetElementIdsForTesting(); - - // Animate the transform on the render surface. - AddAnimatedTransformToElementWithAnimation(animating_surface->element_id(), - timeline(), 10.0, 30, 0); - // This is just an animating layer, not a surface. - AddAnimatedTransformToElementWithAnimation(animating_child->element_id(), - timeline(), 10.0, 30, 0); - - root->SetBounds(gfx::Size(100, 100)); - child->SetBounds(gfx::Size(100, 100)); - child->SetTransform(backface_matrix); - animating_surface->SetBounds(gfx::Size(100, 100)); - animating_surface->SetTransform(backface_matrix); - animating_surface->SetForceRenderSurfaceForTesting(true); - child_of_animating_surface->SetBounds(gfx::Size(100, 100)); - child_of_animating_surface->SetTransform(backface_matrix); - animating_child->SetBounds(gfx::Size(100, 100)); - animating_child->SetTransform(backface_matrix); - child2->SetBounds(gfx::Size(100, 100)); - - CommitAndActivate(); - - EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_TRUE(GetRenderSurfaceImpl(animating_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(child_of_animating_surface), - GetRenderSurfaceImpl(animating_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(animating_child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); - - EXPECT_EQ(1u, update_layer_impl_list().size()); - - // The back facing layers are culled from the layer list, and have an empty - // visible rect. - EXPECT_TRUE(UpdateLayerImplListContains(child2->id())); - EXPECT_TRUE(ImplOf(child)->visible_layer_rect().IsEmpty()); - EXPECT_TRUE(ImplOf(animating_surface)->visible_layer_rect().IsEmpty()); - EXPECT_TRUE( - ImplOf(child_of_animating_surface)->visible_layer_rect().IsEmpty()); - EXPECT_TRUE(ImplOf(animating_child)->visible_layer_rect().IsEmpty()); - - EXPECT_EQ(gfx::Rect(100, 100), ImplOf(child2)->visible_layer_rect()); -} - -// Verify the behavior of back-face culling for a render surface that is -// created when it flattens its subtree, and its parent has preserves-3d. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - BackFaceCullingWithPreserves3dForFlatteningSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto front_facing_surface = Layer::Create(); - root->AddChild(front_facing_surface); - auto back_facing_surface = Layer::Create(); - root->AddChild(back_facing_surface); - auto child1 = Layer::Create(); - front_facing_surface->AddChild(child1); - auto child2 = Layer::Create(); - back_facing_surface->AddChild(child2); - - // RenderSurfaces are not double-sided - front_facing_surface->SetDoubleSided(false); - back_facing_surface->SetDoubleSided(false); - - // Everything draws content. - front_facing_surface->SetIsDrawable(true); - back_facing_surface->SetIsDrawable(true); - child1->SetIsDrawable(true); - child2->SetIsDrawable(true); - - gfx::Transform backface_matrix; - backface_matrix.Translate(50.0, 50.0); - backface_matrix.RotateAboutYAxis(180.0); - backface_matrix.Translate(-50.0, -50.0); - - root->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetBounds(gfx::Size(100, 100)); - front_facing_surface->SetForceRenderSurfaceForTesting(true); - back_facing_surface->SetBounds(gfx::Size(100, 100)); - back_facing_surface->SetTransform(backface_matrix); - back_facing_surface->SetForceRenderSurfaceForTesting(true); - child1->SetBounds(gfx::Size(100, 100)); - child2->SetBounds(gfx::Size(100, 100)); - - front_facing_surface->Set3dSortingContextId(1); - back_facing_surface->Set3dSortingContextId(1); - - CommitAndActivate(); - - // Verify which render surfaces were created and used. - EXPECT_TRUE(GetRenderSurfaceImpl(front_facing_surface)); - - // We expect the render surface to have been created, but remain unused. - EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), - GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child1), - GetRenderSurfaceImpl(front_facing_surface)); - EXPECT_EQ(GetRenderSurfaceImpl(child2), - GetRenderSurfaceImpl(back_facing_surface)); - - EXPECT_EQ(2u, update_layer_impl_list().size()); - EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerImplListContains(child1->id())); -} - -using LayerTreeHostCommonScalingTest = LayerTreeHostCommonTest; +using DrawPropertiesScalingTest = DrawPropertiesTest; // Verify draw and screen space transforms of layers not in a surface. -TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesScalingTest, LayerTransformsInHighDPI) { + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); @@ -4098,19 +3111,18 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { float device_scale_factor = 2.5f; - SetupRootProperties(root); CopyProperties(root, child); child->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); CopyProperties(root, child2); child2->SetOffsetToTransformParent(gfx::Vector2dF(2.f, 2.f)); - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_FLOAT_EQ(device_scale_factor, root->GetIdealContentsScale()); EXPECT_FLOAT_EQ(device_scale_factor, child->GetIdealContentsScale()); EXPECT_FLOAT_EQ(device_scale_factor, child2->GetIdealContentsScale()); - EXPECT_EQ(1u, render_surface_list_impl()->size()); + EXPECT_EQ(1u, GetRenderSurfaceList().size()); // Verify root transforms gfx::Transform expected_root_transform; @@ -4171,7 +3183,7 @@ TEST_F(LayerTreeHostCommonScalingTest, LayerTransformsInHighDPI) { } // Verify draw and screen space transforms of layers in a surface. -TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { +TEST_F(DrawPropertiesScalingTest, SurfaceLayerTransformsInHighDPI) { gfx::Transform perspective_matrix; perspective_matrix.ApplyPerspectiveDepth(2.0); gfx::Vector2dF perspective_surface_offset(2.f, 2.f); @@ -4179,11 +3191,9 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { gfx::Transform scale_small_matrix; scale_small_matrix.Scale(SK_MScalar1 / 10.f, SK_MScalar1 / 12.f); - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); - - LayerImpl* page_scale = AddLayer<LayerImpl>(); - page_scale->SetBounds(gfx::Size(100, 100)); + SetupViewport(root, gfx::Size(100, 100), gfx::Size(100, 100)); LayerImpl* parent = AddLayer<LayerImpl>(); parent->SetBounds(gfx::Size(100, 100)); @@ -4197,11 +3207,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { scale_surface->SetBounds(gfx::Size(10, 10)); scale_surface->SetDrawsContent(true); - SetupRootProperties(root); - CopyProperties(root, page_scale); - auto& page_scale_transform_node = CreateTransformNode(page_scale); - page_scale_transform_node.in_subtree_of_page_scale_layer = true; - CopyProperties(page_scale, parent); + CopyProperties(OuterViewportScrollLayer(), parent); CopyProperties(parent, perspective_surface); auto& perspective_surface_transform = CreateTransformNode(perspective_surface); @@ -4218,15 +3224,9 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { float device_scale_factor = 2.5f; float page_scale_factor = 3.f; - const gfx::Transform kDeviceTransform; - - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale->id(); - root->layer_tree_impl()->SetViewportLayersFromIds(viewport_ids); - root->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale_factor); + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - ExecuteCalculateDrawProperties(root, device_scale_factor, kDeviceTransform, - page_scale_factor, page_scale); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, parent->GetIdealContentsScale()); @@ -4248,11 +3248,10 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { gfx::Vector2dF target_space_transform_scales = MathUtil::ComputeTransform2dScaleComponents( scale_surface->draw_properties().target_space_transform, 0.f); - EXPECT_FLOAT_EQ(max_2d_scale, - std::max(target_space_transform_scales.x(), - target_space_transform_scales.y())); + EXPECT_FLOAT_EQ(max_2d_scale, std::max(target_space_transform_scales.x(), + target_space_transform_scales.y())); - EXPECT_EQ(3u, render_surface_list_impl()->size()); + EXPECT_EQ(3u, GetRenderSurfaceList().size()); gfx::Transform expected_parent_draw_transform; expected_parent_draw_transform.Scale(device_scale_factor * page_scale_factor, @@ -4282,7 +3281,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { perspective_surface->DrawTransform()); } -TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { +TEST_F(DrawPropertiesScalingTest, SmallIdealScale) { gfx::Transform parent_scale_matrix; SkMScalar initial_parent_scale = 1.75; parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); @@ -4291,7 +3290,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { SkMScalar initial_child_scale = 0.25; child_scale_matrix.Scale(initial_child_scale, initial_child_scale); - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); LayerImpl* page_scale = AddLayer<LayerImpl>(); @@ -4307,9 +3306,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { float device_scale_factor = 2.5f; float page_scale_factor = 0.01f; - const gfx::Transform kDeviceTransform; - SetupRootProperties(root); CopyProperties(root, page_scale); CreateTransformNode(page_scale).in_subtree_of_page_scale_layer = true; CopyProperties(page_scale, parent); @@ -4317,8 +3314,13 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { CopyProperties(parent, child_scale); CreateTransformNode(child_scale).local = child_scale_matrix; - ExecuteCalculateDrawProperties(root, device_scale_factor, kDeviceTransform, - page_scale_factor, page_scale); + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale->transform_tree_index(); + host_impl()->active_tree()->SetViewportPropertyIds(viewport_property_ids); + + host_impl()->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // The ideal scale is able to go below 1. float expected_ideal_scale = @@ -4332,7 +3334,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { EXPECT_FLOAT_EQ(expected_ideal_scale, child_scale->GetIdealContentsScale()); } -TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { +TEST_F(DrawPropertiesScalingTest, IdealScaleForAnimatingLayer) { gfx::Transform parent_scale_matrix; SkMScalar initial_parent_scale = 1.75; parent_scale_matrix.Scale(initial_parent_scale, initial_parent_scale); @@ -4341,7 +3343,7 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { SkMScalar initial_child_scale = 1.25; child_scale_matrix.Scale(initial_child_scale, initial_child_scale); - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); LayerImpl* parent = AddLayer<LayerImpl>(); @@ -4352,13 +3354,12 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { child_scale->SetBounds(gfx::Size(10, 10)); child_scale->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); CreateTransformNode(parent).local = parent_scale_matrix; CopyProperties(parent, child_scale); CreateTransformNode(child_scale).local = child_scale_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FLOAT_EQ(initial_parent_scale, parent->GetIdealContentsScale()); // Animating layers compute ideal scale in the same way as when @@ -4367,8 +3368,8 @@ TEST_F(LayerTreeHostCommonScalingTest, IdealScaleForAnimatingLayer) { child_scale->GetIdealContentsScale()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { - LayerImpl* parent = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, RenderSurfaceTransformsInHighDPI) { + LayerImpl* parent = root_layer(); parent->SetBounds(gfx::Size(30, 30)); parent->SetDrawsContent(true); @@ -4385,7 +3386,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { float device_scale_factor = 1.5f; gfx::Vector2dF child_offset(2.f, 2.f); - SetupRootProperties(parent); CopyProperties(parent, child); CreateTransformNode(child).post_translation = child_offset; CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; @@ -4393,11 +3393,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { duplicate_child_non_owner->SetOffsetToTransformParent( child->offset_to_transform_parent()); - ExecuteCalculateDrawProperties(parent, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // We should have two render surfaces. The root's render surface and child's // render surface (it needs one because of force_render_surface). - EXPECT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(2u, GetRenderSurfaceList().size()); gfx::Transform expected_parent_transform; expected_parent_transform.Scale(device_scale_factor, device_scale_factor); @@ -4450,9 +3450,9 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceTransformsInHighDPI) { GetRenderSurface(child)->screen_space_transform()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, RenderSurfaceTransformsInHighDPIAccurateScaleZeroPosition) { - LayerImpl* parent = root_layer_for_testing(); + LayerImpl* parent = root_layer(); parent->SetBounds(gfx::Size(33, 31)); parent->SetDrawsContent(true); @@ -4462,15 +3462,14 @@ TEST_F(LayerTreeHostCommonTest, float device_scale_factor = 1.7f; - SetupRootProperties(parent); CopyProperties(parent, child); CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(parent, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); // We should have two render surfaces. The root's render surface and child's // render surface (it needs one because of force_render_surface). - EXPECT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(2u, GetRenderSurfaceList().size()); EXPECT_TRANSFORMATION_MATRIX_EQ(gfx::Transform(), GetRenderSurface(child)->draw_transform()); @@ -4481,7 +3480,7 @@ TEST_F(LayerTreeHostCommonTest, } // Needs layer tree mode: mask layer. Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, LayerSearch) { +TEST_F(DrawPropertiesTestWithLayerTree, LayerSearch) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child = Layer::Create(); scoped_refptr<Layer> grand_child = Layer::Create(); @@ -4502,8 +3501,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, LayerSearch) { EXPECT_FALSE(host()->LayerById(nonexistent_id)); } -TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransparentChildRenderSurfaceCreation) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -4512,16 +3511,15 @@ TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { grand_child->SetBounds(gfx::Size(10, 10)); grand_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateEffectNode(child).opacity = 0.5f; CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(GetRenderSurface(child), GetRenderSurface(root)); } -TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { +TEST_F(DrawPropertiesTest, OpacityAnimatingOnPendingTree) { host_impl()->CreatePendingTree(); LayerImpl* root = EnsureRootLayerInPendingTree(); root->SetBounds(gfx::Size(100, 100)); @@ -4532,7 +3530,6 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { child->SetDrawsContent(true); host_impl()->pending_tree()->SetElementIdsForTesting(); - SetupRootProperties(root); CopyProperties(root, child); CreateEffectNode(child).opacity = 0.0f; @@ -4540,17 +3537,17 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { AddOpacityTransitionToElementWithAnimation( child->element_id(), timeline_impl(), 10.0, 0.0f, 1.0f, false); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); // We should have one render surface and two layers. The child // layer should be included even though it is transparent. - ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(1u, host_impl()->pending_tree()->GetRenderSurfaceList().size()); ASSERT_EQ(2, GetRenderSurface(root)->num_contributors()); // If the root itself is hidden, the child should not be drawn even if it has // an animating opacity. SetOpacity(root, 0.0f); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); EXPECT_FALSE(GetEffectNode(child)->is_drawn); @@ -4558,7 +3555,7 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { // it has animating opacity even if it has opacity 0. SetOpacity(root, 1.0f); SetOpacity(child, 0.0f); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); EXPECT_TRUE(GetEffectNode(child)->is_drawn); EXPECT_TRUE(GetPropertyTrees(root)->effect_tree.ContributesToDrawnSurface( @@ -4568,13 +3565,12 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { // be drawn. host_impl()->ActivateSyncTree(); LayerTreeImpl* active_tree = host_impl()->active_tree(); - LayerImpl* active_root = active_tree->LayerById(root->id()); LayerImpl* active_child = active_tree->LayerById(child->id()); EffectTree& active_effect_tree = active_tree->property_trees()->effect_tree; EXPECT_TRUE(active_effect_tree.needs_update()); - ExecuteCalculateDrawProperties(active_root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(GetEffectNode(active_child)->is_drawn); EXPECT_FALSE(active_effect_tree.ContributesToDrawnSurface( @@ -4582,10 +3578,10 @@ TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { } using LCDTextTestParam = std::tuple<bool, bool>; -class LCDTextTest : public LayerTreeHostCommonTestBase, +class LCDTextTest : public DrawPropertiesTestBase, public testing::TestWithParam<LCDTextTestParam> { public: - LCDTextTest() : LayerTreeHostCommonTestBase(LCDTextTestLayerTreeSettings()) {} + LCDTextTest() : DrawPropertiesTestBase(LCDTextTestLayerTreeSettings()) {} protected: LayerTreeSettings LCDTextTestLayerTreeSettings() { @@ -4599,7 +3595,7 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, } void SetUp() override { - root_ = root_layer_for_testing(); + root_ = root_layer(); child_ = AddLayer<LayerImpl>(); grand_child_ = AddLayer<LayerImpl>(); SetElementIdsForTesting(); @@ -4616,7 +3612,6 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, child_->SetBounds(gfx::Size(1, 1)); grand_child_->SetBounds(gfx::Size(1, 1)); - SetupRootProperties(root_); CopyProperties(root_, child_); CreateTransformNode(child_); CreateEffectNode(child_).render_surface_reason = RenderSurfaceReason::kTest; @@ -4636,7 +3631,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Case 1: Identity transform. - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4646,7 +3641,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { integral_translation.Translate(1.0, 2.0); SetTransform(child_, integral_translation); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4655,7 +3650,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform non_integral_translation; non_integral_translation.Translate(1.5, 2.5); SetTransform(child_, non_integral_translation); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4664,7 +3659,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform rotation; rotation.Rotate(10.0); SetTransform(child_, rotation); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4673,7 +3668,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform scale; scale.Scale(2.0, 2.0); SetTransform(child_, scale); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4682,7 +3677,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { gfx::Transform skew; skew.Skew(10.0, 0.0); SetTransform(child_, skew); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4690,7 +3685,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 7: Translucent. SetTransform(child_, gfx::Transform()); SetOpacity(child_, 0.5f); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -4698,28 +3693,28 @@ TEST_P(LCDTextTest, CanUseLCDText) { // Case 8: Sanity check: restore transform and opacity. SetTransform(child_, gfx::Transform()); SetOpacity(child_, 1.f); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 9: Non-opaque content. child_->SetContentsOpaque(false); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 10: Sanity check: restore content opaqueness. child_->SetContentsOpaque(true); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); // Case 11: will-change: transform child_->SetHasWillChangeTransformHint(true); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4730,7 +3725,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Sanity check: Make sure can_use_lcd_text_ is set on each node. - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4739,7 +3734,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { SetOpacity(child_, 0.9f); AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); // Text LCD should be adjusted while animation is active. EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); @@ -4751,7 +3746,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Sanity check: Make sure can_use_lcd_text_ is set on each node. - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4760,19 +3755,19 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) { child_->SetContentsOpaque(false); AddOpacityTransitionToElementWithAnimation(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_); + UpdateActiveTreeDrawProperties(); // LCD text should be disabled for non-opaque layers even during animations. EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); } -INSTANTIATE_TEST_SUITE_P(LayerTreeHostCommonTest, +INSTANTIATE_TEST_SUITE_P(DrawPropertiesTest, LCDTextTest, testing::Combine(testing::Bool(), testing::Bool())); // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4796,7 +3791,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { // We should have one render surface and two layers. The grand child has // hidden itself. - ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); EXPECT_TRUE(ImplOf(child)->contributes_to_drawn_render_surface()); @@ -4804,7 +3799,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_SingleLayerImpl) { } // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4826,7 +3821,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { // We should have one render surface and one layer. The child has // hidden itself and the grand child. - ASSERT_EQ(1u, render_surface_list_impl()->size()); + ASSERT_EQ(1u, GetRenderSurfaceList().size()); ASSERT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); EXPECT_TRUE(ImplOf(root)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); @@ -4834,7 +3829,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHidden_TwoLayersImpl) { } // Needs layer tree mode: mask layer, hide_layer_and_subtree and copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHiddenWithCopyRequest) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCopyRequest) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4900,15 +3895,15 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHiddenWithCopyRequest) { // We should have four render surfaces, one for the root, one for the grand // parent since it has opacity and two drawing descendants, one for the parent // since it owns a surface, and one for the copy_layer. - ASSERT_EQ(4u, render_surface_list_impl()->size()); + ASSERT_EQ(4u, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); EXPECT_EQ(static_cast<uint64_t>(copy_grand_parent->id()), - render_surface_list_impl()->at(1)->id()); + GetRenderSurfaceList().at(1)->id()); EXPECT_EQ(static_cast<uint64_t>(copy_parent->id()), - render_surface_list_impl()->at(2)->id()); + GetRenderSurfaceList().at(2)->id()); EXPECT_EQ(static_cast<uint64_t>(copy_layer->id()), - render_surface_list_impl()->at(3)->id()); + GetRenderSurfaceList().at(3)->id()); // The root render surface should have 2 contributing layers. EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); @@ -4948,7 +3943,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeHiddenWithCopyRequest) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, ClippedOutCopyRequest) { +TEST_F(DrawPropertiesTestWithLayerTree, ClippedOutCopyRequest) { auto root = Layer::Create(); root->SetBounds(gfx::Size(50, 50)); root->SetIsDrawable(true); @@ -4978,9 +3973,9 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, ClippedOutCopyRequest) { CommitAndActivate(); // We should have two render surface, as the others are clipped out. - ASSERT_EQ(2u, render_surface_list_impl()->size()); + ASSERT_EQ(2u, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); // The root render surface should have only 2 contributing layer, since the // other layers are clipped away. @@ -4989,7 +3984,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, ClippedOutCopyRequest) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SingularTransformAndCopyRequests) { +TEST_F(DrawPropertiesTestWithLayerTree, SingularTransformAndCopyRequests) { auto root = Layer::Create(); host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); @@ -5040,7 +4035,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SingularTransformAndCopyRequests) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, VisibleRectInNonRootCopyRequest) { +TEST_F(DrawPropertiesTestWithLayerTree, VisibleRectInNonRootCopyRequest) { auto root = Layer::Create(); host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); @@ -5105,12 +4100,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, VisibleRectInNonRootCopyRequest) { EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect()); // Case 3: When there is device scale factor. - float device_scale_factor = 2.f; + SetDeviceScaleAndUpdateViewportRect(host(), 2.f); copy_layer->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); ASSERT_TRUE(copy_layer->HasCopyRequest()); - CommitAndActivate(device_scale_factor); + CommitAndActivate(); ASSERT_FALSE(copy_layer->HasCopyRequest()); EXPECT_EQ(gfx::Rect(50, 50), ImplOf(copy_layer)->visible_layer_rect()); @@ -5120,7 +4115,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, VisibleRectInNonRootCopyRequest) { EXPECT_EQ(gfx::Rect(5, 5), ImplOf(copy_surface)->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { +TEST_F(DrawPropertiesTest, TransformedClipParent) { // Ensure that a transform between the layer and its render surface is not a // problem. Constructs the following layer tree. // @@ -5133,12 +4128,11 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { // // The render surface should be resized correctly and the clip child should // inherit the right clip rect. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(50, 50)); LayerImpl* render_surface = AddLayer<LayerImpl>(); render_surface->SetBounds(gfx::Size(10, 10)); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -5166,7 +4160,7 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { CopyProperties(intervening, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_TRUE(GetRenderSurface(root)); ASSERT_TRUE(GetRenderSurface(render_surface)); @@ -5190,7 +4184,7 @@ TEST_F(LayerTreeHostCommonTest, TransformedClipParent) { GetRenderSurface(render_surface)->content_rect())); } -TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { +TEST_F(DrawPropertiesTest, ClipParentWithInterveningRenderSurface) { // Ensure that intervening render surfaces are not a problem in the basic // case. In the following tree, both render surfaces should be resized to // accomodate for the clip child, despite an intervening clip. @@ -5203,7 +4197,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { // + render_surface2 (also sets opacity) // + clip_child (clipped by clip_parent) // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* intervening = AddLayer<LayerImpl>(); @@ -5214,7 +4208,6 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { clip_parent->SetBounds(gfx::Size(40, 40)); clip_parent->SetOffsetToTransformParent(gfx::Vector2dF(1, 1)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -5243,7 +4236,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { CopyProperties(render_surface2, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); EXPECT_TRUE(GetRenderSurface(render_surface1)); @@ -5285,7 +4278,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentWithInterveningRenderSurface) { EXPECT_FALSE(clip_child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { +TEST_F(DrawPropertiesTest, ClipParentScrolledInterveningLayer) { // Ensure that intervening render surfaces are not a problem, even if there // is a scroll involved. Note, we do _not_ have to consider any other sort // of transform. @@ -5298,7 +4291,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { // + render_surface2 (also has render surface) // + clip_child (clipped by clip_parent) // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* intervening = AddLayer<LayerImpl>(); @@ -5308,7 +4301,6 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { root->SetBounds(gfx::Size(50, 50)); clip_parent->SetBounds(gfx::Size(40, 40)); - SetupRootProperties(root); CopyProperties(root, clip_parent); auto& clip_parent_transform = CreateTransformNode(clip_parent); clip_parent_transform.local.Translate(2, 2); @@ -5343,7 +4335,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); SetScrollOffset(intervening, gfx::ScrollOffset(3, 3)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); EXPECT_TRUE(GetRenderSurface(render_surface1)); @@ -5384,7 +4376,7 @@ TEST_F(LayerTreeHostCommonTest, ClipParentScrolledInterveningLayer) { EXPECT_FALSE(clip_child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { +TEST_F(DrawPropertiesTest, DescendantsOfClipChildren) { // Ensures that descendants of the clip child inherit the correct clip. // // Virtual layer tree: @@ -5394,7 +4386,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { // + clip_child (clipped by clip_parent, skipping intervening) // + child // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* intervening = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -5403,7 +4395,6 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { root->SetBounds(gfx::Size(50, 50)); clip_parent->SetBounds(gfx::Size(40, 40)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); @@ -5420,7 +4411,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { child->SetBounds(gfx::Size(60, 60)); CopyProperties(clip_child, child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); @@ -5432,7 +4423,7 @@ TEST_F(LayerTreeHostCommonTest, DescendantsOfClipChildren) { EXPECT_TRUE(child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, SurfacesShouldBeUnaffectedByNonDescendantClipChildren) { // Ensures that non-descendant clip children in the tree do not affect // render surfaces. @@ -5446,7 +4437,7 @@ TEST_F(LayerTreeHostCommonTest, // + non_clip_child (in normal clip hierarchy) // // In this example render_surface2 should be unaffected by clip_child. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); @@ -5467,7 +4458,6 @@ TEST_F(LayerTreeHostCommonTest, non_clip_child->SetDrawsContent(true); non_clip_child->SetBounds(gfx::Size(5, 5)); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); CopyProperties(clip_parent, clip_layer); @@ -5484,7 +4474,7 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); CopyProperties(render_surface2, non_clip_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetRenderSurface(root)); EXPECT_TRUE(GetRenderSurface(render_surface1)); @@ -5515,171 +4505,8 @@ TEST_F(LayerTreeHostCommonTest, GetRenderSurface(render_surface2)->content_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - CreateRenderSurfaceWhenFlattenInsideRenderingContext) { - // Verifies that Render Surfaces are created at the edge of rendering context. - - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child1 = Layer::Create(); - root->AddChild(child1); - auto child2 = Layer::Create(); - child1->AddChild(child2); - auto child3 = Layer::Create(); - child2->AddChild(child3); - root->SetIsDrawable(true); - - gfx::Size bounds(100, 100); - - root->SetBounds(bounds); - child1->SetBounds(bounds); - child1->SetIsDrawable(true); - child1->SetShouldFlattenTransform(false); - child1->Set3dSortingContextId(1); - child2->SetBounds(bounds); - child2->SetIsDrawable(true); - child2->Set3dSortingContextId(1); - child3->SetBounds(bounds); - child3->SetIsDrawable(true); - child3->Set3dSortingContextId(1); - - CommitAndActivate(); - - // Verify which render surfaces were created. - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child1), GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(child3), GetRenderSurfaceImpl(child2)); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - DoNotIncludeBackfaceInvisibleSurfaces) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto back_facing = Layer::Create(); - root->AddChild(back_facing); - - auto render_surface1 = Layer::Create(); - back_facing->AddChild(render_surface1); - auto child1 = Layer::Create(); - render_surface1->AddChild(child1); - - auto flattener = Layer::Create(); - back_facing->AddChild(flattener); - auto render_surface2 = Layer::Create(); - flattener->AddChild(render_surface2); - auto child2 = Layer::Create(); - render_surface2->AddChild(child2); - - child1->SetIsDrawable(true); - child2->SetIsDrawable(true); - - root->SetBounds(gfx::Size(50, 50)); - back_facing->SetBounds(gfx::Size(50, 50)); - back_facing->SetShouldFlattenTransform(false); - - render_surface1->SetBounds(gfx::Size(30, 30)); - render_surface1->SetShouldFlattenTransform(false); - render_surface1->SetForceRenderSurfaceForTesting(true); - render_surface1->SetDoubleSided(false); - child1->SetBounds(gfx::Size(20, 20)); - - flattener->SetBounds(gfx::Size(30, 30)); - render_surface2->SetBounds(gfx::Size(30, 30)); - render_surface2->SetShouldFlattenTransform(false); - render_surface2->SetForceRenderSurfaceForTesting(true); - render_surface2->SetDoubleSided(false); - child2->SetBounds(gfx::Size(20, 20)); - - CommitAndActivate(); - - EXPECT_EQ(3u, render_surface_list_impl()->size()); - EXPECT_EQ(2, render_surface_list_impl()->at(0)->num_contributors()); - EXPECT_EQ(1, render_surface_list_impl()->at(1)->num_contributors()); - - gfx::Transform rotation_transform; - rotation_transform.RotateAboutXAxis(180.0); - back_facing->SetTransform(rotation_transform); - - CommitAndActivate(); - - // render_surface1 is in the same 3d rendering context as back_facing and is - // not double sided, so it should not be in RSLL. render_surface2 is also not - // double-sided, but will still be in RSLL as it's in a different 3d rendering - // context. - EXPECT_EQ(2u, render_surface_list_impl()->size()); - EXPECT_EQ(1, render_surface_list_impl()->at(0)->num_contributors()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - DoNotIncludeBackfaceInvisibleLayers) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grand_child = Layer::Create(); - child->AddChild(grand_child); - - root->SetBounds(gfx::Size(50, 50)); - root->SetShouldFlattenTransform(false); - child->SetBounds(gfx::Size(30, 30)); - child->SetDoubleSided(false); - child->SetShouldFlattenTransform(false); - grand_child->SetBounds(gfx::Size(20, 20)); - grand_child->SetIsDrawable(true); - grand_child->SetUseParentBackfaceVisibility(true); - grand_child->SetShouldFlattenTransform(false); - - CommitAndActivate(); - - EXPECT_EQ(1u, render_surface_list_impl()->size()); - EXPECT_TRUE(ImplOf(grand_child)->contributes_to_drawn_render_surface()); - - // A ll layers with invisible backfgaces should be checked. - EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); - - gfx::Transform rotation_transform; - rotation_transform.RotateAboutXAxis(180.0); - - child->SetTransform(rotation_transform); - child->Set3dSortingContextId(1); - grand_child->Set3dSortingContextId(1); - - CommitAndActivate(); - - EXPECT_EQ(1u, render_surface_list_impl()->size()); - EXPECT_EQ(0, render_surface_list_impl()->at(0)->num_contributors()); - - // We should check for backface visibilty of child as it has a rotation - // transform. We should also check for grand_child as it uses the backface - // visibility of its parent. - EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); - - grand_child->SetUseParentBackfaceVisibility(false); - grand_child->SetDoubleSided(false); - - CommitAndActivate(); - - EXPECT_EQ(1u, render_surface_list_impl()->size()); - EXPECT_EQ(0, render_surface_list_impl()->at(0)->num_contributors()); - - // We should check the backface visibility of child as it has a rotation - // transform and for grand_child as it is in a 3d rendering context and not - // the root of it. - EXPECT_FALSE(ImplOf(root)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(child)->should_check_backface_visibility()); - EXPECT_TRUE(ImplOf(grand_child)->should_check_backface_visibility()); -} - -TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TransformAnimationUpdatesBackfaceVisibility) { + LayerImpl* root = root_layer(); LayerImpl* back_facing = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); @@ -5693,7 +4520,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { render_surface2->SetBounds(gfx::Size(30, 30)); SetElementIdsForTesting(); - SetupRootProperties(root); CopyProperties(root, back_facing); auto& back_facing_transform_node = CreateTransformNode(back_facing); back_facing_transform_node.flattens_inherited_transform = false; @@ -5716,7 +4542,7 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { RenderSurfaceReason::kTest; render_surface2_effect_node.double_sided = false; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); @@ -5725,21 +4551,21 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationUpdatesBackfaceVisibility) { gfx::Transform()); root->layer_tree_impl()->SetTransformMutated(render_surface2->element_id(), rotate_about_y); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FALSE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); root->layer_tree_impl()->SetTransformMutated(render_surface1->element_id(), rotate_about_y); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(GetEffectNode(render_surface1)->hidden_by_backface_visibility); EXPECT_TRUE(GetEffectNode(render_surface2)->hidden_by_backface_visibility); } -TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { +TEST_F(DrawPropertiesTest, ScrollChildAndScrollParentDifferentTargets) { // Tests the computation of draw transform for the scroll child when its // render surface is different from its scroll parent's render surface. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* scroll_child_target = AddLayer<LayerImpl>(); LayerImpl* scroll_child = AddLayer<LayerImpl>(); LayerImpl* scroll_parent_target = AddLayer<LayerImpl>(); @@ -5753,7 +4579,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { scroll_child->SetBounds(gfx::Size(50, 50)); scroll_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, scroll_child_target); auto& child_target_effect_node = CreateEffectNode(scroll_child_target); child_target_effect_node.render_surface_reason = RenderSurfaceReason::kTest; @@ -5772,19 +4597,18 @@ TEST_F(LayerTreeHostCommonTest, ScrollChildAndScrollParentDifferentTargets) { scroll_child->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10)); float device_scale_factor = 1.5f; - ExecuteCalculateDrawProperties(root, device_scale_factor); - + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(scroll_child->effect_tree_index(), scroll_child_target->effect_tree_index()); EXPECT_EQ(scroll_child->visible_layer_rect(), gfx::Rect(10, 10, 40, 40)); EXPECT_EQ(scroll_child->clip_rect(), gfx::Rect(15, 15, 75, 75)); gfx::Transform scale; - scale.Scale(1.5f, 1.5f); + scale.Scale(device_scale_factor, device_scale_factor); EXPECT_TRANSFORMATION_MATRIX_EQ(scroll_child->DrawTransform(), scale); } -TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, SingularTransformSubtreesDoNotDraw) { + LayerImpl* root = root_layer(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -5795,7 +4619,6 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { child->SetBounds(gfx::Size(20, 20)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, parent); CreateTransformNode(parent).sorting_context_id = 1; CreateEffectNode(parent).render_surface_reason = RenderSurfaceReason::kTest; @@ -5803,29 +4626,29 @@ TEST_F(LayerTreeHostCommonTest, SingularTransformSubtreesDoNotDraw) { CreateTransformNode(child).sorting_context_id = 1; CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - EXPECT_EQ(3u, render_surface_list_impl()->size()); + EXPECT_EQ(3u, GetRenderSurfaceList().size()); gfx::Transform singular_transform; - singular_transform.Scale3d( - SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), SkDoubleToMScalar(0.0)); + singular_transform.Scale3d(SkDoubleToMScalar(1.0), SkDoubleToMScalar(1.0), + SkDoubleToMScalar(0.0)); SetTransform(child, singular_transform); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - EXPECT_EQ(2u, render_surface_list_impl()->size()); + EXPECT_EQ(2u, GetRenderSurfaceList().size()); // Ensure that the entire subtree under a layer with singular transform does // not get rendered. SetTransform(parent, singular_transform); SetTransform(child, gfx::Transform()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); - EXPECT_EQ(1u, render_surface_list_impl()->size()); + EXPECT_EQ(1u, GetRenderSurfaceList().size()); } -TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { +TEST_F(DrawPropertiesTest, ScrollSnapping) { // This test verifies that a scrolling layer gets scroll offset snapped to // integer coordinates. // @@ -5834,7 +4657,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { // + container // + scroller // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* container = AddLayer<LayerImpl>(); LayerImpl* scroller = AddLayer<LayerImpl>(); @@ -5842,7 +4665,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { container->SetBounds(gfx::Size(40, 40)); container->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, container); gfx::Vector2dF container_offset(10, 20); @@ -5859,7 +4681,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { { gfx::Vector2dF scroll_delta(3.0, 5.0); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR_EQ( scroller->draw_properties().screen_space_transform.To2dTranslation(), @@ -5870,7 +4692,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { { gfx::Vector2dF scroll_delta(4.1f, 8.1f); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Vector2dF rounded_scroll_delta(4.f, 8.f); EXPECT_VECTOR_EQ( @@ -5879,8 +4701,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnapping) { } } -TEST_F(LayerTreeHostCommonTest, - ScrollSnappingWithAnimatedScreenSpaceTransform) { +TEST_F(DrawPropertiesTest, ScrollSnappingWithAnimatedScreenSpaceTransform) { // This test verifies that a scrolling layer whose screen space transform is // animating doesn't get snapped to integer coordinates. // @@ -5891,7 +4712,7 @@ TEST_F(LayerTreeHostCommonTest, // + container // + scroller // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* animated_layer = AddLayer<FakePictureLayerImpl>(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* container = AddLayer<LayerImpl>(); @@ -5904,7 +4725,6 @@ TEST_F(LayerTreeHostCommonTest, start_scale.Scale(1.5f, 1.5f); animated_layer->SetBounds(gfx::Size(50, 50)); - SetupRootProperties(root); CopyProperties(root, animated_layer); CreateTransformNode(animated_layer).local = start_scale; @@ -5936,14 +4756,14 @@ TEST_F(LayerTreeHostCommonTest, gfx::Vector2dF scroll_delta(5.f, 9.f); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Vector2dF expected_draw_transform_translation(-7.5f, -13.5f); EXPECT_VECTOR2DF_EQ(expected_draw_transform_translation, scroller->DrawTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { +TEST_F(DrawPropertiesTest, ScrollSnappingWithScrollChild) { // This test verifies that a scrolling child of a scrolling layer doesn't get // snapped to integer coordinates. // @@ -5953,7 +4773,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { // + scroller // + scroll_child (transform parent is scroller) // - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* container = AddLayer<LayerImpl>(); LayerImpl* scroller = AddLayer<LayerImpl>(); LayerImpl* scroll_child = AddLayer<LayerImpl>(); @@ -5962,7 +4782,6 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { root->SetBounds(gfx::Size(50, 50)); container->SetBounds(gfx::Size(50, 50)); - SetupRootProperties(root); CopyProperties(root, container); gfx::Vector2dF container_offset(10.3f, 10.3f); @@ -5981,7 +4800,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { gfx::Vector2dF scroll_delta(5.f, 9.f); SetScrollOffsetDelta(scroller, scroll_delta); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Vector2dF expected_scroller_screen_space_transform_translation(5.f, 1.f); EXPECT_VECTOR2DF_EQ(expected_scroller_screen_space_transform_translation, @@ -5994,7 +4813,7 @@ TEST_F(LayerTreeHostCommonTest, ScrollSnappingWithScrollChild) { scroll_child->ScreenSpaceTransform()); } -class LayerTreeHostCommonStickyPositionTest : public LayerTreeHostCommonTest { +class DrawPropertiesStickyPositionTest : public DrawPropertiesTest { protected: // Setup layers and property trees. // Virtual layer hierarchy: @@ -6041,11 +4860,11 @@ class LayerTreeHostCommonStickyPositionTest : public LayerTreeHostCommonTest { } void CommitAndUpdateImplPointers() { - ExecuteCalculateDrawProperties(root_.get()); - host()->host_impl()->CreatePendingTree(); + UpdateMainDrawProperties(); + host_impl()->CreatePendingTree(); host()->CommitAndCreatePendingTree(); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + host_impl()->ActivateSyncTree(); + LayerTreeImpl* layer_tree_impl = host_impl()->active_tree(); root_impl_ = layer_tree_impl->LayerById(root_->id()); scroller_impl_ = layer_tree_impl->LayerById(scroller_->id()); sticky_pos_impl_ = layer_tree_impl->LayerById(sticky_pos_->id()); @@ -6065,7 +4884,7 @@ class LayerTreeHostCommonStickyPositionTest : public LayerTreeHostCommonTest { LayerImpl* sticky_pos_impl_; }; -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionTop) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20)); @@ -6087,19 +4906,19 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) { // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(5.f, 15.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6107,13 +4926,13 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionTop) { // Scroll past the end of the sticky container (note: this element does not // have its own layer as it does not need to be composited). SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, -10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionSubpixelScroll) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionSubpixelScroll) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 200)); @@ -6130,13 +4949,13 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionSubpixelScroll) { SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.8f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionBottom) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 150)); @@ -6157,7 +4976,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) { sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 95.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6165,25 +4984,25 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionBottom) { // Once we get past the top of the container it moves to be aligned 10px // up from the the bottom of the scroller. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 80.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Once we scroll past its initial location, it sticks there. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 150.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionBottomOuterViewportDelta) { CreateTree(); @@ -6214,7 +5033,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, GetPropertyTrees(scroller_impl_) ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -10.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 70.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6222,7 +5041,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, // On hiding more of the toolbar the sticky element starts to stick. GetPropertyTrees(scroller_impl_) ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -20.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); // On hiding more the sticky element stops moving as it has reached its // limit. @@ -6232,14 +5051,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, GetPropertyTrees(scroller_impl_) ->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(0.f, -30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 60.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionLeftRight) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(145, 0)); @@ -6258,12 +5077,12 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // Initially the sticky element is moved the leftmost side of the container. - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(100.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(95.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6271,12 +5090,12 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // Once we get past the left side of the container it moves to be aligned 10px // up from the the right of the scroller. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(25.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(80.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(30.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(80.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6284,36 +5103,36 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // When we get to the sticky element's original position we stop sticking // to the right. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(95.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(50.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(105.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(40.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // The element starts sticking to the left once we scroll far enough. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(150.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(10.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(155.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(10.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Finally it stops sticking when it hits the right side of the container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(190.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(195.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6322,7 +5141,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionLeftRight) { // This test ensures that the compositor sticky position code correctly accounts // for the element having been given a position from the main thread sticky // position code. -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionMainThreadUpdates) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(10, 20)); @@ -6344,14 +5163,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(5.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(5.f, 15.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(15.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6369,14 +5188,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { // (0, 0) because we have synced a scroll offset of (15, 15) from the main // thread. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And if we scroll a little further it remains there. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(-5.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6385,8 +5204,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionMainThreadUpdates) { // This tests the main thread updates with a composited sticky container. In // this case the position received from main is relative to the container but // the constraint rects are relative to the ancestor scroller. -TEST_F(LayerTreeHostCommonStickyPositionTest, - StickyPositionCompositedContainer) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionCompositedContainer) { CreateRootAndScroller(); scoped_refptr<Layer> sticky_container = Layer::Create(); @@ -6416,14 +5234,14 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 25.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the sticking point, the Y coordinate should now be clamped. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6440,28 +5258,28 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, // (0, 0) because we have synced a scroll offset of (0, 25) from the main // thread. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 0.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And if we scroll a little further it remains there. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // And hits the bottom of the container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 10.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(20.f, 5.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } // A transform on a sticky element should not affect its sticky position. -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledStickyBox) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 20)); @@ -6487,7 +5305,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 5.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6495,19 +5313,19 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { // Scroll past the sticking point, the box is positioned at the scroller // edge. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 0.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the end of the sticky container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, -10.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6515,7 +5333,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledStickyBox) { // Tests that a transform does not affect the sticking points. The sticky // element will however move relative to the viewport due to its transform. -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionScaledContainer) { CreateRootAndScroller(); scoped_refptr<Layer> sticky_container = Layer::Create(); @@ -6543,7 +5361,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) { // Scroll less than sticking point, sticky element should move with scroll as // we haven't gotten to the initial sticky item location yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 15.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 25.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); @@ -6551,25 +5369,25 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionScaledContainer) { // Scroll past the sticking point, the box is positioned at the scroller // edge but is also scaled by its container so it begins to move down. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 25.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 25.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 30.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); // Scroll past the end of the sticky container. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 50.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 30.f), sticky_pos_impl_->ScreenSpaceTransform().To2dTranslation()); } -TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { +TEST_F(DrawPropertiesStickyPositionTest, StickyPositionNested) { CreateTree(); SetPostTranslation(sticky_pos_.get(), gfx::Vector2dF(0, 50)); @@ -6609,7 +5427,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { // Scroll less than the sticking point. Both sticky elements should move with // scroll as we haven't gotten to the sticky item locations yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 5.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 45.f), outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); @@ -6620,7 +5438,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { // Scroll such that the inner sticky should stick, but the outer one should // keep going as it hasn't reached its position yet. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 30.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 20.f), outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); @@ -6630,7 +5448,7 @@ TEST_F(LayerTreeHostCommonStickyPositionTest, StickyPositionNested) { // Keep going, both should stick. SetScrollOffsetDelta(scroller_impl_, gfx::Vector2dF(0.f, 100.f)); - ExecuteCalculateDrawProperties(root_impl_); + UpdateActiveTreeDrawProperties(); EXPECT_VECTOR2DF_EQ( gfx::Vector2dF(0.f, 10.f), outer_sticky_impl->ScreenSpaceTransform().To2dTranslation()); @@ -6658,8 +5476,8 @@ class AnimationScaleFactorTrackingLayerImpl : public LayerImpl { } }; -TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, MaximumAnimationScaleFactor) { + LayerImpl* root = root_layer(); auto* grand_parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); auto* parent = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); auto* child = AddLayer<AnimationScaleFactorTrackingLayerImpl>(); @@ -6672,7 +5490,6 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { child->SetBounds(gfx::Size(1, 2)); grand_child->SetBounds(gfx::Size(1, 2)); - SetupRootProperties(root); CopyProperties(root, grand_parent); CreateTransformNode(grand_parent); CopyProperties(grand_parent, parent); @@ -6682,7 +5499,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { CopyProperties(child, grand_child); CreateTransformNode(grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // No layers have animations. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6741,7 +5558,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(child_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // Only |child| has a scale-affecting animation. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6756,7 +5573,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(grand_parent_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent| and |child| have scale-affecting animations. EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent)); @@ -6773,7 +5590,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(parent_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent|, |parent|, and |child| have scale-affecting animations. EXPECT_EQ(5.f, GetMaximumAnimationScale(grand_parent)); @@ -6798,7 +5615,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(child_animation.get(), 1.0, TransformOperations(), perspective); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |child| has a scale-affecting animation but computing the maximum of this // animation is not supported. @@ -6822,7 +5639,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { AddAnimatedTransformToAnimation(parent_animation.get(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent| and |parent| each have scale 2.f. |parent| has a scale // animation with maximum scale 5.f. @@ -6839,7 +5656,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { gfx::Transform perspective_matrix; perspective_matrix.ApplyPerspectiveDepth(2.f); SetTransform(child, perspective_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |child| has a transform that's neither a translation nor a scale. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6853,7 +5670,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { EXPECT_EQ(kNotScaled, GetStartingAnimationScale(grand_child)); SetTransform(parent, perspective_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |parent| and |child| have transforms that are neither translations nor // scales. @@ -6871,7 +5688,7 @@ TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { SetTransform(child, gfx::Transform()); SetTransform(grand_parent, perspective_matrix); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // |grand_parent| has a transform that's neither a translation nor a scale. EXPECT_EQ(kNotScaled, GetMaximumAnimationScale(grand_parent)); @@ -6894,14 +5711,11 @@ static void GatherDrawnLayers(LayerTreeImpl* tree_impl, if (it.state() != EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE) continue; - - if (it.current_render_surface()->MaskLayer()) - drawn_layers->insert(it.current_render_surface()->MaskLayer()); } } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceLayerListMembership) { +TEST_F(DrawPropertiesTestWithLayerTree, RenderSurfaceLayerListMembership) { auto root = Layer::Create(); auto grand_parent = Layer::Create(); auto parent = Layer::Create(); @@ -7043,11 +5857,13 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceLayerListMembership) { EXPECT_FALSE(ImplOf(grand_parent)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(parent)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); - EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); + // Mask layer has its own render surface in layer tree mode. + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(grand_child1)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(grand_child2)->contributes_to_drawn_render_surface()); expected.clear(); + expected.insert(ImplOf(mask)); actual.clear(); GatherDrawnLayers(host_impl()->active_tree(), &actual); EXPECT_EQ(expected, actual); @@ -7102,9 +5918,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceLayerListMembership) { } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { +TEST_F(DrawPropertiesTestWithLayerTree, DrawPropertyDeviceScale) { auto root = Layer::Create(); - auto page_scale = Layer::Create(); auto child1 = Layer::Create(); auto child2 = Layer::Create(); @@ -7123,14 +5938,11 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { mask->SetBounds(child1->bounds()); child1->SetMaskLayer(mask); - page_scale->AddChild(child1); - page_scale->AddChild(child2); - root->AddChild(page_scale); + root->AddChild(child1); + root->AddChild(child2); host()->SetRootLayer(root); host()->SetElementIdsForTesting(); - CommitAndActivate(); - TransformOperations scale; scale.AppendScale(5.f, 8.f, 3.f); @@ -7143,12 +5955,80 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { CommitAndActivate(); EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(3.f, ImplOf(mask)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); + EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2))); + + // Changing device-scale would affect ideal_contents_scale and + // maximum_animation_contents_scale. + + float device_scale_factor = 4.0f; + CommitAndActivate(device_scale_factor); + + EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(12.f, ImplOf(child1)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(12.f, ImplOf(mask)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(20.f, ImplOf(child2)->GetIdealContentsScale()); + + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); + EXPECT_FLOAT_EQ(32.f, GetMaximumAnimationScale(ImplOf(child2))); +} + +TEST_F(DrawPropertiesTest, DrawPropertyScales) { + auto root = Layer::Create(); + auto page_scale = Layer::Create(); + auto child1 = Layer::Create(); + auto child2 = Layer::Create(); + + gfx::Transform scale_transform_child1, scale_transform_child2; + scale_transform_child1.Scale(2, 3); + scale_transform_child2.Scale(4, 5); + + root->SetBounds(gfx::Size(1, 1)); + root->SetIsDrawable(true); + child1->SetBounds(gfx::Size(1, 1)); + child1->SetIsDrawable(true); + child2->SetBounds(gfx::Size(1, 1)); + child2->SetIsDrawable(true); + + root->AddChild(child1); + root->AddChild(child2); + root->AddChild(page_scale); + host()->SetRootLayer(root); + host()->SetElementIdsForTesting(); + + SetupRootProperties(root.get()); + CopyProperties(root.get(), page_scale.get()); + CreateTransformNode(page_scale.get()); + CopyProperties(page_scale.get(), child1.get()); + CreateTransformNode(child1.get()).local = scale_transform_child1; + CopyProperties(page_scale.get(), child2.get()); + CreateTransformNode(child2.get()).local = scale_transform_child2; + + LayerTreeHost::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale->transform_tree_index(); + host()->RegisterViewportPropertyIds(viewport_property_ids); + + TransformOperations scale; + scale.AppendScale(5.f, 8.f, 3.f); + + AddAnimatedTransformToElementWithAnimation(child2->element_id(), timeline(), + 1.0, TransformOperations(), scale); + + CommitAndActivate(); + + EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(1.f, ImplOf(page_scale)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(3.f, ImplOf(child1)->GetIdealContentsScale()); + EXPECT_FLOAT_EQ(5.f, ImplOf(child2)->GetIdealContentsScale()); + + EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(page_scale))); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(child1))); EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(ImplOf(child2))); @@ -7157,13 +6037,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { // maximum_animation_contents_scale. float device_scale_factor = 1.0f; - float page_scale_factor = 3.f; - CommitAndActivate(device_scale_factor, page_scale_factor, page_scale.get()); + host()->SetPageScaleFactorAndLimits(3.f, 3.f, 3.f); + CommitAndActivate(); EXPECT_FLOAT_EQ(1.f, ImplOf(root)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(3.f, ImplOf(page_scale)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(9.f, ImplOf(child1)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(9.f, ImplOf(mask)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(15.f, ImplOf(child2)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); @@ -7175,12 +6054,11 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { // maximum_animation_contents_scale. device_scale_factor = 4.0f; - CommitAndActivate(device_scale_factor, page_scale_factor, page_scale.get()); + CommitAndActivate(device_scale_factor); EXPECT_FLOAT_EQ(4.f, ImplOf(root)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(12.f, ImplOf(page_scale)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(36.f, ImplOf(child1)->GetIdealContentsScale()); - EXPECT_FLOAT_EQ(36.f, ImplOf(mask)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(60.f, ImplOf(child2)->GetIdealContentsScale()); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(ImplOf(root))); @@ -7189,10 +6067,10 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, DrawPropertyScales) { EXPECT_FLOAT_EQ(96.f, GetMaximumAnimationScale(ImplOf(child2))); } -TEST_F(LayerTreeHostCommonTest, AnimationScales) { - LayerImpl* root = root_layer_for_testing(); - auto* child1 = AddChildToRoot<LayerImpl>(); - auto* child2 = AddChildToRoot<LayerImpl>(); +TEST_F(DrawPropertiesTest, AnimationScales) { + LayerImpl* root = root_layer(); + auto* child1 = AddLayer<LayerImpl>(); + auto* child2 = AddLayer<LayerImpl>(); SetElementIdsForTesting(); gfx::Transform scale_transform_child1, scale_transform_child2; @@ -7203,7 +6081,6 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { child1->SetBounds(gfx::Size(1, 1)); child2->SetBounds(gfx::Size(1, 1)); - SetupRootProperties(root); CopyProperties(root, child1); CreateTransformNode(child1).local = scale_transform_child1; CopyProperties(child1, child2); @@ -7214,7 +6091,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { AddAnimatedTransformToElementWithAnimation( child2->element_id(), timeline_impl(), 1.0, TransformOperations(), scale); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(root)); EXPECT_FLOAT_EQ(kNotScaled, GetMaximumAnimationScale(child1)); @@ -7228,7 +6105,7 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { SetTransform(child1, gfx::Transform()); root->layer_tree_impl()->SetTransformMutated(child1->element_id(), gfx::Transform()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_FLOAT_EQ(8.f, GetMaximumAnimationScale(child2)); EXPECT_FLOAT_EQ(1.f, GetStartingAnimationScale(child2)); @@ -7239,8 +6116,8 @@ TEST_F(LayerTreeHostCommonTest, AnimationScales) { EXPECT_FLOAT_EQ(100.f, GetStartingAnimationScale(child2)); } -TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleContentRectInChildRenderSurface) { + LayerImpl* root = root_layer(); LayerImpl* clip = AddLayer<LayerImpl>(); LayerImpl* content = AddLayer<LayerImpl>(); @@ -7251,74 +6128,64 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { content->SetBounds(gfx::Size(768 / 2, 10000)); content->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip); CreateClipNode(clip); CopyProperties(clip, content); CreateEffectNode(content).render_surface_reason = RenderSurfaceReason::kTest; - gfx::Rect device_viewport_rect(768, 582); - RenderSurfaceList render_surface_list_impl; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, device_viewport_rect, gfx::Transform(), &render_surface_list_impl); - inputs.device_scale_factor = 2.f; - inputs.page_scale_factor = 1.f; - inputs.page_scale_layer = nullptr; - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + // Not calling UpdateActiveTreeDrawProperties() because we want to set a + // special device viewport rect. + host_impl()->active_tree()->SetDeviceViewportRect(gfx::Rect(768, 582)); + float device_scale_factor = 2.f; + host_impl()->active_tree()->SetDeviceScaleFactor(device_scale_factor); + UpdateDrawProperties(host_impl()->active_tree()); // Layers in the root render surface have their visible content rect clipped // by the viewport. - EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), root->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor), + root->visible_layer_rect()); // Layers drawing to a child render surface should still have their visible // content rect clipped by the viewport. - EXPECT_EQ(gfx::Rect(768 / 2, 582 / 2), content->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(768 / device_scale_factor, 582 / device_scale_factor), + content->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ViewportBoundsDeltaAffectVisibleContentRect) { - // Set two layers: the root layer clips it's child, - // the child draws its content. - - gfx::Size root_size = gfx::Size(300, 500); - - // Sublayer should be bigger than the root enlarged by bounds_delta. - gfx::Size sublayer_size = gfx::Size(300, 1000); +TEST_F(DrawPropertiesTest, ViewportBoundsDeltaAffectVisibleContentRect) { + gfx::Size container_size = gfx::Size(300, 500); + gfx::Size scroll_size = gfx::Size(300, 1000); // Device viewport accomidated the root and the browser controls. gfx::Rect device_viewport_rect = gfx::Rect(300, 600); - host_impl()->active_tree()->SetDeviceViewportRect(device_viewport_rect); - - LayerImpl* root = root_layer_for_testing(); - root->SetBounds(root_size); - root->SetMasksToBounds(true); - - // Make root the inner viewport scroll layer. This ensures the later call to - // |SetViewportBoundsDelta| will be on a viewport layer. - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.inner_viewport_scroll = root->id(); - host_impl()->active_tree()->SetViewportLayersFromIds(viewport_ids); + LayerTreeImpl* active_tree = host_impl()->active_tree(); + active_tree->SetDeviceViewportRect(device_viewport_rect); + active_tree->set_browser_controls_shrink_blink_size(true); + active_tree->SetTopControlsHeight(50); + active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 1.0f); - LayerImpl* sublayer = AddLayer<LayerImpl>(); - sublayer->SetBounds(sublayer_size); - sublayer->SetDrawsContent(true); + LayerImpl* root = root_layer(); + root->SetBounds(device_viewport_rect.size()); + SetupViewport(root, container_size, scroll_size); - SetupRootProperties(root); - CreateClipNode(root); - CopyProperties(root, sublayer); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + scroll_layer->SetDrawsContent(true); - ExecuteCalculateDrawProperties(root); - EXPECT_EQ(gfx::Rect(root_size), sublayer->visible_layer_rect()); + active_tree->SetCurrentBrowserControlsShownRatio(1.0f); + active_tree->UpdateViewportContainerSizes(); + UpdateActiveTreeDrawProperties(); + EXPECT_EQ(gfx::Rect(container_size), scroll_layer->visible_layer_rect()); - root->SetViewportBoundsDelta(gfx::Vector2dF(0.0, 50.0)); - ExecuteCalculateDrawProperties(root); + active_tree->SetCurrentBrowserControlsShownRatio(0.0f); + active_tree->UpdateViewportContainerSizes(); + UpdateActiveTreeDrawProperties(); - gfx::Rect affected_by_delta(0, 0, root_size.width(), - root_size.height() + 50); - EXPECT_EQ(affected_by_delta, sublayer->visible_layer_rect()); + gfx::Rect affected_by_delta(container_size.width(), + container_size.height() + 50); + EXPECT_EQ(affected_by_delta, scroll_layer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { +TEST_F(DrawPropertiesTest, VisibleContentRectForAnimatedLayer) { host_impl()->CreatePendingTree(); LayerImpl* root = EnsureRootLayerInPendingTree(); LayerImpl* animated = AddLayerInPendingTree<LayerImpl>(); @@ -7329,18 +6196,17 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectForAnimatedLayer) { root->SetBounds(gfx::Size(100, 100)); animated->SetBounds(gfx::Size(20, 20)); - SetupRootProperties(root); CopyProperties(root, animated); CreateEffectNode(animated).opacity = 0.f; AddOpacityTransitionToElementWithAnimation( animated->element_id(), timeline_impl(), 10.0, 0.f, 1.f, false); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); EXPECT_FALSE(animated->visible_layer_rect().IsEmpty()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, VisibleContentRectForAnimatedLayerWithSingularTransform) { host_impl()->CreatePendingTree(); LayerImpl* root = EnsureRootLayerInPendingTree(); @@ -7365,7 +6231,6 @@ TEST_F(LayerTreeHostCommonTest, surface->SetBounds(gfx::Size(100, 100)); descendant_of_keyframe_model->SetBounds(gfx::Size(200, 200)); - SetupRootProperties(root); CopyProperties(root, clip); CreateClipNode(clip); CopyProperties(clip, animated); @@ -7382,7 +6247,7 @@ TEST_F(LayerTreeHostCommonTest, AddAnimatedTransformToElementWithAnimation( animated->element_id(), timeline_impl(), 10.0, start_transform_operations, end_transform_operations); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); // Since animated has singular transform, it is not be part of render // surface layer list but should be rastered. EXPECT_FALSE(animated->contributes_to_drawn_render_surface()); @@ -7402,7 +6267,7 @@ TEST_F(LayerTreeHostCommonTest, zero_matrix.Scale3d(0.f, 0.f, 0.f); root->layer_tree_impl()->SetTransformMutated(animated->element_id(), zero_matrix); - ExecuteCalculateDrawProperties(root); + UpdatePendingTreeDrawProperties(); // The animated layer will be treated as fully visible when we combine clips // in screen space. @@ -7417,7 +6282,7 @@ TEST_F(LayerTreeHostCommonTest, host_impl()->ActivateSyncTree(); LayerImpl* active_root = host_impl()->active_tree()->LayerById(root->id()); - ExecuteCalculateDrawProperties(active_root); + UpdateActiveTreeDrawProperties(); // Since the animated has singular transform, it is not be part of render // surface layer list. @@ -7432,159 +6297,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(120, 120), active_animated->visible_layer_rect()); } -// Verify that having animated opacity but current opacity 1 still creates -// a render surface. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - AnimatedOpacityCreatesRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grandchild = Layer::Create(); - child->AddChild(grandchild); - - root->SetBounds(gfx::Size(50, 50)); - child->SetBounds(gfx::Size(50, 50)); - child->SetIsDrawable(true); - grandchild->SetBounds(gfx::Size(50, 50)); - grandchild->SetIsDrawable(true); - - host()->SetElementIdsForTesting(); - AddOpacityTransitionToElementWithAnimation(child->element_id(), timeline(), - 10.0, 1.f, 0.2f, false); - CommitAndActivate(); - - EXPECT_EQ(1.f, ImplOf(child)->Opacity()); - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); -} - -static bool FilterIsAnimating(LayerImpl* layer) { - MutatorHost* host = layer->layer_tree_impl()->mutator_host(); - return host->IsAnimatingFilterProperty(layer->element_id(), - layer->GetElementTypeForAnimation()); -} - -// Verify that having an animated filter (but no current filter, as these -// are mutually exclusive) correctly creates a render surface. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - AnimatedFilterCreatesRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grandchild = Layer::Create(); - child->AddChild(grandchild); - - root->SetBounds(gfx::Size(50, 50)); - child->SetBounds(gfx::Size(50, 50)); - grandchild->SetBounds(gfx::Size(50, 50)); - - host()->SetElementIdsForTesting(); - AddAnimatedFilterToElementWithAnimation(child->element_id(), timeline(), 10.0, - 0.1f, 0.2f); - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); - EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); - - EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); - EXPECT_TRUE(FilterIsAnimating(ImplOf(child))); - EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); -} - -bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) { - MutatorHost* host = layer.layer_tree_impl()->mutator_host(); - return host->HasPotentiallyRunningFilterAnimation( - layer.element_id(), layer.GetElementTypeForAnimation()); -} - -// Verify that having a filter animation with a delayed start time creates a -// render surface. -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - DelayedFilterAnimationCreatesRenderSurface) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto child = Layer::Create(); - root->AddChild(child); - auto grandchild = Layer::Create(); - child->AddChild(grandchild); - - root->SetBounds(gfx::Size(50, 50)); - child->SetBounds(gfx::Size(50, 50)); - grandchild->SetBounds(gfx::Size(50, 50)); - - host()->SetElementIdsForTesting(); - - std::unique_ptr<KeyframedFilterAnimationCurve> curve( - KeyframedFilterAnimationCurve::Create()); - FilterOperations start_filters; - start_filters.Append(FilterOperation::CreateBrightnessFilter(0.1f)); - FilterOperations end_filters; - end_filters.Append(FilterOperation::CreateBrightnessFilter(0.3f)); - curve->AddKeyframe( - FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); - curve->AddKeyframe(FilterKeyframe::Create( - base::TimeDelta::FromMilliseconds(100), end_filters, nullptr)); - std::unique_ptr<KeyframeModel> keyframe_model = - KeyframeModel::Create(std::move(curve), 0, 1, TargetProperty::FILTER); - keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE); - keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); - - AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), - std::move(keyframe_model)); - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); - EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); - - EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); - EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(root))); - EXPECT_FALSE(FilterIsAnimating(ImplOf(child))); - EXPECT_TRUE(HasPotentiallyRunningFilterAnimation(*ImplOf(child))); - EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); - EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(grandchild))); -} - -// Needs layer tree mode: needs_rebuild flag. Not using impl-side -// PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - ChangingAxisAlignmentTriggersRebuild) { - gfx::Transform translate; - gfx::Transform rotate; - - translate.Translate(10, 10); - rotate.Rotate(45); - - scoped_refptr<Layer> root = Layer::Create(); - root->SetBounds(gfx::Size(800, 800)); - - host()->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_FALSE(host()->property_trees()->needs_rebuild); - - root->SetTransform(translate); - EXPECT_FALSE(host()->property_trees()->needs_rebuild); - - root->SetTransform(rotate); - EXPECT_TRUE(host()->property_trees()->needs_rebuild); -} - -TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ChangeTransformOrigin) { + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); gfx::Transform scale_matrix; @@ -7595,21 +6309,20 @@ TEST_F(LayerTreeHostCommonTest, ChangeTransformOrigin) { child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child).local = scale_matrix; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); SetTransformOrigin(child, gfx::Point3F(10.f, 10.f, 10.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(5, 5, 5, 5), child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, UpdateScrollChildPosition) { + LayerImpl* root = root_layer(); LayerImpl* scroll_parent = AddLayer<LayerImpl>(); LayerImpl* scroll_child = AddLayer<LayerImpl>(); @@ -7624,27 +6337,26 @@ TEST_F(LayerTreeHostCommonTest, UpdateScrollChildPosition) { scroll_child->SetBounds(gfx::Size(40, 40)); scroll_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, scroll_parent); CreateTransformNode(scroll_parent); CreateScrollNode(scroll_parent); CopyProperties(scroll_parent, scroll_child); CreateTransformNode(scroll_child).local.Scale(2.f, 2.f); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(25, 25), scroll_child->visible_layer_rect()); SetScrollOffset(scroll_parent, gfx::ScrollOffset(0.f, 10.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(0, 5, 25, 25), scroll_child->visible_layer_rect()); SetPostTranslation(scroll_child, gfx::Vector2dF(0, -10.f)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(0, 10, 25, 25), scroll_child->visible_layer_rect()); } // Needs layer tree mode: copy request. Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, HasCopyRequestsInTargetSubtree) { +TEST_F(DrawPropertiesTestWithLayerTree, HasCopyRequestsInTargetSubtree) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> child1 = Layer::Create(); scoped_refptr<Layer> child2 = Layer::Create(); @@ -7662,7 +6374,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, HasCopyRequestsInTargetSubtree) { greatgrandchild->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); child2->SetOpacity(0.f); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(LayerSubtreeHasCopyRequest(root.get())); EXPECT_TRUE(LayerSubtreeHasCopyRequest(child1.get())); @@ -7673,7 +6385,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, HasCopyRequestsInTargetSubtree) { // Needs layer tree mode: hide_layer_and_subtree, etc. // Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingSubtreeMain) { FakeContentLayerClient client; scoped_refptr<Layer> root = Layer::Create(); @@ -7697,7 +6409,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { host()->SetElementIdsForTesting(); // Check the non-skipped case. - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); // Now we will reset the visible rect from property trees for the grandchild, @@ -7708,12 +6420,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { singular.matrix().set(0, 0, 0); child->SetTransform(singular); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); child->SetTransform(gfx::Transform()); child->SetHideLayerAndSubtree(true); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); child->SetHideLayerAndSubtree(false); @@ -7731,14 +6443,14 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); RemoveKeyframeModelFromElementWithExistingKeyframeEffect( child->element_id(), timeline(), keyframe_model_id); child->SetTransform(gfx::Transform()); child->SetOpacity(0.f); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_FALSE(UpdateLayerListContains(grandchild->id())); // Now, even though child has zero opacity, we will configure |grandchild| and @@ -7746,7 +6458,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { // processed anyhow. grandchild->RequestCopyOfOutput( viz::CopyOutputRequest::CreateStubForTesting()); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); // Add an opacity animation with a start delay. @@ -7758,12 +6470,12 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingSubtreeMain) { keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); AddKeyframeModelToElementWithExistingKeyframeEffect( child->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EXPECT_TRUE(UpdateLayerListContains(grandchild->id())); } // Needs layer tree mode: hide_layer_and_subtree, etc. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayerImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayerImpl) { auto root = Layer::Create(); host()->SetRootLayer(root); auto parent = Layer::Create(); @@ -7892,7 +6604,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayerImpl) { // we can ignore the size of all its children. We need to make sure that // we don't do this if an animation can replace this transform in the // compositor without recomputing the trees. -TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { +TEST_F(DrawPropertiesTest, LayerSkippingInSubtreeOfSingularTransform) { // Set up a transform animation std::unique_ptr<KeyframedTransformAnimationCurve> curve( KeyframedTransformAnimationCurve::Create()); @@ -7914,7 +6626,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { animation->AddKeyframeModel(std::move(transform_animation)); // Set up some layers to have a tree. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* child = AddLayer<LayerImpl>(); LayerImpl* grand_child = AddLayer<LayerImpl>(); @@ -7939,12 +6651,11 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); - SetupRootProperties(root); CopyProperties(root, child); CreateTransformNode(child); CopyProperties(child, grand_child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); @@ -7952,7 +6663,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { SetTransform(child, singular); grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(), grand_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(), child->visible_layer_rect()); @@ -7961,7 +6672,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { grand_child->set_visible_layer_rect(gfx::Rect()); child->set_visible_layer_rect(gfx::Rect()); root->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); ASSERT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); ASSERT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); @@ -7973,14 +6684,14 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { SetTransform(child, singular); grand_child->set_visible_layer_rect(gfx::Rect(1, 1)); child->set_visible_layer_rect(gfx::Rect(1, 1)); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), grand_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(10, 10), child->visible_layer_rect()); } // This tests that we skip computing the visible areas for the subtree // rooted at nodes with constant zero opacity. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingPendingLayerImpl) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingPendingLayerImpl) { auto root = Layer::Create(); auto child = Layer::Create(); auto grandchild = Layer::Create(); @@ -8035,7 +6746,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingPendingLayerImpl) { } // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayer) { +TEST_F(DrawPropertiesTestWithLayerTree, SkippingLayer) { auto root = Layer::Create(); host()->SetRootLayer(root); auto child = Layer::Create(); @@ -8074,86 +6785,11 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SkippingLayer) { EXPECT_EQ(gfx::Rect(0, 0), ImplOf(child)->visible_layer_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -// Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, ResetPropertyTreeIndices) { - scoped_refptr<Layer> root = Layer::Create(); - root->SetBounds(gfx::Size(800, 800)); - - gfx::Transform translate_z; - translate_z.Translate3d(0, 0, 10); - - scoped_refptr<Layer> child = Layer::Create(); - child->SetTransform(translate_z); - child->SetBounds(gfx::Size(100, 100)); - - root->AddChild(child); - - host()->SetRootLayer(root); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_NE(-1, child->transform_tree_index()); - - child->RemoveFromParent(); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_EQ(-1, child->transform_tree_index()); -} - -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RenderSurfaceClipsSubtree) { - // Ensure that a Clip Node is added when a render surface applies clip. - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto significant_transform = Layer::Create(); - root->AddChild(significant_transform); - auto layer_clips_subtree = Layer::Create(); - significant_transform->AddChild(layer_clips_subtree); - auto render_surface = Layer::Create(); - layer_clips_subtree->AddChild(render_surface); - auto test_layer = Layer::Create(); - render_surface->AddChild(test_layer); - - // This transform should be a significant one so that a transform node is - // formed for it. - gfx::Transform transform1; - transform1.RotateAboutYAxis(45); - transform1.RotateAboutXAxis(30); - // This transform should be a 3d transform as we want the render surface - // to flatten the transform - gfx::Transform transform2; - transform2.Translate3d(10, 10, 10); - - root->SetBounds(gfx::Size(30, 30)); - significant_transform->SetTransform(transform1); - significant_transform->SetBounds(gfx::Size(30, 30)); - layer_clips_subtree->SetBounds(gfx::Size(30, 30)); - layer_clips_subtree->SetMasksToBounds(true); - layer_clips_subtree->SetForceRenderSurfaceForTesting(true); - render_surface->SetTransform(transform2); - render_surface->SetBounds(gfx::Size(30, 30)); - render_surface->SetForceRenderSurfaceForTesting(true); - test_layer->SetBounds(gfx::Size(30, 30)); - test_layer->SetIsDrawable(true); - - CommitAndActivate(); - - EXPECT_TRUE(GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(significant_transform), - GetRenderSurfaceImpl(root)); - EXPECT_TRUE(GetRenderSurfaceImpl(layer_clips_subtree)); - EXPECT_NE(GetRenderSurfaceImpl(render_surface), GetRenderSurfaceImpl(root)); - EXPECT_EQ(GetRenderSurfaceImpl(test_layer), - GetRenderSurfaceImpl(render_surface)); - - EXPECT_EQ(gfx::Rect(30, 20), ImplOf(test_layer)->visible_layer_rect()); -} - -TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { +TEST_F(DrawPropertiesTest, TransformOfParentClipNodeAncestorOfTarget) { // Ensure that when parent clip node's transform is an ancestor of current // clip node's target, clip is 'projected' from parent space to current // target space and visible rects are calculated correctly. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* target_layer = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -8169,7 +6805,6 @@ TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { test_layer->SetBounds(gfx::Size(30, 30)); test_layer->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_layer); CreateTransformNode(clip_layer).local = transform; CreateClipNode(clip_layer); @@ -8178,16 +6813,15 @@ TEST_F(LayerTreeHostCommonTest, TransformOfParentClipNodeAncestorOfTarget) { CreateClipNode(target_layer); CopyProperties(target_layer, test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), test_layer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, - RenderSurfaceWithUnclippedDescendantsClipsSubtree) { +TEST_F(DrawPropertiesTest, RenderSurfaceWithUnclippedDescendantsClipsSubtree) { // Ensure clip rect is calculated correctly when render surface has unclipped // descendants. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* between_clip_parent_and_child = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); @@ -8200,7 +6834,6 @@ TEST_F(LayerTreeHostCommonTest, test_layer->SetBounds(gfx::Size(30, 30)); test_layer->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateTransformNode(clip_parent).local.Translate(2, 2); CreateClipNode(clip_parent); @@ -8214,7 +6847,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, test_layer); test_layer->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRUE(test_layer->is_clipped()); EXPECT_FALSE(test_layer->render_target()->is_clipped()); @@ -8222,12 +6855,12 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(28, 28), test_layer->drawable_content_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, RenderSurfaceWithUnclippedDescendantsButDoesntApplyOwnClip) { // Ensure that the visible layer rect of a descendant of a surface with // unclipped descendants is computed correctly, when the surface doesn't apply // a clip. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -8241,7 +6874,6 @@ TEST_F(LayerTreeHostCommonTest, child->SetBounds(gfx::Size(40, 40)); child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CopyProperties(clip_parent, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -8250,13 +6882,13 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); CopyProperties(clip_child, child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 10), child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, +TEST_F(DrawPropertiesTest, RenderSurfaceClipsSubtreeAndHasUnclippedDescendants) { - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* test_layer1 = AddLayer<LayerImpl>(); @@ -8274,7 +6906,6 @@ TEST_F(LayerTreeHostCommonTest, test_layer2->SetBounds(gfx::Size(50, 50)); test_layer2->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, clip_parent); CopyProperties(clip_parent, render_surface); @@ -8286,15 +6917,15 @@ TEST_F(LayerTreeHostCommonTest, clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); CopyProperties(clip_child, test_layer2); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), render_surface->visible_layer_rect()); EXPECT_EQ(gfx::Rect(30, 30), test_layer1->visible_layer_rect()); EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(30, 30), test_layer2->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, UnclippedClipParent) { + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -8307,7 +6938,6 @@ TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { clip_child->SetBounds(gfx::Size(50, 50)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CopyProperties(clip_parent, render_surface); CreateEffectNode(render_surface).render_surface_reason = @@ -8316,7 +6946,7 @@ TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { CopyProperties(render_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); // The clip child should inherit its clip parent's clipping state, not its // tree parent's clipping state. @@ -8325,11 +6955,11 @@ TEST_F(LayerTreeHostCommonTest, UnclippedClipParent) { EXPECT_FALSE(clip_child->is_clipped()); } -TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { +TEST_F(DrawPropertiesTest, RenderSurfaceContentRectWithMultipleSurfaces) { // Tests the value of render surface content rect when we have multiple types // of surfaces : unclipped surfaces, surfaces with unclipped surfaces and // clipped surfaces. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* unclipped_surface = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); @@ -8352,7 +6982,6 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { clipped_surface->SetBounds(gfx::Size(70, 70)); clipped_surface->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, unclipped_surface); CreateEffectNode(unclipped_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8373,7 +7002,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { CreateEffectNode(clipped_surface).render_surface_reason = RenderSurfaceReason::kTest; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(50, 50), GetRenderSurface(unclipped_surface)->content_rect()); EXPECT_EQ(gfx::Rect(50, 50), @@ -8384,10 +7013,10 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceContentRectWithMultipleSurfaces) { GetRenderSurface(clipped_surface)->content_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { +TEST_F(DrawPropertiesTest, ClipBetweenClipChildTargetAndClipParentTarget) { // Tests the value of render surface content rect when we have a layer that // clips between the clip parent's target and clip child's target. - LayerImpl* root = root_layer_for_testing(); + LayerImpl* root = root_layer(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); @@ -8403,7 +7032,6 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, surface); CreateTransformNode(surface).local.RotateAboutXAxis(10); CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8418,14 +7046,14 @@ TEST_F(LayerTreeHostCommonTest, ClipBetweenClipChildTargetAndClipParentTarget) { CopyProperties(unclipped_desc_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurface(unclipped_desc_surface)->content_rect()); } -TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, VisibleRectForDescendantOfScaledSurface) { + LayerImpl* root = root_layer(); LayerImpl* surface = AddLayer<LayerImpl>(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); @@ -8441,7 +7069,6 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, surface); CreateTransformNode(surface).local.Scale(2, 2); CreateEffectNode(surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8455,13 +7082,13 @@ TEST_F(LayerTreeHostCommonTest, VisibleRectForDescendantOfScaledSurface) { CopyProperties(unclipped_desc_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(20, 20), clip_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LayerWithInputHandlerAndZeroOpacity) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -8478,7 +7105,6 @@ TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { touch_action_region.Union(kTouchActionNone, gfx::Rect(0, 0, 20, 20)); test_layer->SetTouchActionRegion(std::move(touch_action_region)); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateEffectNode(render_surface).render_surface_reason = RenderSurfaceReason::kTest; @@ -8487,13 +7113,13 @@ TEST_F(LayerTreeHostCommonTest, LayerWithInputHandlerAndZeroOpacity) { CreateTransformNode(test_layer).local = translation; CreateEffectNode(test_layer).opacity = 0.f; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_TRANSFORMATION_MATRIX_EQ(translation, test_layer->ScreenSpaceTransform()); } -TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipParentDrawsIntoScaledRootSurface) { + LayerImpl* root = root_layer(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* clip_parent_child = AddLayer<LayerImpl>(); @@ -8509,7 +7135,6 @@ TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { clip_child->SetBounds(gfx::Size(100, 100)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_layer); CreateClipNode(clip_layer); CopyProperties(clip_layer, clip_parent); @@ -8523,18 +7148,18 @@ TEST_F(LayerTreeHostCommonTest, ClipParentDrawsIntoScaledRootSurface) { clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); float device_scale_factor = 1.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(gfx::Rect(-10, -10, 20, 20), clip_child->clip_rect()); EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect()); device_scale_factor = 2.f; - ExecuteCalculateDrawProperties(root, device_scale_factor); + UpdateActiveTreeDrawProperties(device_scale_factor); EXPECT_EQ(gfx::Rect(-20, -20, 40, 40), clip_child->clip_rect()); EXPECT_EQ(gfx::Rect(10, 10), clip_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, ClipChildVisibleRect) { + LayerImpl* root = root_layer(); LayerImpl* clip_parent = AddLayer<LayerImpl>(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* clip_child = AddLayer<LayerImpl>(); @@ -8546,7 +7171,6 @@ TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { clip_child->SetBounds(gfx::Size(50, 50)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CopyProperties(root, clip_parent); CreateClipNode(clip_parent); CopyProperties(clip_parent, render_surface); @@ -8556,13 +7180,12 @@ TEST_F(LayerTreeHostCommonTest, ClipChildVisibleRect) { CopyProperties(render_surface, clip_child); clip_child->SetClipTreeIndex(clip_parent->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), clip_child->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, - LayerClipRectLargerThanClippingRenderSurfaceRect) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LayerClipRectLargerThanClippingRenderSurfaceRect) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* test_layer = AddLayer<LayerImpl>(); @@ -8574,7 +7197,6 @@ TEST_F(LayerTreeHostCommonTest, test_layer->SetBounds(gfx::Size(50, 50)); test_layer->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, render_surface); CreateTransformNode(render_surface); @@ -8584,7 +7206,7 @@ TEST_F(LayerTreeHostCommonTest, CopyProperties(render_surface, test_layer); CreateClipNode(test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(30, 30), root->clip_rect()); EXPECT_EQ(gfx::Rect(50, 50), render_surface->clip_rect()); @@ -8592,7 +7214,7 @@ TEST_F(LayerTreeHostCommonTest, } // Needs layer tree mode: hide_layer_and_subtree. -TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeIsHiddenTest) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeIsHiddenTest) { // Tests that subtree is hidden is updated. auto root = Layer::Create(); host()->SetRootLayer(root); @@ -8621,8 +7243,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, SubtreeIsHiddenTest) { GetRenderSurfaceImpl(test)->OwningEffectNode()->screen_space_opacity); } -TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, TwoUnclippedRenderSurfaces) { + LayerImpl* root = root_layer(); LayerImpl* clip_layer = AddLayer<LayerImpl>(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); @@ -8637,7 +7259,6 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { clip_child->SetBounds(gfx::Size(30, 30)); clip_child->SetDrawsContent(true); - SetupRootProperties(root); CreateClipNode(root); CopyProperties(root, clip_layer); CreateClipNode(clip_layer); @@ -8652,13 +7273,13 @@ TEST_F(LayerTreeHostCommonTest, TwoUnclippedRenderSurfaces) { CopyProperties(render_surface2, clip_child); clip_child->SetClipTreeIndex(root->clip_tree_index()); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Rect(-10, -10, 30, 30), render_surface2->clip_rect()); } // Needs layer tree mode: mask layer. -TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { +TEST_F(DrawPropertiesTestWithLayerTree, MaskLayerDrawProperties) { // Tests that a mask layer's draw properties are computed correctly. auto root = Layer::Create(); host()->SetRootLayer(root); @@ -8675,7 +7296,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { root->SetIsDrawable(true); child->SetTransform(transform); child->SetBounds(gfx::Size(30, 30)); - child->SetIsDrawable(false); + child->SetIsDrawable(true); + child->SetOpacity(0.f); mask->SetBounds(gfx::Size(30, 30)); CommitAndActivate(); @@ -8684,13 +7306,14 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { // mask doesn't contribute to a drawn render surface. This means it has an // empty visible rect, but its screen space transform can still be computed // correctly on-demand. + EXPECT_FALSE(ImplOf(child)->contributes_to_drawn_render_surface()); EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(), ImplOf(mask)->visible_layer_rect()); EXPECT_TRANSFORMATION_MATRIX_EQ(transform, ImplOf(mask)->ScreenSpaceTransform()); // Make the child's render surface have contributing content. - child->SetIsDrawable(true); + child->SetOpacity(1.f); CommitAndActivate(); EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); EXPECT_EQ(gfx::Rect(30, 30), ImplOf(mask)->visible_layer_rect()); @@ -8703,11 +7326,21 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, MaskLayerDrawProperties) { EXPECT_TRANSFORMATION_MATRIX_EQ(transform, ImplOf(mask)->ScreenSpaceTransform()); EXPECT_EQ(gfx::Rect(20, 20), ImplOf(mask)->visible_layer_rect()); + + // For now SetIsDrawable of masked layer doesn't affect draw properties of + // the mask layer because it doesn't affect property trees. + child->SetIsDrawable(false); + CommitAndActivate(); + EXPECT_TRUE(ImplOf(mask)->contributes_to_drawn_render_surface()); + + // SetIsDrawable of mask layer itself affects its draw properties. + mask->SetIsDrawable(false); + CommitAndActivate(); + EXPECT_FALSE(ImplOf(mask)->contributes_to_drawn_render_surface()); } -TEST_F(LayerTreeHostCommonTest, - SublayerScaleWithTransformNodeBetweenTwoTargets) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, SublayerScaleWithTransformNodeBetweenTwoTargets) { + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* between_targets = AddLayer<LayerImpl>(); LayerImpl* render_surface2 = AddLayer<LayerImpl>(); @@ -8726,7 +7359,6 @@ TEST_F(LayerTreeHostCommonTest, // We want layer between the two targets to create a clip node and effect // node but it shouldn't create a render surface. between_targets->SetMasksToBounds(true); - SetupRootProperties(root); CopyProperties(root, render_surface1); CreateTransformNode(render_surface1).local = scale; CreateEffectNode(render_surface1).render_surface_reason = @@ -8739,7 +7371,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceReason::kTest; CopyProperties(render_surface2, test_layer); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), GetEffectNode(render_surface1)->surface_contents_scale); @@ -8751,8 +7383,8 @@ TEST_F(LayerTreeHostCommonTest, EXPECT_EQ(gfx::Rect(15, 15), test_layer->visible_layer_rect()); } -TEST_F(LayerTreeHostCommonTest, NoisyTransform) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, NoisyTransform) { + LayerImpl* root = root_layer(); LayerImpl* render_surface = AddLayer<LayerImpl>(); LayerImpl* parent = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -8770,7 +7402,6 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { transform.matrix().setDouble(2, 2, 6.12323e-17); transform.matrix().setDouble(2, 0, -1); - SetupRootProperties(root); CopyProperties(root, render_surface); CreateTransformNode(render_surface).local = transform; CreateEffectNode(render_surface).render_surface_reason = @@ -8779,7 +7410,7 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { CopyProperties(parent, child); CreateTransformNode(child).local = transform; - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); gfx::Transform expected; expected.matrix().setDouble(0, 0, 3.749395e-33); @@ -8789,8 +7420,8 @@ TEST_F(LayerTreeHostCommonTest, NoisyTransform) { EXPECT_TRANSFORMATION_MATRIX_EQ(expected, child->ScreenSpaceTransform()); } -TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { - LayerImpl* root = root_layer_for_testing(); +TEST_F(DrawPropertiesTest, LargeTransformTest) { + LayerImpl* root = root_layer(); LayerImpl* render_surface1 = AddLayer<LayerImpl>(); LayerImpl* child = AddLayer<LayerImpl>(); @@ -8813,7 +7444,6 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { // what exactly happens here. child->SetBounds(gfx::Size(30, 30)); - SetupRootProperties(root); CopyProperties(root, render_surface1); CreateEffectNode(render_surface1).render_surface_reason = RenderSurfaceReason::kTest; @@ -8821,7 +7451,7 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { CreateTransformNode(child).local = large_transform; CreateClipNode(child); - ExecuteCalculateDrawProperties(root); + UpdateActiveTreeDrawProperties(); EXPECT_EQ(gfx::RectF(), GetRenderSurface(render_surface1)->DrawableContentRect()); @@ -8835,54 +7465,11 @@ TEST_F(LayerTreeHostCommonTest, LargeTransformTest) { EXPECT_TRUE(is_inf_or_nan); // The root layer should be in the RenderSurfaceList. - const auto* rsl = render_surface_list_impl(); - EXPECT_TRUE(base::Contains(*rsl, GetRenderSurface(root))); -} - -// Needs layer tree mode: testing needs_rebuild flag. -// Not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - PropertyTreesRebuildWithOpacityChanges) { - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> child = Layer::Create(); - child->SetIsDrawable(true); - root->AddChild(child); - host()->SetRootLayer(root); - - root->SetBounds(gfx::Size(100, 100)); - child->SetBounds(gfx::Size(20, 20)); - ExecuteCalculateDrawProperties(root.get()); - - // Changing the opacity from 1 to non-1 value should trigger rebuild of - // property trees as a new effect node will be created. - child->SetOpacity(0.5f); - PropertyTrees* property_trees = host()->property_trees(); - EXPECT_TRUE(property_trees->needs_rebuild); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); - - // child already has an effect node. Changing its opacity shouldn't trigger - // a property trees rebuild. - child->SetOpacity(0.8f); - property_trees = host()->property_trees(); - EXPECT_FALSE(property_trees->needs_rebuild); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); - - // Changing the opacity from non-1 value to 1 should trigger a rebuild of - // property trees as the effect node may no longer be needed. - child->SetOpacity(1.f); - property_trees = host()->property_trees(); - EXPECT_TRUE(property_trees->needs_rebuild); - - ExecuteCalculateDrawProperties(root.get()); - EXPECT_EQ(child->effect_tree_index(), root->effect_tree_index()); + EXPECT_TRUE(base::Contains(GetRenderSurfaceList(), GetRenderSurface(root))); } // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, OpacityAnimationsTrackingTest) { +TEST_F(DrawPropertiesTestWithLayerTree, OpacityAnimationsTrackingTest) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> animated = Layer::Create(); animated->SetIsDrawable(true); @@ -8912,7 +7499,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OpacityAnimationsTrackingTest) { AddKeyframeModelToElementWithExistingKeyframeEffect( animated->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); EffectNode* node = GetEffectNode(animated.get()); EXPECT_FALSE(node->is_currently_animating_opacity); @@ -8932,7 +7519,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, OpacityAnimationsTrackingTest) { } // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformAnimationsTrackingTest) { +TEST_F(DrawPropertiesTestWithLayerTree, TransformAnimationsTrackingTest) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> animated = Layer::Create(); animated->SetIsDrawable(true); @@ -8970,7 +7557,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformAnimationsTrackingTest) { AddKeyframeModelToElementWithExistingKeyframeEffect( animated->element_id(), timeline(), std::move(keyframe_model)); - ExecuteCalculateDrawProperties(root.get()); + UpdateMainDrawProperties(); TransformNode* node = GetTransformNode(animated.get()); EXPECT_FALSE(node->is_currently_animating); @@ -8990,7 +7577,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, TransformAnimationsTrackingTest) { } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, CopyRequestScalingTest) { +TEST_F(DrawPropertiesTestWithLayerTree, CopyRequestScalingTest) { auto root = Layer::Create(); host()->SetRootLayer(root); auto scale_layer = Layer::Create(); @@ -9044,8 +7631,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CopyRequestScalingTest) { } // Needs layer tree mode: hide_layer_and_subtree, etc. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - SubtreeHiddenWithCacheRenderSurface) { +TEST_F(DrawPropertiesTestWithLayerTree, SubtreeHiddenWithCacheRenderSurface) { auto root = Layer::Create(); host()->SetRootLayer(root); root->SetBounds(gfx::Size(50, 50)); @@ -9101,15 +7687,15 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, // We should have four render surfaces, one for the root, one for the grand // parent since it has opacity and two drawing descendants, one for the parent // since it owns a surface, and one for the cache. - ASSERT_EQ(4u, render_surface_list_impl()->size()); + ASSERT_EQ(4u, GetRenderSurfaceList().size()); EXPECT_EQ(static_cast<uint64_t>(root->id()), - render_surface_list_impl()->at(0)->id()); + GetRenderSurfaceList().at(0)->id()); EXPECT_EQ(static_cast<uint64_t>(cache_grand_parent->id()), - render_surface_list_impl()->at(1)->id()); + GetRenderSurfaceList().at(1)->id()); EXPECT_EQ(static_cast<uint64_t>(cache_parent->id()), - render_surface_list_impl()->at(2)->id()); + GetRenderSurfaceList().at(2)->id()); EXPECT_EQ(static_cast<uint64_t>(cache_render_surface->id()), - render_surface_list_impl()->at(3)->id()); + GetRenderSurfaceList().at(3)->id()); // The root render surface should have 2 contributing layers. EXPECT_EQ(2, GetRenderSurfaceImpl(root)->num_contributors()); @@ -9152,7 +7738,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, } // Needs layer tree mode: copy request. -TEST_F(LayerTreeHostCommonTestWithLayerTree, +TEST_F(DrawPropertiesTestWithLayerTree, VisibleRectInNonRootCacheRenderSurface) { auto root = Layer::Create(); host()->SetRootLayer(root); @@ -9260,1132 +7846,8 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, EXPECT_EQ(gfx::Rect(20, 20), ImplOf(cache_surface)->visible_layer_rect()); } -// Needs layer tree mode: testing PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RenderSurfaceListForTrilinearFiltering) { - auto root = Layer::Create(); - host()->SetRootLayer(root); - auto parent = Layer::Create(); - root->AddChild(parent); - auto child1 = Layer::Create(); - parent->AddChild(child1); - auto child2 = Layer::Create(); - parent->AddChild(child2); - - gfx::Transform scale_matrix; - scale_matrix.Scale(.25f, .25f); - - root->SetBounds(gfx::Size(200, 200)); - parent->SetTransform(scale_matrix); - parent->SetTrilinearFiltering(true); - child1->SetBounds(gfx::Size(50, 50)); - child1->SetIsDrawable(true); - child1->SetForceRenderSurfaceForTesting(true); - child2->SetPosition(gfx::PointF(50, 50)); - child2->SetBounds(gfx::Size(50, 50)); - child2->SetIsDrawable(true); - child2->SetForceRenderSurfaceForTesting(true); - - CommitAndActivate(); - - ASSERT_TRUE(GetRenderSurfaceImpl(parent)); - EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); - EXPECT_EQ(4U, render_surface_list_impl()->size()); - - // The rectangle enclosing child1 and child2 (0,0 100x100), scaled by the - // scale matrix to (0,0 25x25). - EXPECT_EQ(gfx::RectF(0, 0, 25, 25), - GetRenderSurfaceImpl(parent)->DrawableContentRect()); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, RoundedCornerBounds) { - // Layer Tree: - // +root - // +--render surface - // +----rounded corner layer 1 [should trigger render surface] - // +----layer 1 - // +--rounded corner layer 2 [should trigger render surface] - // +----layer 2 - // +------rounded corner layer 3 [should trigger render surface] - // +--------rounded corner layer 4 [should trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - constexpr int kRoundedCorner3Radius = 1; - constexpr int kRoundedCorner4Radius = 1; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(15.f, 15.f, 20.f, 20.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); - constexpr gfx::RectF kRoundedCornerLayer3Bound(0.f, 15.f, 5.f, 5.f); - constexpr gfx::RectF kRoundedCornerLayer4Bound(1.f, 1.f, 3.f, 3.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> render_surface = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - scoped_refptr<Layer> layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); - - // Set up layer tree - root->AddChild(render_surface); - root->AddChild(rounded_corner_layer_2); - - render_surface->AddChild(rounded_corner_layer_1); - render_surface->AddChild(layer_1); - - rounded_corner_layer_2->AddChild(layer_2); - - layer_2->AddChild(rounded_corner_layer_3); - - rounded_corner_layer_3->AddChild(rounded_corner_layer_4); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - render_surface->SetPosition(gfx::PointF(0, 0)); - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - layer_1->SetPosition(gfx::PointF(10.f, 10.f)); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - layer_2->SetPosition(gfx::PointF(30.f, 30.f)); - rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); - rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - render_surface->SetBounds(gfx::Size(50, 50)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - layer_1->SetBounds(gfx::Size(10, 10)); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - layer_2->SetBounds(gfx::Size(25, 25)); - rounded_corner_layer_3->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); - rounded_corner_layer_4->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); - - // Add Layer transforms. - gfx::Transform layer_2_transform; - constexpr gfx::Vector2dF kLayer2Translation(10.f, 10.f); - layer_2_transform.Translate(kLayer2Translation); - layer_2->SetTransform(layer_2_transform); - - gfx::Transform rounded_corner_layer_3_transform; - constexpr float kRoundedCorner3Scale = 2.f; - rounded_corner_layer_3_transform.Scale(kRoundedCorner3Scale, - kRoundedCorner3Scale); - rounded_corner_layer_3->SetTransform(rounded_corner_layer_3_transform); - - // Set the layer properties - render_surface->SetForceRenderSurfaceForTesting(true); - - root->SetIsDrawable(true); - render_surface->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - layer_2->SetIsDrawable(true); - rounded_corner_layer_3->SetIsDrawable(true); - rounded_corner_layer_4->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - rounded_corner_layer_3->SetRoundedCorner( - {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, - kRoundedCorner3Radius}); - rounded_corner_layer_4->SetRoundedCorner( - {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, - kRoundedCorner4Radius}); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this effect node has no descendants that draw and no descendant that - // has a rounded corner, it does not need a render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this node has descendants with roudned corners, it needs a render - // surface. It also has 2 descendants that draw. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - // Since this node has a descendant that has a rounded corner, it will trigger - // the creation of a render surface. - effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), - kRoundedCorner3Radius); - EXPECT_EQ(rounded_corner_bounds_3.rect(), - gfx::RectF(kRoundedCornerLayer3Bound.size())); - - // Since this node has no descendants that draw nor any descendant that has a - // rounded corner, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_4.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), - kRoundedCorner4Radius); - EXPECT_EQ(rounded_corner_bounds_4.rect(), - gfx::RectF(kRoundedCornerLayer4Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_1_impl = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_2_impl = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - LayerImpl* rounded_corner_layer_3_impl = - layer_tree_impl->LayerById(rounded_corner_layer_3->id()); - LayerImpl* rounded_corner_layer_4_impl = - layer_tree_impl->LayerById(rounded_corner_layer_4->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |render_surface|, hence its target - // bounds are relative to |render_surface|. - // The offset from the origin of the render target is [15, 15] and the device - // scale factor is 1.6 thus giving the target space origin of [24, 24]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 2 - // The render target for this layer is |root|. - // The offset from the origin of the render target is [40, 40] and the device - // scale factor is 1.6 thus giving the target space origin of [64, 64]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_2 = - rounded_corner_layer_2_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Rounded corner layer 3 - // The render target for this layer is |rounded_corner_2|. - // The net offset from the origin of the render target is [40, 55] and the - // device scale factor is 1.6 thus giving the target space origin of [64, 88]. - // The corner radius is also scaled by a factor of 1.6 * transform scale. - const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_3_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer3Bound; - bounds_in_target_space += - layer_2->position().OffsetFromOrigin() + kLayer2Translation; - bounds_in_target_space.Scale(kDeviceScale); - gfx::SizeF transformed_size = bounds_in_target_space.size(); - transformed_size.Scale(kRoundedCorner3Scale); - bounds_in_target_space.set_size(transformed_size); - - const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_3_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), - kRoundedCorner3Radius * kDeviceScale * kRoundedCorner3Scale); - - // Rounded corner layer 4 - // The render target for this layer is |rounded_corner_3|. - // The net offset from the origin of the render target is [1, 1] and the - // net scale is 1.6 * transform scale = 3.2 thus giving the target space o - // rigin of [3.2, 3.2]. - // The corner radius is also scaled by a factor of 3.2. - const gfx::RRectF actual_rrect_4 = - rounded_corner_layer_4_impl->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer4Bound; - bounds_in_target_space.Scale(kDeviceScale * kRoundedCorner3Scale); - EXPECT_EQ(actual_rrect_4.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_4.GetSimpleRadius(), - kRoundedCorner4Radius * kDeviceScale * kRoundedCorner3Scale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RoundedCornerBoundsInterveningRenderTarget) { - // Layer Tree: - // +root - // +--rounded corner layer 1 [should not trigger render surface] - // +----render surface [Does not draw] - // +------rounded corner layer 2 [should not trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(60.f, 0.f, 40.f, 30.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 30.f, 20.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> render_surface = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - - // Set up layer tree - root->AddChild(rounded_corner_layer_1); - rounded_corner_layer_1->AddChild(render_surface); - render_surface->AddChild(rounded_corner_layer_2); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - render_surface->SetPosition(gfx::PointF(0, 0)); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - render_surface->SetBounds(gfx::Size(30, 30)); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - - // Set the layer properties - render_surface->SetForceRenderSurfaceForTesting(true); - - root->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this effect node has only 1 descendant that draws and no descendant - // that has a rounded corner before the render surface, it does not need a - // render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this effect node has no descendants that draw and no descendant that - // has a rounded corner, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_1_impl = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_2_impl = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |root|, hence its target - // bounds are relative to |root|. - // The offset from the origin of the render target is [60, 0] and the device - // scale factor is 1.6 thus giving the target space origin of [96, 0]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 2 - // The render target for this layer is |render_surface|. - // The offset from the origin of the render target is [0, 0]. - const gfx::RRectF actual_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - RoundedCornerBoundsSiblingRenderTarget) { - // Layer Tree: - // +root - // +--rounded corner layer 1 [should trigger render surface] - // +----render surface [Does not draw] - // +----rounded corner layer 2 [should not trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 60.f, 30.f, 40.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 20.f, 30.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> render_surface = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - - // Set up layer tree - root->AddChild(rounded_corner_layer_1); - rounded_corner_layer_1->AddChild(render_surface); - rounded_corner_layer_1->AddChild(rounded_corner_layer_2); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - render_surface->SetPosition(gfx::PointF(0, 0)); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - render_surface->SetBounds(gfx::Size(30, 30)); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - - // Set the layer properties - render_surface->SetForceRenderSurfaceForTesting(true); - - root->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this effect node has 1 descendant with a rounded corner without a - // render surface along the chain, it need a render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this effect node has no descendants that draw and no descendant that - // has a rounded corner, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_1_impl = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_2_impl = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |root|, hence its target - // bounds are relative to |root|. - // The offset from the origin of the render target is [0, 60] and the device - // scale factor is 1.6 thus giving the target space origin of [0, 96]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_1 = - rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); - - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_1 = - rounded_corner_layer_1_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 2 - // The render target for this layer is |render_surface|. - // The offset from the origin of the render target is [0, 0]. - const gfx::RRectF actual_rrect_2 = - rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - FastRoundedCornerDoesNotTriggerRenderSurface) { - // Layer Tree: - // +root - // +--fast rounded corner layer [should not trigger render surface] - // +----layer 1 - // +----layer 2 - // +--rounded corner layer [should trigger render surface] - // +----layer 3 - // +----layer 4 - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 0.f, 50.f, 50.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> fast_rounded_corner_layer = Layer::Create(); - scoped_refptr<Layer> layer_1 = Layer::Create(); - scoped_refptr<Layer> layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer = Layer::Create(); - scoped_refptr<Layer> layer_3 = Layer::Create(); - scoped_refptr<Layer> layer_4 = Layer::Create(); - - // Set up layer tree - root->AddChild(fast_rounded_corner_layer); - root->AddChild(rounded_corner_layer); - - fast_rounded_corner_layer->AddChild(layer_1); - fast_rounded_corner_layer->AddChild(layer_2); - - rounded_corner_layer->AddChild(layer_3); - rounded_corner_layer->AddChild(layer_4); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - fast_rounded_corner_layer->SetPosition(kRoundedCornerLayer1Bound.origin()); - layer_1->SetPosition(gfx::PointF(0.f, 0.f)); - layer_2->SetPosition(gfx::PointF(25.f, 0.f)); - rounded_corner_layer->SetPosition(kRoundedCornerLayer2Bound.origin()); - layer_3->SetPosition(gfx::PointF(0.f, 0.f)); - layer_4->SetPosition(gfx::PointF(30.f, 0.f)); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - fast_rounded_corner_layer->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - layer_1->SetBounds(gfx::Size(25, 25)); - layer_2->SetBounds(gfx::Size(25, 25)); - rounded_corner_layer->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - layer_3->SetBounds(gfx::Size(30, 60)); - layer_4->SetBounds(gfx::Size(30, 60)); - - root->SetIsDrawable(true); - fast_rounded_corner_layer->SetIsDrawable(true); - layer_1->SetIsDrawable(true); - layer_2->SetIsDrawable(true); - rounded_corner_layer->SetIsDrawable(true); - layer_3->SetIsDrawable(true); - layer_4->SetIsDrawable(true); - - // Set Rounded corners - fast_rounded_corner_layer->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - - fast_rounded_corner_layer->SetIsFastRoundedCorner(true); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this layer has a fast rounded corner, it should not have a render - // surface even though it has 2 layers in the subtree that draws content. - const EffectNode* effect_node = - GetEffectNode(fast_rounded_corner_layer.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this node has 2 descendants that draw, it will have a rounded corner. - effect_node = GetEffectNode(rounded_corner_layer.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* fast_rounded_corner_layer_impl = - layer_tree_impl->LayerById(fast_rounded_corner_layer->id()); - LayerImpl* layer_1_impl = layer_tree_impl->LayerById(layer_1->id()); - LayerImpl* layer_2_impl = layer_tree_impl->LayerById(layer_2->id()); - LayerImpl* rounded_corner_layer_impl = - layer_tree_impl->LayerById(rounded_corner_layer->id()); - LayerImpl* layer_3_impl = layer_tree_impl->LayerById(layer_3->id()); - LayerImpl* layer_4_impl = layer_tree_impl->LayerById(layer_4->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Fast rounded corner layer. - // The render target for this layer is |root|, hence its target bounds are - // relative to |root|. - // The offset from the origin of the render target is [0, 0] and the device - // scale factor is 1.6. - const gfx::RRectF actual_rrect_1 = - fast_rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Layer 1 and layer 2 rounded corner bounds - // This should have the same rounded corner boudns as fast rounded corner - // layer. - const gfx::RRectF layer_1_rrect = - layer_1_impl->draw_properties().rounded_corner_bounds; - const gfx::RRectF layer_2_rrect = - layer_2_impl->draw_properties().rounded_corner_bounds; - EXPECT_EQ(actual_rrect_1, layer_1_rrect); - EXPECT_EQ(actual_rrect_1, layer_2_rrect); - - // Rounded corner layer - // The render target for this layer is |root|. - // The offset from the origin of the render target is [40, 40] and the device - // scale factor is 1.6 thus giving the target space origin of [64, 64]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_2 = - rounded_corner_layer_impl->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Layer 3 and layer 4 should have no rounded corner bounds set as their - // parent is a render surface. - const gfx::RRectF layer_3_rrect = - layer_3_impl->draw_properties().rounded_corner_bounds; - const gfx::RRectF layer_4_rrect = - layer_4_impl->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(layer_3_rrect.IsEmpty()); - EXPECT_TRUE(layer_4_rrect.IsEmpty()); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - FastRoundedCornerTriggersRenderSurfaceInAncestor) { - // Layer Tree: - // +root - // +--rounded corner layer [1] [should trigger render surface] - // +----fast rounded corner layer [2] [should not trigger render surface] - // +--rounded corner layer [3] [should trigger render surface] - // +----rounded corner layer [4] [should not trigger render surface] - - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - constexpr int kRoundedCorner3Radius = 1; - constexpr int kRoundedCorner4Radius = 3; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(5.f, 5.f, 50.f, 50.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 25.f, 25.f); - constexpr gfx::RectF kRoundedCornerLayer3Bound(40.f, 40.f, 60.f, 60.f); - constexpr gfx::RectF kRoundedCornerLayer4Bound(30.f, 0.f, 30.f, 60.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> fast_rounded_corner_layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); - - // Set up layer tree - root->AddChild(rounded_corner_layer_1); - root->AddChild(rounded_corner_layer_3); - - rounded_corner_layer_1->AddChild(fast_rounded_corner_layer_2); - - rounded_corner_layer_3->AddChild(rounded_corner_layer_4); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - fast_rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); - rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); - rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - fast_rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - rounded_corner_layer_3->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); - rounded_corner_layer_4->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); - - root->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - fast_rounded_corner_layer_2->SetIsDrawable(true); - rounded_corner_layer_3->SetIsDrawable(true); - rounded_corner_layer_4->SetIsDrawable(true); - - // Set Rounded corners - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - fast_rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - rounded_corner_layer_3->SetRoundedCorner( - {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, - kRoundedCorner3Radius}); - rounded_corner_layer_4->SetRoundedCorner( - {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, - kRoundedCorner4Radius}); - - fast_rounded_corner_layer_2->SetIsFastRoundedCorner(true); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this layer has a descendant that has rounded corner, this node will - // require a render surface. - const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this layer has no descendant with rounded corner or drawable, it will - // not have a render surface. - effect_node = GetEffectNode(fast_rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - // Since this layer has 1 descendant with a rounded corner, it should have a - // render surface. - effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), - kRoundedCorner3Radius); - EXPECT_EQ(rounded_corner_bounds_3.rect(), - gfx::RectF(kRoundedCornerLayer3Bound.size())); - - // Since this layer no descendants, it would no thave a render pass. - effect_node = GetEffectNode(rounded_corner_layer_4.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), - kRoundedCorner4Radius); - EXPECT_EQ(rounded_corner_bounds_4.rect(), - gfx::RectF(kRoundedCornerLayer4Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* rounded_corner_layer_impl_1 = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* fast_rounded_corner_layer_impl_2 = - layer_tree_impl->LayerById(fast_rounded_corner_layer_2->id()); - LayerImpl* rounded_corner_layer_impl_3 = - layer_tree_impl->LayerById(rounded_corner_layer_3->id()); - LayerImpl* rounded_corner_layer_impl_4 = - layer_tree_impl->LayerById(rounded_corner_layer_4->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Rounded corner layer 1. - // The render target for this layer is |root|, hence its target bounds are - // relative to |root|. - // The offset from the origin of the render target is [5, 5] and the device - // scale factor is 1.6 giving a total offset of [8, 8]. - const gfx::RRectF actual_self_rrect_1 = - rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); - - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_1 = - rounded_corner_layer_impl_1->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Fast rounded corner layer 2 - // The render target for this layer is |rounded_corner_layer_1|. - // The offset from the origin of the render target is [0, 0] and the device - // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - fast_rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Rounded corner layer 3 - // The render target for this layer is |root|. - // The offset from the origin of the render target is [40, 40] and the device - // scale factor is 1.6 thus giving the target space origin of [64, 64]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer3Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_impl_3->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), - kRoundedCorner3Radius * kDeviceScale); - - // Rounded corner layer 4 - // The render target for this layer is |rounded_corner_layer_3|. - // The offset from the origin of the render target is [30, 0] and the device - // scale factor is 1.6 thus giving the target space origin of [48, 0]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_4 = - rounded_corner_layer_impl_4->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer4Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), - kRoundedCorner4Radius * kDeviceScale); -} - -// In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - FastRoundedCornerDoesNotTriggerRenderSurfaceFromSubtree) { - // Layer Tree: - // +root - // +--fast rounded corner layer 1 [should trigger render surface] - // +----rounded corner layer 1 [should not trigger render surface] - // +--rounded corner layer 2 [should trigger render surface] - // +----rounded corner layer 3 [should not trigger render surface] - constexpr int kRoundedCorner1Radius = 2; - constexpr int kRoundedCorner2Radius = 5; - constexpr int kRoundedCorner3Radius = 4; - constexpr int kRoundedCorner4Radius = 5; - - constexpr gfx::RectF kRoundedCornerLayer1Bound(10.f, 5.f, 45.f, 50.f); - constexpr gfx::RectF kRoundedCornerLayer2Bound(5.f, 5.f, 20.f, 20.f); - constexpr gfx::RectF kRoundedCornerLayer3Bound(60.f, 5.f, 40.f, 25.f); - constexpr gfx::RectF kRoundedCornerLayer4Bound(0.f, 10.f, 10.f, 20.f); - - constexpr float kDeviceScale = 1.6f; - - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> fast_rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); - scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); - - // Set up layer tree - root->AddChild(fast_rounded_corner_layer_1); - root->AddChild(rounded_corner_layer_2); - - fast_rounded_corner_layer_1->AddChild(rounded_corner_layer_1); - rounded_corner_layer_2->AddChild(rounded_corner_layer_3); - - // Set the root layer on host. - host()->SetRootLayer(root); - - // Set layer positions. - fast_rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); - rounded_corner_layer_1->SetPosition(kRoundedCornerLayer2Bound.origin()); - rounded_corner_layer_2->SetPosition(kRoundedCornerLayer3Bound.origin()); - rounded_corner_layer_3->SetPosition(kRoundedCornerLayer4Bound.origin()); - - // Set up layer bounds. - root->SetBounds(gfx::Size(100, 100)); - fast_rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); - rounded_corner_layer_1->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); - rounded_corner_layer_2->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); - rounded_corner_layer_3->SetBounds( - gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); - - root->SetIsDrawable(true); - fast_rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_1->SetIsDrawable(true); - rounded_corner_layer_2->SetIsDrawable(true); - rounded_corner_layer_3->SetIsDrawable(true); - - // Set Rounded corners - fast_rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, - kRoundedCorner1Radius}); - rounded_corner_layer_1->SetRoundedCorner( - {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, - kRoundedCorner2Radius}); - rounded_corner_layer_2->SetRoundedCorner( - {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, - kRoundedCorner3Radius}); - rounded_corner_layer_3->SetRoundedCorner( - {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, - kRoundedCorner4Radius}); - - fast_rounded_corner_layer_1->SetIsFastRoundedCorner(true); - - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); - - // Since this layer has a descendant with rounded corner, it needs a render - // surface. - const EffectNode* effect_node = - GetEffectNode(fast_rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_TRUE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), - kRoundedCorner1Radius); - EXPECT_EQ(rounded_corner_bounds_1.rect(), - gfx::RectF(kRoundedCornerLayer1Bound.size())); - - // Since this layer has no descendant with rounded corner or drawable, it will - // not have a render surface. - effect_node = GetEffectNode(rounded_corner_layer_1.get()); - gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), - kRoundedCorner2Radius); - EXPECT_EQ(rounded_corner_bounds_2.rect(), - gfx::RectF(kRoundedCornerLayer2Bound.size())); - - // Since this layer has a descendant with rounded corner, it should have a - // render surface. - effect_node = GetEffectNode(rounded_corner_layer_2.get()); - gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; - EXPECT_TRUE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), - kRoundedCorner3Radius); - EXPECT_EQ(rounded_corner_bounds_3.rect(), - gfx::RectF(kRoundedCornerLayer3Bound.size())); - - // Since this layer has no descendant, it does not need a render surface. - effect_node = GetEffectNode(rounded_corner_layer_3.get()); - gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; - EXPECT_FALSE(effect_node->HasRenderSurface()); - EXPECT_FALSE(effect_node->is_fast_rounded_corner); - EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), - kRoundedCorner4Radius); - EXPECT_EQ(rounded_corner_bounds_4.rect(), - gfx::RectF(kRoundedCornerLayer4Bound.size())); - - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); - LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); - - // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); - LayerImpl* fast_rounded_corner_layer_impl_1 = - layer_tree_impl->LayerById(fast_rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_impl_1 = - layer_tree_impl->LayerById(rounded_corner_layer_1->id()); - LayerImpl* rounded_corner_layer_impl_2 = - layer_tree_impl->LayerById(rounded_corner_layer_2->id()); - LayerImpl* rounded_corner_layer_impl_3 = - layer_tree_impl->LayerById(rounded_corner_layer_3->id()); - - // Set the root layer on host. - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); - - // Fast rounded corner layer 1. - // The render target for this layer is |root|, hence its target bounds are - // relative to |root|. - // The offset from the origin of the render target is [5, 5] and the device - // scale factor is 1.6. - const gfx::RRectF actual_self_rrect_1 = - fast_rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); - - gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_1 = - fast_rounded_corner_layer_impl_1->render_target() - ->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), - kRoundedCorner1Radius * kDeviceScale); - - // Rounded corner layer 1 - // The render target for this layer is |fast_rounded_corner_layer_1|. - // The offset from the origin of the render target is [0, 0] and the device - // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_2 = - rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer2Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), - kRoundedCorner2Radius * kDeviceScale); - - // Rounded corner layer 3 - // The render target for this layer is |root|. - // The offset from the origin of the render target is [5, 5] and the device - // scale factor is 1.6 thus giving the target space origin of [8, 8]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_3 = - rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; - EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); - - bounds_in_target_space = kRoundedCornerLayer3Bound; - bounds_in_target_space.Scale(kDeviceScale); - const gfx::RRectF actual_render_target_rrect_3 = - rounded_corner_layer_impl_2->render_target()->rounded_corner_bounds(); - EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), - kRoundedCorner3Radius * kDeviceScale); - - // Rounded corner layer 4 - // The render target for this layer is |rounded_corner_layer_2|. - // The offset from the origin of the render target is [0, 5] and the device - // scale factor is 1.6 thus giving the target space origin of [0, 8]. The - // corner radius is also scaled by a factor of 1.6. - const gfx::RRectF actual_self_rrect_4 = - rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; - bounds_in_target_space = kRoundedCornerLayer4Bound; - bounds_in_target_space.Scale(kDeviceScale); - EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); - EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), - kRoundedCorner4Radius * kDeviceScale); -} - // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { +TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBounds) { // The custom clip API should have the same effect as if an intermediate // clip layer has been added to the layer tree. To check this the test creates // 2 subtree for a root layer. One of the subtree uses the clip API to clip @@ -10453,24 +7915,17 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { parent->SetClipRect(kClipBounds); clip_layer->SetMasksToBounds(true); - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); + UpdateMainDrawProperties(kDeviceScale); EXPECT_EQ(GetClipNode(parent.get())->clip, gfx::RectF(kClipBounds)); EXPECT_TRUE(!parent->clip_rect().IsEmpty()); EXPECT_EQ(GetClipNode(child.get())->clip, gfx::RectF(kClipBounds)); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); + CommitAndActivate(kDeviceScale); LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id()); LayerImpl* child_impl = layer_tree_impl->LayerById(child->id()); LayerImpl* expected_parent_impl = @@ -10478,7 +7933,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { LayerImpl* expected_child_impl = layer_tree_impl->LayerById(expected_child->id()); - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); EXPECT_TRUE(parent_impl->is_clipped()); EXPECT_TRUE(child_impl->is_clipped()); @@ -10490,8 +7945,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, CustomLayerClipBounds) { } // In layer tree mode, not using impl-side PropertyTreeBuilder. -TEST_F(LayerTreeHostCommonTestWithLayerTree, - CustomLayerClipBoundsWithMaskToBounds) { +TEST_F(DrawPropertiesTestWithLayerTree, CustomLayerClipBoundsWithMaskToBounds) { // The custom clip API should have the same effect as if an intermediate // clip layer has been added to the layer tree. To check this the test creates // 2 subtree for a root layer. One of the subtree uses the clip API to clip @@ -10563,7 +8017,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, clip_layer->SetMasksToBounds(true); expected_parent->SetMasksToBounds(true); - ExecuteCalculateDrawProperties(root.get(), kDeviceScale); + UpdateMainDrawProperties(kDeviceScale); const gfx::RectF expected_clip_bounds = gfx::IntersectRects( gfx::RectF(kClipBounds), gfx::RectF(kParentLayerBounds)); @@ -10572,17 +8026,10 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, EXPECT_EQ(GetClipNode(child.get())->clip, expected_clip_bounds); - host()->host_impl()->CreatePendingTree(); - host()->CommitAndCreatePendingTree(); - // TODO(https://crbug.com/939968) This call should be handled by - // FakeLayerTreeHost instead of manually pushing the properties from the - // layer tree host to the pending tree. - root->layer_tree_host()->PushLayerTreePropertiesTo(host()->pending_tree()); - host()->host_impl()->ActivateSyncTree(); + CommitAndActivate(kDeviceScale); LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); // Get the layer impl for each Layer. - LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); LayerImpl* parent_impl = layer_tree_impl->LayerById(parent->id()); LayerImpl* child_impl = layer_tree_impl->LayerById(child->id()); LayerImpl* expected_parent_impl = @@ -10590,7 +8037,7 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, LayerImpl* expected_child_impl = layer_tree_impl->LayerById(expected_child->id()); - ExecuteCalculateDrawProperties(root_impl, kDeviceScale); + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); EXPECT_TRUE(parent_impl->is_clipped()); EXPECT_TRUE(child_impl->is_clipped()); @@ -10601,5 +8048,74 @@ TEST_F(LayerTreeHostCommonTestWithLayerTree, EXPECT_EQ(child_impl->clip_rect(), expected_child_impl->clip_rect()); } +// In layer tree mode, not using impl-side PropertyTreeBuilder. +TEST_F(DrawPropertiesTestWithLayerTree, RoundedCornerOnRenderSurface) { + // -Root + // - Parent 1 + // - [Render Surface] Child 1 with rounded corner + // - [Render Surface] Parent 2 with rounded corner + // - [Render Surface] Child 2 + // - Parent 3 with rounded corner + // - [Render Surface] Child 3 + + scoped_refptr<Layer> root = Layer::Create(); + host()->SetRootLayer(root); + root->SetBounds(gfx::Size(250, 250)); + root->SetIsDrawable(true); + + scoped_refptr<Layer> parent_1 = Layer::Create(); + root->AddChild(parent_1); + parent_1->SetBounds(gfx::Size(80, 80)); + parent_1->SetPosition(gfx::PointF(0, 0)); + parent_1->SetIsDrawable(true); + + scoped_refptr<Layer> parent_2 = Layer::Create(); + root->AddChild(parent_2); + parent_2->SetBounds(gfx::Size(80, 80)); + parent_1->SetPosition(gfx::PointF(80, 80)); + parent_2->SetIsDrawable(true); + parent_2->SetForceRenderSurfaceForTesting(true); + parent_2->SetRoundedCorner(gfx::RoundedCornersF(10.f)); + parent_2->SetIsFastRoundedCorner(true); + + scoped_refptr<Layer> parent_3 = Layer::Create(); + root->AddChild(parent_3); + parent_3->SetBounds(gfx::Size(80, 80)); + parent_1->SetPosition(gfx::PointF(160, 160)); + parent_3->SetIsDrawable(true); + parent_3->SetRoundedCorner(gfx::RoundedCornersF(10.f)); + parent_3->SetIsFastRoundedCorner(true); + + scoped_refptr<Layer> child_1 = Layer::Create(); + parent_1->AddChild(child_1); + child_1->SetBounds(gfx::Size(80, 80)); + child_1->SetIsDrawable(true); + child_1->SetForceRenderSurfaceForTesting(true); + child_1->SetRoundedCorner(gfx::RoundedCornersF(10.f)); + child_1->SetIsFastRoundedCorner(true); + + scoped_refptr<Layer> child_2 = Layer::Create(); + parent_2->AddChild(child_2); + child_2->SetBounds(gfx::Size(80, 80)); + child_2->SetIsDrawable(true); + child_2->SetForceRenderSurfaceForTesting(true); + + scoped_refptr<Layer> child_3 = Layer::Create(); + parent_3->AddChild(child_3); + child_3->SetBounds(gfx::Size(80, 80)); + child_3->SetIsDrawable(true); + child_3->SetForceRenderSurfaceForTesting(true); + + UpdateMainDrawProperties(); + CommitAndActivate(); + + EXPECT_FALSE( + GetRenderSurfaceImpl(child_1)->rounded_corner_bounds().IsEmpty()); + EXPECT_FALSE( + GetRenderSurfaceImpl(child_2)->rounded_corner_bounds().IsEmpty()); + EXPECT_FALSE( + GetRenderSurfaceImpl(child_3)->rounded_corner_bounds().IsEmpty()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index 57241bad713..ad08ae82627 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -8,6 +8,7 @@ #include <vector> +#include "base/containers/adapters.h" #include "base/containers/stack.h" #include "cc/base/math_util.h" #include "cc/layers/draw_properties.h" @@ -30,21 +31,21 @@ namespace draw_property_utils { namespace { -static gfx::Rect ToEnclosingClipRect(const gfx::RectF& clip_rect) { +gfx::Rect ToEnclosingClipRect(const gfx::RectF& clip_rect) { constexpr float kClipError = 0.00001f; return gfx::ToEnclosingRectIgnoringError(clip_rect, kClipError); } -static bool IsRootLayer(const Layer* layer) { +bool IsRootLayer(const Layer* layer) { return !layer->parent(); } -static bool IsRootLayer(const LayerImpl* layer) { +bool IsRootLayer(const LayerImpl* layer) { return layer->layer_tree_impl()->IsRootLayer(layer); } -static void PostConcatSurfaceContentsScale(const EffectNode* effect_node, - gfx::Transform* transform) { +void PostConcatSurfaceContentsScale(const EffectNode* effect_node, + gfx::Transform* transform) { if (!effect_node) { // This can happen when PaintArtifactCompositor builds property trees as it // doesn't set effect ids on clip nodes. @@ -55,11 +56,11 @@ static void PostConcatSurfaceContentsScale(const EffectNode* effect_node, effect_node->surface_contents_scale.y(), 1.f); } -static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, - int source_effect_id, - int dest_effect_id, - gfx::RectF clip_in_source_space, - gfx::RectF* clip_in_dest_space) { +bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, + int source_effect_id, + int dest_effect_id, + gfx::RectF clip_in_source_space, + gfx::RectF* clip_in_dest_space) { const EffectNode* source_effect_node = property_trees->effect_tree.Node(source_effect_id); int source_transform_id = source_effect_node->transform_id; @@ -89,7 +90,7 @@ static bool ConvertRectBetweenSurfaceSpaces(const PropertyTrees* property_trees, return true; } -static ConditionalClip ComputeTargetRectInLocalSpace( +ConditionalClip ComputeTargetRectInLocalSpace( gfx::RectF rect, const PropertyTrees* property_trees, int target_transform_id, @@ -110,7 +111,7 @@ static ConditionalClip ComputeTargetRectInLocalSpace( MathUtil::ProjectClippedRect(target_to_local, rect)}; } -static ConditionalClip ComputeLocalRectInTargetSpace( +ConditionalClip ComputeLocalRectInTargetSpace( gfx::RectF rect, const PropertyTrees* property_trees, int current_transform_id, @@ -131,10 +132,10 @@ static ConditionalClip ComputeLocalRectInTargetSpace( MathUtil::ProjectClippedRect(current_to_target, rect)}; } -static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, - const PropertyTrees* property_trees, - int target_transform_id, - int target_effect_id) { +ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, + const PropertyTrees* property_trees, + int target_transform_id, + int target_effect_id) { if (clip_node->transform_id != target_transform_id) { return ComputeLocalRectInTargetSpace(clip_node->clip, property_trees, clip_node->transform_id, @@ -152,12 +153,12 @@ static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, return ConditionalClip{true /* is_clipped */, current_clip}; } -static bool ApplyClipNodeToAccumulatedClip(const PropertyTrees* property_trees, - bool include_expanding_clips, - int target_id, - int target_transform_id, - const ClipNode* clip_node, - gfx::RectF* accumulated_clip) { +bool ApplyClipNodeToAccumulatedClip(const PropertyTrees* property_trees, + bool include_expanding_clips, + int target_id, + int target_transform_id, + const ClipNode* clip_node, + gfx::RectF* accumulated_clip) { switch (clip_node->clip_type) { case ClipNode::ClipType::APPLIES_LOCAL_CLIP: { ConditionalClip current_clip = ComputeCurrentClip( @@ -207,10 +208,10 @@ static bool ApplyClipNodeToAccumulatedClip(const PropertyTrees* property_trees, return true; } -static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, - bool include_expanding_clips, - int local_clip_id, - int target_id) { +ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, + bool include_expanding_clips, + int local_clip_id, + int target_id) { ClipRectData* cached_data = property_trees->FetchClipRectFromCache(local_clip_id, target_id); if (cached_data->target_id != EffectTree::kInvalidNodeId) { @@ -325,15 +326,14 @@ static ConditionalClip ComputeAccumulatedClip(PropertyTrees* property_trees, return clip; } -static bool HasSingularTransform(int transform_tree_index, - const TransformTree& tree) { +bool HasSingularTransform(int transform_tree_index, const TransformTree& tree) { const TransformNode* node = tree.Node(transform_tree_index); return !node->is_invertible || !node->ancestors_are_invertible; } -static int LowestCommonAncestor(int clip_id_1, - int clip_id_2, - const ClipTree* clip_tree) { +int LowestCommonAncestor(int clip_id_1, + int clip_id_2, + const ClipTree* clip_tree) { const ClipNode* clip_node_1 = clip_tree->Node(clip_id_1); const ClipNode* clip_node_2 = clip_tree->Node(clip_id_2); while (clip_node_1->id != clip_node_2->id) { @@ -345,9 +345,9 @@ static int LowestCommonAncestor(int clip_id_1, return clip_node_1->id; } -static void SetHasContributingLayerThatEscapesClip(int lca_clip_id, - int target_effect_id, - EffectTree* effect_tree) { +void SetHasContributingLayerThatEscapesClip(int lca_clip_id, + int target_effect_id, + EffectTree* effect_tree) { const EffectNode* effect_node = effect_tree->Node(target_effect_id); // Find all ancestor targets starting from effect_node who are clipped by // a descendant of lowest ancestor clip and set their @@ -362,14 +362,14 @@ static void SetHasContributingLayerThatEscapesClip(int lca_clip_id, } template <typename LayerType> -static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, - const TransformTree& tree) { +int TransformTreeIndexForBackfaceVisibility(LayerType* layer, + const TransformTree& tree) { if (!layer->use_parent_backface_visibility() || !layer->has_transform_node()) return layer->transform_tree_index(); return tree.Node(layer->transform_tree_index())->parent_id; } -static bool IsTargetSpaceTransformBackFaceVisible( +bool IsTargetSpaceTransformBackFaceVisible( Layer* layer, int transform_tree_index, const PropertyTrees* property_trees) { @@ -378,7 +378,7 @@ static bool IsTargetSpaceTransformBackFaceVisible( return false; } -static bool IsTargetSpaceTransformBackFaceVisible( +bool IsTargetSpaceTransformBackFaceVisible( LayerImpl* layer, int transform_tree_index, const PropertyTrees* property_trees) { @@ -390,30 +390,30 @@ static bool IsTargetSpaceTransformBackFaceVisible( } template <typename LayerType> -static bool IsLayerBackFaceVisible(LayerType* layer, - int transform_tree_index, - const PropertyTrees* property_trees) { +bool IsLayerBackFaceVisible(LayerType* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { return IsTargetSpaceTransformBackFaceVisible(layer, transform_tree_index, property_trees); } -static inline bool TransformToScreenIsKnown(Layer* layer, - int transform_tree_index, - const TransformTree& tree) { +inline bool TransformToScreenIsKnown(Layer* layer, + int transform_tree_index, + const TransformTree& tree) { const TransformNode* node = tree.Node(transform_tree_index); return !node->to_screen_is_potentially_animated; } -static inline bool TransformToScreenIsKnown(LayerImpl* layer, - int transform_tree_index, - const TransformTree& tree) { +inline bool TransformToScreenIsKnown(LayerImpl* layer, + int transform_tree_index, + const TransformTree& tree) { return true; } template <typename LayerType> -static bool LayerNeedsUpdateInternal(LayerType* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees) { +bool LayerNeedsUpdate(LayerType* layer, + bool layer_is_drawn, + const PropertyTrees* property_trees) { // Layers can be skipped if any of these conditions are met. // - is not drawn due to it or one of its ancestors being hidden (or having // no copy requests). @@ -454,7 +454,7 @@ static bool LayerNeedsUpdateInternal(LayerType* layer, } template <typename LayerType> -static inline bool LayerShouldBeSkippedInternal( +inline bool LayerShouldBeSkippedForDrawPropertiesComputation( LayerType* layer, const TransformTree& transform_tree, const EffectTree& effect_tree) { @@ -470,7 +470,7 @@ static inline bool LayerShouldBeSkippedInternal( effect_node->hidden_by_backface_visibility || !effect_node->is_drawn; } -static gfx::Rect LayerDrawableContentRect( +gfx::Rect LayerDrawableContentRect( const LayerImpl* layer, const gfx::Rect& layer_bounds_in_target_space, const gfx::Rect& clip_rect) { @@ -480,8 +480,8 @@ static gfx::Rect LayerDrawableContentRect( return layer_bounds_in_target_space; } -static void SetSurfaceIsClipped(const ClipTree& clip_tree, - RenderSurfaceImpl* render_surface) { +void SetSurfaceIsClipped(const ClipTree& clip_tree, + RenderSurfaceImpl* render_surface) { bool is_clipped; if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { // Root render surface is always clipped. @@ -504,8 +504,8 @@ static void SetSurfaceIsClipped(const ClipTree& clip_tree, render_surface->SetIsClipped(is_clipped); } -static void SetSurfaceDrawOpacity(const EffectTree& tree, - RenderSurfaceImpl* render_surface) { +void SetSurfaceDrawOpacity(const EffectTree& tree, + RenderSurfaceImpl* render_surface) { // Draw opacity of a surface is the product of opacities between the surface // (included) and its target surface (excluded). const EffectNode* node = tree.Node(render_surface->EffectTreeIndex()); @@ -517,7 +517,7 @@ static void SetSurfaceDrawOpacity(const EffectTree& tree, render_surface->SetDrawOpacity(draw_opacity); } -static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { +float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { if (!layer->render_target()) return 0.f; @@ -536,20 +536,18 @@ static float LayerDrawOpacity(const LayerImpl* layer, const EffectTree& tree) { } template <typename LayerType> -static gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, - const TransformTree& tree) { +gfx::Transform ScreenSpaceTransformInternal(LayerType* layer, + const TransformTree& tree) { gfx::Transform xform(1, 0, 0, 1, layer->offset_to_transform_parent().x(), layer->offset_to_transform_parent().y()); gfx::Transform ssxform = tree.ToScreen(layer->transform_tree_index()); xform.ConcatTransform(ssxform); - if (layer->should_flatten_screen_space_transform_from_property_tree()) - xform.FlattenTo2d(); return xform; } -static void SetSurfaceClipRect(const ClipNode* parent_clip_node, - PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface) { +void SetSurfaceClipRect(const ClipNode* parent_clip_node, + PropertyTrees* property_trees, + RenderSurfaceImpl* render_surface) { if (!render_surface->is_clipped()) { render_surface->SetClipRect(gfx::Rect()); return; @@ -573,8 +571,8 @@ static void SetSurfaceClipRect(const ClipNode* parent_clip_node, } } -static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface) { +void SetSurfaceDrawTransform(const PropertyTrees* property_trees, + RenderSurfaceImpl* render_surface) { const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; const TransformNode* transform_node = @@ -597,8 +595,7 @@ static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, render_surface->SetDrawTransform(render_surface_transform); } -static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, - LayerImpl* layer) { +gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, LayerImpl* layer) { const EffectNode* effect_node = property_trees->effect_tree.Node(layer->effect_tree_index()); int effect_ancestor_with_cache_render_surface = @@ -655,8 +652,7 @@ static gfx::Rect LayerVisibleRect(PropertyTrees* property_trees, return visible_rect; } -static ConditionalClip LayerClipRect(PropertyTrees* property_trees, - LayerImpl* layer) { +ConditionalClip LayerClipRect(PropertyTrees* property_trees, LayerImpl* layer) { const EffectTree* effect_tree = &property_trees->effect_tree; const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); const EffectNode* target_node = @@ -668,7 +664,7 @@ static ConditionalClip LayerClipRect(PropertyTrees* property_trees, layer->clip_tree_index(), target_node->id); } -static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( +std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( const PropertyTrees* property_trees, int effect_tree_index, bool for_render_surface) { @@ -693,9 +689,16 @@ static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( break; } - // Simply break if we reached a node that has a render surface or is the - // render target. - if (node->HasRenderSurface() || node->id == target_id) + // If the iteration has reached a node in the parent chain that has a render + // surface, then break. If this iteration is for a render surface to begin + // with, then ensure |node| is a parent of |effect_node|. + if (node->HasRenderSurface() && + (!for_render_surface || effect_node != node)) { + break; + } + + // Simply break if we reached a node that is the render target. + if (node->id == target_id) break; node = effect_tree->parent(node); @@ -710,17 +713,16 @@ static std::pair<gfx::RRectF, bool> GetRoundedCornerRRect( if (!property_trees->GetToTarget(node->transform_id, target_id, &to_target)) return kEmptyRoundedCornerInfo; - DCHECK(to_target.Preserves2dAxisAlignment()); + auto result = + std::make_pair(node->rounded_corner_bounds, node->is_fast_rounded_corner); - SkRRect result; - if (!SkRRect(node->rounded_corner_bounds) - .transform(to_target.matrix(), &result)) { + if (!to_target.TransformRRectF(&result.first)) return kEmptyRoundedCornerInfo; - } - return std::make_pair(gfx::RRectF(result), node->is_fast_rounded_corner); + + return result; } -static void UpdateRenderTarget(EffectTree* effect_tree) { +void UpdateRenderTarget(EffectTree* effect_tree) { for (int i = EffectTree::kContentsRootNodeId; i < static_cast<int>(effect_tree->size()); ++i) { EffectNode* node = effect_tree->Node(i); @@ -735,7 +737,7 @@ static void UpdateRenderTarget(EffectTree* effect_tree) { } } -static void ComputeClips(PropertyTrees* property_trees) { +void ComputeClips(PropertyTrees* property_trees) { DCHECK(!property_trees->transform_tree.needs_update()); ClipTree* clip_tree = &property_trees->clip_tree; if (!clip_tree->needs_update()) @@ -765,6 +767,352 @@ static void ComputeClips(PropertyTrees* property_trees) { clip_tree->set_needs_update(false); } +void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, + RenderSurfaceImpl* render_surface) { + SetSurfaceIsClipped(property_trees->clip_tree, render_surface); + SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); + SetSurfaceDrawTransform(property_trees, render_surface); + + render_surface->SetRoundedCornerRRect( + GetRoundedCornerRRect(property_trees, render_surface->EffectTreeIndex(), + /*for_render_surface*/ true) + .first); + render_surface->SetScreenSpaceTransform( + property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( + render_surface->TransformTreeIndex(), + render_surface->EffectTreeIndex())); + + const ClipNode* clip_node = + property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); + SetSurfaceClipRect(clip_node, property_trees, render_surface); +} + +void AddSurfaceToRenderSurfaceList(RenderSurfaceImpl* render_surface, + RenderSurfaceList* render_surface_list, + PropertyTrees* property_trees) { + // |render_surface| must appear after its target, so first make sure its + // target is in the list. + RenderSurfaceImpl* target = render_surface->render_target(); + bool is_root = + render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; + if (!is_root && !target->is_render_surface_list_member()) { + AddSurfaceToRenderSurfaceList(target, render_surface_list, property_trees); + } + render_surface->ClearAccumulatedContentRect(); + render_surface_list->push_back(render_surface); + render_surface->set_is_render_surface_list_member(true); + if (is_root) { + // The root surface does not contribute to any other surface, it has no + // target. + render_surface->set_contributes_to_drawn_surface(false); + } else { + bool contributes_to_drawn_surface = + property_trees->effect_tree.ContributesToDrawnSurface( + render_surface->EffectTreeIndex()); + render_surface->set_contributes_to_drawn_surface( + contributes_to_drawn_surface); + } + + ComputeSurfaceDrawProperties(property_trees, render_surface); + + // Ignore occlusion from outside the surface when surface contents need to be + // fully drawn. Layers with copy-request need to be complete. We could be + // smarter about layers with filters that move pixels and exclude regions + // where both layers and the filters are occluded, but this seems like + // overkill. + // TODO(senorblanco): make this smarter for the SkImageFilter case (check for + // pixel-moving filters) + const FilterOperations& filters = render_surface->Filters(); + bool is_occlusion_immune = render_surface->HasCopyRequest() || + render_surface->ShouldCacheRenderSurface() || + filters.HasReferenceFilter() || + filters.HasFilterThatMovesPixels(); + if (is_occlusion_immune) { + render_surface->SetNearestOcclusionImmuneAncestor(render_surface); + } else if (is_root) { + render_surface->SetNearestOcclusionImmuneAncestor(nullptr); + } else { + render_surface->SetNearestOcclusionImmuneAncestor( + render_surface->render_target()->nearest_occlusion_immune_ancestor()); + } +} + +bool SkipForInvertibility(const LayerImpl* layer, + PropertyTrees* property_trees) { + const TransformNode* transform_node = + property_trees->transform_tree.Node(layer->transform_tree_index()); + const EffectNode* effect_node = + property_trees->effect_tree.Node(layer->effect_tree_index()); + bool non_root_copy_request = + effect_node->closest_ancestor_with_copy_request_id > + EffectTree::kContentsRootNodeId; + gfx::Transform from_target; + // If there is a copy request, we check the invertibility of the transform + // between the node corresponding to the layer and the node corresponding to + // the copy request. Otherwise, we are interested in the invertibility of + // screen space transform which is already cached on the transform node. + return non_root_copy_request + ? !property_trees->GetFromTarget( + layer->transform_tree_index(), + effect_node->closest_ancestor_with_copy_request_id, + &from_target) + : !transform_node->ancestors_are_invertible; +} + +void ComputeInitialRenderSurfaceList(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + RenderSurfaceList* render_surface_list) { + EffectTree& effect_tree = property_trees->effect_tree; + for (int i = EffectTree::kContentsRootNodeId; + i < static_cast<int>(effect_tree.size()); ++i) { + if (RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(i)) { + render_surface->set_is_render_surface_list_member(false); + render_surface->reset_num_contributors(); + } + } + + RenderSurfaceImpl* root_surface = + effect_tree.GetRenderSurface(EffectTree::kContentsRootNodeId); + // The root surface always gets added to the render surface list. + AddSurfaceToRenderSurfaceList(root_surface, render_surface_list, + property_trees); + // For all non-skipped layers, add their target to the render surface list if + // it's not already been added, and add their content rect to the target + // surface's accumulated content rect. + for (LayerImpl* layer : *layer_tree_impl) { + DCHECK(layer); + layer->EnsureValidPropertyTreeIndices(); + + layer->set_contributes_to_drawn_render_surface(false); + layer->set_raster_even_if_not_drawn(false); + + bool is_root = layer_tree_impl->IsRootLayer(layer); + + bool skip_draw_properties_computation = + LayerShouldBeSkippedForDrawPropertiesComputation( + layer, property_trees->transform_tree, property_trees->effect_tree); + + bool skip_for_invertibility = SkipForInvertibility(layer, property_trees); + + bool skip_layer = !is_root && (skip_draw_properties_computation || + skip_for_invertibility); + + layer->set_raster_even_if_not_drawn(skip_for_invertibility && + !skip_draw_properties_computation); + if (skip_layer) + continue; + + bool layer_is_drawn = + property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn; + bool layer_should_be_drawn = + LayerNeedsUpdate(layer, layer_is_drawn, property_trees); + if (!layer_should_be_drawn) + continue; + + RenderSurfaceImpl* render_target = layer->render_target(); + if (!render_target->is_render_surface_list_member()) { + AddSurfaceToRenderSurfaceList(render_target, render_surface_list, + property_trees); + } + + layer->set_contributes_to_drawn_render_surface(true); + + // The layer contributes its drawable content rect to its render target. + render_target->AccumulateContentRectFromContributingLayer(layer); + render_target->increment_num_contributors(); + } +} + +void ComputeSurfaceContentRects(PropertyTrees* property_trees, + RenderSurfaceList* render_surface_list, + int max_texture_size) { + // Walk the list backwards, accumulating each surface's content rect into its + // target's content rect. + for (RenderSurfaceImpl* render_surface : + base::Reversed(*render_surface_list)) { + if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { + // The root surface's content rect is always the entire viewport. + render_surface->SetContentRectToViewport(); + continue; + } + + // Now all contributing drawable content rect has been accumulated to this + // render surface, calculate the content rect. + render_surface->CalculateContentRectFromAccumulatedContentRect( + max_texture_size); + + // Now the render surface's content rect is calculated correctly, it could + // contribute to its render target. + RenderSurfaceImpl* render_target = render_surface->render_target(); + DCHECK(render_target->is_render_surface_list_member()); + render_target->AccumulateContentRectFromContributingRenderSurface( + render_surface); + render_target->increment_num_contributors(); + } +} + +void ComputeListOfNonEmptySurfaces(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + RenderSurfaceList* initial_surface_list, + RenderSurfaceList* final_surface_list) { + // Walk the initial surface list forwards. The root surface and each + // surface with a non-empty content rect go into the final render surface + // layer list. Surfaces with empty content rects or whose target isn't in + // the final list do not get added to the final list. + bool removed_surface = false; + for (RenderSurfaceImpl* surface : *initial_surface_list) { + bool is_root = + surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; + RenderSurfaceImpl* target_surface = surface->render_target(); + if (!is_root && (surface->content_rect().IsEmpty() || + !target_surface->is_render_surface_list_member())) { + surface->set_is_render_surface_list_member(false); + removed_surface = true; + target_surface->decrement_num_contributors(); + continue; + } + final_surface_list->push_back(surface); + } + if (removed_surface) { + for (LayerImpl* layer : *layer_tree_impl) { + if (layer->contributes_to_drawn_render_surface()) { + RenderSurfaceImpl* render_target = layer->render_target(); + if (!render_target->is_render_surface_list_member()) { + layer->set_contributes_to_drawn_render_surface(false); + render_target->decrement_num_contributors(); + } + } + } + } +} + +void CalculateRenderSurfaceLayerList(LayerTreeImpl* layer_tree_impl, + PropertyTrees* property_trees, + RenderSurfaceList* render_surface_list, + const int max_texture_size) { + RenderSurfaceList initial_render_surface_list; + + // First compute a list that might include surfaces that later turn out to + // have an empty content rect. After surface content rects are computed, + // produce a final list that omits empty surfaces. + ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees, + &initial_render_surface_list); + ComputeSurfaceContentRects(property_trees, &initial_render_surface_list, + max_texture_size); + ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, + &initial_render_surface_list, + render_surface_list); +} + +void RecordRenderSurfaceReasonsForTracing( + const PropertyTrees* property_trees, + const RenderSurfaceList* render_surface_list) { + static const auto* tracing_enabled = + TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("cc"); + if (!*tracing_enabled || + // Don't output single root render surface. + render_surface_list->size() <= 1) + return; + + TRACE_EVENT_INSTANT1("cc", "RenderSurfaceReasonCount", + TRACE_EVENT_SCOPE_THREAD, "total", + render_surface_list->size()); + + // kTest is the last value which is not included for tracing. + constexpr auto kNumReasons = static_cast<size_t>(RenderSurfaceReason::kTest); + int reason_counts[kNumReasons] = {0}; + for (const auto* render_surface : *render_surface_list) { + const auto* effect_node = + property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); + reason_counts[static_cast<size_t>(effect_node->render_surface_reason)]++; + } + for (size_t i = 0; i < kNumReasons; i++) { + if (!reason_counts[i]) + continue; + TRACE_EVENT_INSTANT1( + "cc", "RenderSurfaceReasonCount", TRACE_EVENT_SCOPE_THREAD, + RenderSurfaceReasonToString(static_cast<RenderSurfaceReason>(i)), + reason_counts[i]); + } +} + +void UpdateElasticOverscroll( + PropertyTrees* property_trees, + TransformNode* overscroll_elasticity_transform_node, + const gfx::Vector2dF& elastic_overscroll) { + if (!overscroll_elasticity_transform_node) { + DCHECK(elastic_overscroll.IsZero()); + return; + } + + if (overscroll_elasticity_transform_node->scroll_offset == + gfx::ScrollOffset(elastic_overscroll)) + return; + + overscroll_elasticity_transform_node->scroll_offset = + gfx::ScrollOffset(elastic_overscroll); + overscroll_elasticity_transform_node->needs_local_transform_update = true; + property_trees->transform_tree.set_needs_update(true); +} + +void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, + PropertyTrees* property_trees) { + // Compute transforms + for (LayerImpl* layer : *layer_list) { + const TransformNode* transform_node = + property_trees->transform_tree.Node(layer->transform_tree_index()); + + layer->draw_properties().screen_space_transform = + ScreenSpaceTransformInternal(layer, property_trees->transform_tree); + layer->draw_properties().target_space_transform = DrawTransform( + layer, property_trees->transform_tree, property_trees->effect_tree); + layer->draw_properties().screen_space_transform_is_animating = + transform_node->to_screen_is_potentially_animated; + auto rounded_corner_info = + GetRoundedCornerRRect(property_trees, layer->effect_tree_index(), + /*from_render_surface*/ false); + layer->draw_properties().rounded_corner_bounds = rounded_corner_info.first; + layer->draw_properties().is_fast_rounded_corner = + rounded_corner_info.second; + } + + // Compute effects and determine if render surfaces have contributing layers + // that escape clip. + for (LayerImpl* layer : *layer_list) { + layer->draw_properties().opacity = + LayerDrawOpacity(layer, property_trees->effect_tree); + RenderSurfaceImpl* render_target = layer->render_target(); + int lca_clip_id = LowestCommonAncestor(layer->clip_tree_index(), + render_target->ClipTreeIndex(), + &property_trees->clip_tree); + if (lca_clip_id != render_target->ClipTreeIndex()) { + SetHasContributingLayerThatEscapesClip(lca_clip_id, + render_target->EffectTreeIndex(), + &property_trees->effect_tree); + } + } + + // Compute clips and visible rects + for (LayerImpl* layer : *layer_list) { + ConditionalClip clip = LayerClipRect(property_trees, layer); + // is_clipped should be set before visible rect computation as it is used + // there. + layer->draw_properties().is_clipped = clip.is_clipped; + layer->draw_properties().clip_rect = ToEnclosingClipRect(clip.clip_rect); + layer->draw_properties().visible_layer_rect = + LayerVisibleRect(property_trees, layer); + } + + // Compute drawable content rects + for (LayerImpl* layer : *layer_list) { + gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( + layer->draw_properties().target_space_transform, + gfx::Rect(layer->bounds())); + layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( + layer, bounds_in_target_space, layer->draw_properties().clip_rect); + } +} + } // namespace void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, @@ -776,23 +1124,9 @@ void ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, 1.0 / effect_node->surface_contents_scale.y()); } -bool LayerShouldBeSkippedForDrawPropertiesComputation( - LayerImpl* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { - return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); -} - -bool LayerShouldBeSkippedForDrawPropertiesComputation( - Layer* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree) { - return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); -} - void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, - const PropertyTrees* property_trees, LayerList* update_layer_list) { + const PropertyTrees* property_trees = layer_tree_host->property_trees(); const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; for (auto* layer : *layer_tree_host) { @@ -806,20 +1140,12 @@ void FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, if (LayerNeedsUpdate(layer, layer_is_drawn, property_trees)) { update_layer_list->push_back(layer); } - - // Append mask layers to the update layer list. They don't have valid - // visible rects, so need to get added after the above calculation. - if (PictureLayer* mask_layer = layer->mask_layer()) { - // Layers with empty bounds should never be painted, including masks. - if (!mask_layer->bounds().IsEmpty()) - update_layer_list->push_back(mask_layer); - } } } void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, - const PropertyTrees* property_trees, std::vector<LayerImpl*>* visible_layer_list) { + const PropertyTrees* property_trees = layer_tree_impl->property_trees(); const TransformTree& transform_tree = property_trees->transform_tree; const EffectTree& effect_tree = property_trees->effect_tree; @@ -868,11 +1194,10 @@ void ComputeEffects(EffectTree* effect_tree) { effect_tree->set_needs_update(false); } -void UpdatePropertyTrees(LayerTreeHost* layer_tree_host, - PropertyTrees* property_trees) { +void UpdatePropertyTrees(LayerTreeHost* layer_tree_host) { DCHECK(layer_tree_host); + auto* property_trees = layer_tree_host->property_trees(); DCHECK(property_trees); - DCHECK_EQ(layer_tree_host->property_trees(), property_trees); if (property_trees->transform_tree.needs_update()) { property_trees->clip_tree.set_needs_update(true); property_trees->effect_tree.set_needs_update(true); @@ -899,18 +1224,6 @@ void UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, ComputeClips(property_trees); } -bool LayerNeedsUpdate(Layer* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees) { - return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); -} - -bool LayerNeedsUpdate(LayerImpl* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees) { - return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); -} - gfx::Transform DrawTransform(const LayerImpl* layer, const TransformTree& transform_tree, const EffectTree& effect_tree) { @@ -921,8 +1234,6 @@ gfx::Transform DrawTransform(const LayerImpl* layer, transform_tree.property_trees()->GetToTarget( layer->transform_tree_index(), layer->render_target_effect_tree_index(), &xform); - if (layer->should_flatten_screen_space_transform_from_property_tree()) - xform.FlattenTo2d(); xform.Translate(layer->offset_to_transform_parent().x(), layer->offset_to_transform_parent().y()); return xform; @@ -938,110 +1249,6 @@ gfx::Transform ScreenSpaceTransform(const LayerImpl* layer, return ScreenSpaceTransformInternal(layer, tree); } -void ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, - PropertyTrees* property_trees) { - // Compute transforms - for (LayerImpl* layer : *layer_list) { - const TransformNode* transform_node = - property_trees->transform_tree.Node(layer->transform_tree_index()); - - layer->draw_properties().screen_space_transform = - ScreenSpaceTransformInternal(layer, property_trees->transform_tree); - layer->draw_properties().target_space_transform = DrawTransform( - layer, property_trees->transform_tree, property_trees->effect_tree); - layer->draw_properties().screen_space_transform_is_animating = - transform_node->to_screen_is_potentially_animated; - auto rounded_corner_info = - GetRoundedCornerRRect(property_trees, layer->effect_tree_index(), - /*from_render_surface*/ false); - layer->draw_properties().rounded_corner_bounds = rounded_corner_info.first; - layer->draw_properties().is_fast_rounded_corner = - rounded_corner_info.second; - } - - // Compute effects and determine if render surfaces have contributing layers - // that escape clip. - for (LayerImpl* layer : *layer_list) { - layer->draw_properties().opacity = - LayerDrawOpacity(layer, property_trees->effect_tree); - RenderSurfaceImpl* render_target = layer->render_target(); - int lca_clip_id = LowestCommonAncestor(layer->clip_tree_index(), - render_target->ClipTreeIndex(), - &property_trees->clip_tree); - if (lca_clip_id != render_target->ClipTreeIndex()) { - SetHasContributingLayerThatEscapesClip(lca_clip_id, - render_target->EffectTreeIndex(), - &property_trees->effect_tree); - } - } - - // Compute clips and visible rects - for (LayerImpl* layer : *layer_list) { - ConditionalClip clip = LayerClipRect(property_trees, layer); - // is_clipped should be set before visible rect computation as it is used - // there. - layer->draw_properties().is_clipped = clip.is_clipped; - layer->draw_properties().clip_rect = ToEnclosingClipRect(clip.clip_rect); - layer->draw_properties().visible_layer_rect = - LayerVisibleRect(property_trees, layer); - } - - // Compute drawable content rects - for (LayerImpl* layer : *layer_list) { - gfx::Rect bounds_in_target_space = MathUtil::MapEnclosingClippedRect( - layer->draw_properties().target_space_transform, - gfx::Rect(layer->bounds())); - layer->draw_properties().drawable_content_rect = LayerDrawableContentRect( - layer, bounds_in_target_space, layer->draw_properties().clip_rect); - } -} - -void ComputeMaskDrawProperties(LayerImpl* mask_layer, - PropertyTrees* property_trees) { - // Mask draw properties are used only for rastering, so most of the draw - // properties computed for other layers are not needed. - // Draw transform of a mask layer has to be a 2d scale. - // TODO(sunxd): the draw transform of a mask layer misses the "scale to fit" - // factor from mask layer to its parent. So does the screen space transform. - // It does not cause a problem because currently we only have 1:1 mask layer. - mask_layer->draw_properties().target_space_transform = DrawTransform( - mask_layer, property_trees->transform_tree, property_trees->effect_tree); - mask_layer->draw_properties().screen_space_transform = - ScreenSpaceTransformInternal(mask_layer, - property_trees->transform_tree); - - ConditionalClip clip = LayerClipRect(property_trees, mask_layer); - // is_clipped should be set before visible rect computation as it is used - // there. - mask_layer->draw_properties().is_clipped = clip.is_clipped; - mask_layer->draw_properties().clip_rect = ToEnclosingClipRect(clip.clip_rect); - // Calculate actual visible layer rect for mask layers, since we could have - // tiled mask layers and the tile manager would need this info for rastering. - mask_layer->draw_properties().visible_layer_rect = - LayerVisibleRect(property_trees, mask_layer); - mask_layer->draw_properties().opacity = 1; -} - -void ComputeSurfaceDrawProperties(PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface) { - SetSurfaceIsClipped(property_trees->clip_tree, render_surface); - SetSurfaceDrawOpacity(property_trees->effect_tree, render_surface); - SetSurfaceDrawTransform(property_trees, render_surface); - - render_surface->SetRoundedCornerRRect( - GetRoundedCornerRRect(property_trees, render_surface->EffectTreeIndex(), - /*for_render_surface*/ true) - .first); - render_surface->SetScreenSpaceTransform( - property_trees->ToScreenSpaceTransformWithoutSurfaceContentsScale( - render_surface->TransformTreeIndex(), - render_surface->EffectTreeIndex())); - - const ClipNode* clip_node = - property_trees->clip_tree.Node(render_surface->ClipTreeIndex()); - SetSurfaceClipRect(clip_node, property_trees, render_surface); -} - void UpdatePageScaleFactor(PropertyTrees* property_trees, TransformNode* page_scale_node, float page_scale_factor) { @@ -1061,24 +1268,77 @@ void UpdatePageScaleFactor(PropertyTrees* property_trees, property_trees->transform_tree.set_needs_update(true); } -void UpdateElasticOverscroll(PropertyTrees* property_trees, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll) { - if (!overscroll_elasticity_element_id) { - DCHECK(elastic_overscroll.IsZero()); - return; +void CalculateDrawProperties( + LayerTreeImpl* layer_tree_impl, + RenderSurfaceList* output_render_surface_list, + LayerImplList* output_update_layer_list_for_testing) { + output_render_surface_list->clear(); + + LayerImplList visible_layer_list; + // Since page scale and elastic overscroll are SyncedProperties, changes + // on the active tree immediately affect the pending tree, so instead of + // trying to update property trees whenever these values change, we + // update property trees before using them. + + // We should never be setting a non-unit page scale factor on an oopif + // subframe ... if we attempt this log it and fail. + // TODO(wjmaclean): Remove as part of conditions for closing the bug. + // https://crbug.com/845097 + PropertyTrees* property_trees = layer_tree_impl->property_trees(); + if (layer_tree_impl->current_page_scale_factor() != + property_trees->transform_tree.page_scale_factor() && + !layer_tree_impl->PageScaleTransformNode()) { + LOG(ERROR) << "Setting PageScale on subframe: new psf = " + << layer_tree_impl->page_scale_factor() << ", old psf = " + << property_trees->transform_tree.page_scale_factor() + << ", in_oopif = " + << layer_tree_impl->settings().is_layer_tree_for_subframe; + NOTREACHED(); } - TransformNode* node = property_trees->transform_tree.FindNodeFromElementId( - overscroll_elasticity_element_id); - DCHECK(node); + UpdatePageScaleFactor(property_trees, + layer_tree_impl->PageScaleTransformNode(), + layer_tree_impl->current_page_scale_factor()); + UpdateElasticOverscroll(property_trees, + layer_tree_impl->OverscrollElasticityTransformNode(), + layer_tree_impl->current_elastic_overscroll()); + // Similarly, the device viewport and device transform are shared + // by both trees. + property_trees->clip_tree.SetViewportClip( + gfx::RectF(layer_tree_impl->GetDeviceViewport())); + property_trees->transform_tree.SetRootScaleAndTransform( + layer_tree_impl->device_scale_factor(), layer_tree_impl->DrawTransform()); + UpdatePropertyTreesAndRenderSurfaces(layer_tree_impl->root_layer(), + property_trees); + + { + TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates"); + FindLayersThatNeedUpdates(layer_tree_impl, &visible_layer_list); + } - if (node->scroll_offset == gfx::ScrollOffset(elastic_overscroll)) - return; + { + TRACE_EVENT1("cc", + "draw_property_utils::ComputeDrawPropertiesOfVisibleLayers", + "visible_layers", visible_layer_list.size()); + ComputeDrawPropertiesOfVisibleLayers(&visible_layer_list, property_trees); + } - node->scroll_offset = gfx::ScrollOffset(elastic_overscroll); - node->needs_local_transform_update = true; - property_trees->transform_tree.set_needs_update(true); + { + TRACE_EVENT0("cc", "CalculateRenderSurfaceLayerList"); + CalculateRenderSurfaceLayerList(layer_tree_impl, property_trees, + output_render_surface_list, + layer_tree_impl->max_texture_size()); + } + RecordRenderSurfaceReasonsForTracing(property_trees, + output_render_surface_list); + + // A root layer render_surface should always exist after + // CalculateDrawProperties. + DCHECK(property_trees->effect_tree.GetRenderSurface( + EffectTree::kContentsRootNodeId)); + + if (output_update_layer_list_for_testing) + *output_update_layer_list_for_testing = std::move(visible_layer_list); } } // namespace draw_property_utils diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h index 54c7a458d33..2f286c2550d 100644 --- a/chromium/cc/trees/draw_property_utils.h +++ b/chromium/cc/trees/draw_property_utils.h @@ -10,7 +10,6 @@ namespace gfx { class Transform; -class Vector2dF; } // namespace gfx namespace cc { @@ -19,13 +18,11 @@ class Layer; class LayerImpl; class LayerTreeHost; class LayerTreeImpl; -class RenderSurfaceImpl; class EffectTree; class TransformTree; class PropertyTrees; struct EffectNode; struct TransformNode; -struct ElementId; namespace draw_property_utils { @@ -39,52 +36,25 @@ void CC_EXPORT ComputeTransforms(TransformTree* transform_tree); // Computes screen space opacity for every node in the opacity tree. void CC_EXPORT ComputeEffects(EffectTree* effect_tree); -void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host, - PropertyTrees* property_trees); +void CC_EXPORT UpdatePropertyTrees(LayerTreeHost* layer_tree_host); void CC_EXPORT UpdatePropertyTreesAndRenderSurfaces(LayerImpl* root_layer, PropertyTrees* property_trees); void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeHost* layer_tree_host, - const PropertyTrees* property_trees, LayerList* update_layer_list); void CC_EXPORT FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, - const PropertyTrees* property_trees, std::vector<LayerImpl*>* visible_layer_list); -void CC_EXPORT -ComputeDrawPropertiesOfVisibleLayers(const LayerImplList* layer_list, - PropertyTrees* property_trees); - -void CC_EXPORT ComputeMaskDrawProperties(LayerImpl* mask_layer, - PropertyTrees* property_trees); - -void CC_EXPORT ComputeSurfaceDrawProperties(PropertyTrees* property_trees, - RenderSurfaceImpl* render_surface); - -bool CC_EXPORT LayerShouldBeSkippedForDrawPropertiesComputation( - LayerImpl* layer, - const TransformTree& transform_tree, - const EffectTree& effect_tree); - -bool CC_EXPORT LayerNeedsUpdate(Layer* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees); - -bool CC_EXPORT LayerNeedsUpdate(LayerImpl* layer, - bool layer_is_drawn, - const PropertyTrees* property_trees); - gfx::Transform CC_EXPORT DrawTransform(const LayerImpl* layer, const TransformTree& transform_tree, const EffectTree& effect_tree); gfx::Transform CC_EXPORT ScreenSpaceTransform(const Layer* layer, const TransformTree& tree); - gfx::Transform CC_EXPORT ScreenSpaceTransform(const LayerImpl* layer, const TransformTree& tree); @@ -92,10 +62,10 @@ void CC_EXPORT UpdatePageScaleFactor(PropertyTrees* property_trees, TransformNode* page_scale_node, float page_scale_factor); -void CC_EXPORT -UpdateElasticOverscroll(PropertyTrees* property_trees, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll); +void CC_EXPORT CalculateDrawProperties( + LayerTreeImpl* layer_tree_impl, + RenderSurfaceList* output_render_surface_list, + LayerImplList* output_update_layer_list_for_testing = nullptr); } // namespace draw_property_utils } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/draw_property_utils_perftest.cc index 14283d082f6..3facfbd838f 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/draw_property_utils_perftest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "cc/trees/draw_property_utils.h" + #include <stddef.h> #include <memory> @@ -19,11 +21,10 @@ #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/layer_tree_json_parser.h" #include "cc/test/layer_tree_test.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/transform_node.h" #include "components/viz/test/paths.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -32,9 +33,9 @@ static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -class LayerTreeHostCommonPerfTest : public LayerTreeTest { +class DrawPropertyUtilsPerfTest : public LayerTreeTest { public: - LayerTreeHostCommonPerfTest() + DrawPropertyUtilsPerfTest() : timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) {} @@ -58,22 +59,25 @@ class LayerTreeHostCommonPerfTest : public LayerTreeTest { content_layer_client_.set_bounds(viewport); } - void SetTestName(const std::string& name) { test_name_ = name; } + void SetUpReporter(const std::string& story_name) { + reporter_ = std::make_unique<perf_test::PerfResultReporter>( + "calc_draw_props_time", story_name); + reporter_->RegisterImportantMetric("", "us"); + } void AfterTest() override { - CHECK(!test_name_.empty()) << "Must SetTestName() before TearDown()."; - perf_test::PrintResult("calc_draw_props_time", "", test_name_, - timer_.TimePerLap().InMicrosecondsF(), "us", true); + CHECK(reporter_) << "Must SetUpReporter() before TearDown()."; + reporter_->AddResult("", timer_.TimePerLap().InMicrosecondsF()); } protected: FakeContentLayerClient content_layer_client_; base::LapTimer timer_; - std::string test_name_; std::string json_; + std::unique_ptr<perf_test::PerfResultReporter> reporter_; }; -class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { +class CalcDrawPropsTest : public DrawPropertyUtilsPerfTest { public: void RunCalcDrawProps() { RunTest(CompositorMode::SINGLE_THREADED); } @@ -81,59 +85,38 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { timer_.Reset(); - LayerTreeImpl* active_tree = host_impl->active_tree(); do { - int max_texture_size = 8096; - DoCalcDrawPropertiesImpl(max_texture_size, active_tree, host_impl); - + RenderSurfaceList render_surface_list; + draw_property_utils::CalculateDrawProperties(host_impl->active_tree(), + &render_surface_list); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); EndTest(); } - - void DoCalcDrawPropertiesImpl(int max_texture_size, - LayerTreeImpl* active_tree, - LayerTreeHostImpl* host_impl) { - RenderSurfaceList update_list; - LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - active_tree->root_layer_for_testing(), active_tree->GetDeviceViewport(), - host_impl->DrawTransform(), active_tree->device_scale_factor(), - active_tree->current_page_scale_factor(), - active_tree->InnerViewportContainerLayer(), - active_tree->InnerViewportScrollLayer(), - active_tree->OuterViewportScrollLayer(), - active_tree->elastic_overscroll()->Current(active_tree->IsActiveTree()), - active_tree->OverscrollElasticityElementId(), max_texture_size, - &update_list, active_tree->property_trees(), - active_tree->property_trees()->transform_tree.Node( - active_tree->InnerViewportContainerLayer() - ->transform_tree_index())); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); - } }; TEST_F(CalcDrawPropsTest, TenTen) { - SetTestName("10_10"); + SetUpReporter("10_10"); ReadTestFile("10_10_layer_tree"); RunCalcDrawProps(); } TEST_F(CalcDrawPropsTest, HeavyPage) { - SetTestName("heavy_page"); + SetUpReporter("heavy_page"); ReadTestFile("heavy_layer_tree"); RunCalcDrawProps(); } TEST_F(CalcDrawPropsTest, TouchRegionLight) { - SetTestName("touch_region_light"); + SetUpReporter("touch_region_light"); ReadTestFile("touch_region_light"); RunCalcDrawProps(); } TEST_F(CalcDrawPropsTest, TouchRegionHeavy) { - SetTestName("touch_region_heavy"); + SetUpReporter("touch_region_heavy"); ReadTestFile("touch_region_heavy"); RunCalcDrawProps(); } diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc index 339be0b576b..b84952f357e 100644 --- a/chromium/cc/trees/effect_node.cc +++ b/chromium/cc/trees/effect_node.cc @@ -31,7 +31,6 @@ EffectNode::EffectNode() is_currently_animating_backdrop_filter(false), is_currently_animating_opacity(false), has_masking_child(false), - is_masked(false), effect_changed(false), subtree_has_copy_request(false), is_fast_rounded_corner(false), @@ -39,7 +38,6 @@ EffectNode::EffectNode() transform_id(0), clip_id(0), target_id(1), - mask_layer_id(Layer::INVALID_ID), closest_ancestor_with_cached_render_surface_id(-1), closest_ancestor_with_copy_request_id(-1) {} @@ -66,7 +64,6 @@ bool EffectNode::operator==(const EffectNode& other) const { HasRenderSurface() == other.HasRenderSurface() && blend_mode == other.blend_mode && surface_contents_scale == other.surface_contents_scale && - unscaled_mask_target_size == other.unscaled_mask_target_size && hidden_by_backface_visibility == other.hidden_by_backface_visibility && double_sided == other.double_sided && trilinear_filtering == other.trilinear_filtering && @@ -83,11 +80,10 @@ bool EffectNode::operator==(const EffectNode& other) const { is_currently_animating_opacity == other.is_currently_animating_opacity && has_masking_child == other.has_masking_child && - is_masked == other.is_masked && effect_changed == other.effect_changed && subtree_has_copy_request == other.subtree_has_copy_request && transform_id == other.transform_id && clip_id == other.clip_id && - target_id == other.target_id && mask_layer_id == other.mask_layer_id && + target_id == other.target_id && closest_ancestor_with_cached_render_surface_id == other.closest_ancestor_with_cached_render_surface_id && closest_ancestor_with_copy_request_id == @@ -126,8 +122,6 @@ const char* RenderSurfaceReasonToString(RenderSurfaceReason reason) { return "clip axis alignment"; case RenderSurfaceReason::kMask: return "mask"; - case RenderSurfaceReason::kRootOrIsolatedGroup: - return "root or isolated group"; case RenderSurfaceReason::kTrilinearFiltering: return "trilinear filtering"; case RenderSurfaceReason::kCache: @@ -144,7 +138,7 @@ const char* RenderSurfaceReasonToString(RenderSurfaceReason reason) { void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("backdrop_mask_element_id", - backdrop_mask_element_id.GetInternalValue()); + backdrop_mask_element_id.GetStableId()); value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); value->SetInteger("stable_id", stable_id); @@ -171,7 +165,6 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetBoolean("has_potential_opacity_animation", has_potential_opacity_animation); value->SetBoolean("has_masking_child", has_masking_child); - value->SetBoolean("is_masked", is_masked); value->SetBoolean("effect_changed", effect_changed); value->SetBoolean("subtree_has_copy_request", subtree_has_copy_request); value->SetString("render_surface_reason", @@ -179,7 +172,6 @@ void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("transform_id", transform_id); value->SetInteger("clip_id", clip_id); value->SetInteger("target_id", target_id); - value->SetInteger("mask_layer_id", mask_layer_id); value->SetInteger("closest_ancestor_with_cached_render_surface_id", closest_ancestor_with_cached_render_surface_id); value->SetInteger("closest_ancestor_with_copy_request_id", diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h index 0f9d220d218..50a8d725dec 100644 --- a/chromium/cc/trees/effect_node.h +++ b/chromium/cc/trees/effect_node.h @@ -37,7 +37,6 @@ enum class RenderSurfaceReason : uint8_t { kClipPath, kClipAxisAlignment, kMask, - kRootOrIsolatedGroup, kTrilinearFiltering, kCache, kCopyRequest, @@ -88,8 +87,6 @@ struct CC_EXPORT EffectNode { gfx::Vector2dF surface_contents_scale; - gfx::Size unscaled_mask_target_size; - bool cache_render_surface : 1; bool has_copy_request : 1; bool hidden_by_backface_visibility : 1; @@ -118,8 +115,6 @@ struct CC_EXPORT EffectNode { bool is_currently_animating_opacity : 1; // Whether this node has a child node with kDstIn blend mode. bool has_masking_child : 1; - // Whether this node has a mask. This bit is not used when using layer lists. - bool is_masked : 1; // Whether this node's effect has been changed since the last // frame. Needed in order to compute damage rect. bool effect_changed : 1; @@ -140,9 +135,6 @@ struct CC_EXPORT EffectNode { // This is the id of the ancestor effect node that induces a // RenderSurfaceImpl. int target_id; - // The layer id of the mask layer, if any, to apply to this effect - // node's content when rendering to a surface. - int mask_layer_id; int closest_ancestor_with_cached_render_surface_id; int closest_ancestor_with_copy_request_id; diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.cc b/chromium/cc/trees/latency_info_swap_promise_monitor.cc index 5da4b6895b3..a69055c986d 100644 --- a/chromium/cc/trees/latency_info_swap_promise_monitor.cc +++ b/chromium/cc/trees/latency_info_swap_promise_monitor.cc @@ -25,16 +25,6 @@ bool AddRenderingScheduledComponent(ui::LatencyInfo* latency_info, return true; } -bool AddForwardingScrollUpdateToMainComponent(ui::LatencyInfo* latency_info) { - if (latency_info->FindLatency( - ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT, - nullptr)) - return false; - latency_info->AddLatencyNumber( - ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT); - return true; -} - } // namespace namespace cc { @@ -67,20 +57,4 @@ void LatencyInfoSwapPromiseMonitor::OnSetNeedsRedrawOnImpl() { } } -void LatencyInfoSwapPromiseMonitor::OnForwardScrollUpdateToMainThreadOnImpl() { - if (AddForwardingScrollUpdateToMainComponent(latency_)) { - ui::LatencyInfo new_latency; - new_latency.CopyLatencyFrom( - *latency_, - ui::INPUT_EVENT_LATENCY_FORWARD_SCROLL_UPDATE_TO_MAIN_COMPONENT); - new_latency.AddLatencyNumberWithTraceName( - ui::LATENCY_BEGIN_SCROLL_LISTENER_UPDATE_MAIN_COMPONENT, - "ScrollUpdate"); - std::unique_ptr<SwapPromise> swap_promise( - new LatencyInfoSwapPromise(new_latency)); - host_impl_->QueueSwapPromiseForMainThreadScrollUpdate( - std::move(swap_promise)); - } -} - } // namespace cc diff --git a/chromium/cc/trees/latency_info_swap_promise_monitor.h b/chromium/cc/trees/latency_info_swap_promise_monitor.h index c127b966018..eb1d8f4a635 100644 --- a/chromium/cc/trees/latency_info_swap_promise_monitor.h +++ b/chromium/cc/trees/latency_info_swap_promise_monitor.h @@ -26,7 +26,6 @@ class CC_EXPORT LatencyInfoSwapPromiseMonitor : public SwapPromiseMonitor { void OnSetNeedsCommitOnMain() override; void OnSetNeedsRedrawOnImpl() override; - void OnForwardScrollUpdateToMainThreadOnImpl() override; private: ui::LatencyInfo* latency_; diff --git a/chromium/cc/trees/layer_tree_frame_sink_client.h b/chromium/cc/trees/layer_tree_frame_sink_client.h index 50848593309..e56d9c563cd 100644 --- a/chromium/cc/trees/layer_tree_frame_sink_client.h +++ b/chromium/cc/trees/layer_tree_frame_sink_client.h @@ -15,12 +15,12 @@ #include "ui/gfx/geometry/rect.h" namespace gfx { -struct PresentationFeedback; class Transform; } namespace viz { class BeginFrameSource; +struct FrameTimingDetails; struct HitTestRegionList; } @@ -57,11 +57,10 @@ class CC_EXPORT LayerTreeFrameSinkClient { // so that frames are submitted only at the rate it can handle them. virtual void DidReceiveCompositorFrameAck() = 0; - // See ui/gfx/presentation_feedback.h for details on args. |time| is always - // non-zero. + // See components/viz/common/frame_timing_details.h for details on args. virtual void DidPresentCompositorFrame( - uint32_t presentation_token, - const gfx::PresentationFeedback& feedback) = 0; + uint32_t frame_token, + const viz::FrameTimingDetails& details) = 0; // The LayerTreeFrameSink is lost when the viz::ContextProviders held by it // encounter an error. In this case the LayerTreeFrameSink (and the diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc index 1fab49e82ec..09cd244629c 100644 --- a/chromium/cc/trees/layer_tree_host.cc +++ b/chromium/cc/trees/layer_tree_host.cc @@ -48,12 +48,13 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host_client.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" +#include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/property_tree_builder.h" #include "cc/trees/proxy_main.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/swap_promise_manager.h" @@ -126,6 +127,7 @@ LayerTreeHost::LayerTreeHost(InitParams params, CompositorMode mode) compositor_mode_(mode), ui_resource_manager_(std::make_unique<UIResourceManager>()), client_(params.client), + scheduling_client_(params.scheduling_client), rendering_stats_instrumentation_(RenderingStatsInstrumentation::Create()), settings_(*params.settings), debug_state_(settings_.initial_debug_state), @@ -199,9 +201,6 @@ LayerTreeHost::~LayerTreeHost() { // Clear any references into the LayerTreeHost. mutator_host_->SetMutatorHostClient(nullptr); - // We must clear any pointers into the layer tree prior to destroying it. - RegisterViewportLayers(ViewportLayers()); - if (root_layer_) { root_layer_->SetLayerTreeHost(nullptr); @@ -289,8 +288,12 @@ const LayerTreeDebugState& LayerTreeHost::GetDebugState() const { return debug_state_; } -void LayerTreeHost::RequestMainFrameUpdate() { +void LayerTreeHost::RequestMainFrameUpdate(bool report_cc_metrics) { client_->UpdateLayerTreeHost(); + if (report_cc_metrics) + begin_main_frame_metrics_ = client_->GetBeginMainFrameMetrics(); + else + begin_main_frame_metrics_.reset(); } // This function commits the LayerTreeHost to an impl tree. When modifying @@ -368,6 +371,7 @@ void LayerTreeHost::FinishCommitOnImplThread( TRACE_EVENT0("cc", "LayerTreeHost::AnimationHost::PushProperties"); DCHECK(host_impl->mutator_host()); mutator_host_->PushPropertiesTo(host_impl->mutator_host()); + MoveChangeTrackingToLayers(sync_tree); // Updating elements affects whether animations are in effect based on their // properties so run after pushing updated animation properties. @@ -402,6 +406,27 @@ void LayerTreeHost::FinishCommitOnImplThread( } } +void LayerTreeHost::MoveChangeTrackingToLayers(LayerTreeImpl* tree_impl) { + // This is only true for single-thread compositing (i.e. not via Blink). + bool property_trees_changed_on_active_tree = + tree_impl->IsActiveTree() && tree_impl->property_trees()->changed; + + if (property_trees_changed_on_active_tree) { + // Property trees may store damage status. We preserve the sync tree damage + // status by pushing the damage status from sync tree property trees to main + // thread property trees or by moving it onto the layers. + if (root_layer_) { + if (property_trees_.sequence_number == + tree_impl->property_trees()->sequence_number) + tree_impl->property_trees()->PushChangeTrackingTo(&property_trees_); + else + tree_impl->MoveChangeTrackingToLayers(); + } + } else { + tree_impl->MoveChangeTrackingToLayers(); + } +} + void LayerTreeHost::ImageDecodesFinished( const std::vector<std::pair<int, bool>>& results) { // Issue stored callbacks and remove them from the pending list. @@ -442,8 +467,8 @@ void LayerTreeHost::WillCommit() { // PushPropertiesTo() propagates layer debug info to the impl side -- // otherwise this won't happen for the layers that remain unchanged since // tracing started. - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsPushProperties(); }); + for (auto* layer : *this) + layer->SetNeedsPushProperties(); } for (Layer* layer : LayersThatShouldPushProperties()) @@ -454,8 +479,7 @@ void LayerTreeHost::WillCommit() { void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() { proxy_->SetDeferMainFrameUpdate( defer_main_frame_update_count_ > 0 || - (settings_.enable_surface_synchronization && - !local_surface_id_allocation_from_parent_.IsValid())); + !local_surface_id_allocation_from_parent_.IsValid()); } bool LayerTreeHost::IsUsingLayerLists() const { @@ -526,13 +550,13 @@ LayerTreeHost::CreateLayerTreeHostImpl( std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( settings_, client, task_runner_provider_.get(), rendering_stats_instrumentation_.get(), task_graph_runner_, - std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_)); + std::move(mutator_host_impl), id_, std::move(image_worker_task_runner_), + scheduling_client_); if (ukm_recorder_factory_) { host_impl->InitializeUkm(ukm_recorder_factory_->CreateRecorder()); ukm_recorder_factory_.reset(); } - host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); host_impl->SetContentHasSlowPaths(content_has_slow_paths_); host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); task_graph_runner_ = nullptr; @@ -653,16 +677,6 @@ void LayerTreeHost::SetDebugState( SetNeedsCommit(); } -void LayerTreeHost::SetHasGpuRasterizationTrigger(bool has_trigger) { - if (has_trigger == has_gpu_rasterization_trigger_) - return; - - has_gpu_rasterization_trigger_ = has_trigger; - TRACE_EVENT_INSTANT1("cc", "LayerTreeHost::SetHasGpuRasterizationTrigger", - TRACE_EVENT_SCOPE_THREAD, "has_trigger", - has_gpu_rasterization_trigger_); -} - void LayerTreeHost::ApplyPageScaleDeltaFromImplSide( float page_scale_delta) { DCHECK(CommitRequested()); @@ -687,7 +701,7 @@ void LayerTreeHost::LayoutAndUpdateLayers() { DCHECK(IsSingleThreaded()); // This function is only valid when not using the scheduler. DCHECK(!settings_.single_thread_proxy_scheduler); - RequestMainFrameUpdate(); + RequestMainFrameUpdate(false); UpdateLayers(); } @@ -702,6 +716,7 @@ void LayerTreeHost::Composite(base::TimeTicks frame_begin_time, bool raster) { bool LayerTreeHost::UpdateLayers() { if (!root_layer()) { property_trees_.clear(); + viewport_property_ids_ = ViewportPropertyIds(); return false; } @@ -713,8 +728,11 @@ bool LayerTreeHost::UpdateLayers() { client_->DidUpdateLayers(); micro_benchmark_controller_.DidUpdateLayers(); + base::TimeDelta elapsed_delta = timer.Elapsed(); + if (begin_main_frame_metrics_) + begin_main_frame_metrics_->update_layers = elapsed_delta; if (const char* client_name = GetClientNameForMetrics()) { - auto elapsed = timer.Elapsed().InMicroseconds(); + auto elapsed = elapsed_delta.InMicroseconds(); std::string histogram_name = base::StringPrintf("Compositing.%s.LayersUpdateTime", client_name); @@ -761,8 +779,6 @@ void LayerTreeHost::RecordGpuRasterizationHistogram( UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled", gpu_rasterization_enabled); if (gpu_rasterization_enabled) { - UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationTriggered", - has_gpu_rasterization_trigger_); UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent", !content_has_slow_paths_); UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSlowPathsWithNonAAPaint", @@ -801,13 +817,7 @@ bool LayerTreeHost::DoUpdateLayers() { // need to be built here. if (!IsUsingLayerLists()) { TRACE_EVENT0("cc", "LayerTreeHost::UpdateLayers::BuildPropertyTrees"); - Layer* page_scale_layer = viewport_layers_.page_scale.get(); - gfx::Transform identity_transform; - PropertyTreeBuilder::BuildPropertyTrees( - root_layer_.get(), page_scale_layer, inner_viewport_scroll_layer(), - outer_viewport_scroll_layer(), overscroll_elasticity_element_id(), - elastic_overscroll_, page_scale_factor_, device_scale_factor_, - device_viewport_rect_, identity_transform, &property_trees_); + PropertyTreeBuilder::BuildPropertyTrees(this); TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "LayerTreeHost::UpdateLayers_BuiltPropertyTrees", TRACE_EVENT_SCOPE_THREAD, "property_trees", @@ -848,11 +858,10 @@ bool LayerTreeHost::DoUpdateLayers() { CHECK(property_trees_.effect_tree.Node(root_layer_->effect_tree_index())); #endif - draw_property_utils::UpdatePropertyTrees(this, &property_trees_); + draw_property_utils::UpdatePropertyTrees(this); LayerList update_layer_list; - draw_property_utils::FindLayersThatNeedUpdates(this, &property_trees_, - &update_layer_list); + draw_property_utils::FindLayersThatNeedUpdates(this, &update_layer_list); bool painted_content_has_slow_paths = false; bool painted_content_has_non_aa_paint = false; @@ -898,10 +907,13 @@ void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) { // Preemptively apply the scroll offset and scale delta here before sending // it to the client. If the client comes back and sets it to the same // value, then the layer can early out without needing a full commit. - if (viewport_layers_.inner_viewport_scroll) { - viewport_layers_.inner_viewport_scroll->SetScrollOffsetFromImplSide( - viewport_layers_.inner_viewport_scroll->CurrentScrollOffset() + - inner_viewport_scroll_delta); + if (auto* inner_scroll = property_trees()->scroll_tree.Node( + viewport_property_ids_.inner_scroll)) { + if (auto* inner_scroll_layer = LayerByElementId(inner_scroll->element_id)) { + inner_scroll_layer->SetScrollOffsetFromImplSide( + inner_scroll_layer->CurrentScrollOffset() + + inner_viewport_scroll_delta); + } } ApplyPageScaleDeltaFromImplSide(info.page_scale_delta); @@ -1100,36 +1112,26 @@ void LayerTreeHost::SetNonBlinkManagedRootLayer( force_use_property_tree_builder_ = true; } -void LayerTreeHost::RegisterViewportLayers(const ViewportLayers& layers) { - DCHECK(!layers.inner_viewport_scroll || - layers.inner_viewport_scroll != layers.outer_viewport_scroll); - // The page scale layer only affects the innter viewport scroll layer. The - // page scale layer should be sandwiched between the inner viewport scroll and - // inner viewport container layers: - // inner viewport container - // overscroll elasticity (optional) - // page scale - // inner viewport scroll - DCHECK(IsUsingLayerLists() || !layers.page_scale || - layers.inner_viewport_scroll->parent() == layers.page_scale); - DCHECK(IsUsingLayerLists() || !layers.page_scale || - layers.page_scale->parent()->element_id() == - layers.overscroll_elasticity_element_id || - layers.page_scale->parent() == layers.inner_viewport_container); - viewport_layers_.overscroll_elasticity_element_id = - layers.overscroll_elasticity_element_id; - viewport_layers_.page_scale = layers.page_scale; - viewport_layers_.inner_viewport_container = layers.inner_viewport_container; - viewport_layers_.outer_viewport_container = layers.outer_viewport_container; - viewport_layers_.inner_viewport_scroll = layers.inner_viewport_scroll; - viewport_layers_.outer_viewport_scroll = layers.outer_viewport_scroll; -} - void LayerTreeHost::RegisterViewportPropertyIds( const ViewportPropertyIds& ids) { - DCHECK(!viewport_layers_.inner_viewport_scroll); DCHECK(IsUsingLayerLists()); viewport_property_ids_ = ids; + // Outer viewport properties exist only if inner viewport property exists. + DCHECK(ids.inner_scroll != ScrollTree::kInvalidNodeId || + (ids.outer_scroll == ScrollTree::kInvalidNodeId && + ids.outer_clip == ClipTree::kInvalidNodeId)); +} + +Layer* LayerTreeHost::InnerViewportScrollLayerForTesting() const { + auto* scroll_node = + property_trees()->scroll_tree.Node(viewport_property_ids_.inner_scroll); + return scroll_node ? LayerByElementId(scroll_node->element_id) : nullptr; +} + +Layer* LayerTreeHost::OuterViewportScrollLayerForTesting() const { + auto* scroll_node = + property_trees()->scroll_tree.Node(viewport_property_ids_.outer_scroll); + return scroll_node ? LayerByElementId(scroll_node->element_id) : nullptr; } void LayerTreeHost::RegisterSelection(const LayerSelection& selection) { @@ -1172,8 +1174,8 @@ void LayerTreeHost::SetEventListenerProperties( old_properties == EventListenerProperties::kBlockingAndPassive; if (old_property_is_blocking != new_property_is_blocking) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsPushProperties(); }); + for (auto* layer : *this) + layer->SetNeedsPushProperties(); } } @@ -1321,8 +1323,8 @@ void LayerTreeHost::SetRasterColorSpace( return; raster_color_space_id_ = gfx::ColorSpace::GetNextId(); raster_color_space_ = raster_color_space; - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](Layer* layer) { layer->SetNeedsDisplay(); }); + for (auto* layer : *this) + layer->SetNeedsDisplay(); } void LayerTreeHost::SetExternalPageScaleFactor( @@ -1396,11 +1398,8 @@ void LayerTreeHost::SetLocalSurfaceIdAllocationFromParent( } void LayerTreeHost::RequestNewLocalSurfaceId() { - // If surface synchronization is enabled, then we can still request a new - // viz::LocalSurfaceId but that request will be deferred until we have a valid - // viz::LocalSurfaceId from the parent. - DCHECK(settings_.enable_surface_synchronization || - local_surface_id_allocation_from_parent_.IsValid()); + // We can still request a new viz::LocalSurfaceId but that request will be + // deferred until we have a valid viz::LocalSurfaceId from the parent. if (new_local_surface_id_request_) return; new_local_surface_id_request_ = true; @@ -1554,32 +1553,7 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) { EventListenerClass::kTouchEndOrCancel, event_listener_properties(EventListenerClass::kTouchEndOrCancel)); - if (viewport_layers_.inner_viewport_scroll) { - LayerTreeImpl::ViewportLayerIds ids; - if (viewport_layers_.overscroll_elasticity_element_id) { - ids.overscroll_elasticity_element_id = - viewport_layers_.overscroll_elasticity_element_id; - } - if (viewport_layers_.page_scale) { - ids.page_scale = viewport_layers_.page_scale->id(); - } - if (viewport_layers_.inner_viewport_container) { - ids.inner_viewport_container = - viewport_layers_.inner_viewport_container->id(); - } - if (viewport_layers_.outer_viewport_container) { - ids.outer_viewport_container = - viewport_layers_.outer_viewport_container->id(); - } - ids.inner_viewport_scroll = viewport_layers_.inner_viewport_scroll->id(); - if (viewport_layers_.outer_viewport_scroll) - ids.outer_viewport_scroll = viewport_layers_.outer_viewport_scroll->id(); - tree_impl->SetViewportLayersFromIds(ids); - } else { - tree_impl->ClearViewportLayers(); - } - - tree_impl->set_viewport_property_ids(viewport_property_ids_); + tree_impl->SetViewportPropertyIds(viewport_property_ids_); tree_impl->RegisterSelection(selection_); @@ -1641,7 +1615,6 @@ void LayerTreeHost::PushSurfaceRangesTo(LayerTreeImpl* tree_impl) { void LayerTreeHost::PushLayerTreeHostPropertiesTo( LayerTreeHostImpl* host_impl) { - host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); host_impl->SetContentHasSlowPaths(content_has_slow_paths_); host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_); host_impl->set_external_pinch_gesture_active( @@ -1684,21 +1657,13 @@ void LayerTreeHost::UpdateActiveElements() { mutator_host_->UpdateRegisteredElementIds(ElementListType::ACTIVE); } -static void SetElementIdForTesting(Layer* layer) { - layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); -} - void LayerTreeHost::SetElementIdsForTesting() { - LayerTreeHostCommon::CallFunctionForEveryLayer(this, SetElementIdForTesting); + for (auto* layer : *this) + layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); } void LayerTreeHost::BuildPropertyTreesForTesting() { - gfx::Transform identity_transform; - PropertyTreeBuilder::BuildPropertyTrees( - root_layer(), page_scale_layer(), inner_viewport_scroll_layer(), - outer_viewport_scroll_layer(), overscroll_elasticity_element_id(), - elastic_overscroll(), page_scale_factor(), device_scale_factor(), - device_viewport_rect(), identity_transform, property_trees()); + PropertyTreeBuilder::BuildPropertyTrees(this); } bool LayerTreeHost::IsElementInPropertyTrees(ElementId element_id, @@ -1846,20 +1811,20 @@ void LayerTreeHost::QueueImageDecode(const PaintImage& image, SetNeedsCommit(); } -LayerListIterator<Layer> LayerTreeHost::begin() const { - return LayerListIterator<Layer>(root_layer_.get()); +LayerListIterator LayerTreeHost::begin() const { + return LayerListIterator(root_layer_.get()); } -LayerListIterator<Layer> LayerTreeHost::end() const { - return LayerListIterator<Layer>(nullptr); +LayerListIterator LayerTreeHost::end() const { + return LayerListIterator(nullptr); } -LayerListReverseIterator<Layer> LayerTreeHost::rbegin() { - return LayerListReverseIterator<Layer>(root_layer_.get()); +LayerListReverseIterator LayerTreeHost::rbegin() { + return LayerListReverseIterator(root_layer_.get()); } -LayerListReverseIterator<Layer> LayerTreeHost::rend() { - return LayerListReverseIterator<Layer>(nullptr); +LayerListReverseIterator LayerTreeHost::rend() { + return LayerListReverseIterator(nullptr); } void LayerTreeHost::SetPropertyTreesForTesting( diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index 0c3405f8cb7..104cc541e97 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -33,6 +33,7 @@ #include "cc/input/scrollbar.h" #include "cc/layers/layer_collections.h" #include "cc/layers/layer_list_iterator.h" +#include "cc/metrics/begin_main_frame_metrics.h" #include "cc/paint/node_id.h" #include "cc/trees/compositor_mode.h" #include "cc/trees/layer_tree_frame_sink.h" @@ -57,7 +58,6 @@ namespace cc { class HeadsUpDisplayLayer; class Layer; -class LayerTreeHostClient; class LayerTreeHostImpl; class LayerTreeHostImplClient; class LayerTreeHostSingleThreadClient; @@ -96,6 +96,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { InitParams& operator=(InitParams&&); LayerTreeHostClient* client = nullptr; + LayerTreeHostSchedulingClient* scheduling_client = nullptr; TaskGraphRunner* task_graph_runner = nullptr; LayerTreeSettings const* settings = nullptr; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner; @@ -172,14 +173,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // when a main frame is requested. SwapPromiseManager* GetSwapPromiseManager(); - // Sets or gets whether the content is suitable to use Gpu Rasterization. This - // flag is used to enable gpu rasterization, and can be modified at any time - // to change the setting based on content. - void SetHasGpuRasterizationTrigger(bool has_trigger); - bool has_gpu_rasterization_trigger() const { - return has_gpu_rasterization_trigger_; - } - // Visibility and LayerTreeFrameSink ------------------------------- // Sets or gets if the LayerTreeHost is visible. When not visible it will: @@ -280,8 +273,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // Input Handling --------------------------------------------- - // Sets the state of the browser controls. (Used for URL bar animations on - // android). + // Sets the state of the browser controls. (Used for URL bar animations). void UpdateBrowserControlsState(BrowserControlsState constraints, BrowserControlsState current, bool animate); @@ -332,37 +324,24 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // caller inform blink about the layer and remove the function. void SetNonBlinkManagedRootLayer(scoped_refptr<Layer> root_layer); - // Sets or gets the collection of viewport Layers, defined to allow pinch-zoom - // transformations on the compositor thread. - void RegisterViewportLayers(const ViewportLayers& viewport_layers); - ElementId overscroll_elasticity_element_id() const { - return viewport_layers_.overscroll_elasticity_element_id; - } - Layer* page_scale_layer() const { return viewport_layers_.page_scale.get(); } - Layer* inner_viewport_container_layer() const { - return viewport_layers_.inner_viewport_container.get(); - } - Layer* outer_viewport_container_layer() const { - return viewport_layers_.outer_viewport_container.get(); - } - Layer* inner_viewport_scroll_layer() const { - return viewport_layers_.inner_viewport_scroll.get(); - } - Layer* outer_viewport_scroll_layer() const { - return viewport_layers_.outer_viewport_scroll.get(); - } - - // Counterpart of ViewportLayers for CompositeAfterPaint which doesn't create - // viewport layers. struct ViewportPropertyIds { + int overscroll_elasticity_transform = TransformTree::kInvalidNodeId; int page_scale_transform = TransformTree::kInvalidNodeId; int inner_scroll = ScrollTree::kInvalidNodeId; - // TODO(crbug.com/909750): Switch other usages of viewport layers to - // property ids for CompositeAfterPaint. + int outer_clip = ClipTree::kInvalidNodeId; + int outer_scroll = ScrollTree::kInvalidNodeId; }; + // Sets the collection of viewport property ids, defined to allow viewport + // pinch-zoom etc. on the compositor thread. void RegisterViewportPropertyIds(const ViewportPropertyIds&); + LayerTreeHost::ViewportPropertyIds ViewportPropertyIdsForTesting() const { + return viewport_property_ids_; + } + Layer* InnerViewportScrollLayerForTesting() const; + Layer* OuterViewportScrollLayerForTesting() const; + // Sets or gets the position of touch handles for a text selection. These are // submitted to the display compositor along with the Layer tree's contents // allowing it to present the selection handles. This is done because the @@ -546,6 +525,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl); void PushSurfaceRangesTo(LayerTreeImpl* tree_impl); void PushLayerTreeHostPropertiesTo(LayerTreeHostImpl* host_impl); + void MoveChangeTrackingToLayers(LayerTreeImpl* tree_impl); MutatorHost* mutator_host() const { return mutator_host_; } @@ -564,10 +544,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void BuildPropertyTreesForTesting(); // Layer iterators. - LayerListIterator<Layer> begin() const; - LayerListIterator<Layer> end() const; - LayerListReverseIterator<Layer> rbegin(); - LayerListReverseIterator<Layer> rend(); + LayerListIterator begin() const; + LayerListIterator end() const; + LayerListReverseIterator rbegin(); + LayerListReverseIterator rend(); // LayerTreeHost interface to Proxy. void WillBeginMainFrame(); @@ -576,7 +556,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void BeginMainFrameNotExpectedSoon(); void BeginMainFrameNotExpectedUntil(base::TimeTicks time); void AnimateLayers(base::TimeTicks monotonic_frame_begin_time); - void RequestMainFrameUpdate(); + void RequestMainFrameUpdate(bool report_cc_metrics); void FinishCommitOnImplThread(LayerTreeHostImpl* host_impl); void WillCommit(); void CommitComplete(); @@ -602,6 +582,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time); LayerTreeHostClient* client() { return client_; } + LayerTreeHostSchedulingClient* scheduling_client() { + return scheduling_client_; + } bool gpu_rasterization_histogram_recorded() const { return gpu_rasterization_histogram_recorded_; @@ -744,6 +727,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { std::unique_ptr<UIResourceManager> ui_resource_manager_; LayerTreeHostClient* client_; + LayerTreeHostSchedulingClient* scheduling_client_; std::unique_ptr<Proxy> proxy_; std::unique_ptr<TaskRunnerProvider> task_runner_provider_; @@ -766,7 +750,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { bool visible_ = false; - bool has_gpu_rasterization_trigger_ = false; bool content_has_slow_paths_ = false; bool content_has_non_aa_paint_ = false; bool gpu_rasterization_histogram_recorded_ = false; @@ -788,8 +771,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { scoped_refptr<Layer> root_layer_; - ViewportLayers viewport_layers_; - // For CompositeAfterPaint. ViewportPropertyIds viewport_property_ids_; float top_controls_height_ = 0.f; @@ -886,6 +867,12 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient { // added here. std::vector<PresentationTimeCallback> pending_presentation_time_callbacks_; + // Latency information for work done in ProxyMain::BeginMainFrame. The + // unique_ptr is allocated in RequestMainFrameUpdate, and passed to Blink's + // LocalFrameView that fills in the fields. This object adds the timing for + // UpdateLayers. CC reads the data during commit, and clears the unique_ptr. + std::unique_ptr<BeginMainFrameMetrics> begin_main_frame_metrics_; + // Used to vend weak pointers to LayerTreeHost to ScopedDeferMainFrameUpdate // objects. base::WeakPtrFactory<LayerTreeHost> defer_main_frame_update_weak_ptr_factory_{ diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index 7f424be64e6..8cf1a5682a0 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -22,6 +22,7 @@ struct BeginFrameArgs; } namespace cc { +struct BeginMainFrameMetrics; struct ElementId; struct ApplyViewportChangesArgs { @@ -149,11 +150,29 @@ class LayerTreeHostClient { // the time from the start of BeginMainFrame to the Commit, or early out. virtual void RecordStartOfFrameMetrics() = 0; virtual void RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) = 0; + // Return metrics information for the stages of BeginMainFrame. This is + // ultimately implemented by Blink's LocalFrameUKMAggregator. It must be a + // distinct call from the FrameMetrics above because the BeginMainFrameMetrics + // for compositor latency must be gathered before the layer tree is + // committed to the compositor, which is before the call to + // RecordEndOfFrameMetrics. + virtual std::unique_ptr<BeginMainFrameMetrics> GetBeginMainFrameMetrics() = 0; protected: virtual ~LayerTreeHostClient() {} }; +// LayerTreeHost->WebThreadScheduler callback interface. Instances of this class +// must be safe to use on both the compositor and main threads. +class LayerTreeHostSchedulingClient { + public: + // Indicates that the compositor thread scheduled a BeginMainFrame to run on + // the main thread. + virtual void DidScheduleBeginMainFrame() = 0; + // Called unconditionally when BeginMainFrame runs on the main thread. + virtual void DidRunBeginMainFrame() = 0; +}; + } // namespace cc #endif // CC_TREES_LAYER_TREE_HOST_CLIENT_H_ diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc deleted file mode 100644 index e91bd95593a..00000000000 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ /dev/null @@ -1,687 +0,0 @@ -// Copyright 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "cc/trees/layer_tree_host_common.h" - -#include <stddef.h> - -#include <algorithm> - -#include "base/containers/adapters.h" -#include "base/trace_event/trace_event.h" -#include "cc/base/math_util.h" -#include "cc/layers/heads_up_display_layer_impl.h" -#include "cc/layers/layer.h" -#include "cc/layers/layer_impl.h" -#include "cc/trees/draw_property_utils.h" -#include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_impl.h" -#include "cc/trees/property_tree_builder.h" -#include "cc/trees/scroll_node.h" -#include "cc/trees/transform_node.h" -#include "ui/gfx/geometry/rect_conversions.h" -#include "ui/gfx/geometry/vector2d_conversions.h" -#include "ui/gfx/transform.h" -#include "ui/gfx/transform_util.h" - -namespace cc { - -LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer) - : root_layer(root_layer), - device_viewport_rect(device_viewport_rect), - device_transform(device_transform), - device_scale_factor(device_scale_factor), - page_scale_factor(page_scale_factor), - page_scale_layer(page_scale_layer), - inner_viewport_scroll_layer(inner_viewport_scroll_layer), - outer_viewport_scroll_layer(outer_viewport_scroll_layer) {} - -LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform) - : CalcDrawPropsMainInputsForTesting(root_layer, - device_viewport_rect, - device_transform, - 1.f, - 1.f, - nullptr, - nullptr, - nullptr) {} - -LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting:: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect) - : CalcDrawPropsMainInputsForTesting(root_layer, - device_viewport_rect, - gfx::Transform()) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( - LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const gfx::Vector2dF& elastic_overscroll, - const ElementId elastic_overscroll_element_id, - int max_texture_size, - RenderSurfaceList* render_surface_list, - PropertyTrees* property_trees, - TransformNode* page_scale_transform_node) - : root_layer(root_layer), - device_viewport_rect(device_viewport_rect), - device_transform(device_transform), - device_scale_factor(device_scale_factor), - page_scale_factor(page_scale_factor), - page_scale_layer(page_scale_layer), - inner_viewport_scroll_layer(inner_viewport_scroll_layer), - outer_viewport_scroll_layer(outer_viewport_scroll_layer), - elastic_overscroll(elastic_overscroll), - elastic_overscroll_element_id(elastic_overscroll_element_id), - max_texture_size(max_texture_size), - render_surface_list(render_surface_list), - property_trees(property_trees), - page_scale_transform_node(page_scale_transform_node) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputs(root_layer, - device_viewport_rect, - device_transform, - device_scale_factor, - 1.f, - nullptr, - nullptr, - nullptr, - gfx::Vector2dF(), - ElementId(), - std::numeric_limits<int>::max() / 2, - render_surface_list, - GetPropertyTrees(root_layer), - nullptr) { - DCHECK(root_layer); - DCHECK(render_surface_list); -} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_rect, - device_transform, - 1.f, - render_surface_list) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_rect, - gfx::Transform(), - 1.f, - render_surface_list) {} - -LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - float device_scale_factor, - RenderSurfaceList* render_surface_list) - : CalcDrawPropsImplInputsForTesting(root_layer, - device_viewport_rect, - gfx::Transform(), - device_scale_factor, - render_surface_list) {} - -bool LayerTreeHostCommon::ScrollUpdateInfo::operator==( - const LayerTreeHostCommon::ScrollUpdateInfo& other) const { - return element_id == other.element_id && scroll_delta == other.scroll_delta; -} - -LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo() - : element_id(), hidden(true) {} - -LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo(ElementId id, - bool hidden) - : element_id(id), hidden(hidden) {} - -bool LayerTreeHostCommon::ScrollbarsUpdateInfo::operator==( - const LayerTreeHostCommon::ScrollbarsUpdateInfo& other) const { - return element_id == other.element_id && hidden == other.hidden; -} - -ScrollAndScaleSet::ScrollAndScaleSet() - : page_scale_delta(1.f), - is_pinch_gesture_active(false), - top_controls_delta(0.f), - browser_controls_constraint(BrowserControlsState::kBoth), - browser_controls_constraint_changed(false), - scroll_gesture_did_end(false), - manipulation_info(kManipulationInfoNone) {} - -ScrollAndScaleSet::~ScrollAndScaleSet() = default; - -static inline void SetMaskLayersContributeToDrawnRenderSurface( - RenderSurfaceImpl* surface, - PropertyTrees* property_trees) { - LayerImpl* mask_layer = surface->MaskLayer(); - if (mask_layer) { - mask_layer->set_contributes_to_drawn_render_surface(true); - draw_property_utils::ComputeMaskDrawProperties(mask_layer, property_trees); - } -} - -static inline void ClearMaskLayersContributeToDrawnRenderSurface( - RenderSurfaceImpl* surface) { - LayerImpl* mask_layer = surface->MaskLayer(); - if (mask_layer) - mask_layer->set_contributes_to_drawn_render_surface(false); -} - -static float TranslationFromActiveTreeLayerScreenSpaceTransform( - LayerImpl* pending_tree_layer) { - LayerTreeImpl* layer_tree_impl = pending_tree_layer->layer_tree_impl(); - if (layer_tree_impl) { - LayerImpl* active_tree_layer = - layer_tree_impl->FindActiveTreeLayerById(pending_tree_layer->id()); - if (active_tree_layer) { - gfx::Transform active_tree_screen_space_transform = - active_tree_layer->draw_properties().screen_space_transform; - if (active_tree_screen_space_transform.IsIdentity()) - return 0.f; - if (active_tree_screen_space_transform.ApproximatelyEqual( - pending_tree_layer->draw_properties().screen_space_transform)) - return 0.f; - return (active_tree_layer->draw_properties() - .screen_space_transform.To2dTranslation() - - pending_tree_layer->draw_properties() - .screen_space_transform.To2dTranslation()) - .Length(); - } - } - return 0.f; -} - -// A layer jitters if its screen space transform is same on two successive -// commits, but has changed in between the commits. CalculateLayerJitter -// computes the jitter for the layer. -int LayerTreeHostCommon::CalculateLayerJitter(LayerImpl* layer) { - float jitter = 0.f; - layer->performance_properties().translation_from_last_frame = 0.f; - layer->performance_properties().last_commit_screen_space_transform = - layer->draw_properties().screen_space_transform; - - if (!layer->visible_layer_rect().IsEmpty()) { - if (layer->draw_properties().screen_space_transform.ApproximatelyEqual( - layer->performance_properties() - .last_commit_screen_space_transform)) { - float translation_from_last_commit = - TranslationFromActiveTreeLayerScreenSpaceTransform(layer); - if (translation_from_last_commit > 0.f) { - layer->performance_properties().num_fixed_point_hits++; - layer->performance_properties().translation_from_last_frame = - translation_from_last_commit; - if (layer->performance_properties().num_fixed_point_hits > - layer->layer_tree_impl()->kFixedPointHitsThreshold) { - // Jitter = Translation from fixed point * sqrt(Area of the layer). - // The square root of the area is used instead of the area to match - // the dimensions of both terms on the rhs. - jitter += translation_from_last_commit * - sqrt(layer->visible_layer_rect().size().GetArea()); - } - } else { - layer->performance_properties().num_fixed_point_hits = 0; - } - } - } - return jitter; -} - -enum PropertyTreeOption { BUILD_PROPERTY_TREES, DONT_BUILD_PROPERTY_TREES }; - -static void AddSurfaceToRenderSurfaceList( - RenderSurfaceImpl* render_surface, - RenderSurfaceList* render_surface_list, - PropertyTrees* property_trees) { - // |render_surface| must appear after its target, so first make sure its - // target is in the list. - RenderSurfaceImpl* target = render_surface->render_target(); - bool is_root = - render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; - if (!is_root && !target->is_render_surface_list_member()) { - AddSurfaceToRenderSurfaceList(target, render_surface_list, property_trees); - } - render_surface->ClearAccumulatedContentRect(); - render_surface_list->push_back(render_surface); - render_surface->set_is_render_surface_list_member(true); - if (is_root) { - // The root surface does not contribute to any other surface, it has no - // target. - render_surface->set_contributes_to_drawn_surface(false); - } else { - bool contributes_to_drawn_surface = - property_trees->effect_tree.ContributesToDrawnSurface( - render_surface->EffectTreeIndex()); - render_surface->set_contributes_to_drawn_surface( - contributes_to_drawn_surface); - } - - draw_property_utils::ComputeSurfaceDrawProperties(property_trees, - render_surface); - - // Ignore occlusion from outside the surface when surface contents need to be - // fully drawn. Layers with copy-request need to be complete. We could be - // smarter about layers with filters that move pixels and exclude regions - // where both layers and the filters are occluded, but this seems like - // overkill. - // TODO(senorblanco): make this smarter for the SkImageFilter case (check for - // pixel-moving filters) - const FilterOperations& filters = render_surface->Filters(); - bool is_occlusion_immune = render_surface->HasCopyRequest() || - render_surface->ShouldCacheRenderSurface() || - filters.HasReferenceFilter() || - filters.HasFilterThatMovesPixels(); - if (is_occlusion_immune) { - render_surface->SetNearestOcclusionImmuneAncestor(render_surface); - } else if (is_root) { - render_surface->SetNearestOcclusionImmuneAncestor(nullptr); - } else { - render_surface->SetNearestOcclusionImmuneAncestor( - render_surface->render_target()->nearest_occlusion_immune_ancestor()); - } -} - -static bool SkipForInvertibility(const LayerImpl* layer, - PropertyTrees* property_trees) { - const TransformNode* transform_node = - property_trees->transform_tree.Node(layer->transform_tree_index()); - const EffectNode* effect_node = - property_trees->effect_tree.Node(layer->effect_tree_index()); - bool non_root_copy_request = - effect_node->closest_ancestor_with_copy_request_id > - EffectTree::kContentsRootNodeId; - gfx::Transform from_target; - // If there is a copy request, we check the invertibility of the transform - // between the node corresponding to the layer and the node corresponding to - // the copy request. Otherwise, we are interested in the invertibility of - // screen space transform which is already cached on the transform node. - return non_root_copy_request - ? !property_trees->GetFromTarget( - layer->transform_tree_index(), - effect_node->closest_ancestor_with_copy_request_id, - &from_target) - : !transform_node->ancestors_are_invertible; -} - -static void ComputeInitialRenderSurfaceList( - LayerTreeImpl* layer_tree_impl, - PropertyTrees* property_trees, - RenderSurfaceList* render_surface_list) { - EffectTree& effect_tree = property_trees->effect_tree; - for (int i = EffectTree::kContentsRootNodeId; - i < static_cast<int>(effect_tree.size()); ++i) { - if (RenderSurfaceImpl* render_surface = effect_tree.GetRenderSurface(i)) { - render_surface->set_is_render_surface_list_member(false); - render_surface->reset_num_contributors(); - ClearMaskLayersContributeToDrawnRenderSurface(render_surface); - } - } - - RenderSurfaceImpl* root_surface = - effect_tree.GetRenderSurface(EffectTree::kContentsRootNodeId); - // The root surface always gets added to the render surface list. - AddSurfaceToRenderSurfaceList(root_surface, render_surface_list, - property_trees); - // For all non-skipped layers, add their target to the render surface list if - // it's not already been added, and add their content rect to the target - // surface's accumulated content rect. - for (LayerImpl* layer : *layer_tree_impl) { - DCHECK(layer); - layer->EnsureValidPropertyTreeIndices(); - - layer->set_contributes_to_drawn_render_surface(false); - layer->set_raster_even_if_not_drawn(false); - - bool is_root = layer_tree_impl->IsRootLayer(layer); - - bool skip_draw_properties_computation = - draw_property_utils::LayerShouldBeSkippedForDrawPropertiesComputation( - layer, property_trees->transform_tree, property_trees->effect_tree); - - bool skip_for_invertibility = SkipForInvertibility(layer, property_trees); - - bool skip_layer = !is_root && (skip_draw_properties_computation || - skip_for_invertibility); - - layer->set_raster_even_if_not_drawn(skip_for_invertibility && - !skip_draw_properties_computation); - if (skip_layer) - continue; - - bool layer_is_drawn = - property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn; - bool layer_should_be_drawn = draw_property_utils::LayerNeedsUpdate( - layer, layer_is_drawn, property_trees); - if (!layer_should_be_drawn) - continue; - - RenderSurfaceImpl* render_target = layer->render_target(); - if (!render_target->is_render_surface_list_member()) { - AddSurfaceToRenderSurfaceList(render_target, render_surface_list, - property_trees); - } - - layer->set_contributes_to_drawn_render_surface(true); - - // The layer contributes its drawable content rect to its render target. - render_target->AccumulateContentRectFromContributingLayer(layer); - render_target->increment_num_contributors(); - } -} - -static void ComputeSurfaceContentRects(PropertyTrees* property_trees, - RenderSurfaceList* render_surface_list, - int max_texture_size) { - // Walk the list backwards, accumulating each surface's content rect into its - // target's content rect. - for (RenderSurfaceImpl* render_surface : - base::Reversed(*render_surface_list)) { - if (render_surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId) { - // The root surface's content rect is always the entire viewport. - render_surface->SetContentRectToViewport(); - continue; - } - - // Now all contributing drawable content rect has been accumulated to this - // render surface, calculate the content rect. - render_surface->CalculateContentRectFromAccumulatedContentRect( - max_texture_size); - - // Now the render surface's content rect is calculated correctly, it could - // contribute to its render target. - RenderSurfaceImpl* render_target = render_surface->render_target(); - DCHECK(render_target->is_render_surface_list_member()); - render_target->AccumulateContentRectFromContributingRenderSurface( - render_surface); - render_target->increment_num_contributors(); - } -} - -static void ComputeListOfNonEmptySurfaces( - LayerTreeImpl* layer_tree_impl, - PropertyTrees* property_trees, - RenderSurfaceList* initial_surface_list, - RenderSurfaceList* final_surface_list) { - // Walk the initial surface list forwards. The root surface and each - // surface with a non-empty content rect go into the final render surface - // layer list. Surfaces with empty content rects or whose target isn't in - // the final list do not get added to the final list. - bool removed_surface = false; - for (RenderSurfaceImpl* surface : *initial_surface_list) { - bool is_root = - surface->EffectTreeIndex() == EffectTree::kContentsRootNodeId; - RenderSurfaceImpl* target_surface = surface->render_target(); - if (!is_root && (surface->content_rect().IsEmpty() || - !target_surface->is_render_surface_list_member())) { - surface->set_is_render_surface_list_member(false); - removed_surface = true; - target_surface->decrement_num_contributors(); - continue; - } - SetMaskLayersContributeToDrawnRenderSurface(surface, property_trees); - final_surface_list->push_back(surface); - } - if (removed_surface) { - for (LayerImpl* layer : *layer_tree_impl) { - if (layer->contributes_to_drawn_render_surface()) { - RenderSurfaceImpl* render_target = layer->render_target(); - if (!render_target->is_render_surface_list_member()) { - layer->set_contributes_to_drawn_render_surface(false); - render_target->decrement_num_contributors(); - } - } - } - } -} - -static void CalculateRenderSurfaceLayerList( - LayerTreeImpl* layer_tree_impl, - PropertyTrees* property_trees, - RenderSurfaceList* render_surface_list, - const int max_texture_size) { - RenderSurfaceList initial_render_surface_list; - - // First compute a list that might include surfaces that later turn out to - // have an empty content rect. After surface content rects are computed, - // produce a final list that omits empty surfaces. - ComputeInitialRenderSurfaceList(layer_tree_impl, property_trees, - &initial_render_surface_list); - ComputeSurfaceContentRects(property_trees, &initial_render_surface_list, - max_texture_size); - ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, - &initial_render_surface_list, - render_surface_list); -} - -static void RecordRenderSurfaceReasonsForTracing( - const PropertyTrees* property_trees, - const RenderSurfaceList* render_surface_list) { - static const auto* tracing_enabled = - TRACE_EVENT_API_GET_CATEGORY_GROUP_ENABLED("cc"); - if (!*tracing_enabled || - // Don't output single root render surface. - render_surface_list->size() <= 1) - return; - - TRACE_EVENT_INSTANT1("cc", "RenderSurfaceReasonCount", - TRACE_EVENT_SCOPE_THREAD, "total", - render_surface_list->size()); - - // kTest is the last value which is not included for tracing. - constexpr auto kNumReasons = static_cast<size_t>(RenderSurfaceReason::kTest); - int reason_counts[kNumReasons] = {0}; - for (const auto* render_surface : *render_surface_list) { - const auto* effect_node = - property_trees->effect_tree.Node(render_surface->EffectTreeIndex()); - reason_counts[static_cast<size_t>(effect_node->render_surface_reason)]++; - } - for (size_t i = 0; i < kNumReasons; i++) { - if (!reason_counts[i]) - continue; - TRACE_EVENT_INSTANT1( - "cc", "RenderSurfaceReasonCount", TRACE_EVENT_SCOPE_THREAD, - RenderSurfaceReasonToString(static_cast<RenderSurfaceReason>(i)), - reason_counts[i]); - } -} - -static void CalculateDrawPropertiesInternal( - LayerTreeHostCommon::CalcDrawPropsImplInputs* inputs, - PropertyTreeOption property_tree_option, - LayerImplList* output_update_layer_list) { - inputs->render_surface_list->clear(); - - LayerImplList visible_layer_list; - switch (property_tree_option) { - case BUILD_PROPERTY_TREES: { - // The translation from layer to property trees is an intermediate - // state. We will eventually get these data passed directly to the - // compositor. - PropertyTreeBuilder::BuildPropertyTrees( - inputs->root_layer, inputs->page_scale_layer, - inputs->inner_viewport_scroll_layer, - inputs->outer_viewport_scroll_layer, - inputs->elastic_overscroll_element_id, inputs->elastic_overscroll, - inputs->page_scale_factor, inputs->device_scale_factor, - inputs->device_viewport_rect, inputs->device_transform, - inputs->property_trees); - draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( - inputs->root_layer, inputs->property_trees); - break; - } - case DONT_BUILD_PROPERTY_TREES: { - // Since page scale and elastic overscroll are SyncedProperties, changes - // on the active tree immediately affect the pending tree, so instead of - // trying to update property trees whenever these values change, we - // update property trees before using them. - - // We should never be setting a non-unit page scale factor on an oopif - // subframe ... if we attempt this log it and fail. - // TODO(wjmaclean): Remove as part of conditions for closing the bug. - // https://crbug.com/845097 - if (inputs->page_scale_factor != - inputs->property_trees->transform_tree.page_scale_factor() && - !inputs->page_scale_transform_node) { - LOG(ERROR) << "Setting PageScale on subframe: new psf = " - << inputs->page_scale_factor << ", old psf = " - << inputs->property_trees->transform_tree.page_scale_factor() - << ", in_oopif = " - << inputs->root_layer->layer_tree_impl() - ->settings() - .is_layer_tree_for_subframe; - NOTREACHED(); - } - - DCHECK_NE(inputs->page_scale_layer, inputs->root_layer); - draw_property_utils::UpdatePageScaleFactor( - inputs->property_trees, inputs->page_scale_transform_node, - inputs->page_scale_factor); - draw_property_utils::UpdateElasticOverscroll( - inputs->property_trees, inputs->elastic_overscroll_element_id, - inputs->elastic_overscroll); - // Similarly, the device viewport and device transform are shared - // by both trees. - PropertyTrees* property_trees = inputs->property_trees; - property_trees->clip_tree.SetViewportClip( - gfx::RectF(inputs->device_viewport_rect)); - property_trees->transform_tree.SetRootScaleAndTransform( - inputs->device_scale_factor, inputs->device_transform); - draw_property_utils::UpdatePropertyTreesAndRenderSurfaces( - inputs->root_layer, inputs->property_trees); - break; - } - } - - { - TRACE_EVENT0("cc", "draw_property_utils::FindLayersThatNeedUpdates"); - draw_property_utils::FindLayersThatNeedUpdates( - inputs->root_layer->layer_tree_impl(), inputs->property_trees, - &visible_layer_list); - } - - { - TRACE_EVENT1("cc", - "draw_property_utils::ComputeDrawPropertiesOfVisibleLayers", - "visible_layers", visible_layer_list.size()); - draw_property_utils::ComputeDrawPropertiesOfVisibleLayers( - &visible_layer_list, inputs->property_trees); - } - - { - TRACE_EVENT0("cc", "CalculateRenderSurfaceLayerList"); - CalculateRenderSurfaceLayerList( - inputs->root_layer->layer_tree_impl(), inputs->property_trees, - inputs->render_surface_list, inputs->max_texture_size); - } - RecordRenderSurfaceReasonsForTracing(inputs->property_trees, - inputs->render_surface_list); - - // A root layer render_surface should always exist after - // CalculateDrawProperties. - DCHECK(inputs->property_trees->effect_tree.GetRenderSurface( - EffectTree::kContentsRootNodeId)); - - if (output_update_layer_list) - *output_update_layer_list = std::move(visible_layer_list); -} - -void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( - CalcDrawPropsMainInputsForTesting* inputs) { - LayerList update_layer_list; - PropertyTrees* property_trees = - inputs->root_layer->layer_tree_host()->property_trees(); - if (inputs->root_layer->layer_tree_host()->IsUsingLayerLists()) { - // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all - // unnecessary setting of the flag in layer list mode. - property_trees->needs_rebuild = false; - } else { - gfx::Vector2dF elastic_overscroll; - PropertyTreeBuilder::BuildPropertyTrees( - inputs->root_layer, inputs->page_scale_layer, - inputs->inner_viewport_scroll_layer, - inputs->outer_viewport_scroll_layer, ElementId(), elastic_overscroll, - inputs->page_scale_factor, inputs->device_scale_factor, - inputs->device_viewport_rect, inputs->device_transform, property_trees); - } - draw_property_utils::UpdatePropertyTrees( - inputs->root_layer->layer_tree_host(), property_trees); - draw_property_utils::FindLayersThatNeedUpdates( - inputs->root_layer->layer_tree_host(), property_trees, - &update_layer_list); - - if (inputs->update_layer_list) - *inputs->update_layer_list = std::move(update_layer_list); -} - -void LayerTreeHostCommon::CalculateDrawProperties( - CalcDrawPropsImplInputs* inputs) { - CalculateDrawPropertiesInternal(inputs, DONT_BUILD_PROPERTY_TREES, nullptr); -} - -void LayerTreeHostCommon::PrepareForUpdateDrawPropertiesForTesting( - LayerTreeImpl* layer_tree_impl) { - if (layer_tree_impl->settings().use_layer_lists) { - // TODO(wangxianzhu): We should DCHECK(!needs_rebuild) after we remove all - // unnecessary setting of the flag in layer list mode. - auto* property_trees = layer_tree_impl->property_trees(); - property_trees->needs_rebuild = false; - // The following are needed for tests that modify impl-side property trees. - // In production code impl-side property trees are pushed from the main - // thread and the following are done in other ways. - std::vector<std::unique_ptr<RenderSurfaceImpl>> old_render_surfaces; - property_trees->effect_tree.TakeRenderSurfaces(&old_render_surfaces); - property_trees->effect_tree.CreateOrReuseRenderSurfaces( - &old_render_surfaces, layer_tree_impl); - property_trees->ResetCachedData(); - } -} - -void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( - CalcDrawPropsImplInputsForTesting* inputs) { - PrepareForUpdateDrawPropertiesForTesting( - inputs->root_layer->layer_tree_impl()); - CalculateDrawPropertiesInternal(inputs, - inputs->property_trees->needs_rebuild - ? BUILD_PROPERTY_TREES - : DONT_BUILD_PROPERTY_TREES, - inputs->update_layer_list); -} - -PropertyTrees* GetPropertyTrees(const Layer* layer) { - return layer->layer_tree_host()->property_trees(); -} - -PropertyTrees* GetPropertyTrees(const LayerImpl* layer) { - return layer->layer_tree_impl()->property_trees(); -} - -} // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h deleted file mode 100644 index 6c9dfd5f065..00000000000 --- a/chromium/cc/trees/layer_tree_host_common.h +++ /dev/null @@ -1,232 +0,0 @@ -// Copyright 2011 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CC_TREES_LAYER_TREE_HOST_COMMON_H_ -#define CC_TREES_LAYER_TREE_HOST_COMMON_H_ - -#include <stddef.h> - -#include <limits> -#include <vector> - -#include "base/bind.h" -#include "base/memory/ref_counted.h" -#include "cc/cc_export.h" -#include "cc/input/browser_controls_state.h" -#include "cc/layers/layer.h" -#include "cc/layers/layer_collections.h" -#include "cc/layers/layer_impl.h" -#include "cc/layers/picture_layer.h" -#include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_impl.h" -#include "cc/trees/property_tree.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/vector2d.h" -#include "ui/gfx/transform.h" - -namespace cc { - -class LayerImpl; -class Layer; -class SwapPromise; -class PropertyTrees; - -class CC_EXPORT LayerTreeHostCommon { - public: - struct CC_EXPORT CalcDrawPropsMainInputsForTesting { - public: - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer); - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform); - CalcDrawPropsMainInputsForTesting(Layer* root_layer, - const gfx::Rect& device_viewport_rect); - Layer* root_layer; - gfx::Rect device_viewport_rect; - gfx::Transform device_transform; - float device_scale_factor; - float page_scale_factor; - const Layer* page_scale_layer; - const Layer* inner_viewport_scroll_layer; - const Layer* outer_viewport_scroll_layer; - // If not null, accepts layers output from FindLayersThatNeedUpdates(). - LayerList* update_layer_list = nullptr; - }; - - struct CC_EXPORT CalcDrawPropsImplInputs { - public: - CalcDrawPropsImplInputs(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - float page_scale_factor, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const gfx::Vector2dF& elastic_overscroll, - const ElementId elastic_overscroll_element_id, - int max_texture_size, - RenderSurfaceList* render_surface_list, - PropertyTrees* property_trees, - TransformNode* page_scale_transform_node); - - LayerImpl* root_layer; - gfx::Rect device_viewport_rect; - gfx::Transform device_transform; - float device_scale_factor; - float page_scale_factor; - const LayerImpl* page_scale_layer; - const LayerImpl* inner_viewport_scroll_layer; - const LayerImpl* outer_viewport_scroll_layer; - gfx::Vector2dF elastic_overscroll; - const ElementId elastic_overscroll_element_id; - int max_texture_size; - RenderSurfaceList* render_surface_list; - PropertyTrees* property_trees; - TransformNode* page_scale_transform_node; - }; - - struct CC_EXPORT CalcDrawPropsImplInputsForTesting - : public CalcDrawPropsImplInputs { - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - float device_scale_factor, - RenderSurfaceList* render_surface_list); - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - const gfx::Transform& device_transform, - RenderSurfaceList* render_surface_list); - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - RenderSurfaceList* render_surface_list); - CalcDrawPropsImplInputsForTesting(LayerImpl* root_layer, - const gfx::Rect& device_viewport_rect, - float device_scale_factor, - RenderSurfaceList* render_surface_list); - - // If not null, accepts layers output from FindLayersThatNeedUpdates(). - LayerImplList* update_layer_list = nullptr; - }; - - static int CalculateLayerJitter(LayerImpl* scrolling_layer); - static void CalculateDrawPropertiesForTesting( - CalcDrawPropsMainInputsForTesting* inputs); - - static void CalculateDrawProperties(CalcDrawPropsImplInputs* inputs); - - // TODO(wangxianzhu): Move these functions into testing classes. - static void PrepareForUpdateDrawPropertiesForTesting(LayerTreeImpl*); - static void CalculateDrawPropertiesForTesting( - CalcDrawPropsImplInputsForTesting* inputs); - - template <typename Function> - static void CallFunctionForEveryLayer(LayerTreeHost* host, - const Function& function); - - template <typename Function> - static void CallFunctionForEveryLayer(LayerTreeImpl* layer, - const Function& function); - - struct CC_EXPORT ScrollUpdateInfo { - ElementId element_id; - gfx::ScrollOffset scroll_delta; - - bool operator==(const ScrollUpdateInfo& other) const; - }; - - // Used to communicate scrollbar visibility from Impl thread to Blink. - // Scrollbar input is handled by Blink but the compositor thread animates - // opacity on scrollbars to fade them out when they're overlay. Blink needs - // to be told when they're faded out so it can stop handling input for - // invisible scrollbars. - struct CC_EXPORT ScrollbarsUpdateInfo { - ElementId element_id; - bool hidden; - - ScrollbarsUpdateInfo(); - ScrollbarsUpdateInfo(ElementId element_id, bool hidden); - - bool operator==(const ScrollbarsUpdateInfo& other) const; - }; -}; - -struct CC_EXPORT ScrollAndScaleSet { - ScrollAndScaleSet(); - ScrollAndScaleSet(const ScrollAndScaleSet&) = delete; - ~ScrollAndScaleSet(); - - ScrollAndScaleSet& operator=(const ScrollAndScaleSet&) = delete; - - // The inner viewport scroll delta is kept separate since it's special. - // Because the inner (visual) viewport's maximum offset depends on the - // current page scale, the two must be committed at the same time to prevent - // clamping. - LayerTreeHostCommon::ScrollUpdateInfo inner_viewport_scroll; - - std::vector<LayerTreeHostCommon::ScrollUpdateInfo> scrolls; - float page_scale_delta; - bool is_pinch_gesture_active; - - // Elastic overscroll effect offset delta. This is used only on Mac and shows - // the pixels that the page is rubber-banned/stretched by. - gfx::Vector2dF elastic_overscroll_delta; - - // Unconsumed scroll delta used to send overscroll events to the latched - // element on the main thread; - gfx::Vector2dF overscroll_delta; - - // The element id of the node to which scrolling is latched. This is used to - // send overscroll/scrollend DOM events to proper targets whenever needed. - ElementId scroll_latched_element_id; - - float top_controls_delta; - std::vector<LayerTreeHostCommon::ScrollbarsUpdateInfo> scrollbars; - std::vector<std::unique_ptr<SwapPromise>> swap_promises; - BrowserControlsState browser_controls_constraint; - bool browser_controls_constraint_changed; - - // Set to true when a scroll gesture being handled on the compositor has - // ended. - bool scroll_gesture_did_end; - - // Tracks different methods of scrolling (e.g. wheel, touch, precision - // touchpad, etc.). - ManipulationInfo manipulation_info; -}; - -template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeHost* host, - const Function& function) { - for (auto* layer : *host) { - function(layer); - if (PictureLayer* mask_layer = layer->mask_layer()) - function(mask_layer); - } -} - -template <typename Function> -void LayerTreeHostCommon::CallFunctionForEveryLayer(LayerTreeImpl* tree_impl, - const Function& function) { - for (auto* layer : *tree_impl) - function(layer); - - for (int id : tree_impl->property_trees()->effect_tree.mask_layer_ids()) { - function(tree_impl->LayerById(id)); - } -} - -CC_EXPORT PropertyTrees* GetPropertyTrees(const Layer* layer); -CC_EXPORT PropertyTrees* GetPropertyTrees(const LayerImpl* layer); - -} // namespace cc - -#endif // CC_TREES_LAYER_TREE_HOST_COMMON_H_ diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index 49112276c53..0dd3041f319 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -79,12 +79,12 @@ #include "cc/trees/image_animation_controller.h" #include "cc/trees/latency_info_swap_promise_monitor.h" #include "cc/trees/layer_tree_frame_sink.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/presentation_time_callback_buffer.h" #include "cc/trees/render_frame_metadata.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" @@ -92,6 +92,7 @@ #include "components/viz/common/features.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/delay_based_time_source.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/hit_test/hit_test_region_list.h" #include "components/viz/common/quads/compositor_frame.h" #include "components/viz/common/quads/compositor_frame_metadata.h" @@ -117,7 +118,6 @@ #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/geometry/size_conversions.h" #include "ui/gfx/geometry/vector2d_conversions.h" -#include "ui/gfx/presentation_feedback.h" #include "ui/gfx/skia_util.h" namespace cc { @@ -202,25 +202,6 @@ void RecordCompositorSlowScrollMetric(InputHandler::ScrollInputType type, } } -ui::FrameMetricsSettings LTHI_FrameMetricsSettings( - const LayerTreeSettings& settings) { - ui::FrameMetricsSource source = - settings.commit_to_active_tree - ? ui::FrameMetricsSource::UiCompositor - : ui::FrameMetricsSource::RendererCompositor; - ui::FrameMetricsSourceThread source_thread = - settings.commit_to_active_tree - ? ui::FrameMetricsSourceThread::UiCompositor - : ui::FrameMetricsSourceThread::RendererCompositor; - ui::FrameMetricsCompileTarget compile_target = - settings.using_synchronous_renderer_compositor - ? ui::FrameMetricsCompileTarget::SynchronousCompositor - : settings.wait_for_all_pipeline_stages_before_draw - ? ui::FrameMetricsCompileTarget::Headless - : ui::FrameMetricsCompileTarget::Chromium; - return ui::FrameMetricsSettings(source, source_thread, compile_target); -} - class ScopedPostAnimationEventsToMainThread { public: ScopedPostAnimationEventsToMainThread(MutatorHost* animation_host, @@ -263,11 +244,12 @@ std::unique_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner) { + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client) { return base::WrapUnique(new LayerTreeHostImpl( settings, client, task_runner_provider, rendering_stats_instrumentation, task_graph_runner, std::move(mutator_host), id, - std::move(image_worker_task_runner))); + std::move(image_worker_task_runner), scheduling_client)); } LayerTreeHostImpl::LayerTreeHostImpl( @@ -278,8 +260,10 @@ LayerTreeHostImpl::LayerTreeHostImpl( TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner) + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client) : client_(client), + scheduling_client_(scheduling_client), task_runner_provider_(task_runner_provider), current_begin_frame_tracker_(BEGINFRAMETRACKER_FROM_HERE), compositor_frame_reporting_controller_( @@ -314,12 +298,11 @@ LayerTreeHostImpl::LayerTreeHostImpl( image_animation_controller_(GetTaskRunner(), this, settings_.enable_image_animation_resync), - frame_metrics_(LTHI_FrameMetricsSettings(settings_)), - skipped_frame_tracker_(&frame_metrics_), is_animating_for_snap_(false), paint_image_generator_client_id_(PaintImage::GetNextGeneratorClientId()), scrollbar_controller_(std::make_unique<ScrollbarController>(this)), - frame_trackers_(compositor_frame_reporting_controller_.get()), + frame_trackers_(settings.single_thread_proxy_scheduler, + compositor_frame_reporting_controller_.get()), scroll_gesture_did_end_(false) { DCHECK(mutator_host_); mutator_host_->SetMutatorHostClient(this); @@ -388,6 +371,11 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { mutator_host_->SetMutatorHostClient(nullptr); } +void LayerTreeHostImpl::WillSendBeginMainFrame() { + if (scheduling_client_) + scheduling_client_->DidScheduleBeginMainFrame(); +} + void LayerTreeHostImpl::DidSendBeginMainFrame(const viz::BeginFrameArgs& args) { if (impl_thread_phase_ == ImplThreadPhase::INSIDE_IMPL_FRAME) begin_main_frame_sent_during_impl_ = true; @@ -756,8 +744,8 @@ void LayerTreeHostImpl::AnimateInternal() { did_animate |= AnimateScrollbars(monotonic_time); did_animate |= AnimateBrowserControls(monotonic_time); - // Animating stuff can change the root scroll offset, so inform the - // synchronous input handler. + // Animating stuff can change the root scroll offset, so inform the + // synchronous input handler. UpdateRootLayerStateForSynchronousInputHandler(); if (did_animate) { // If the tree changed, then we want to draw at the end of the current @@ -766,7 +754,6 @@ void LayerTreeHostImpl::AnimateInternal() { } } - bool LayerTreeHostImpl::PrepareTiles() { if (!tile_priorities_dirty_) return false; @@ -802,8 +789,8 @@ void LayerTreeHostImpl::StartPageScaleAnimation( gfx::ScrollOffset scroll_total = active_tree_->TotalScrollOffset(); gfx::SizeF scrollable_size = active_tree_->ScrollableSize(); - gfx::SizeF viewport_size = - gfx::SizeF(active_tree_->InnerViewportContainerLayer()->bounds()); + gfx::SizeF viewport_size( + active_tree_->InnerViewportScrollNode()->container_bounds); // TODO(miletus) : Pass in ScrollOffset. page_scale_animation_ = @@ -836,9 +823,7 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingViewport() const { auto* node = CurrentlyScrollingNode(); if (!node) return false; - if (!viewport()->MainScrollLayer()) - return false; - return node->id == viewport()->MainScrollLayer()->scroll_tree_index(); + return node == viewport()->MainScrollNode(); } bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt( @@ -1028,11 +1013,13 @@ void LayerTreeHostImpl::FrameData::AsValueInto( base::trace_event::TracedValue* value) const { value->SetBoolean("has_no_damage", has_no_damage); - // Quad data can be quite large, so only dump render passes if we select - // viz.quads. - bool quads_enabled; - TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("viz.quads"), - &quads_enabled); + // Quad data can be quite large, so only dump render passes if we are + // logging verbosely or viz.quads tracing category is enabled. + bool quads_enabled = VLOG_IS_ON(3); + if (!quads_enabled) { + TRACE_EVENT_CATEGORY_GROUP_ENABLED(TRACE_DISABLED_BY_DEFAULT("viz.quads"), + &quads_enabled); + } if (quads_enabled) { value->BeginArray("render_passes"); for (size_t i = 0; i < render_passes.size(); ++i) { @@ -1044,6 +1031,18 @@ void LayerTreeHostImpl::FrameData::AsValueInto( } } +std::string LayerTreeHostImpl::FrameData::ToString() const { + base::trace_event::TracedValue value; + AsValueInto(&value); + std::string str; + base::JSONWriter::WriteWithOptions( + *value.ToBaseValue(), + base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION | + base::JSONWriter::OPTIONS_PRETTY_PRINT, + &str); + return str; +} + DrawMode LayerTreeHostImpl::GetDrawMode() const { if (resourceless_software_draw_) { return DRAW_MODE_RESOURCELESS_SOFTWARE; @@ -1150,8 +1149,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { // must compute all damage tracking before drawing anything, so that we know // the root damage rect. The root damage rect is then used to scissor each // surface. - DamageTracker::UpdateDamageTracking(active_tree_.get(), - active_tree_->GetRenderSurfaceList()); + DamageTracker::UpdateDamageTracking(active_tree_.get()); if (HasDamage()) { consecutive_frame_with_damage_count_++; @@ -1469,7 +1467,6 @@ void LayerTreeHostImpl::InvalidateLayerTreeFrameSink(bool needs_redraw) { DCHECK(layer_tree_frame_sink()); layer_tree_frame_sink()->Invalidate(needs_redraw); - skipped_frame_tracker_.DidProduceFrame(); } DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { @@ -1588,6 +1585,15 @@ DrawResult LayerTreeHostImpl::PrepareToDraw(FrameData* frame) { } DrawResult draw_result = CalculateRenderPasses(frame); + + // Dump render passes and draw quads if run with: + // --vmodule=layer_tree_host_impl=3 + if (VLOG_IS_ON(3)) { + VLOG(3) << "Prepare to draw (" + << (client_name ? client_name : "<unknown client>") << ")\n" + << frame->ToString(); + } + if (draw_result != DRAW_SUCCESS) { DCHECK(!resourceless_software_draw_); return draw_result; @@ -1696,6 +1702,7 @@ void LayerTreeHostImpl::ResetTreesForTesting() { active_tree()->top_controls_shown_ratio(), active_tree()->elastic_overscroll()); active_tree_->property_trees()->is_active = true; + active_tree_->property_trees()->clear(); if (pending_tree_) pending_tree_->DetachLayers(); pending_tree_ = nullptr; @@ -1995,25 +2002,19 @@ void LayerTreeHostImpl::DidReceiveCompositorFrameAck() { void LayerTreeHostImpl::DidPresentCompositorFrame( uint32_t frame_token, - const gfx::PresentationFeedback& feedback) { - frame_trackers_.NotifyFramePresented(frame_token, feedback); + const viz::FrameTimingDetails& details) { + frame_trackers_.NotifyFramePresented(frame_token, + details.presentation_feedback); PresentationTimeCallbackBuffer::PendingCallbacks activated = presentation_time_callbacks_.PopPendingCallbacks(frame_token); - // Update compositor frame latency and smoothness stats only for frames - // that caused on-screen damage. - if (!activated.frame_time.is_null()) { - frame_metrics_.AddFrameDisplayed(activated.frame_time, feedback.timestamp); - } - // Send all the main-thread callbacks to the client in one batch. The client // is in charge of posting them to the main thread. client_->DidPresentCompositorFrameOnImplThread( - frame_token, std::move(activated.main_thread_callbacks), feedback); + frame_token, std::move(activated.main_thread_callbacks), details); } void LayerTreeHostImpl::DidNotNeedBeginFrame() { - skipped_frame_tracker_.WillNotProduceFrame(); frame_trackers_.NotifyPauseFrameProduction(); } @@ -2233,7 +2234,6 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { DCHECK(CanDraw()); DCHECK_EQ(frame->has_no_damage, frame->render_passes.empty()); ResetRequiresHighResToDraw(); - skipped_frame_tracker_.DidProduceFrame(); if (frame->has_no_damage) { DCHECK(!resourceless_software_draw_); @@ -2314,11 +2314,11 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( TRACE_EVENT_IS_NEW_TRACE(&is_new_trace); if (is_new_trace) { if (pending_tree_) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - pending_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); + for (auto* layer : *pending_tree_) + layer->DidBeginTracing(); } - LayerTreeHostCommon::CallFunctionForEveryLayer( - active_tree(), [](LayerImpl* layer) { layer->DidBeginTracing(); }); + for (auto* layer : *active_tree_) + layer->DidBeginTracing(); } { @@ -2362,15 +2362,7 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( active_tree()->TakeForceSendMetadataRequest()); } - metadata.latency_info.emplace_back(ui::SourceEventType::FRAME); - ui::LatencyInfo& new_latency_info = metadata.latency_info.back(); - if (CommitToActiveTree()) { - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, frame_time); - } else { - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, frame_time); - + if (!CommitToActiveTree()) { base::TimeTicks draw_time = base::TimeTicks::Now(); for (auto& latency : metadata.latency_info) { latency.AddLatencyNumberWithTimestamp( @@ -2399,20 +2391,18 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame( resources, &compositor_frame.resource_list, layer_tree_frame_sink_->context_provider()); compositor_frame.render_pass_list = std::move(frame->render_passes); - // TODO(fsamuel): Once all clients get their viz::LocalSurfaceId from their - // parent, the viz::LocalSurfaceId should hang off CompositorFrameMetadata. - if (settings_.enable_surface_synchronization) { - // If surface synchronization is on, we should always have a valid - // LocalSurfaceId in LayerTreeImpl unless we don't have a scheduler because - // without a scheduler commits are not deferred and LayerTrees without valid - // LocalSurfaceId might slip through, but single-thread-without-scheduler - // mode is only used in tests so it doesn't matter. - CHECK(!settings_.single_thread_proxy_scheduler || - active_tree()->local_surface_id_allocation_from_parent().IsValid()); - layer_tree_frame_sink_->SetLocalSurfaceId( - child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation() - .local_surface_id()); - } + + // We should always have a valid LocalSurfaceId in LayerTreeImpl unless we + // don't have a scheduler because without a scheduler commits are not deferred + // and LayerTrees without valid LocalSurfaceId might slip through, but + // single-thread-without-scheduler mode is only used in tests so it doesn't + // matter. + CHECK(!settings_.single_thread_proxy_scheduler || + active_tree()->local_surface_id_allocation_from_parent().IsValid()); + layer_tree_frame_sink_->SetLocalSurfaceId( + child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation() + .local_surface_id()); + last_draw_local_surface_id_allocation_ = child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation(); return compositor_frame; @@ -2440,13 +2430,6 @@ int LayerTreeHostImpl::RequestedMSAASampleCount() const { return settings_.gpu_rasterization_msaa_sample_count; } -void LayerTreeHostImpl::SetHasGpuRasterizationTrigger(bool flag) { - if (has_gpu_rasterization_trigger_ != flag) { - has_gpu_rasterization_trigger_ = flag; - need_update_gpu_rasterization_status_ = true; - } -} - void LayerTreeHostImpl::SetContentHasSlowPaths(bool flag) { if (content_has_slow_paths_ != flag) { content_has_slow_paths_ = flag; @@ -2471,9 +2454,15 @@ void LayerTreeHostImpl::GetGpuRasterizationCapabilities( *max_msaa_samples = 0; *supports_disable_msaa = false; + if (settings_.gpu_rasterization_disabled) { + DCHECK(!settings_.gpu_rasterization_forced); + return; + } + if (!(layer_tree_frame_sink_ && layer_tree_frame_sink_->context_provider() && - layer_tree_frame_sink_->worker_context_provider())) + layer_tree_frame_sink_->worker_context_provider())) { return; + } viz::RasterContextProvider* context_provider = layer_tree_frame_sink_->worker_context_provider(); @@ -2559,8 +2548,6 @@ bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() { } } else if (!gpu_rasterization_enabled) { gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE; - } else if (!has_gpu_rasterization_trigger_) { - gpu_rasterization_status_ = GpuRasterizationStatus::OFF_VIEWPORT; } else if (content_has_slow_paths_ && using_msaa_for_slow_paths) { use_gpu = use_msaa = true; gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT; @@ -2612,6 +2599,15 @@ void LayerTreeHostImpl::UpdateTreeResourcesForGpuRasterizationIfNeeded() { SetRequiresHighResToDraw(); } +void LayerTreeHostImpl::RegisterCompositorPresentationTimeCallback( + uint32_t frame_token, + LayerTreeHost::PresentationTimeCallback callback) { + std::vector<LayerTreeHost::PresentationTimeCallback> as_vector; + as_vector.emplace_back(std::move(callback)); + presentation_time_callbacks_.RegisterCompositorPresentationCallbacks( + frame_token, std::move(as_vector)); +} + bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) { impl_thread_phase_ = ImplThreadPhase::INSIDE_IMPL_FRAME; current_begin_frame_tracker_.Start(args); @@ -2639,8 +2635,6 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) { for (auto* it : video_frame_controllers_) it->OnBeginFrame(args); - skipped_frame_tracker_.BeginFrame(args.frame_time, args.interval); - bool recent_frame_had_no_damage = consecutive_frame_with_damage_count_ < settings_.damaged_frame_limit; // Check damage early if the setting is enabled and a recent frame had no @@ -2650,8 +2644,7 @@ bool LayerTreeHostImpl::WillBeginImplFrame(const viz::BeginFrameArgs& args) { CanDraw()) { bool ok = active_tree()->UpdateDrawProperties(); DCHECK(ok); - DamageTracker::UpdateDamageTracking(active_tree_.get(), - active_tree_->GetRenderSurfaceList()); + DamageTracker::UpdateDamageTracking(active_tree_.get()); bool has_damage = HasDamage(); // Animations are updated after we attempt to draw. If the frame is aborted, // update animations now. @@ -2676,7 +2669,6 @@ void LayerTreeHostImpl::DidFinishImplFrame() { frame_trackers_.NotifyMainFrameCausedNoDamage( current_begin_frame_tracker_.Current()); } - skipped_frame_tracker_.FinishFrame(); impl_thread_phase_ = ImplThreadPhase::IDLE; current_begin_frame_tracker_.Finish(); } @@ -2859,26 +2851,10 @@ void LayerTreeHostImpl::SetNeedsCommit() { client_->SetNeedsCommitOnImplThread(); } -LayerImpl* LayerTreeHostImpl::InnerViewportContainerLayer() const { - return active_tree_->InnerViewportContainerLayer(); -} - -LayerImpl* LayerTreeHostImpl::InnerViewportScrollLayer() const { - return active_tree_->InnerViewportScrollLayer(); -} - ScrollNode* LayerTreeHostImpl::InnerViewportScrollNode() const { return active_tree_->InnerViewportScrollNode(); } -LayerImpl* LayerTreeHostImpl::OuterViewportContainerLayer() const { - return active_tree_->OuterViewportContainerLayer(); -} - -LayerImpl* LayerTreeHostImpl::OuterViewportScrollLayer() const { - return active_tree_->OuterViewportScrollLayer(); -} - ScrollNode* LayerTreeHostImpl::OuterViewportScrollNode() const { return active_tree_->OuterViewportScrollNode(); } @@ -3155,8 +3131,6 @@ void LayerTreeHostImpl::SetNeedsOneBeginImplFrame() { void LayerTreeHostImpl::SetNeedsRedraw() { NotifySwapPromiseMonitorsOfSetNeedsRedraw(); client_->SetNeedsRedrawOnImplThread(); - if (CurrentlyScrollingNode()) - skipped_frame_tracker_.WillProduceFrame(); } ManagedMemoryPolicy LayerTreeHostImpl::ActualManagedMemoryPolicy() const { @@ -3306,16 +3280,8 @@ void LayerTreeHostImpl::SetPaintWorkletLayerPainter( paint_worklet_painter_ = std::move(painter); } -LayerImpl* LayerTreeHostImpl::ViewportMainScrollLayer() { - return viewport()->MainScrollLayer(); -} - ScrollNode* LayerTreeHostImpl::ViewportMainScrollNode() { - if (!ViewportMainScrollLayer()) - return nullptr; - - return active_tree_->property_trees()->scroll_tree.Node( - ViewportMainScrollLayer()->scroll_tree_index()); + return viewport()->MainScrollNode(); } void LayerTreeHostImpl::QueueImageDecode(int request_id, @@ -3482,6 +3448,8 @@ bool LayerTreeHostImpl::InitializeFrameSink( has_valid_layer_tree_frame_sink_ = true; auto* context_provider = layer_tree_frame_sink_->context_provider(); + frame_trackers_.StartSequence(FrameSequenceTrackerType::kUniversal); + if (context_provider) { max_texture_size_ = context_provider->ContextCapabilities().max_texture_size; @@ -3940,7 +3908,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin( ElementId current_native_scrolling_element = scroll_state->data()->current_native_scrolling_element(); - if (current_native_scrolling_element.GetInternalValue() != 0) { + if (current_native_scrolling_element.GetStableId() != 0) { auto& scroll_tree = active_tree_->property_trees()->scroll_tree; scrolling_node = scroll_tree.FindNodeFromElementId(current_native_scrolling_element); @@ -4240,8 +4208,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( } bool scrolls_main_viewport_scroll_layer = - viewport()->MainScrollLayer() && - viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node->id; + scroll_node == viewport()->MainScrollNode(); if (scrolls_main_viewport_scroll_layer) { // Flash the overlay scrollbar even if the scroll dalta is 0. if (settings_.scrollbar_flash_after_any_scroll_update) { @@ -4728,11 +4695,6 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( if (did_scroll_content) { ShowScrollbarsForImplScroll(current_scrolling_node->element_id); - // If we are scrolling with an active scroll handler, forward latency - // tracking information to the main thread so the delay introduced by the - // handler is accounted for. - if (scroll_affects_scroll_handler()) - NotifySwapPromiseMonitorsOfForwardingToMainThread(); client_->SetNeedsCommitOnImplThread(); SetNeedsRedraw(); client_->RenewTreePriority(); @@ -4830,7 +4792,7 @@ void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset( if (!changed) return; - ShowScrollbarsForImplScroll(OuterViewportScrollLayer()->element_id()); + ShowScrollbarsForImplScroll(OuterViewportScrollNode()->element_id); client_->SetNeedsCommitOnImplThread(); // After applying the synchronous input handler's scroll offset, tell it what // we ended up with. @@ -4859,6 +4821,8 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() { ScrollOffsetToVector2dF(snap_position - current_position); bool scrolls_main_viewport_scroll_layer = scroll_node == ViewportMainScrollNode(); + + bool did_animate = false; if (scrolls_main_viewport_scroll_layer) { // Flash the overlay scrollbar even if the scroll dalta is 0. if (settings_.scrollbar_flash_after_any_scroll_update) { @@ -4871,27 +4835,23 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() { } gfx::Vector2dF scaled_delta(delta); scaled_delta.Scale(active_tree()->page_scale_factor_for_scroll()); - viewport()->ScrollAnimated(scaled_delta, base::TimeDelta()); + gfx::Vector2dF consumed_delta = + viewport()->ScrollAnimated(scaled_delta, base::TimeDelta()); + did_animate = !consumed_delta.IsZero(); } else { - ScrollAnimationCreate(scroll_node, delta, base::TimeDelta()); + did_animate = ScrollAnimationCreate(scroll_node, delta, base::TimeDelta()); } DCHECK(!is_animating_for_snap_); - is_animating_for_snap_ = true; - return true; + is_animating_for_snap_ = did_animate; + return did_animate; } gfx::ScrollOffset LayerTreeHostImpl::GetVisualScrollOffset( const ScrollNode& scroll_node) const { - const ScrollTree& scroll_tree = active_tree()->property_trees()->scroll_tree; - - bool scrolls_main_viewport_scroll_layer = - viewport()->MainScrollLayer() && - viewport()->MainScrollLayer()->scroll_tree_index() == scroll_node.id; - - if (scrolls_main_viewport_scroll_layer) + if (&scroll_node == viewport()->MainScrollNode()) return viewport()->TotalScrollOffset(); - else - return scroll_tree.current_scroll_offset(scroll_node.element_id); + return active_tree()->property_trees()->scroll_tree.current_scroll_offset( + scroll_node.element_id); } bool LayerTreeHostImpl::GetSnapFlingInfo( @@ -4968,7 +4928,8 @@ void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state, bool should_snap) { } InputHandlerPointerResult LayerTreeHostImpl::MouseDown( - const gfx::PointF& viewport_point) { + const gfx::PointF& viewport_point, + bool shift_modifier) { ScrollbarAnimationController* animation_controller = ScrollbarAnimationControllerForElementId( scroll_element_id_mouse_currently_over_); @@ -4979,8 +4940,10 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseDown( } InputHandlerPointerResult result; - if (settings().compositor_threaded_scrollbar_scrolling) - result = scrollbar_controller_->HandlePointerDown(viewport_point); + if (settings().compositor_threaded_scrollbar_scrolling) { + result = scrollbar_controller_->HandlePointerDown(viewport_point, + shift_modifier); + } return result; } @@ -5008,9 +4971,10 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseUp( InputHandlerPointerResult LayerTreeHostImpl::MouseMoveAt( const gfx::Point& viewport_point) { InputHandlerPointerResult result; - if (settings().compositor_threaded_scrollbar_scrolling) + if (settings().compositor_threaded_scrollbar_scrolling) { result = - scrollbar_controller_->HandleMouseMove(gfx::PointF(viewport_point)); + scrollbar_controller_->HandlePointerMove(gfx::PointF(viewport_point)); + } // Early out if there are no animation controllers and avoid the hit test. // This happens on platforms without animated scrollbars. @@ -5039,9 +5003,9 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseMoveAt( scroll_element_id = scroll_node->element_id; // Scrollbars for the viewport are registered with the outer viewport layer. - if (InnerViewportScrollNode() && OuterViewportScrollLayer() && + if (InnerViewportScrollNode() && OuterViewportScrollNode() && scroll_element_id == InnerViewportScrollNode()->element_id) - scroll_element_id = OuterViewportScrollLayer()->element_id(); + scroll_element_id = OuterViewportScrollNode()->element_id; } ScrollbarAnimationController* new_animation_controller = @@ -5139,8 +5103,8 @@ void LayerTreeHostImpl::CollectScrollbarUpdates( ScrollAndScaleSet* scroll_info) const { scroll_info->scrollbars.reserve(scrollbar_animation_controllers_.size()); for (auto& pair : scrollbar_animation_controllers_) { - scroll_info->scrollbars.push_back(LayerTreeHostCommon::ScrollbarsUpdateInfo( - pair.first, pair.second->ScrollbarsHidden())); + scroll_info->scrollbars.push_back( + {pair.first, pair.second->ScrollbarsHidden()}); } } @@ -5367,16 +5331,16 @@ LayerTreeHostImpl::ScrollbarAnimationControllerForElementId( // The viewport layers have only one set of scrollbars. On Android, these are // registered with the inner viewport, otherwise they're registered with the // outer viewport. If a controller for one exists, the other shouldn't. - if (InnerViewportScrollNode() && OuterViewportScrollLayer()) { + if (InnerViewportScrollNode() && OuterViewportScrollNode()) { if (scroll_element_id == InnerViewportScrollNode()->element_id || - scroll_element_id == OuterViewportScrollLayer()->element_id()) { + scroll_element_id == OuterViewportScrollNode()->element_id) { auto itr = scrollbar_animation_controllers_.find( InnerViewportScrollNode()->element_id); if (itr != scrollbar_animation_controllers_.end()) return itr->second.get(); itr = scrollbar_animation_controllers_.find( - OuterViewportScrollLayer()->element_id()); + OuterViewportScrollNode()->element_id); if (itr != scrollbar_animation_controllers_.end()) return itr->second.get(); @@ -5872,12 +5836,6 @@ void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfSetNeedsRedraw() { (*it)->OnSetNeedsRedrawOnImpl(); } -void LayerTreeHostImpl::NotifySwapPromiseMonitorsOfForwardingToMainThread() { - auto it = swap_promise_monitor_.begin(); - for (; it != swap_promise_monitor_.end(); it++) - (*it)->OnForwardScrollUpdateToMainThreadOnImpl(); -} - void LayerTreeHostImpl::UpdateRootLayerStateForSynchronousInputHandler() { if (!input_handler_client_) return; diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index 395419652fc..4242cd1e415 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -60,7 +60,6 @@ #include "components/viz/common/surfaces/surface_id.h" #include "components/viz/common/surfaces/surface_range.h" #include "ui/gfx/geometry/rect.h" -#include "ui/latency/frame_metrics.h" namespace gfx { class ScrollOffset; @@ -69,7 +68,8 @@ class ScrollOffset; namespace viz { class CompositorFrame; class CompositorFrameMetadata; -} +struct FrameTimingDetails; +} // namespace viz namespace cc { @@ -106,7 +106,6 @@ enum class GpuRasterizationStatus { ON, ON_FORCED, OFF_DEVICE, - OFF_VIEWPORT, MSAA_CONTENT, }; @@ -160,7 +159,7 @@ class LayerTreeHostImplClient { virtual void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) = 0; + const viz::FrameTimingDetails& details) = 0; // Returns whether the main-thread is expected to receive a BeginMainFrame. virtual bool IsBeginMainFrameExpected() = 0; @@ -198,6 +197,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, FrameData& operator=(const FrameData&) = delete; void AsValueInto(base::trace_event::TracedValue* value) const; + std::string ToString() const; // frame_token is populated by the LayerTreeHostImpl when submitted. uint32_t frame_token = 0; @@ -251,7 +251,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner); + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client); LayerTreeHostImpl(const LayerTreeHostImpl&) = delete; ~LayerTreeHostImpl() override; @@ -277,8 +278,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, const gfx::ScrollOffset& root_content_offset) override; void ScrollEnd(ScrollState* scroll_state, bool should_snap = false) override; - InputHandlerPointerResult MouseDown( - const gfx::PointF& viewport_point) override; + InputHandlerPointerResult MouseDown(const gfx::PointF& viewport_point, + bool shift_modifier) override; InputHandlerPointerResult MouseUp(const gfx::PointF& viewport_point) override; InputHandlerPointerResult MouseMoveAt( const gfx::Point& viewport_point) override; @@ -336,7 +337,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, return viewport_damage_rect_; } - virtual void WillSendBeginMainFrame() {} + virtual void WillSendBeginMainFrame(); virtual void DidSendBeginMainFrame(const viz::BeginFrameArgs& args); virtual void BeginMainFrameAborted( CommitEarlyOutReason reason, @@ -494,7 +495,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, void DidReceiveCompositorFrameAck() override; void DidPresentCompositorFrame( uint32_t frame_token, - const gfx::PresentationFeedback& feedback) override; + const viz::FrameTimingDetails& details) override; void ReclaimResources( const std::vector<viz::ReturnedResource>& resources) override; void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override; @@ -521,7 +522,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, virtual bool InitializeFrameSink(LayerTreeFrameSink* layer_tree_frame_sink); TileManager* tile_manager() { return &tile_manager_; } - void SetHasGpuRasterizationTrigger(bool flag); void SetContentHasSlowPaths(bool flag); void SetContentHasNonAAPaint(bool flag); void GetGpuRasterizationCapabilities(bool* gpu_rasterization_enabled, @@ -547,6 +547,14 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, uint32_t next_frame_token() const { return *next_frame_token_; } + // Buffers |callback| until a relevant frame swap ocurrs, at which point the + // callback will be run on the compositor thread. A frame swap is considered + // relevant if the swapped frame's token is greater than or equal to + // |frame_token|. + void RegisterCompositorPresentationTimeCallback( + uint32_t frame_token, + LayerTreeHost::PresentationTimeCallback callback); + virtual bool WillBeginImplFrame(const viz::BeginFrameArgs& args); virtual void DidFinishImplFrame(); void DidNotProduceFrame(const viz::BeginFrameAck& ack); @@ -566,11 +574,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, virtual void ActivateSyncTree(); // Shortcuts to layers/nodes on the active tree. - LayerImpl* InnerViewportContainerLayer() const; - LayerImpl* InnerViewportScrollLayer() const; ScrollNode* InnerViewportScrollNode() const; - LayerImpl* OuterViewportContainerLayer() const; - LayerImpl* OuterViewportScrollLayer() const; ScrollNode* OuterViewportScrollNode() const; ScrollNode* CurrentlyScrollingNode(); const ScrollNode* CurrentlyScrollingNode() const; @@ -764,7 +768,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, // of these -- we call that the "main" scroll node. When scrolling it, we // scroll using the Viewport class which knows how to distribute scroll // between the two. - LayerImpl* ViewportMainScrollLayer(); ScrollNode* ViewportMainScrollNode(); void QueueImageDecode(int request_id, const PaintImage& image); @@ -810,7 +813,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, TaskGraphRunner* task_graph_runner, std::unique_ptr<MutatorHost> mutator_host, int id, - scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner); + scoped_refptr<base::SequencedTaskRunner> image_worker_task_runner, + LayerTreeHostSchedulingClient* scheduling_client); // Virtual for testing. virtual bool AnimateLayers(base::TimeTicks monotonic_time, @@ -824,6 +828,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, static void RemoveRenderPasses(FrameData* frame); LayerTreeHostImplClient* const client_; + LayerTreeHostSchedulingClient* const scheduling_client_; TaskRunnerProvider* const task_runner_provider_; BeginFrameTracker current_begin_frame_tracker_; @@ -944,7 +949,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, bool lost); void NotifySwapPromiseMonitorsOfSetNeedsRedraw(); - void NotifySwapPromiseMonitorsOfForwardingToMainThread(); void UpdateRootLayerStateForSynchronousInputHandler(); @@ -1034,7 +1038,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, bool need_update_gpu_rasterization_status_ = false; bool content_has_slow_paths_ = false; bool content_has_non_aa_paint_ = false; - bool has_gpu_rasterization_trigger_ = false; bool use_gpu_rasterization_ = false; bool use_oop_rasterization_ = false; bool use_msaa_ = false; @@ -1237,8 +1240,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_; PresentationTimeCallbackBuffer presentation_time_callbacks_; - ui::FrameMetrics frame_metrics_; - ui::SkippedFrameTracker skipped_frame_tracker_; bool is_animating_for_snap_; const PaintImage::GeneratorClientId paint_image_generator_client_id_; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index f695646918f..986eca85577 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -44,6 +44,7 @@ #include "cc/resources/ui_resource_bitmap.h" #include "cc/resources/ui_resource_manager.h" #include "cc/test/animation_test_common.h" +#include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_mask_layer_impl.h" @@ -62,11 +63,11 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/latency_info_swap_promise.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/render_frame_metadata.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" @@ -107,6 +108,10 @@ using ::testing::AtLeast; using ::testing::_; using media::VideoFrame; +namespace viz { +struct FrameTimingDetails; +} + namespace cc { namespace { @@ -145,12 +150,19 @@ class LayerTreeHostImplTest : public testing::Test, } LayerTreeSettings DefaultSettings() { - LayerTreeSettings settings; - settings.enable_surface_synchronization = true; + LayerListSettings settings; settings.minimum_occlusion_tracking_size = gfx::Size(); return settings; } + // Settings with GPU rasterization disabled. New tests should test with GPU + // rasterization enabled by default. + LayerTreeSettings LegacySWSettings() { + LayerTreeSettings settings = DefaultSettings(); + settings.gpu_rasterization_disabled = true; + return settings; + } + void SetUp() override { CreateHostImpl(DefaultSettings(), CreateLayerTreeFrameSink()); } @@ -237,7 +249,7 @@ class LayerTreeHostImplTest : public testing::Test, void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) override {} + const viz::FrameTimingDetails& details) override {} void NotifyAnimationWorkletStateChange(AnimationWorkletMutationState state, ElementListType tree_type) override {} void NotifyPaintWorkletStateChange( @@ -247,30 +259,22 @@ class LayerTreeHostImplTest : public testing::Test, reduce_memory_result_ = reduce_memory_result; } - virtual bool CreateHostImpl( - const LayerTreeSettings& settings, - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) { - return CreateHostImplWithTaskRunnerProvider( - settings, std::move(layer_tree_frame_sink), &task_runner_provider_); - } - AnimationHost* GetImplAnimationHost() const { return static_cast<AnimationHost*>(host_impl_->mutator_host()); } - virtual bool CreateHostImplWithTaskRunnerProvider( + virtual bool CreateHostImpl( const LayerTreeSettings& settings, - std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink, - TaskRunnerProvider* task_runner_provider) { + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) { if (host_impl_) host_impl_->ReleaseLayerTreeFrameSink(); host_impl_.reset(); InitializeImageWorker(settings); host_impl_ = LayerTreeHostImpl::Create( - settings, this, task_runner_provider, &stats_instrumentation_, + settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, - image_worker_ ? image_worker_->task_runner() : nullptr); + image_worker_ ? image_worker_->task_runner() : nullptr, nullptr); layer_tree_frame_sink_ = std::move(layer_tree_frame_sink); host_impl_->SetVisible(true); bool init = host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get()); @@ -293,13 +297,32 @@ class LayerTreeHostImplTest : public testing::Test, return init; } - void SetupRootLayerImpl(std::unique_ptr<LayerImpl> root) { - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->draw_properties().visible_layer_rect = gfx::Rect(0, 0, 10, 10); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); + template <typename T, typename... Args> + T* SetupRootLayer(LayerTreeImpl* layer_tree_impl, + const gfx::Size& viewport_size, + Args&&... args) { + const int kRootLayerId = 1; + DCHECK(!layer_tree_impl->root_layer()); + DCHECK(!layer_tree_impl->LayerById(kRootLayerId)); + layer_tree_impl->SetRootLayerForTesting( + T::Create(layer_tree_impl, kRootLayerId, std::forward<Args>(args)...)); + auto* root = layer_tree_impl->root_layer(); + root->SetBounds(viewport_size); + layer_tree_impl->SetDeviceViewportRect( + gfx::Rect(DipSizeToPixelSize(viewport_size))); + SetupRootProperties(root); + return static_cast<T*>(root); + } + + LayerImpl* SetupDefaultRootLayer(const gfx::Size& viewport_size) { + return SetupRootLayer<LayerImpl>(host_impl_->active_tree(), viewport_size); + } + + LayerImpl* root_layer() { return host_impl_->active_tree()->root_layer(); } + + gfx::Size DipSizeToPixelSize(const gfx::Size& size) { + return gfx::ScaleToRoundedSize( + size, host_impl_->active_tree()->device_scale_factor()); } static gfx::Vector2dF ScrollDelta(LayerImpl* layer_impl) { @@ -359,138 +382,98 @@ class LayerTreeHostImplTest : public testing::Test, ASSERT_EQ(0, times_encountered); } - LayerImpl* CreateScrollAndContentsLayers(LayerTreeImpl* layer_tree_impl, - const gfx::Size& content_size) { - // Clear any existing viewport layers that were setup so this function can - // be called multiple times. - layer_tree_impl->ClearViewportLayers(); - - // Create both an inner viewport scroll layer and an outer viewport scroll - // layer. The MaxScrollOffset of the outer viewport scroll layer will be - // 0x0, so the scrolls will be applied directly to the inner viewport. - const int kOuterViewportClipLayerId = 116; - const int kOuterViewportScrollLayerId = 117; - const int kContentLayerId = 118; - const int kInnerViewportScrollLayerId = 2; - const int kInnerViewportClipLayerId = 4; - const int kPageScaleLayerId = 5; - - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(content_size); - root->test_properties()->position = gfx::PointF(); - root->test_properties()->force_render_surface = true; - - std::unique_ptr<LayerImpl> inner_scroll = - LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); - inner_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - inner_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - inner_scroll->element_id(), gfx::ScrollOffset()); - - std::unique_ptr<LayerImpl> inner_clip = - LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); - gfx::Size viewport_scroll_bounds = - gfx::Size(content_size.width() / 2, content_size.height() / 2); - inner_clip->SetBounds(viewport_scroll_bounds); - - std::unique_ptr<LayerImpl> page_scale = - LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - - inner_scroll->SetScrollable(viewport_scroll_bounds); - inner_scroll->SetHitTestable(true); - inner_scroll->SetElementId( - LayerIdToElementIdForTesting(inner_scroll->id())); - inner_scroll->SetBounds(content_size); - inner_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> outer_clip = - LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId); - outer_clip->SetBounds(content_size); - outer_clip->test_properties()->is_container_for_fixed_position_layers = - true; - - std::unique_ptr<LayerImpl> outer_scroll = - LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollable(content_size); - outer_scroll->SetHitTestable(true); - outer_scroll->SetElementId( - LayerIdToElementIdForTesting(outer_scroll->id())); - outer_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - outer_scroll->element_id(), gfx::ScrollOffset()); - outer_scroll->SetBounds(content_size); - outer_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> contents = - LayerImpl::Create(layer_tree_impl, kContentLayerId); - contents->SetDrawsContent(true); - contents->SetBounds(content_size); - contents->test_properties()->position = gfx::PointF(); - - outer_scroll->test_properties()->AddChild(std::move(contents)); - outer_clip->test_properties()->AddChild(std::move(outer_scroll)); - inner_scroll->test_properties()->AddChild(std::move(outer_clip)); - page_scale->test_properties()->AddChild(std::move(inner_scroll)); - inner_clip->test_properties()->AddChild(std::move(page_scale)); - root->test_properties()->AddChild(std::move(inner_clip)); - - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = kPageScaleLayerId; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.outer_viewport_container = kOuterViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - viewport_ids.outer_viewport_scroll = kOuterViewportScrollLayerId; - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); + template <typename T, typename... Args> + T* AddLayer(LayerTreeImpl* layer_tree_impl, Args&&... args) { + std::unique_ptr<T> layer = T::Create(layer_tree_impl, next_layer_id_++, + std::forward<Args>(args)...); + T* result = layer.get(); + layer_tree_impl->AddLayer(std::move(layer)); + return result; + } + LayerImpl* AddLayer() { + return AddLayer<LayerImpl>(host_impl_->active_tree()); + } + + void SetupViewportLayers(LayerTreeImpl* layer_tree_impl, + const gfx::Size& inner_viewport_size, + const gfx::Size& outer_viewport_size, + const gfx::Size& content_size) { + DCHECK(!layer_tree_impl->root_layer()); + auto* root = + SetupRootLayer<LayerImpl>(layer_tree_impl, inner_viewport_size); + SetupViewport(root, outer_viewport_size, content_size); + + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); - return layer_tree_impl->InnerViewportScrollLayer(); } - LayerImpl* SetupScrollAndContentsLayers(const gfx::Size& content_size) { - LayerImpl* scroll_layer = - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->DidBecomeActive(); - return scroll_layer; + // Calls SetupViewportLayers() passing |content_size| as that function's + // |outer_viewport_size| and |content_size|, which makes the outer viewport + // not scrollable, and scrolls will be applied directly to the inner viewport. + void SetupViewportLayersInnerScrolls(const gfx::Size& inner_viewport_size, + const gfx::Size& content_size) { + const auto& outer_viewport_size = content_size; + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); + } + + // Calls SetupViewportLayers() passing |viewport_size| as that function's + // |inner_viewport_size| and |outer_viewport_size|, which makes the inner + // viewport not scrollable, and scrolls will be applied to the outer + // viewport only. + void SetupViewportLayersOuterScrolls(const gfx::Size& viewport_size, + const gfx::Size& content_size) { + SetupViewportLayers(host_impl_->active_tree(), viewport_size, viewport_size, + content_size); + } + + LayerImpl* AddContentLayer() { + LayerImpl* scroll_layer = OuterViewportScrollLayer(); + DCHECK(scroll_layer); + LayerImpl* layer = AddLayer(); + layer->SetBounds(scroll_layer->bounds()); + layer->SetDrawsContent(true); + CopyProperties(scroll_layer, layer); + return layer; } - void CreateAndTestNonScrollableLayers(const bool& transparent_layer) { + // Calls SetupViewportLayers() with the same |viewport_bounds|, + // |inner_scroll_bounds| and |outer_scroll_bounds|, which makes neither + // of inner viewport and outer viewport scrollable. + void SetupViewportLayersNoScrolls(const gfx::Size& bounds) { + SetupViewportLayers(host_impl_->active_tree(), bounds, bounds, bounds); + } + + void CreateAndTestNonScrollableLayers(bool transparent_layer) { LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); gfx::Size content_size = gfx::Size(360, 600); gfx::Size scroll_content_size = gfx::Size(345, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(content_size)); - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(content_size); - root->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); - scroll->SetBounds(scroll_content_size); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar = - PaintedScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, false, - true); + LayerImpl* root = SetupRootLayer<LayerImpl>(layer_tree_impl, content_size); + LayerImpl* scroll = + AddScrollableLayer(root, content_size, scroll_content_size); + + auto* squash2 = AddLayer<LayerImpl>(layer_tree_impl); + squash2->SetBounds(gfx::Size(140, 300)); + squash2->SetDrawsContent(true); + squash2->SetHitTestable(true); + CopyProperties(scroll, squash2); + squash2->SetOffsetToTransformParent(gfx::Vector2dF(220, 300)); + + auto* scrollbar = AddLayer<PaintedScrollbarLayerImpl>( + layer_tree_impl, VERTICAL, false, true); + SetupScrollbarLayer(scroll, scrollbar); scrollbar->SetBounds(scrollbar_size); - scrollbar->test_properties()->position = gfx::PointF(345, 0); - scrollbar->SetScrollElementId(scroll->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->SetHitTestable(true); - scrollbar->test_properties()->opacity = 1.f; + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - std::unique_ptr<LayerImpl> squash1 = LayerImpl::Create(layer_tree_impl, 5); + auto* squash1 = AddLayer<LayerImpl>(layer_tree_impl); squash1->SetBounds(gfx::Size(140, 300)); - squash1->test_properties()->position = gfx::PointF(220, 0); + CopyProperties(root, squash1); + squash1->SetOffsetToTransformParent(gfx::Vector2dF(220, 0)); if (transparent_layer) { - squash1->test_properties()->opacity = 0.0f; + CreateEffectNode(squash1).opacity = 0.0f; // The transparent layer should still participate in hit testing even // through it does not draw content. squash1->SetHitTestable(true); @@ -499,19 +482,7 @@ class LayerTreeHostImplTest : public testing::Test, squash1->SetHitTestable(true); } - std::unique_ptr<LayerImpl> squash2 = LayerImpl::Create(layer_tree_impl, 6); - squash2->SetBounds(gfx::Size(140, 300)); - squash2->test_properties()->position = gfx::PointF(220, 300); - squash2->SetDrawsContent(true); - squash2->SetHitTestable(true); - - scroll->test_properties()->AddChild(std::move(squash2)); - root->test_properties()->AddChild(std::move(scroll)); - root->test_properties()->AddChild(std::move(scrollbar)); - root->test_properties()->AddChild(std::move(squash1)); - - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); // The point hits squash1 layer and also scroll layer, because scroll layer @@ -536,58 +507,66 @@ class LayerTreeHostImplTest : public testing::Test, ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); } - // Sets up a typical virtual viewport setup with one child content layer. - // Returns a pointer to the content layer. - LayerImpl* CreateBasicVirtualViewportLayers(const gfx::Size& viewport_size, - const gfx::Size& content_size) { - // CreateScrollAndContentsLayers makes the outer viewport unscrollable and - // the inner a different size from the outer. We'll reuse its layer - // hierarchy but adjust the sizing to our needs. - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - - LayerImpl* content_layer = host_impl_->OuterViewportScrollLayer() - ->test_properties() - ->children.back(); - content_layer->SetBounds(content_size); - host_impl_->OuterViewportScrollLayer()->SetBounds(content_size); - host_impl_->OuterViewportScrollLayer()->SetScrollable(viewport_size); - host_impl_->OuterViewportScrollLayer()->SetHitTestable(true); - - LayerImpl* outer_clip = - host_impl_->OuterViewportScrollLayer()->test_properties()->parent; - outer_clip->SetBounds(viewport_size); - - LayerImpl* inner_clip_layer = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - inner_clip_layer->SetBounds(viewport_size); - host_impl_->InnerViewportScrollLayer()->SetBounds(viewport_size); - host_impl_->InnerViewportScrollLayer()->SetScrollable(viewport_size); - host_impl_->InnerViewportScrollLayer()->SetHitTestable(true); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - host_impl_->active_tree()->DidBecomeActive(); - - return content_layer; - } - - std::unique_ptr<LayerImpl> CreateScrollableLayer(int id, - const gfx::Size& size) { - std::unique_ptr<LayerImpl> layer = - LayerImpl::Create(host_impl_->active_tree(), id); + LayerImpl* AddScrollableLayer(LayerImpl* container, + const gfx::Size& scroll_container_bounds, + const gfx::Size& content_size) { + LayerImpl* layer = AddLayer<LayerImpl>(container->layer_tree_impl()); layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); layer->SetDrawsContent(true); - layer->SetBounds(size); - gfx::Size scroll_container_bounds = - gfx::Size(size.width() / 2, size.height() / 2); + layer->SetBounds(content_size); layer->SetScrollable(scroll_container_bounds); layer->SetHitTestable(true); + CopyProperties(container, layer); + CreateTransformNode(layer); + CreateScrollNode(layer); return layer; } + void SetupScrollbarLayerCommon(LayerImpl* scroll_layer, + ScrollbarLayerImplBase* scrollbar) { + auto* tree_impl = scroll_layer->layer_tree_impl(); + scrollbar->SetScrollElementId(scroll_layer->element_id()); + scrollbar->SetDrawsContent(true); + CopyProperties(scroll_layer, scrollbar); + auto* property_trees = tree_impl->property_trees(); + if (scroll_layer == tree_impl->OuterViewportScrollLayerForTesting()) { + scrollbar->SetTransformTreeIndex(tree_impl->PageScaleTransformNode()->id); + scrollbar->SetScrollTreeIndex( + tree_impl->root_layer()->scroll_tree_index()); + } else { + scrollbar->SetTransformTreeIndex( + property_trees->transform_tree + .Node(scroll_layer->transform_tree_index()) + ->parent_id); + scrollbar->SetScrollTreeIndex( + property_trees->scroll_tree.Node(scroll_layer->scroll_tree_index()) + ->parent_id); + } + } + + void SetupScrollbarLayer(LayerImpl* scroll_layer, + SolidColorScrollbarLayerImpl* scrollbar) { + scrollbar->SetElementId(LayerIdToElementIdForTesting(scrollbar->id())); + SetupScrollbarLayerCommon(scroll_layer, scrollbar); + auto& effect = CreateEffectNode(scrollbar); + effect.opacity = 0.f; + effect.has_potential_opacity_animation = true; + } + + void SetupScrollbarLayer(LayerImpl* scroll_layer, + PaintedScrollbarLayerImpl* scrollbar) { + SetupScrollbarLayerCommon(scroll_layer, scrollbar); + scrollbar->SetHitTestable(true); + CreateEffectNode(scrollbar).opacity = 1.f; + } + + LayerImpl* InnerViewportScrollLayer() { + return host_impl_->active_tree()->InnerViewportScrollLayerForTesting(); + } + LayerImpl* OuterViewportScrollLayer() { + return host_impl_->active_tree()->OuterViewportScrollLayerForTesting(); + } + std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) { ScrollStateData scroll_state_data; scroll_state_data.is_beginning = true; @@ -619,6 +598,7 @@ class LayerTreeHostImplTest : public testing::Test, } void DrawFrame() { + PrepareForUpdateDrawProperties(host_impl_->active_tree()); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); host_impl_->DrawLayers(&frame); @@ -645,14 +625,10 @@ class LayerTreeHostImplTest : public testing::Test, // Create the pending tree. host_impl_->BeginCommit(); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->SetDeviceViewportRect(gfx::Rect(layer_size)); - pending_tree->SetRootLayerForTesting( - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 1, - raster_source)); - auto* root = static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); - root->SetBounds(layer_size); + LayerImpl* root = SetupRootLayer<FakePictureLayerImpl>( + pending_tree, layer_size, raster_source); root->SetDrawsContent(true); - pending_tree->BuildPropertyTreesForTesting(); + UpdateDrawProperties(pending_tree); // CompleteCommit which should perform a PrepareTiles, adding tilings for // the root layer, each one having a raster task. @@ -669,10 +645,8 @@ class LayerTreeHostImplTest : public testing::Test, void WhiteListedTouchActionTestHelper(float device_scale_factor, float page_scale_factor) { - LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); DrawFrame(); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); // Just hard code some random number, we care about the actual page scale // factor on the active tree. @@ -682,18 +656,14 @@ class LayerTreeHostImplTest : public testing::Test, page_scale_factor, min_page_scale_factor, max_page_scale_factor); host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor); - std::unique_ptr<LayerImpl> child_layer = - LayerImpl::Create(host_impl_->active_tree(), 6); - LayerImpl* child = child_layer.get(); - child_layer->SetDrawsContent(true); - child_layer->test_properties()->position = gfx::PointF(0, 0); - child_layer->SetBounds(gfx::Size(25, 25)); - scroll->test_properties()->AddChild(std::move(child_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* child = AddLayer(); + child->SetDrawsContent(true); + child->SetBounds(gfx::Size(25, 25)); + CopyProperties(InnerViewportScrollLayer(), child); TouchActionRegion root_touch_action_region; root_touch_action_region.Union(kTouchActionPanX, gfx::Rect(0, 0, 50, 50)); - root->SetTouchActionRegion(root_touch_action_region); + root_layer()->SetTouchActionRegion(root_touch_action_region); TouchActionRegion child_touch_action_region; child_touch_action_region.Union(kTouchActionPanLeft, gfx::Rect(0, 0, 25, 25)); @@ -722,38 +692,31 @@ class LayerTreeHostImplTest : public testing::Test, } LayerImpl* CreateLayerForSnapping() { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - LayerImpl* scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); gfx::Size overflow_size(400, 400); - EXPECT_EQ(1u, scroll_layer->test_properties()->children.size()); - LayerImpl* overflow = scroll_layer->test_properties()->children[0]; - overflow->SetBounds(overflow_size); - overflow->SetScrollable(gfx::Size(100, 100)); - overflow->SetHitTestable(true); - overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); - overflow->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), - gfx::ScrollOffset()); - overflow->test_properties()->position = gfx::PointF(0, 0); - + LayerImpl* overflow = AddScrollableLayer( + OuterViewportScrollLayer(), gfx::Size(100, 100), overflow_size); SnapContainerData container_data( ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory), gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(300, 300)); SnapAreaData area_data(ScrollSnapAlign(SnapAlignment::kStart), gfx::RectF(50, 50, 100, 100), false); container_data.AddSnapAreaData(area_data); - overflow->test_properties()->snap_container_data.emplace(container_data); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(overflow)->snap_container_data.emplace(container_data); DrawFrame(); return overflow; } + void ClearLayersAndPropertyTrees(LayerTreeImpl* layer_tree_impl) { + layer_tree_impl->SetRootLayerForTesting(nullptr); + layer_tree_impl->DetachLayers(); + layer_tree_impl->property_trees()->clear(); + layer_tree_impl->SetViewportPropertyIds( + LayerTreeImpl::ViewportPropertyIds()); + } + void pinch_zoom_pan_viewport_forces_commit_redraw(float device_scale_factor); void pinch_zoom_pan_viewport_test(float device_scale_factor); void pinch_zoom_pan_viewport_and_scroll_test(float device_scale_factor); @@ -772,6 +735,7 @@ class LayerTreeHostImplTest : public testing::Test, } void DrawOneFrame() { + PrepareForUpdateDrawProperties(host_impl_->active_tree()); TestFrameData frame_data; host_impl_->PrepareToDraw(&frame_data); host_impl_->DidDrawAllLayers(frame_data); @@ -828,6 +792,7 @@ class LayerTreeHostImplTest : public testing::Test, viz::RenderPassList last_on_draw_render_passes_; scoped_refptr<AnimationTimeline> timeline_; std::unique_ptr<base::Thread> image_worker_; + int next_layer_id_ = 2; }; class CommitToPendingTreeLayerTreeHostImplTest : public LayerTreeHostImplTest { @@ -931,19 +896,18 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { on_can_draw_state_changed_called_ = false; // Set up the root layer, which allows us to draw. - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; // Toggle the root layer to make sure it toggles can_draw - host_impl_->active_tree()->SetRootLayerForTesting(nullptr); - host_impl_->active_tree()->DetachLayers(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); EXPECT_FALSE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); EXPECT_TRUE(on_can_draw_state_changed_called_); on_can_draw_state_changed_called_ = false; @@ -962,8 +926,7 @@ TEST_F(LayerTreeHostImplTest, NotifyIfCanDrawChanged) { TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware()); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_TRUE(host_impl_->CanDraw()); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect()); @@ -980,7 +943,7 @@ TEST_F(LayerTreeHostImplTest, ResourcelessDrawWithEmptyViewport) { } TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { - ASSERT_FALSE(host_impl_->active_tree()->root_layer_for_testing()); + host_impl_->active_tree()->SetRootLayerForTesting(nullptr); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -988,26 +951,19 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaNoLayers) { } TEST_F(LayerTreeHostImplTest, ScrollDeltaTreeButNoChanges) { + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 2)); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 3)); - root->test_properties()->children[1]->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 4)); - root->test_properties()->children[1]->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 5)); - root->test_properties() - ->children[1] - ->test_properties() - ->children[0] - ->test_properties() - ->AddChild(LayerImpl::Create(host_impl_->active_tree(), 6)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - } - LayerImpl* root = *host_impl_->active_tree()->begin(); + LayerImpl* child1 = AddLayer(); + CopyProperties(root, child1); + LayerImpl* child2 = AddLayer(); + CopyProperties(root, child2); + LayerImpl* grand_child1 = AddLayer(); + CopyProperties(child2, grand_child1); + LayerImpl* grand_child2 = AddLayer(); + CopyProperties(child2, grand_child2); + LayerImpl* great_grand_child = AddLayer(); + CopyProperties(grand_child1, great_grand_child); + } ExpectClearedScrollDeltasRecursive(root); @@ -1026,19 +982,15 @@ TEST_F(LayerTreeHostImplTest, ScrollDeltaRepeatedScrolls) { gfx::ScrollOffset scroll_offset(20, 30); gfx::ScrollOffset scroll_delta(11, -15); - auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); - auto* root = root_owned.get(); - - root->SetBounds(gfx::Size(110, 110)); - root->SetScrollable(gfx::Size(10, 10)); + auto* root = SetupDefaultRootLayer(gfx::Size(110, 110)); root->SetHitTestable(true); - root->SetElementId(LayerIdToElementIdForTesting(root->id())); + root->SetScrollable(gfx::Size(10, 10)); + CreateScrollNode(root); root->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(root->element_id(), scroll_offset); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -1102,10 +1054,7 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRootLayerAttached) { } TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1124,10 +1073,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) { } TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1162,7 +1108,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::Create3d(std::move(gl_owned)))); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); // We should not crash when trying to scroll after the renderer initialization // fails. @@ -1174,8 +1120,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) { } TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); // We should not crash if the tree is replaced while we are scrolling. @@ -1184,9 +1129,10 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { host_impl_ ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) .thread); - host_impl_->active_tree()->DetachLayers(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); - scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); // We should still be scrolling, because the scrolled layer also exists in the // new tree. @@ -1202,8 +1148,8 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) { } TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { - LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll = InnerViewportScrollLayer(); scroll->SetWheelEventHandlerRegion(Region(gfx::Rect(20, 20))); DrawFrame(); @@ -1229,22 +1175,16 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) { } TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { - LayerImpl* scroll = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - LayerImpl* child = nullptr; - { - std::unique_ptr<LayerImpl> child_layer = - LayerImpl::Create(host_impl_->active_tree(), 6); - child = child_layer.get(); - child_layer->SetDrawsContent(true); - child_layer->test_properties()->position = gfx::PointF(0, 20); - child_layer->SetBounds(gfx::Size(50, 50)); - scroll->test_properties()->AddChild(std::move(child_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - } + LayerImpl* root = root_layer(); + LayerImpl* scroll = InnerViewportScrollLayer(); + LayerImpl* child = AddLayer(); + child->SetDrawsContent(true); + child->SetBounds(gfx::Size(50, 50)); + CopyProperties(scroll, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(0, 20)); // Touch handler regions determine whether touch events block scroll. TouchAction touch_action; @@ -1283,13 +1223,9 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) { } TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - - root->test_properties()->main_thread_scrolling_reasons = + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + host_impl_->InnerViewportScrollNode()->main_thread_scrolling_reasons = MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1320,41 +1256,24 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { gfx::Size scroll_content_size = gfx::Size(345, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(content_size)); - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(content_size); - root->test_properties()->position = gfx::PointF(); + LayerImpl* root = SetupDefaultRootLayer(content_size); + LayerImpl* scroll = + AddScrollableLayer(root, content_size, scroll_content_size); - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 3); - scroll->SetBounds(scroll_content_size); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - scroll->SetHitTestable(true); - - std::unique_ptr<PaintedScrollbarLayerImpl> drawn_scrollbar = - PaintedScrollbarLayerImpl::Create(layer_tree_impl, 4, VERTICAL, false, - true); + auto* drawn_scrollbar = AddLayer<PaintedScrollbarLayerImpl>( + layer_tree_impl, VERTICAL, false, true); + SetupScrollbarLayer(scroll, drawn_scrollbar); drawn_scrollbar->SetBounds(scrollbar_size); - drawn_scrollbar->test_properties()->position = gfx::PointF(345, 0); - drawn_scrollbar->SetScrollElementId(scroll->element_id()); - drawn_scrollbar->SetDrawsContent(true); - drawn_scrollbar->SetHitTestable(true); - drawn_scrollbar->test_properties()->opacity = 1.f; + drawn_scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - std::unique_ptr<LayerImpl> squash = LayerImpl::Create(layer_tree_impl, 5); + LayerImpl* squash = AddLayer(); squash->SetBounds(gfx::Size(140, 300)); - squash->test_properties()->position = gfx::PointF(220, 0); squash->SetDrawsContent(true); squash->SetHitTestable(true); + CopyProperties(scroll, squash); + squash->SetOffsetToTransformParent(gfx::Vector2dF(220, 0)); - scroll->test_properties()->AddChild(std::move(drawn_scrollbar)); - scroll->test_properties()->AddChild(std::move(squash)); - root->test_properties()->AddChild(std::move(scroll)); - - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); // The point hits squash layer and also scrollbar layer, but because the @@ -1375,13 +1294,11 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) { } TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); // All scroll types inside the non-fast scrollable region should fail. @@ -1424,15 +1341,13 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) { } TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50)); - outer_scroll->test_properties()->position = gfx::PointF(-25.f, 0.f); + SetPostTranslation(outer_scroll, gfx::Vector2dF(-25.f, 0.f)); outer_scroll->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); // This point would fall into the non-fast scrollable region except that we've @@ -1456,9 +1371,8 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) { } TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); EXPECT_FALSE(host_impl_->active_tree()->have_scroll_event_handlers()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); @@ -1470,9 +1384,8 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) { } TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); host_impl_->active_tree()->set_have_scroll_event_handlers(true); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler()); @@ -1484,9 +1397,7 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) { } TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); - + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); DrawFrame(); InputHandler::ScrollStatus status = host_impl_->ScrollBegin( @@ -1728,6 +1639,41 @@ TEST_F(LayerTreeHostImplTest, SnapAnimationCancelledByScroll) { overflow->CurrentScrollOffset()); } +TEST_F(LayerTreeHostImplTest, + SnapAnimationShouldNotStartWhenScrollEndsAtSnapTarget) { + LayerImpl* overflow = CreateLayerForSnapping(); + + gfx::Point pointer_position(10, 10); + EXPECT_EQ( + InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL) + .thread); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset()); + + // There is a snap target at 50, scroll to it directly. + gfx::Vector2dF x_delta(50, 0); + host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get()); + EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing()); + + viz::BeginFrameArgs begin_frame_args = + viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1); + host_impl_->ScrollEnd(EndState().get(), true); + base::TimeTicks start_time = + base::TimeTicks() + base::TimeDelta::FromMilliseconds(100); + BeginImplFrameAndAnimate(begin_frame_args, start_time); + + // We are already at a snap target so we should not animate for snap. + EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing()); + + // Verify that we are not actually animating by running one frame and ensuring + // scroll offset has not changed. + BeginImplFrameAndAnimate(begin_frame_args, + start_time + base::TimeDelta::FromMilliseconds(100)); + EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), overflow->CurrentScrollOffset()); +} + TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) { LayerImpl* overflow = CreateLayerForSnapping(); // Scales the page to its 1/5. @@ -1759,26 +1705,14 @@ TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) { TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { const gfx::Size kViewportSize(100, 100); const gfx::Size kContentSize(200, 200); - CreateBasicVirtualViewportLayers(kViewportSize, kContentSize); + SetupViewportLayersOuterScrolls(kViewportSize, kContentSize); - LayerImpl* scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(kViewportSize)); + LayerImpl* scroll_layer = OuterViewportScrollLayer(); gfx::Size overflow_size(400, 400); - ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); - LayerImpl* overflow = scroll_layer->test_properties()->children[0]; - overflow->SetBounds(overflow_size); - overflow->SetScrollable(gfx::Size(100, 100)); - overflow->SetHitTestable(true); - overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); - overflow->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), - gfx::ScrollOffset()); - overflow->test_properties()->position = gfx::PointF(40, 40); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset(30, 30)); + LayerImpl* overflow = AddScrollableLayer(OuterViewportScrollLayer(), + gfx::Size(100, 100), overflow_size); + SetScrollOffset(scroll_layer, gfx::ScrollOffset(30, 30)); DrawFrame(); gfx::Point pointer_position(50, 50); @@ -1931,25 +1865,13 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) { TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { const gfx::Size kViewportSize(100, 100); const gfx::Size kContentSize(200, 200); - CreateBasicVirtualViewportLayers(kViewportSize, kContentSize); + SetupViewportLayersOuterScrolls(kViewportSize, kContentSize); - LayerImpl* scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(kViewportSize)); + LayerImpl* scroll_layer = OuterViewportScrollLayer(); gfx::Size overflow_size(400, 400); - ASSERT_EQ(1u, scroll_layer->test_properties()->children.size()); - LayerImpl* overflow = scroll_layer->test_properties()->children[0]; - overflow->SetBounds(overflow_size); - overflow->SetScrollable(gfx::Size(100, 100)); - overflow->SetHitTestable(true); - overflow->SetElementId(LayerIdToElementIdForTesting(overflow->id())); - overflow->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting(overflow->element_id(), - gfx::ScrollOffset()); - overflow->test_properties()->position = gfx::PointF(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* overflow = + AddScrollableLayer(scroll_layer, gfx::Size(100, 100), overflow_size); DrawFrame(); gfx::Point scroll_position(10, 10); @@ -1968,8 +1890,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset()); - overflow->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(overflow)->user_scrollable_horizontal = false; DrawFrame(); @@ -1986,8 +1907,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset()); - overflow->test_properties()->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(overflow)->user_scrollable_vertical = false; DrawFrame(); EXPECT_EQ( @@ -2005,13 +1925,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) { } TEST_F(LayerTreeHostImplTest, ForceMainThreadScrollWithoutScrollLayer) { - SetupScrollAndContentsLayers(gfx::Size(200, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - ScrollNode* scroll_node = - host_impl_->active_tree()->property_trees()->scroll_tree.Node( - host_impl_->OuterViewportScrollLayer()->scroll_tree_index()); + SetupViewportLayersInnerScrolls(gfx::Size(100, 100), gfx::Size(200, 200)); + ScrollNode* scroll_node = host_impl_->OuterViewportScrollNode(); // Change the scroll node so that it no longer has an associated layer. scroll_node->element_id = ElementId(42); @@ -2028,29 +1943,23 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, AnimationSchedulingPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - CreatePendingTree(); - auto root_owned = LayerImpl::Create(host_impl_->pending_tree(), 1); - auto* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - root->SetBounds(gfx::Size(50, 50)); - root->test_properties()->force_render_surface = true; + auto* root = + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), gfx::Size(50, 50)); root->SetNeedsPushProperties(); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->pending_tree(), 2)); - LayerImpl* child = root->test_properties()->children[0]; + auto* child = AddLayer<LayerImpl>(host_impl_->pending_tree()); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); child->SetNeedsPushProperties(); host_impl_->pending_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 10.0, 3, 0); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); @@ -2088,21 +1997,14 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, AnimationSchedulingActiveTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - - host_impl_->active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->active_tree(), 1)); - LayerImpl* root = *host_impl_->active_tree()->begin(); - root->SetBounds(gfx::Size(50, 50)); - root->test_properties()->force_render_surface = true; - - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 2)); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(50, 50)); + LayerImpl* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); + host_impl_->active_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); // Add a translate from 6,7 to 8,9. TransformOperations start; @@ -2111,7 +2013,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, end.AppendTranslate(8.f, 9.f, 0.f); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 4.0, start, end); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); base::TimeTicks now = base::TimeTicks::Now(); host_impl_->WillBeginImplFrame( @@ -2150,36 +2052,24 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { - FakeImplTaskRunnerProvider provider(nullptr); - CreateHostImplWithTaskRunnerProvider(DefaultSettings(), - CreateLayerTreeFrameSink(), &provider); EXPECT_TRUE(host_impl_->CommitToActiveTree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - - auto root_owned = LayerImpl::Create(host_impl_->active_tree(), 1); - auto* root = root_owned.get(); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_owned)); - root->SetBounds(gfx::Size(50, 50)); + auto* root = SetupDefaultRootLayer(gfx::Size(50, 50)); - auto child_owned = LayerImpl::Create(host_impl_->active_tree(), 2); - auto* child = child_owned.get(); - root->test_properties()->AddChild(std::move(child_owned)); + auto* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); host_impl_->active_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 10.0, 3, 0); // Set up the property trees so that UpdateDrawProperties will work in // CommitComplete below. - RenderSurfaceList list; - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(50, 50), &list); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); @@ -2199,21 +2089,15 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingCommitToActiveTree) { } TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - - host_impl_->active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->active_tree(), 1)); - LayerImpl* root = *host_impl_->active_tree()->begin(); - root->SetBounds(gfx::Size(50, 50)); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(50, 50)); - root->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 2)); - LayerImpl* child = root->test_properties()->children[0]; + LayerImpl* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); - child->draw_properties().visible_layer_rect = gfx::Rect(10, 10); child->SetDrawsContent(true); host_impl_->active_tree()->SetElementIdsForTesting(); + CopyProperties(root, child); + CreateTransformNode(child); // Add a translate animation. TransformOperations start; @@ -2222,7 +2106,7 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) { end.AppendTranslate(8.f, 9.f, 0.f); AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(), 4.0, start, end); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); base::TimeTicks now = base::TimeTicks::Now(); host_impl_->WillBeginImplFrame( @@ -2243,18 +2127,13 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) { EXPECT_TRUE(did_request_next_frame_); did_request_next_frame_ = false; - // Destroy layer, unregister animation target (element). - child->test_properties()->parent = nullptr; - root->test_properties()->RemoveChild(child); - - // Calling LayerImplTestProperties::RemoveChild above does not actually - // remove the property tree nodes for the removed layer. In the real code, - // you cannot remove a child on LayerImpl, but a child removed on Layer - // will force a full tree sync which will rebuild property trees without that - // child's property tree nodes. Call BuildPropertyTrees to simulate the - // rebuild that would happen during the commit. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - child = nullptr; + // In the real code, you cannot remove a child on LayerImpl, but a child + // removed on Layer will force a full tree sync which will rebuild property + // trees without that child's property tree nodes. Clear active_tree (which + // also clears property trees) to simulate the rebuild that would happen + // before/during the commit. + host_impl_->active_tree()->property_trees()->clear(); + host_impl_->UpdateElements(ElementListType::ACTIVE); // On updating state, we will send an animation event and request one last // frame. @@ -2289,15 +2168,11 @@ class MissingTilesLayer : public LayerImpl { }; TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); - LayerImpl* container_layer = host_impl_->InnerViewportContainerLayer(); - EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + EXPECT_EQ(gfx::Size(50, 50), root_layer()->bounds()); float min_page_scale = 1.f, max_page_scale = 4.f; float page_scale_factor = 1.f; @@ -2320,7 +2195,7 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) { EXPECT_FALSE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); EXPECT_TRUE(did_request_commit_); - EXPECT_EQ(gfx::Size(50, 50), container_layer->bounds()); + EXPECT_EQ(gfx::Size(50, 50), root_layer()->bounds()); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); @@ -2383,50 +2258,31 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollbarGeometry) { // size. const gfx::Size outer_viewport_size = content_size; - PaintedScrollbarLayerImpl* v_scrollbar; - PaintedScrollbarLayerImpl* h_scrollbar; - // Setup - { - LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateLayerTreeFrameSink()); - LayerTreeImpl* active_tree = host_impl_->active_tree(); - active_tree->PushPageScaleFromMainThread(1.f, minimum_scale, 4.f); - - CreateBasicVirtualViewportLayers(viewport_size, content_size); - - // When Chrome on Android loads a non-mobile page, it resizes the main - // frame (outer viewport) such that it matches the width of the content, - // preventing horizontal scrolling. Replicate that behavior here. - host_impl_->OuterViewportScrollLayer()->SetScrollable(outer_viewport_size); - host_impl_->OuterViewportScrollLayer()->SetHitTestable(true); - LayerImpl* outer_clip = - host_impl_->OuterViewportScrollLayer()->test_properties()->parent; - outer_clip->SetBounds(outer_viewport_size); - - // Add scrollbars. They will always exist - even if unscrollable - but their - // visibility will be determined by whether the content can be scrolled. - { - std::unique_ptr<PaintedScrollbarLayerImpl> v_scrollbar_unique = - PaintedScrollbarLayerImpl::Create(active_tree, 400, VERTICAL, false, - true); - std::unique_ptr<PaintedScrollbarLayerImpl> h_scrollbar_unique = - PaintedScrollbarLayerImpl::Create(active_tree, 401, HORIZONTAL, false, - true); - v_scrollbar = v_scrollbar_unique.get(); - h_scrollbar = h_scrollbar_unique.get(); - - LayerImpl* scroll = active_tree->OuterViewportScrollLayer(); - LayerImpl* root = active_tree->InnerViewportContainerLayer(); - v_scrollbar_unique->SetScrollElementId(scroll->element_id()); - h_scrollbar_unique->SetScrollElementId(scroll->element_id()); - root->test_properties()->AddChild(std::move(v_scrollbar_unique)); - root->test_properties()->AddChild(std::move(h_scrollbar_unique)); - } + LayerTreeImpl* active_tree = host_impl_->active_tree(); + active_tree->PushPageScaleFromMainThread(1.f, minimum_scale, 4.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->DidBecomeActive(); - } + // When Chrome on Android loads a non-mobile page, it resizes the main + // frame (outer viewport) such that it matches the width of the content, + // preventing horizontal scrolling. Replicate that behavior here. + SetupViewportLayersInnerScrolls(viewport_size, content_size); + + LayerImpl* scroll = OuterViewportScrollLayer(); + ASSERT_EQ(scroll->scroll_container_bounds(), outer_viewport_size); + scroll->SetHitTestable(true); + ClipNode* outer_clip = host_impl_->active_tree()->OuterViewportClipNode(); + ASSERT_EQ(gfx::SizeF(outer_viewport_size), outer_clip->clip.size()); + + // Add scrollbars. They will always exist - even if unscrollable - but their + // visibility will be determined by whether the content can be scrolled. + auto* v_scrollbar = + AddLayer<PaintedScrollbarLayerImpl>(active_tree, VERTICAL, false, true); + auto* h_scrollbar = + AddLayer<PaintedScrollbarLayerImpl>(active_tree, HORIZONTAL, false, true); + SetupScrollbarLayer(scroll, v_scrollbar); + SetupScrollbarLayer(scroll, h_scrollbar); + + host_impl_->active_tree()->DidBecomeActive(); // Zoom out to the minimum scale. The scrollbars shoud not be scrollable. host_impl_->active_tree()->SetPageScaleOnActiveTree(0.f); @@ -2446,13 +2302,13 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); outer_scroll_layer->SetDrawsContent(true); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); inner_scroll_layer->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500), outer_scroll_layer->MaxScrollOffset()); @@ -2499,19 +2355,17 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) { // Make sure scrolls smaller than a unit applied to the viewport don't get // dropped. crbug.com/539334. TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) { - LayerTreeSettings settings = DefaultSettings(); - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); outer_scroll_layer->SetDrawsContent(true); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); inner_scroll_layer->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // Sanity checks. EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500), @@ -2554,13 +2408,13 @@ TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); outer_scroll_layer->SetDrawsContent(true); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); inner_scroll_layer->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500), outer_scroll_layer->MaxScrollOffset()); @@ -2608,7 +2462,7 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); int offsetFromEdge = Viewport::kPinchZoomSnapMarginDips - 5; gfx::Point anchor(viewport_size.width() - offsetFromEdge, @@ -2622,14 +2476,13 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(250, 250), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(250, 250), + InnerViewportScrollLayer()->CurrentScrollOffset()); // Reset. host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d()); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d()); // Pinch in within the margins. The scroll should stay exactly locked to the // top and left. @@ -2640,14 +2493,13 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + InnerViewportScrollLayer()->CurrentScrollOffset()); // Reset. host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d()); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d()); // Pinch in just outside the margin. There should be no snapping. offsetFromEdge = Viewport::kPinchZoomSnapMarginDips; @@ -2658,14 +2510,13 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(50, 50), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50), + InnerViewportScrollLayer()->CurrentScrollOffset()); // Reset. host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), gfx::Vector2d()); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d()); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d()); // Pinch in just outside the margin. There should be no snapping. offsetFromEdge = Viewport::kPinchZoomSnapMarginDips; @@ -2677,18 +2528,17 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) { host_impl_->PinchGestureEnd(anchor, true); host_impl_->ScrollEnd(EndState().get()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(200, 200), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(200, 200), + InnerViewportScrollLayer()->CurrentScrollOffset()); } TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Zoom into the page by a 2X factor float min_page_scale = 1.f, max_page_scale = 4.f; @@ -2743,7 +2593,7 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { std::unique_ptr<SwapPromise> swap_promise( new LatencyInfoSwapPromise(latency_info)); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ ->ScrollBegin(BeginState(gfx::Point()).get(), @@ -2763,45 +2613,23 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) { // Test that scrolls targeting a layer with a non-null scroll_parent() don't // bubble up. TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { - LayerImpl* viewport_scroll = - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - // This is to build property tree for viewport layers. The remaining part of - // this test is in layer list mode. - // TODO(crbug.com/994361): Avoid PropertyTreeBuilder. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + LayerImpl* viewport_scroll = InnerViewportScrollLayer(); // Set up two scrolling children of the root, one of which is a scroll parent // to the other. Scrolls shouldn't bubbling from the child. - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - LayerImpl* parent; - LayerImpl* child; - LayerImpl* child_clip; - - std::unique_ptr<LayerImpl> scroll_parent = - CreateScrollableLayer(7, gfx::Size(10, 10)); - parent = scroll_parent.get(); - root->test_properties()->AddChild(std::move(scroll_parent)); - CopyProperties(viewport_scroll, parent); - CreateTransformNode(parent); - CreateScrollNode(parent); - - std::unique_ptr<LayerImpl> scroll_child_clip = - LayerImpl::Create(host_impl_->active_tree(), 8); - child_clip = scroll_child_clip.get(); - root->test_properties()->AddChild(std::move(scroll_child_clip)); - CopyProperties(viewport_scroll, child_clip); - // child_clip scrolls in scroll_parent. - child_clip->SetScrollTreeIndex(parent->scroll_tree_index()); - child_clip->SetTransformTreeIndex(parent->transform_tree_index()); - - std::unique_ptr<LayerImpl> scroll_child = - CreateScrollableLayer(9, gfx::Size(10, 10)); - child = scroll_child.get(); - root->test_properties()->AddChild(std::move(scroll_child)); - CopyProperties(child_clip, child); - CreateTransformNode(child).post_translation = gfx::Vector2d(20, 20); - CreateScrollNode(child); + LayerImpl* scroll_parent = + AddScrollableLayer(viewport_scroll, gfx::Size(5, 5), gfx::Size(10, 10)); + + LayerImpl* scroll_child_clip = AddLayer(); + // scroll_child_clip scrolls in scroll_parent, but under viewport_scroll's + // effect. + CopyProperties(scroll_parent, scroll_child_clip); + scroll_child_clip->SetEffectTreeIndex(viewport_scroll->effect_tree_index()); + + LayerImpl* scroll_child = + AddScrollableLayer(scroll_child_clip, gfx::Size(5, 5), gfx::Size(10, 10)); + GetTransformNode(scroll_child)->post_translation = gfx::Vector2d(20, 20); DrawFrame(); @@ -2815,18 +2643,17 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { host_impl_->ScrollEnd(EndState().get()); // The child should be fully scrolled by the first ScrollBy. - EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), child->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), scroll_child->CurrentScrollOffset()); // The scroll_parent shouldn't receive the second ScrollBy. - EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), parent->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + scroll_parent->CurrentScrollOffset()); // The viewport shouldn't have been scrolled at all. - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + OuterViewportScrollLayer()->CurrentScrollOffset()); } { @@ -2843,25 +2670,22 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) { host_impl_->ScrollEnd(EndState().get()); // The ScrollBy's should scroll the parent to its extent. - EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), parent->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), + scroll_parent->CurrentScrollOffset()); // The viewport shouldn't receive any scroll delta. - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->InnerViewportScrollLayer()->CurrentScrollOffset()); - EXPECT_VECTOR_EQ( - gfx::Vector2dF(0, 0), - host_impl_->OuterViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + InnerViewportScrollLayer()->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), + OuterViewportScrollLayer()->CurrentScrollOffset()); } } TEST_F(LayerTreeHostImplTest, PinchGesture) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 1.f; @@ -3031,12 +2855,10 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) { } TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 1.f; @@ -3079,11 +2901,10 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) { } TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollFromFractionalActiveBase) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); SetScrollOffsetDelta(scroll_layer, gfx::Vector2d()); @@ -3115,8 +2936,7 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollFromFractionalActiveBase) { } TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); float min_page_scale = 1.f; @@ -3238,11 +3058,10 @@ TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) { } TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 0.5f; @@ -3368,11 +3187,10 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) { } TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 0.5f; @@ -3430,13 +3248,12 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) { TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50), + gfx::Size(100, 100), gfx::Size(100, 100)); host_impl_->ActivateSyncTree(); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); float min_page_scale = 0.5f; @@ -3553,11 +3370,10 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) { } TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); DrawFrame(); - LayerImpl* scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); DCHECK(scroll_layer); base::TimeTicks start_time = @@ -3603,29 +3419,29 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) { } TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - LayerImpl* inner_container = host_impl_->InnerViewportContainerLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DCHECK(inner_scroll); - DCHECK(inner_container); EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset()); - inner_container->SetViewportBoundsDelta(gfx::Vector2dF(15.f, 15.f)); - inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(7.f, 7.f)); + PropertyTrees* property_trees = host_impl_->active_tree()->property_trees(); + property_trees->SetInnerViewportContainerBoundsDelta( + gfx::Vector2dF(15.f, 15.f)); + property_trees->SetOuterViewportContainerBoundsDelta( + gfx::Vector2dF(7.f, 7.f)); EXPECT_EQ(gfx::ScrollOffset(42, 42), inner_scroll->MaxScrollOffset()); - inner_container->SetViewportBoundsDelta(gfx::Vector2dF()); - inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF()); + property_trees->SetInnerViewportContainerBoundsDelta(gfx::Vector2dF()); + property_trees->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF()); inner_scroll->SetBounds(gfx::Size()); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(inner_scroll)->bounds = inner_scroll->bounds(); DrawFrame(); - inner_scroll->SetViewportBoundsDelta(gfx::Vector2dF(60.f, 60.f)); + property_trees->SetOuterViewportContainerBoundsDelta( + gfx::Vector2dF(60.f, 60.f)); EXPECT_EQ(gfx::ScrollOffset(10, 10), inner_scroll->MaxScrollOffset()); } @@ -3644,6 +3460,7 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { task_graph_runner, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, + nullptr, nullptr) {} viz::BeginFrameArgs CurrentBeginFrameArgs() const override { @@ -3665,6 +3482,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { host_impl_->ReleaseLayerTreeFrameSink(); host_impl_ = nullptr; + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = @@ -3676,28 +3494,20 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { host_impl_->SetVisible(true); host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get()); - SetupScrollAndContentsLayers(content_size); + SetupViewportLayersInnerScrolls(viewport_size, content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(content_size.width() / 2, content_size.height() / 2)); - - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 400, - VERTICAL, 10, 0, false, true); - scrollbar->test_properties()->opacity = 0.f; - EXPECT_FLOAT_EQ(0.f, scrollbar->test_properties()->opacity); - - LayerImpl* scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - LayerImpl* root = host_impl_->active_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollElementId(scroll->element_id()); - root->test_properties()->AddChild(std::move(scrollbar)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 10, 0, false); + SetupScrollbarLayer(OuterViewportScrollLayer(), scrollbar); + host_impl_->active_tree()->DidBecomeActive(); host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent( viz::LocalSurfaceIdAllocation( viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)), base::TimeTicks::Now())); + DrawFrame(); // SetScrollElementId will initialize the scrollbar which will cause it to @@ -3842,10 +3652,10 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { if (host_impl_->active_tree() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( - host_impl_->InnerViewportScrollLayer()->element_id(), + InnerViewportScrollLayer()->element_id(), gfx::ScrollOffset(5, 5))) host_impl_->active_tree()->DidUpdateScrollOffset( - host_impl_->InnerViewportScrollLayer()->element_id()); + InnerViewportScrollLayer()->element_id()); EXPECT_FALSE(did_request_next_frame_); EXPECT_FALSE(did_request_redraw_); EXPECT_EQ(base::TimeDelta(), requested_animation_delay_); @@ -3888,6 +3698,7 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { settings.scrollbar_animator = animator; settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); // If no animator is set, scrollbar won't show and no animation is expected. @@ -3895,30 +3706,24 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { CreateHostImpl(settings, CreateLayerTreeFrameSink()); CreatePendingTree(); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size); - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400, - VERTICAL, 10, 0, false, true); - scrollbar->test_properties()->opacity = 0.f; - LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); - LayerImpl* container = - host_impl_->pending_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollElementId(scroll->element_id()); - scrollbar->SetBounds(gfx::Size(10, 100)); - scrollbar->test_properties()->position = gfx::PointF(90, 0); - scrollbar->SetNeedsPushProperties(); - container->test_properties()->AddChild(std::move(scrollbar)); + SetupViewportLayers(host_impl_->pending_tree(), viewport_size, content_size, + content_size); + + LayerImpl* scroll = + host_impl_->pending_tree()->OuterViewportScrollLayerForTesting(); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->pending_tree(), VERTICAL, 10, 0, false); + SetupScrollbarLayer(scroll, scrollbar); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(90, 0)); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); host_impl_->ActivateSyncTree(); LayerImpl* active_scrollbar_layer = - host_impl_->active_tree()->LayerById(400); + host_impl_->active_tree()->LayerById(scrollbar->id()); - EffectNode* active_tree_node = - host_impl_->active_tree()->property_trees()->effect_tree.Node( - active_scrollbar_layer->effect_tree_index()); + EffectNode* active_tree_node = GetEffectNode(active_scrollbar_layer); EXPECT_FLOAT_EQ(active_scrollbar_layer->Opacity(), active_tree_node->opacity); @@ -3933,22 +3738,23 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { InputHandler::WHEEL); host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get()); host_impl_->ScrollEnd(EndState().get()); + CreatePendingTree(); // To test the case where the effect tree index of scrollbar layer changes, - // we force the container layer to create a render surface. - container = host_impl_->pending_tree()->InnerViewportContainerLayer(); - container->test_properties()->force_render_surface = true; - container->SetBounds(gfx::Size(10, 10)); - container->SetNeedsPushProperties(); - - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - + // we create an effect node with a render surface above the scrollbar's + // effect node. + auto* pending_root = host_impl_->pending_tree()->root_layer(); + auto& new_effect_node = CreateEffectNode( + GetPropertyTrees(pending_root), pending_root->effect_tree_index(), + pending_root->transform_tree_index(), pending_root->clip_tree_index()); + new_effect_node.render_surface_reason = RenderSurfaceReason::kTest; LayerImpl* pending_scrollbar_layer = - host_impl_->pending_tree()->LayerById(400); + host_impl_->pending_tree()->LayerById(scrollbar->id()); + GetEffectNode(pending_scrollbar_layer)->parent_id = new_effect_node.id; pending_scrollbar_layer->SetNeedsPushProperties(); - EffectNode* pending_tree_node = - host_impl_->pending_tree()->property_trees()->effect_tree.Node( - pending_scrollbar_layer->effect_tree_index()); + UpdateDrawProperties(host_impl_->pending_tree()); + + EffectNode* pending_tree_node = GetEffectNode(pending_scrollbar_layer); if (expecting_animations) { EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity); EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity()); @@ -3957,10 +3763,9 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity()); } EXPECT_FLOAT_EQ(0.f, pending_tree_node->opacity); + host_impl_->ActivateSyncTree(); - active_tree_node = - host_impl_->active_tree()->property_trees()->effect_tree.Node( - active_scrollbar_layer->effect_tree_index()); + active_tree_node = GetEffectNode(active_scrollbar_layer); if (expecting_animations) { EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity); EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity()); @@ -3994,65 +3799,32 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest { gfx::Size scrollbar_size_1(gfx::Size(15, viewport_size.height())); gfx::Size scrollbar_size_2(gfx::Size(15, child_layer_size.height())); - const int scrollbar_1_id = 10; - const int scrollbar_2_id = 11; - const int child_scroll_id = 13; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayers(host_impl_->active_tree(), viewport_size, content_size, + content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); // scrollbar_1 on root scroll. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_1 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_1_id, VERTICAL, 15, 0, - true, true); - scrollbar_1_ = scrollbar_1.get(); - scrollbar_1->SetScrollElementId(root_scroll->element_id()); - scrollbar_1->SetDrawsContent(true); - scrollbar_1->SetBounds(scrollbar_size_1); + scrollbar_1_ = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(root_scroll, scrollbar_1_); + scrollbar_1_->SetBounds(scrollbar_size_1); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1)); - scrollbar_1->SetTouchActionRegion(touch_action_region); - scrollbar_1->SetCurrentPos(0); - scrollbar_1->test_properties()->position = gfx::PointF(0, 0); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar_1)); + scrollbar_1_->SetTouchActionRegion(touch_action_region); // scrollbar_2 on child. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_2 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_2_id, VERTICAL, 15, 0, - true, true); - scrollbar_2_ = scrollbar_2.get(); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->test_properties()->position = gfx::PointF(50, 50); - child->SetBounds(child_layer_size); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetScrollable(gfx::Size(100, 100)); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); - ElementId child_element_id = child->element_id(); - - scrollbar_2->SetScrollElementId(child_element_id); - scrollbar_2->SetDrawsContent(true); - scrollbar_2->SetBounds(scrollbar_size_2); - scrollbar_2->SetCurrentPos(0); - scrollbar_2->test_properties()->position = gfx::PointF(0, 0); - - child->test_properties()->AddChild(std::move(scrollbar_2)); - root_scroll->test_properties()->AddChild(std::move(child)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* child = + AddScrollableLayer(root_scroll, gfx::Size(100, 100), child_layer_size); + GetTransformNode(child)->post_translation = gfx::Vector2dF(50, 50); + + scrollbar_2_ = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(child, scrollbar_2_); + scrollbar_2_->SetBounds(scrollbar_size_2); + + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); @@ -4060,10 +3832,9 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest { } void ResetScrollbars() { - scrollbar_1_->test_properties()->opacity = 0.f; - scrollbar_2_->test_properties()->opacity = 0.f; - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetEffectNode(scrollbar_1_)->opacity = 0.f; + GetEffectNode(scrollbar_2_)->opacity = 0.f; + UpdateDrawProperties(host_impl_->active_tree()); if (is_aura_scrollbar_) animation_task_.Reset(); @@ -4149,66 +3920,32 @@ TEST_F(LayerTreeHostImplTest, ScrollHitTestOnScrollbar) { gfx::Size scrollbar_size_1(gfx::Size(15, viewport_size.height())); gfx::Size scrollbar_size_2(gfx::Size(15, child_layer_size.height())); - const int scrollbar_1_id = 10; - const int scrollbar_2_id = 11; - const int child_scroll_id = 13; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); // scrollbar_1 on root scroll. - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar_1 = - PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_1_id, VERTICAL, true, true); - scrollbar_1->SetScrollElementId(root_scroll->element_id()); - scrollbar_1->SetDrawsContent(true); - scrollbar_1->SetHitTestable(true); + auto* scrollbar_1 = AddLayer<PaintedScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, true, true); + SetupScrollbarLayer(root_scroll, scrollbar_1); scrollbar_1->SetBounds(scrollbar_size_1); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1)); scrollbar_1->SetTouchActionRegion(touch_action_region); - scrollbar_1->SetCurrentPos(0); - scrollbar_1->test_properties()->position = gfx::PointF(0, 0); - scrollbar_1->test_properties()->opacity = 0.f; - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar_1)); - // scrollbar_2 on child. - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar_2 = - PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_2_id, VERTICAL, true, true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->test_properties()->position = gfx::PointF(50, 50); - child->SetBounds(child_layer_size); - child->SetDrawsContent(true); - child->SetHitTestable(true); - child->SetScrollable(gfx::Size(100, 100)); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); - ElementId child_element_id = child->element_id(); + LayerImpl* child = + AddScrollableLayer(root_scroll, gfx::Size(100, 100), child_layer_size); + GetTransformNode(child)->post_translation = gfx::Vector2dF(50, 50); - scrollbar_2->SetScrollElementId(child_element_id); - scrollbar_2->SetDrawsContent(true); - scrollbar_2->SetHitTestable(true); + // scrollbar_2 on child. + auto* scrollbar_2 = AddLayer<PaintedScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, true, true); + SetupScrollbarLayer(child, scrollbar_2); scrollbar_2->SetBounds(scrollbar_size_2); - scrollbar_2->SetCurrentPos(0); - scrollbar_2->test_properties()->position = gfx::PointF(0, 0); - scrollbar_2->test_properties()->opacity = 0.f; - - child->test_properties()->AddChild(std::move(scrollbar_2)); - root_scroll->test_properties()->AddChild(std::move(child)); + scrollbar_2->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateScrollbarGeometries(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); // Wheel scroll on root scrollbar should process on impl thread. @@ -4251,26 +3988,21 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) { settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY; settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); CreateHostImpl(settings, CreateLayerTreeFrameSink()); CreatePendingTree(); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), content_size); - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->pending_tree(), 400, - VERTICAL, 10, 0, false, true); - scrollbar->test_properties()->opacity = 0.f; - LayerImpl* scroll = host_impl_->pending_tree()->OuterViewportScrollLayer(); - LayerImpl* container = - host_impl_->pending_tree()->InnerViewportContainerLayer(); - scrollbar->SetScrollElementId(scroll->element_id()); - scrollbar->SetBounds(gfx::Size(10, 100)); - scrollbar->test_properties()->position = gfx::PointF(90, 0); - scrollbar->SetNeedsPushProperties(); - container->test_properties()->AddChild(std::move(scrollbar)); + SetupViewportLayers(host_impl_->pending_tree(), viewport_size, content_size, + content_size); + LayerImpl* scroll = + host_impl_->pending_tree()->OuterViewportScrollLayerForTesting(); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->pending_tree(), VERTICAL, 10, 0, false); + SetupScrollbarLayer(scroll, scrollbar); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(90, 0)); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); host_impl_->ActivateSyncTree(); ScrollbarAnimationController* scrollbar_controller = @@ -4327,32 +4059,16 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) { gfx::Size inner_viewport_size(315, 200); gfx::Size outer_viewport_size(300, 200); gfx::Size content_size(1000, 1000); - - const int horiz_id = 11; - const int child_scroll_id = 15; - - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - inner_viewport_size); - host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( - inner_viewport_size); - host_impl_->active_tree()->OuterViewportContainerLayer()->SetBounds( - outer_viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetScrollable( - outer_viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - std::unique_ptr<PaintedScrollbarLayerImpl> horiz_scrollbar = - PaintedScrollbarLayerImpl::Create(host_impl_->active_tree(), horiz_id, - HORIZONTAL, true, true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); + auto* horiz_scrollbar = AddLayer<PaintedScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, true, true); + SetupScrollbarLayer(root_scroll, horiz_scrollbar); + LayerImpl* child = AddLayer(); child->SetBounds(content_size); child->SetBounds(inner_viewport_size); - horiz_scrollbar->SetScrollElementId(root_scroll->element_id()); - - host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl_->active_tree()->UpdateScrollbarGeometries(); EXPECT_EQ(300, horiz_scrollbar->clip_layer_length()); @@ -4368,45 +4084,27 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { gfx::Size viewport_size(300, 200); gfx::Size content_size(1000, 1000); - const int vert_1_id = 10; - const int horiz_1_id = 11; - const int vert_2_id = 12; - const int horiz_2_id = 13; - const int child_scroll_id = 15; - - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - LayerImpl* container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - container->SetBounds(viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), vert_1_id, VERTICAL, 5, 5, true, true)); - auto* vert_1_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[1]); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), horiz_1_id, HORIZONTAL, 5, 5, true, true)); - auto* horiz_1_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[2]); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), vert_2_id, VERTICAL, 5, 5, true, true)); - auto* vert_2_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[3]); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), horiz_2_id, HORIZONTAL, 5, 5, true, true)); - auto* horiz_2_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[4]); - - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->SetBounds(viewport_size); - LayerImpl* child_ptr = child.get(); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + + auto* container = InnerViewportScrollLayer(); + auto* root_scroll = OuterViewportScrollLayer(); + auto* vert_1_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 5, 5, true); + CopyProperties(container, vert_1_scrollbar); + + auto* horiz_1_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, 5, 5, true); + CopyProperties(container, horiz_1_scrollbar); + + auto* vert_2_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 5, 5, true); + CopyProperties(container, vert_2_scrollbar); + + auto* horiz_2_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, 5, 5, true); + CopyProperties(container, horiz_2_scrollbar); + + UpdateDrawProperties(host_impl_->active_tree()); // Check scrollbar registration on the viewport layers. EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); @@ -4430,11 +4128,9 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { animation_task_.Reset(); // Check scrollbar registration on a sublayer. - child->SetScrollable(viewport_size); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); + LayerImpl* child = + AddScrollableLayer(root_scroll, viewport_size, gfx::Size(200, 200)); ElementId child_scroll_element_id = child->element_id(); - root_scroll->test_properties()->AddChild(std::move(child)); EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( child_scroll_element_id)); @@ -4450,39 +4146,21 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { // Changing one of the child layers should result in a scrollbar animation // update. animation_task_.Reset(); - child_ptr->SetBounds(gfx::Size(200, 200)); - child_ptr->set_needs_show_scrollbars(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + child->set_needs_show_scrollbars(true); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->HandleScrollbarShowRequestsFromMain(); EXPECT_FALSE(animation_task_.is_null()); animation_task_.Reset(); // Check scrollbar unregistration. - container->test_properties()->RemoveChild(vert_1_scrollbar); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( - root_scroll->element_id())); - container->test_properties()->RemoveChild(horiz_1_scrollbar); - EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); + ElementId root_scroll_element_id = root_scroll->element_id(); + host_impl_->active_tree()->DetachLayers(); + EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(root_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( - root_scroll->element_id())); - - EXPECT_EQ(2ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); - container->test_properties()->RemoveChild(vert_2_scrollbar); - EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); - EXPECT_TRUE(host_impl_->ScrollbarAnimationControllerForElementId( - child_scroll_element_id)); - container->test_properties()->RemoveChild(horiz_2_scrollbar); + root_scroll_element_id)); EXPECT_EQ(0ul, host_impl_->ScrollbarsFor(child_scroll_element_id).size()); EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId( - root_scroll->element_id())); - - // Changing scroll offset should no longer trigger any animation. - host_impl_->active_tree()->InnerViewportScrollLayer()->SetCurrentScrollOffset( - gfx::ScrollOffset(20, 20)); - EXPECT_TRUE(animation_task_.is_null()); - child_ptr->SetCurrentScrollOffset(gfx::ScrollOffset(20, 20)); - EXPECT_TRUE(animation_task_.is_null()); + root_scroll_element_id)); } TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) { @@ -4495,23 +4173,15 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) { gfx::Size viewport_size(300, 200); gfx::Size content_size(1000, 1000); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - auto* container = host_impl_->active_tree()->InnerViewportContainerLayer(); - container->SetBounds(viewport_size); - auto* root_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - - container->test_properties()->AddChild(SolidColorScrollbarLayerImpl::Create( - host_impl_->active_tree(), 10, VERTICAL, 5, 0, false, true)); - auto* vert_scrollbar = static_cast<SolidColorScrollbarLayerImpl*>( - container->test_properties()->children[1]); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + auto* root_scroll = OuterViewportScrollLayer(); - vert_scrollbar->SetScrollElementId(root_scroll->element_id()); + auto* vert_scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 5, 0, false); + SetupScrollbarLayer(root_scroll, vert_scrollbar); vert_scrollbar->SetBounds(gfx::Size(10, 200)); - vert_scrollbar->test_properties()->position = gfx::PointF(300, 0); - vert_scrollbar->test_properties()->opacity_can_animate = true; - vert_scrollbar->SetCurrentPos(0); + vert_scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(300, 0)); - host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl_->active_tree()->UpdateScrollbarGeometries(); EXPECT_EQ(1ul, host_impl_->ScrollbarsFor(root_scroll->element_id()).size()); @@ -4559,40 +4229,24 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( settings.scrollbar_animator = LayerTreeSettings::AURA_OVERLAY; gfx::Size viewport_size(300, 200); - gfx::Size device_viewport_size = - gfx::ScaleToFlooredSize(viewport_size, device_scale_factor); gfx::Size content_size(1000, 1000); gfx::Size scrollbar_size(gfx::Size(15, viewport_size.height())); CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(device_scale_factor); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(device_viewport_size)); - - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); // The scrollbar is on the left side. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), 6, - VERTICAL, 15, 0, true, true); - scrollbar->SetScrollElementId(root_scroll->element_id()); - scrollbar->SetDrawsContent(true); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(root_scroll, scrollbar); scrollbar->SetBounds(scrollbar_size); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size)); scrollbar->SetTouchActionRegion(touch_action_region); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); - host_impl_->active_tree()->UpdateDrawProperties(); ScrollbarAnimationController* scrollbar_animation_controller = host_impl_->ScrollbarAnimationControllerForElementId( @@ -4649,9 +4303,8 @@ TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) { // that are different are included in viz::CompositorFrameMetadata's // |activation_dependencies|. TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + LayerImpl* root = root_layer(); std::vector<viz::SurfaceId> primary_surfaces = { MakeSurfaceId(viz::FrameSinkId(1, 1), 1), @@ -4664,14 +4317,13 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { MakeSurfaceId(viz::FrameSinkId(4, 4), 3)}; for (size_t i = 0; i < primary_surfaces.size(); ++i) { - std::unique_ptr<SurfaceLayerImpl> child = - SurfaceLayerImpl::Create(host_impl_->active_tree(), i + 6); - child->test_properties()->position = gfx::PointF(25.f * i, 0.f); + auto* child = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetRange( viz::SurfaceRange(fallback_surfaces[i], primary_surfaces[i]), 2u); - root->test_properties()->AddChild(std::move(child)); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(25.f * i, 0.f)); } base::flat_set<viz::SurfaceRange> surfaces_set; @@ -4681,7 +4333,6 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { viz::SurfaceRange(fallback_surfaces[i], primary_surfaces[i])); } - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetSurfaceRanges(std::move(surfaces_set)); host_impl_->SetFullViewportDamage(); DrawFrame(); @@ -4706,7 +4357,6 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { // Verify that on the next frame generation that the deadline is reset. host_impl_->SetFullViewportDamage(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); { @@ -4732,13 +4382,11 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) { // causes a new CompositorFrame to be submitted, even if there is no other // damage. TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); auto* fake_layer_tree_frame_sink = static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); // Submit an initial CompositorFrame with an empty set of referenced surfaces. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetSurfaceRanges({}); host_impl_->SetFullViewportDamage(); DrawFrame(); @@ -4754,7 +4402,6 @@ TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { // Update the set of referenced surfaces to contain |surface_id| but don't // make any other changes that would cause damage. This mimics updating the // SurfaceLayer for an offscreen tab. - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->SetSurfaceRanges({viz::SurfaceRange(surface_id)}); DrawFrame(); @@ -4767,8 +4414,7 @@ TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) { } TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); { @@ -4831,7 +4477,8 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) { class DidDrawCheckLayer : public LayerImpl { public: - static std::unique_ptr<LayerImpl> Create(LayerTreeImpl* tree_impl, int id) { + static std::unique_ptr<DidDrawCheckLayer> Create(LayerTreeImpl* tree_impl, + int id) { return base::WrapUnique(new DidDrawCheckLayer(tree_impl, id)); } @@ -4868,11 +4515,6 @@ class DidDrawCheckLayer : public LayerImpl { did_draw_called_ = false; } - void AddCopyRequest() { - test_properties()->copy_requests.push_back( - viz::CopyOutputRequest::CreateStubForTesting()); - } - protected: DidDrawCheckLayer(LayerTreeImpl* tree_impl, int id) : LayerImpl(tree_impl, id), @@ -4893,22 +4535,17 @@ class DidDrawCheckLayer : public LayerImpl { }; TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); // Make a child layer that draws. - root->test_properties()->AddChild( - SolidColorLayerImpl::Create(host_impl_->active_tree(), 2)); - auto* layer = - static_cast<SolidColorLayerImpl*>(root->test_properties()->children[0]); + auto* layer = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree()); layer->SetBounds(gfx::Size(10, 10)); layer->SetDrawsContent(true); layer->SetBackgroundColor(SK_ColorRED); + CopyProperties(root, layer); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); { TestFrameData frame; @@ -4927,9 +4564,9 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) { // Stops the child layer from drawing. We should have damage from this but // should not have any quads. This should clear the damaged area. layer->SetDrawsContent(false); - root->test_properties()->opacity = 0.f; + GetEffectNode(root)->opacity = 0.f; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // The background is default to transparent. If the background is opaque, we // would fill the frame with background colour when no layers are contributing // quads. This means we would end up with 0 quad. @@ -4969,73 +4606,43 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) { TEST_F(LayerTreeHostImplTest, WillDrawReturningFalseDoesNotCall) { // The root layer is always drawn, so run this test on a child layer that // will be masked out by the root layer's bounds. - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->test_properties()->force_render_surface = true; - auto* layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + auto* layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); + CopyProperties(root, layer); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - - EXPECT_TRUE(layer->will_draw_returned_true()); - EXPECT_TRUE(layer->append_quads_called()); - EXPECT_TRUE(layer->did_draw_called()); - } + DrawFrame(); + EXPECT_TRUE(layer->will_draw_returned_true()); + EXPECT_TRUE(layer->append_quads_called()); + EXPECT_TRUE(layer->did_draw_called()); host_impl_->SetViewportDamage(gfx::Rect(10, 10)); - { - TestFrameData frame; - - layer->set_will_draw_returns_false(); - layer->ClearDidDrawCheck(); - - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - - EXPECT_FALSE(layer->will_draw_returned_true()); - EXPECT_FALSE(layer->append_quads_called()); - EXPECT_FALSE(layer->did_draw_called()); - } + layer->set_will_draw_returns_false(); + layer->ClearDidDrawCheck(); + DrawFrame(); + EXPECT_FALSE(layer->will_draw_returned_true()); + EXPECT_FALSE(layer->append_quads_called()); + EXPECT_FALSE(layer->did_draw_called()); } TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { // The root layer is always drawn, so run this test on a child layer that // will be masked out by the root layer's bounds. - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - root->SetMasksToBounds(true); - root->test_properties()->force_render_surface = true; - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - auto* layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); - // Ensure visible_layer_rect for layer is empty. - layer->test_properties()->position = gfx::PointF(100.f, 100.f); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + CreateClipNode(root); + auto* layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); layer->SetBounds(gfx::Size(10, 10)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - TestFrameData frame; + CopyProperties(root, layer); + // Ensure visible_layer_rect for layer is not empty + layer->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(layer->will_draw_returned_true()); EXPECT_FALSE(layer->did_draw_called()); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_FALSE(layer->will_draw_returned_true()); EXPECT_FALSE(layer->did_draw_called()); @@ -5043,16 +4650,14 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { EXPECT_TRUE(layer->visible_layer_rect().IsEmpty()); // Ensure visible_layer_rect for layer is not empty - layer->test_properties()->position = gfx::PointF(); + layer->SetOffsetToTransformParent(gfx::Vector2dF()); layer->NoteLayerPropertyChanged(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(layer->will_draw_returned_true()); EXPECT_FALSE(layer->did_draw_called()); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_TRUE(layer->will_draw_returned_true()); EXPECT_TRUE(layer->did_draw_called()); @@ -5062,39 +4667,25 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) { TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { gfx::Size big_size(1000, 1000); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(big_size)); - - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - auto* occluded_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); - root->test_properties()->force_render_surface = true; - auto* top_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[1]); + SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), big_size); + + auto* occluded_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); + CopyProperties(root, occluded_layer); + auto* top_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); // This layer covers the occluded_layer above. Make this layer large so it can // occlude. top_layer->SetBounds(big_size); top_layer->SetContentsOpaque(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - TestFrameData frame; + CopyProperties(occluded_layer, top_layer); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(occluded_layer->will_draw_returned_true()); EXPECT_FALSE(occluded_layer->did_draw_called()); EXPECT_FALSE(top_layer->will_draw_returned_true()); EXPECT_FALSE(top_layer->did_draw_called()); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_FALSE(occluded_layer->will_draw_returned_true()); EXPECT_FALSE(occluded_layer->did_draw_called()); @@ -5103,34 +4694,23 @@ TEST_F(LayerTreeHostImplTest, WillDrawNotCalledOnOccludedLayer) { } TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + auto* layer1 = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); + auto* layer2 = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 2)); - root->test_properties()->force_render_surface = true; - auto* layer1 = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children[0]); + CopyProperties(root, layer1); + CreateTransformNode(layer1).flattens_inherited_transform = true; + CreateEffectNode(layer1).render_surface_reason = RenderSurfaceReason::kTest; + CopyProperties(layer1, layer2); - layer1->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 3)); - auto* layer2 = - static_cast<DidDrawCheckLayer*>(layer1->test_properties()->children[0]); - - layer1->test_properties()->force_render_surface = true; - layer1->test_properties()->should_flatten_transform = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(root->did_draw_called()); EXPECT_FALSE(layer1->did_draw_called()); EXPECT_FALSE(layer2->did_draw_called()); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_TRUE(root->did_draw_called()); EXPECT_TRUE(layer1->did_draw_called()); @@ -5142,7 +4722,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawCalledOnAllLayers) { class MissingTextureAnimatingLayer : public DidDrawCheckLayer { public: - static std::unique_ptr<LayerImpl> Create( + static std::unique_ptr<MissingTextureAnimatingLayer> Create( LayerTreeImpl* tree_impl, int id, bool tile_missing, @@ -5191,7 +4771,6 @@ struct PrepareToDrawSuccessTestCase { bool has_missing_tile = false; bool has_incomplete_tile = false; bool is_animating = false; - bool has_copy_request = false; }; bool high_res_required = false; @@ -5201,24 +4780,26 @@ struct PrepareToDrawSuccessTestCase { DrawResult expected_result; }; -static void CreateLayerFromState( - DidDrawCheckLayer* root, - const scoped_refptr<AnimationTimeline>& timeline, - const PrepareToDrawSuccessTestCase::State& state) { - static int layer_id = 2; - root->test_properties()->AddChild(MissingTextureAnimatingLayer::Create( - root->layer_tree_impl(), layer_id++, state.has_missing_tile, - state.has_incomplete_tile, state.is_animating, timeline)); - auto* layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); - if (state.has_copy_request) - layer->AddCopyRequest(); -} +class LayerTreeHostImplPrepareToDrawTest : public LayerTreeHostImplTest { + public: + void CreateLayerFromState(DidDrawCheckLayer* root, + const scoped_refptr<AnimationTimeline>& timeline, + const PrepareToDrawSuccessTestCase::State& state) { + auto* layer = AddLayer<MissingTextureAnimatingLayer>( + root->layer_tree_impl(), state.has_missing_tile, + state.has_incomplete_tile, state.is_animating, timeline); + CopyProperties(root, layer); + if (state.is_animating) + CreateTransformNode(layer).has_potential_animation = true; + } +}; -TEST_F(CommitToPendingTreeLayerTreeHostImplTest, - PrepareToDrawSucceedsAndFails) { - std::vector<PrepareToDrawSuccessTestCase> cases; +TEST_F(LayerTreeHostImplPrepareToDrawTest, PrepareToDrawSucceedsAndFails) { + LayerTreeSettings settings = DefaultSettings(); + settings.commit_to_active_tree = false; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + std::vector<PrepareToDrawSuccessTestCase> cases; // 0. Default case. cases.push_back(PrepareToDrawSuccessTestCase(DRAW_SUCCESS)); // 1. Animated layer first. @@ -5287,28 +4868,16 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, cases.back().layer_before.has_missing_tile = true; cases.back().layer_before.is_animating = true; - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - } + DrawFrame(); for (size_t i = 0; i < cases.size(); ++i) { // Clean up host_impl_ state. const auto& testcase = cases[i]; - std::vector<LayerImpl*> to_remove; - for (auto* child : root->test_properties()->children) - to_remove.push_back(child); - for (auto* child : to_remove) - root->test_properties()->RemoveChild(child); + host_impl_->active_tree()->DetachLayersKeepingRootLayerForTesting(); timeline()->ClearAnimations(); std::ostringstream scope; @@ -5318,7 +4887,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CreateLayerFromState(root, timeline(), testcase.layer_before); CreateLayerFromState(root, timeline(), testcase.layer_between); CreateLayerFromState(root, timeline(), testcase.layer_after); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); if (testcase.high_res_required) host_impl_->SetRequiresHighResToDraw(); @@ -5330,7 +4899,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, } } -TEST_F(LayerTreeHostImplTest, +TEST_F(LayerTreeHostImplPrepareToDrawTest, PrepareToDrawWhenDrawAndSwapFullViewportEveryFrame) { CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware()); @@ -5357,23 +4926,16 @@ TEST_F(LayerTreeHostImplTest, cases.back().high_res_required = true; cases.back().layer_between.has_missing_tile = true; - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), 1)); - auto* root = static_cast<DidDrawCheckLayer*>( - host_impl_->active_tree()->root_layer_for_testing()); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->OnDraw(external_transform, external_viewport, resourceless_software_draw, false); for (size_t i = 0; i < cases.size(); ++i) { const auto& testcase = cases[i]; - std::vector<LayerImpl*> to_remove; - for (auto* child : root->test_properties()->children) - to_remove.push_back(child); - for (auto* child : to_remove) - root->test_properties()->RemoveChild(child); + host_impl_->active_tree()->DetachLayersKeepingRootLayerForTesting(); std::ostringstream scope; scope << "Test case: " << i; @@ -5382,7 +4944,6 @@ TEST_F(LayerTreeHostImplTest, CreateLayerFromState(root, timeline(), testcase.layer_before); CreateLayerFromState(root, timeline(), testcase.layer_between); CreateLayerFromState(root, timeline(), testcase.layer_after); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); if (testcase.high_res_required) host_impl_->SetRequiresHighResToDraw(); @@ -5393,12 +4954,7 @@ TEST_F(LayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupDefaultRootLayer(gfx::Size(10, 10)); DrawFrame(); // Scroll event is ignored because layer is not scrollable. @@ -5414,17 +4970,15 @@ TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) { TEST_F(LayerTreeHostImplTest, ClampingAfterActivation) { CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50), + gfx::Size(100, 100), gfx::Size(100, 100)); host_impl_->ActivateSyncTree(); CreatePendingTree(); const gfx::ScrollOffset pending_scroll = gfx::ScrollOffset(-100, -100); - LayerImpl* active_outer_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* active_outer_layer = OuterViewportScrollLayer(); LayerImpl* pending_outer_layer = - host_impl_->pending_tree()->OuterViewportScrollLayer(); + host_impl_->pending_tree()->OuterViewportScrollLayerForTesting(); pending_outer_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( @@ -5440,9 +4994,7 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { LayerTreeHostImplBrowserControlsTest() // Make the clip size the same as the layer (content) size so the layer is // non-scrollable. - : layer_size_(10, 10), - clip_size_(layer_size_), - top_controls_height_(50) { + : layer_size_(10, 10), clip_size_(layer_size_), top_controls_height_(50) { viewport_size_ = gfx::Size(clip_size_.width(), clip_size_.height() + top_controls_height_); } @@ -5460,30 +5012,29 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { return init; } + protected: void SetupBrowserControlsAndScrollLayerWithVirtualViewport( const gfx::Size& inner_viewport_size, const gfx::Size& outer_viewport_size, - const gfx::Size& scroll_layer_size, - base::OnceCallback<void(LayerTreeSettings*)> modify_settings = - base::DoNothing()) { - settings_ = DefaultSettings(); - settings_.use_layer_lists = true; - std::move(modify_settings).Run(&settings_); - CreateHostImpl(settings_, CreateLayerTreeFrameSink()); + const gfx::Size& scroll_layer_size) { SetupBrowserControlsAndScrollLayerWithVirtualViewport( host_impl_->active_tree(), inner_viewport_size, outer_viewport_size, scroll_layer_size); } - protected: void SetupBrowserControlsAndScrollLayerWithVirtualViewport( LayerTreeImpl* tree_impl, const gfx::Size& inner_viewport_size, const gfx::Size& outer_viewport_size, const gfx::Size& scroll_layer_size) { - LayerTestCommon::SetupBrowserControlsAndScrollLayerWithVirtualViewport( - host_impl_.get(), tree_impl, top_controls_height_, inner_viewport_size, - outer_viewport_size, scroll_layer_size); + tree_impl->set_browser_controls_shrink_blink_size(true); + tree_impl->SetTopControlsHeight(top_controls_height_); + tree_impl->SetCurrentBrowserControlsShownRatio(1.f); + tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f); + host_impl_->DidChangeBrowserControlsPosition(); + + SetupViewportLayers(tree_impl, inner_viewport_size, outer_viewport_size, + scroll_layer_size); } gfx::Size layer_size_; @@ -5494,6 +5045,30 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { LayerTreeSettings settings_; }; // class LayerTreeHostImplBrowserControlsTest +#define EXPECT_VIEWPORT_GEOMETRIES(expected_browser_controls_shown_ratio) \ + do { \ + auto* tree = host_impl_->active_tree(); \ + auto* property_trees = tree->property_trees(); \ + EXPECT_EQ(expected_browser_controls_shown_ratio, \ + tree->CurrentBrowserControlsShownRatio()); \ + EXPECT_EQ( \ + tree->top_controls_height() * expected_browser_controls_shown_ratio, \ + host_impl_->browser_controls_manager()->ContentTopOffset()); \ + int delta = \ + (tree->top_controls_height() + tree->bottom_controls_height()) * \ + (1 - expected_browser_controls_shown_ratio); \ + int scaled_delta = delta / tree->min_page_scale_factor(); \ + gfx::Size inner_scroll_bounds = tree->InnerViewportScrollNode()->bounds; \ + inner_scroll_bounds.Enlarge(0, scaled_delta); \ + EXPECT_EQ(inner_scroll_bounds, InnerViewportScrollLayer()->bounds()); \ + EXPECT_EQ(gfx::RectF(gfx::SizeF(inner_scroll_bounds)), \ + tree->OuterViewportClipNode()->clip); \ + EXPECT_EQ(gfx::Vector2dF(0, delta), \ + property_trees->inner_viewport_container_bounds_delta()); \ + EXPECT_EQ(gfx::Vector2dF(0, scaled_delta), \ + property_trees->outer_viewport_container_bounds_delta()); \ + } while (false) + // Tests that, on a page with content the same size as the viewport, hiding // the browser controls also increases the ScrollableSize (i.e. the content // size). Since the viewport got larger, the effective scrollable "content" also @@ -5505,26 +5080,11 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, gfx::Size(50, 50), gfx::Size(50, 50), gfx::Size(50, 50)); LayerTreeImpl* active_tree = host_impl_->active_tree(); - - // Create a content layer beneath the outer viewport scroll layer. - int id = host_impl_->OuterViewportScrollLayer()->id(); - host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), id + 2)); - LayerImpl* content = - active_tree->OuterViewportScrollLayer()->test_properties()->children[0]; - content->SetBounds(gfx::Size(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); - LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - // The browser controls should start off showing so the viewport should be // shrunk. - ASSERT_EQ(gfx::Size(50, 50), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 50), outer_container->bounds()); - + EXPECT_VIEWPORT_GEOMETRIES(1); EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -5537,31 +5097,19 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // Hide the browser controls by a bit, the scrollable size should increase but // the actual content bounds shouldn't. - { - host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 75), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 75), outer_container->bounds()); - EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize()); - EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling()); - } + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + EXPECT_VIEWPORT_GEOMETRIES(0.5f); + EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize()); // Fully hide the browser controls. - { - host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); - EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); - EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling()); - } + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + EXPECT_VIEWPORT_GEOMETRIES(0); + EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); // Scrolling additionally shouldn't have any effect. - { - host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); - EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); - EXPECT_EQ(gfx::SizeF(50, 50), content->BoundsForScrolling()); - } + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + EXPECT_VIEWPORT_GEOMETRIES(0); + EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); host_impl_->browser_controls_manager()->ScrollEnd(); host_impl_->ScrollEnd(EndState().get()); @@ -5582,31 +5130,17 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, LayerTreeImpl* active_tree = host_impl_->active_tree(); // Create a content layer beneath the outer viewport scroll layer. - int id = host_impl_->OuterViewportScrollLayer()->id(); - host_impl_->OuterViewportScrollLayer()->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), id + 2)); - LayerImpl* content = - active_tree->OuterViewportScrollLayer()->test_properties()->children[0]; + LayerImpl* content = AddLayer(); content->SetBounds(gfx::Size(100, 100)); - host_impl_->active_tree()->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(OuterViewportScrollLayer(), content); + active_tree->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f); DrawFrame(); - LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - LayerImpl* outer_scroll = active_tree->OuterViewportScrollLayer(); - auto* property_trees = host_impl_->active_tree()->property_trees(); - ClipNode* outer_clip_node = - property_trees->clip_tree.Node(outer_scroll->clip_tree_index()); - // The browser controls should start off showing so the viewport should be // shrunk. - ASSERT_EQ(50, host_impl_->browser_controls_manager()->ContentTopOffset()); - ASSERT_EQ(gfx::Size(100, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(100, 100), outer_container->bounds()); - ASSERT_EQ(gfx::SizeF(200, 1000), active_tree->ScrollableSize()); - ASSERT_EQ(gfx::SizeF(100, 100), outer_clip_node->clip.size()); + EXPECT_VIEWPORT_GEOMETRIES(1.0f); + EXPECT_EQ(gfx::SizeF(200, 1000), active_tree->ScrollableSize()); ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -5614,16 +5148,13 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, InputHandler::TOUCHSCREEN) .thread); - // Hide the browser controls by 10px. The outer clip should expand by 20px as + // Hide the browser controls by 25px. The outer clip should expand by 50px as // because the outer viewport is sized based on the minimum scale, in this // case 0.5. Therefore, changes to the outer viewport need to be divided by // the minimum scale as well. - { - host_impl_->ScrollBy( - UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0.f, 10.f)).get()); - ASSERT_EQ(40, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_EQ(gfx::SizeF(100, 120), outer_clip_node->clip.size()); - } + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0.f, 25.f)).get()); + EXPECT_VIEWPORT_GEOMETRIES(0.5f); host_impl_->ScrollEnd(EndState().get()); } @@ -5637,39 +5168,23 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, LayerTreeImpl* active_tree = host_impl_->active_tree(); // Create a horizontal scrollbar. - const int scrollbar_id = 23; gfx::Size scrollbar_size(gfx::Size(50, 15)); - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_id, HORIZONTAL, 3, 20, - false, true); - scrollbar->SetScrollElementId( - host_impl_->OuterViewportScrollLayer()->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->SetBounds(scrollbar_size); + auto* scrollbar_layer = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), HORIZONTAL, 3, 20, false); + SetupScrollbarLayer(OuterViewportScrollLayer(), scrollbar_layer); + scrollbar_layer->SetBounds(scrollbar_size); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size)); - scrollbar->SetTouchActionRegion(touch_action_region); - scrollbar->SetCurrentPos(0); - scrollbar->test_properties()->position = gfx::PointF(0, 35); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + scrollbar_layer->SetTouchActionRegion(touch_action_region); + scrollbar_layer->SetOffsetToTransformParent(gfx::Vector2dF(0, 35)); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->UpdateScrollbarGeometries(); DrawFrame(); - LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); - LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - auto* scrollbar_layer = static_cast<SolidColorScrollbarLayerImpl*>( - active_tree->LayerById(scrollbar_id)); - // The browser controls should start off showing so the viewport should be // shrunk. - EXPECT_EQ(gfx::Size(50, 50), inner_container->bounds()); - EXPECT_EQ(gfx::Size(50, 50), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(1.0f); EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 0, 10, 3), scrollbar_layer->ComputeThumbQuadRect()); @@ -5687,8 +5202,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, { host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); host_impl_->active_tree()->UpdateScrollbarGeometries(); - ASSERT_EQ(gfx::Size(50, 75), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 75), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(0.5f); EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 25, 10, 3), @@ -5699,8 +5213,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, { host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); host_impl_->active_tree()->UpdateScrollbarGeometries(); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(0); EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 50, 10, 3), @@ -5710,8 +5223,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // Additional scrolling shouldn't have any effect. { host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); - ASSERT_EQ(gfx::Size(50, 100), inner_container->bounds()); - ASSERT_EQ(gfx::Size(50, 100), outer_container->bounds()); + EXPECT_VIEWPORT_GEOMETRIES(0); EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize()); EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds()); EXPECT_EQ(gfx::Rect(20, 50, 10, 3), @@ -5758,16 +5270,10 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100)); DrawFrame(); - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); inner_scroll->SetDrawsContent(true); - LayerImpl* inner_container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - LayerImpl* outer_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetDrawsContent(true); - LayerImpl* outer_container = - host_impl_->active_tree()->OuterViewportContainerLayer(); // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer. outer_scroll->SetDrawsContent(true); @@ -5785,8 +5291,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // The viewport layers should be resized back to their full sizes. EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y()); - EXPECT_EQ(100.f, inner_container->BoundsForScrolling().height()); - EXPECT_EQ(100.f, outer_container->BoundsForScrolling().height()); + EXPECT_EQ(100, inner_scroll->bounds().height()); + EXPECT_EQ(100, outer_scroll->bounds().height()); // The inner viewport should be scrollable by 50px * page_scale. host_impl_->ScrollBy( @@ -5812,8 +5318,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // The outer viewport should be resized to accomodate and scrolled to the // bottom of the document to keep the viewport in place. EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - EXPECT_EQ(50.f, outer_container->BoundsForScrolling().height()); - EXPECT_EQ(50.f, inner_container->BoundsForScrolling().height()); + EXPECT_EQ(50, inner_scroll->bounds().height()); + EXPECT_EQ(100, outer_scroll->bounds().height()); EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y()); EXPECT_EQ(25.f, inner_scroll->CurrentScrollOffset().y()); @@ -5899,11 +5405,9 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsPushUnsentRatio) { DrawFrame(); // Need SetDrawsContent so ScrollBegin's hit test finds an actual layer. - LayerImpl* inner_scroll = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); inner_scroll->SetDrawsContent(true); - LayerImpl* outer_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); outer_scroll->SetDrawsContent(true); host_impl_->active_tree()->PushBrowserControlsFromMainThread(1); @@ -5932,26 +5436,22 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, // Show browser controls EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - LayerImpl* outer_viewport_scroll_layer = - host_impl_->active_tree()->OuterViewportScrollLayer(); - int id = outer_viewport_scroll_layer->id(); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), id + 2); + LayerImpl* outer_viewport_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* child = AddLayer(); child->SetScrollable(sub_content_layer_size); child->SetHitTestable(true); child->SetElementId(LayerIdToElementIdForTesting(child->id())); child->SetBounds(sub_content_size); - child->test_properties()->position = gfx::PointF(); child->SetDrawsContent(true); - child->test_properties()->is_container_for_fixed_position_layers = true; - LayerImpl* child_ptr = child.get(); - outer_viewport_scroll_layer->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(outer_viewport_scroll_layer, child); + CreateTransformNode(child); + CreateScrollNode(child); + UpdateDrawProperties(host_impl_->active_tree()); // Scroll child to the limit. - SetScrollOffsetDelta(child_ptr, gfx::Vector2dF(0, 100.f)); + SetScrollOffsetDelta(child, gfx::Vector2dF(0, 100.f)); // Scroll 25px to hide browser controls gfx::Vector2dF scroll_delta(0.f, 25.f); @@ -5995,12 +5495,9 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->DidChangeBrowserControlsPosition(); - // Now that browser controls have moved, expect the clip to resize. - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); } // Ensure setting the browser controls position explicitly using the setters on @@ -6069,22 +5566,16 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) { 15.f / top_controls_height_); host_impl_->DidChangeBrowserControlsPosition(); - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0.f, 50.f), + property_trees->inner_viewport_container_bounds_delta()); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); host_impl_->ActivateSyncTree(); - inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); - + EXPECT_EQ(gfx::Vector2dF(0.f, 50.f), + property_trees->inner_viewport_container_bounds_delta()); EXPECT_FLOAT_EQ( -15.f, host_impl_->active_tree()->top_controls_shown_ratio()->Delta() * top_controls_height_); @@ -6112,31 +5603,20 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f); host_impl_->DidChangeBrowserControlsPosition(); - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); - host_impl_->sync_tree()->root_layer_for_testing()->SetBounds( - gfx::Size(inner_clip_ptr->bounds().width(), - inner_clip_ptr->bounds().height() - 50.f)); - host_impl_->ActivateSyncTree(); - inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); // The total bounds should remain unchanged since the bounds delta should // account for the difference between the layout height and the current // browser controls offset. - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); - EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), - inner_clip_ptr->ViewportBoundsDelta()); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); host_impl_->DidChangeBrowserControlsPosition(); @@ -6145,10 +5625,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->browser_controls_manager()->TopControlsShownRatio()); EXPECT_EQ(50.f, host_impl_->browser_controls_manager()->TopControlsHeight()); EXPECT_EQ(50.f, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f), - inner_clip_ptr->ViewportBoundsDelta()); - EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() - 50.f), - inner_clip_ptr->bounds()); + EXPECT_EQ(gfx::Vector2dF(), + property_trees->inner_viewport_container_bounds_delta()); } // Test that showing/hiding the browser controls when the viewport is fully @@ -6162,8 +5640,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); // Scroll the viewports to max scroll offset. SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f)); @@ -6250,21 +5728,14 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsAspectRatio) { // Browser controls were hidden by 25px so the inner viewport should have // expanded by that much. - LayerImpl* outer_container = - host_impl_->active_tree()->OuterViewportContainerLayer(); - LayerImpl* inner_container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - EXPECT_EQ(gfx::SizeF(100.f, 100.f + 25.f), - inner_container->BoundsForScrolling()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 25), + property_trees->inner_viewport_container_bounds_delta()); // Outer viewport should match inner's aspect ratio. The bounds are ceiled. - float aspect_ratio = inner_container->BoundsForScrolling().width() / - inner_container->BoundsForScrolling().height(); - gfx::SizeF expected = - gfx::SizeF(gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio))); - EXPECT_EQ(expected, outer_container->BoundsForScrolling()); - EXPECT_EQ(expected, - host_impl_->InnerViewportScrollLayer()->BoundsForScrolling()); + float aspect_ratio = 100.0f / 125.0f; + auto expected = gfx::ToCeiledSize(gfx::SizeF(200, 200 / aspect_ratio)); + EXPECT_EQ(expected, InnerViewportScrollLayer()->bounds()); } // Test that scrolling the outer viewport affects the browser controls. @@ -6287,7 +5758,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); - EXPECT_EQ(host_impl_->OuterViewportScrollLayer()->scroll_tree_index(), + EXPECT_EQ(OuterViewportScrollLayer()->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); host_impl_->ScrollEnd(EndState().get()); @@ -6305,17 +5776,15 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset()); - EXPECT_EQ(host_impl_->OuterViewportScrollLayer()->scroll_tree_index(), + EXPECT_EQ(OuterViewportScrollLayer()->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); host_impl_->ScrollEnd(EndState().get()); // Position the viewports such that the inner viewport will be scrolled. gfx::Vector2dF inner_viewport_offset(0.f, 25.f); - SetScrollOffsetDelta(host_impl_->OuterViewportScrollLayer(), - gfx::Vector2dF()); - SetScrollOffsetDelta(host_impl_->InnerViewportScrollLayer(), - inner_viewport_offset); + SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2dF()); + SetScrollOffsetDelta(InnerViewportScrollLayer(), inner_viewport_offset); scroll_delta = gfx::Vector2dF(0.f, -65.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -6329,7 +5798,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_FLOAT_EQ( inner_viewport_offset.y() + (scroll_delta.y() + top_controls_height_), - ScrollDelta(host_impl_->InnerViewportScrollLayer()).y()); + ScrollDelta(InnerViewportScrollLayer()).y()); host_impl_->ScrollEnd(EndState().get()); } @@ -6351,11 +5820,9 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->browser_controls_manager()->ScrollEnd(); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); // Now that browser controls have moved, expect the clip to resize. - LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() - ->test_properties() - ->parent->test_properties() - ->parent; - EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); + auto* property_trees = host_impl_->active_tree()->property_trees(); + EXPECT_EQ(gfx::Vector2dF(0, 50), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->ScrollEnd(EndState().get()); @@ -6372,9 +5839,8 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_FLOAT_EQ(-scroll_increment_y, host_impl_->browser_controls_manager()->ContentTopOffset()); // Now that browser controls have moved, expect the clip to resize. - EXPECT_EQ(gfx::Size(viewport_size_.width(), - viewport_size_.height() + scroll_increment_y), - inner_clip_ptr->bounds()); + EXPECT_EQ(gfx::Vector2dF(0, 25), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->browser_controls_manager()->ScrollBy( gfx::Vector2dF(0.f, scroll_increment_y)); @@ -6382,14 +5848,13 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_FLOAT_EQ(-2 * scroll_increment_y, host_impl_->browser_controls_manager()->ContentTopOffset()); // Now that browser controls have moved, expect the clip to resize. - EXPECT_EQ(clip_size_, inner_clip_ptr->bounds()); + EXPECT_EQ(gfx::Vector2dF(), + property_trees->inner_viewport_container_bounds_delta()); host_impl_->ScrollEnd(EndState().get()); // Verify the layer is once-again non-scrollable. - EXPECT_EQ( - gfx::ScrollOffset(), - host_impl_->active_tree()->InnerViewportScrollLayer()->MaxScrollOffset()); + EXPECT_EQ(gfx::ScrollOffset(), InnerViewportScrollLayer()->MaxScrollOffset()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -6424,6 +5889,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->pending_tree(), inner_viewport_size, outer_viewport_size, content_size); host_impl_->pending_tree()->set_browser_controls_shrink_blink_size(false); + UpdateDrawProperties(host_impl_->pending_tree()); // Fully scroll the viewport. host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(), @@ -6433,8 +5899,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, host_impl_->ScrollEnd(EndState().get()); } - LayerImpl* outer_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); ASSERT_FLOAT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset()); @@ -6527,29 +5992,20 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { gfx::Size surface_size(10, 10); gfx::Size contents_size(20, 20); - std::unique_ptr<LayerImpl> content_layer = - LayerImpl::Create(host_impl_->active_tree(), 11); - content_layer->SetDrawsContent(true); - content_layer->test_properties()->position = gfx::PointF(); - content_layer->SetBounds(contents_size); + SetupViewportLayersNoScrolls(surface_size); - LayerImpl* scroll_container_layer = - CreateBasicVirtualViewportLayers(surface_size, surface_size); + LayerImpl* scroll_container_layer = AddContentLayer(); + CreateEffectNode(scroll_container_layer).render_surface_reason = + RenderSurfaceReason::kTest; - std::unique_ptr<LayerImpl> scroll_layer = - LayerImpl::Create(host_impl_->active_tree(), 12); - scroll_layer->SetScrollable(surface_size); - scroll_layer->SetHitTestable(true); - scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id())); - scroll_layer->SetBounds(contents_size); - scroll_layer->test_properties()->position = gfx::PointF(); - scroll_layer->test_properties()->AddChild(std::move(content_layer)); - scroll_container_layer->test_properties()->AddChild(std::move(scroll_layer)); + LayerImpl* scroll_layer = + AddScrollableLayer(scroll_container_layer, surface_size, contents_size); - scroll_container_layer->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* content_layer = AddLayer(); + content_layer->SetDrawsContent(true); + content_layer->SetBounds(contents_size); + CopyProperties(scroll_layer, content_layer); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); EXPECT_EQ( @@ -6567,14 +6023,13 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { gfx::Size surface_size(10, 10); gfx::Size contents_size(20, 20); - LayerImpl* root = - CreateBasicVirtualViewportLayers(surface_size, surface_size); + SetupViewportLayersNoScrolls(surface_size); - root->test_properties()->AddChild(CreateScrollableLayer(12, contents_size)); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* content_root = AddContentLayer(); + CreateEffectNode(content_root).render_surface_reason = + RenderSurfaceReason::kTest; + AddScrollableLayer(content_root, surface_size, contents_size); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); EXPECT_EQ( @@ -6589,15 +6044,10 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { } TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { + gfx::Size viewport_size(5, 5); gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->AddChild(CreateScrollableLayer(2, surface_size)); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + LayerImpl* root = SetupDefaultRootLayer(surface_size); + AddScrollableLayer(root, viewport_size, surface_size); DrawFrame(); // Scroll event is ignored because the input coordinate is outside the layer @@ -6613,22 +6063,16 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) { } TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { + gfx::Size viewport_size(5, 5); gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); + LayerImpl* root = SetupDefaultRootLayer(viewport_size); + LayerImpl* child = AddScrollableLayer(root, viewport_size, surface_size); gfx::Transform matrix; matrix.RotateAboutXAxis(180.0); - child->test_properties()->transform = matrix; - child->test_properties()->double_sided = false; - root->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + GetTransformNode(child)->local = matrix; + CreateEffectNode(child).double_sided = false; DrawFrame(); // Scroll event is ignored because the scrollable layer is not facing the @@ -6644,21 +6088,18 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) { } TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { + gfx::Size scroll_container_size(5, 5); gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> content_layer = - CreateScrollableLayer(1, surface_size); - content_layer->test_properties()->main_thread_scrolling_reasons = - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; + LayerImpl* root = SetupDefaultRootLayer(surface_size); // Note: we can use the same clip layer for both since both calls to - // CreateScrollableLayer() use the same surface size. - std::unique_ptr<LayerImpl> scroll_layer = - CreateScrollableLayer(2, surface_size); - scroll_layer->test_properties()->AddChild(std::move(content_layer)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(scroll_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + // AddScrollableLayer() use the same surface size. + LayerImpl* scroll_layer = + AddScrollableLayer(root, scroll_container_size, surface_size); + LayerImpl* content_layer = + AddScrollableLayer(scroll_layer, scroll_container_size, surface_size); + GetScrollNode(content_layer)->main_thread_scrolling_reasons = + MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; DrawFrame(); // Scrolling fails because the content layer is asking to be scrolled on the @@ -6671,25 +6112,18 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) { } TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { - gfx::Size viewport_size(20, 20); - float page_scale = 2.f; - - SetupScrollAndContentsLayers(viewport_size); - - // Setup the layers so that the outer viewport is scrollable. - host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( - viewport_size); - host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); + gfx::Size inner_viewport_size(20, 20); + gfx::Size outer_viewport_size(40, 40); + gfx::Size content_size(80, 80); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); DrawFrame(); - LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); - EXPECT_EQ(viewport_size, root_container->bounds()); - gfx::Vector2d scroll_delta(0, 10); gfx::ScrollOffset expected_scroll_delta(scroll_delta); - LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); - gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + gfx::ScrollOffset expected_max_scroll = outer_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -6699,16 +6133,17 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { host_impl_->ScrollEnd(EndState().get()); // Set new page scale from main thread. + float page_scale = 2.f; host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f); std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); // The scroll range should also have been updated. - EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset()); + EXPECT_EQ(expected_max_scroll, outer_scroll->MaxScrollOffset()); // The page scale delta remains constant because the impl thread did not // scale. @@ -6716,27 +6151,18 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) { } TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { - gfx::Size viewport_size(20, 20); - float page_scale = 2.f; - - SetupScrollAndContentsLayers(viewport_size); - - // Setup the layers so that the outer viewport is scrollable. - host_impl_->InnerViewportScrollLayer()->test_properties()->parent->SetBounds( - viewport_size); - host_impl_->OuterViewportScrollLayer()->SetBounds(gfx::Size(40, 40)); + gfx::Size inner_viewport_size(20, 20); + gfx::Size outer_viewport_size(40, 40); + gfx::Size content_size(80, 80); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size, + outer_viewport_size, content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); - LayerImpl* root_container = host_impl_->OuterViewportContainerLayer(); - EXPECT_EQ(viewport_size, root_container->bounds()); - gfx::Vector2d scroll_delta(0, 10); gfx::ScrollOffset expected_scroll_delta(scroll_delta); - LayerImpl* root_scroll = host_impl_->OuterViewportScrollLayer(); - gfx::ScrollOffset expected_max_scroll = root_scroll->MaxScrollOffset(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + gfx::ScrollOffset expected_max_scroll = outer_scroll->MaxScrollOffset(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -6746,6 +6172,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { host_impl_->ScrollEnd(EndState().get()); // Set new page scale on impl thread by pinching. + float page_scale = 2.f; host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN); host_impl_->PinchGestureBegin(); @@ -6758,12 +6185,12 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { // The scroll delta is not scaled because the main thread did not scale. std::unique_ptr<ScrollAndScaleSet> scroll_info = host_impl_->ProcessScrollDeltas(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), inner_scroll->element_id(), expected_scroll_delta)); // The scroll range should also have been updated. - EXPECT_EQ(expected_max_scroll, root_scroll->MaxScrollOffset()); + EXPECT_EQ(expected_max_scroll, outer_scroll->MaxScrollOffset()); // The page scale delta should match the new scale on the impl side. EXPECT_EQ(page_scale, host_impl_->active_tree()->current_page_scale_factor()); @@ -6771,6 +6198,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) { TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); + gfx::Size viewport_size(5, 5); gfx::Size surface_size(10, 10); float default_page_scale = 1.f; gfx::Transform default_page_scale_matrix; @@ -6780,23 +6208,16 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { gfx::Transform new_page_scale_matrix; new_page_scale_matrix.Scale(new_page_scale, new_page_scale); - // Create a normal scrollable root layer and another scrollable child layer. - LayerImpl* scroll = SetupScrollAndContentsLayers(surface_size); - scroll->SetDrawsContent(true); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); - LayerImpl* child = scroll->test_properties()->children[0]; - child->SetDrawsContent(true); + SetupViewportLayersInnerScrolls(viewport_size, surface_size); + LayerImpl* root = root_layer(); + auto* inner_scroll = InnerViewportScrollLayer(); + auto* outer_scroll = OuterViewportScrollLayer(); - std::unique_ptr<LayerImpl> scrollable_child_clip = - LayerImpl::Create(host_impl_->active_tree(), 6); - std::unique_ptr<LayerImpl> scrollable_child = - CreateScrollableLayer(7, surface_size); - scrollable_child_clip->test_properties()->AddChild( - std::move(scrollable_child)); - child->test_properties()->AddChild(std::move(scrollable_child_clip)); - LayerImpl* grand_child = child->test_properties()->children[0]; - grand_child->SetDrawsContent(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + // Create a normal scrollable root layer and another scrollable child layer. + LayerImpl* scrollable_child_clip = AddLayer(); + CopyProperties(inner_scroll, scrollable_child_clip); + AddScrollableLayer(scrollable_child_clip, viewport_size, surface_size); + UpdateDrawProperties(host_impl_->active_tree()); // Set new page scale on impl thread by pinching. host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), @@ -6809,33 +6230,25 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) { // Make sure all the layers are drawn with the page scale delta applied, i.e., // the page scale delta on the root layer is applied hierarchically. - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(0, 0)); EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(1, 1)); - EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(0, 0)); - EXPECT_EQ(new_page_scale, scroll->DrawTransform().matrix().getDouble(1, 1)); - EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(0, 0)); - EXPECT_EQ(new_page_scale, child->DrawTransform().matrix().getDouble(1, 1)); EXPECT_EQ(new_page_scale, - grand_child->DrawTransform().matrix().getDouble(0, 0)); + inner_scroll->DrawTransform().matrix().getDouble(0, 0)); + EXPECT_EQ(new_page_scale, + inner_scroll->DrawTransform().matrix().getDouble(1, 1)); + EXPECT_EQ(new_page_scale, + outer_scroll->DrawTransform().matrix().getDouble(0, 0)); EXPECT_EQ(new_page_scale, - grand_child->DrawTransform().matrix().getDouble(1, 1)); + outer_scroll->DrawTransform().matrix().getDouble(1, 1)); } TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { - SetupScrollAndContentsLayers(gfx::Size(30, 30)); - - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - - // Make the outer scroll layer scrollable. - outer_scroll->SetBounds(gfx::Size(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupViewportLayers(host_impl_->active_tree(), gfx::Size(15, 15), + gfx::Size(30, 30), gfx::Size(50, 50)); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DrawFrame(); gfx::Vector2d scroll_delta(0, 10); @@ -6852,8 +6265,6 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) { float page_scale = 2.f; host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, page_scale); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawOneFrame(); std::unique_ptr<ScrollAndScaleSet> scroll_info = @@ -6875,21 +6286,14 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - LayerImpl* root = - CreateBasicVirtualViewportLayers(surface_size, surface_size); - - root->test_properties()->force_render_surface = true; - - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size); + SetupViewportLayersNoScrolls(surface_size); + LayerImpl* top = AddContentLayer(); + CreateEffectNode(top).render_surface_reason = RenderSurfaceReason::kTest; + LayerImpl* child_layer = AddScrollableLayer(top, surface_size, content_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, surface_size, content_size); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); - - LayerImpl* child_layer = child.get(); - root->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); grand_child_layer->layer_tree_impl() @@ -6901,7 +6305,6 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(3, 0)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { gfx::Vector2d scroll_delta(-8, -7); @@ -6932,20 +6335,14 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { gfx::Size surface_size(100, 100); gfx::Size content_size(150, 150); - LayerImpl* root = - CreateBasicVirtualViewportLayers(surface_size, surface_size); - root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(13, content_size); - - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(12, content_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); + SetupViewportLayersNoScrolls(surface_size); + LayerImpl* top = AddContentLayer(); + CreateEffectNode(top).render_surface_reason = RenderSurfaceReason::kTest; + LayerImpl* child_layer = AddScrollableLayer(top, surface_size, content_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, surface_size, content_size); - LayerImpl* child_layer = child.get(); - root->test_properties()->AddChild(std::move(child)); - host_impl_->active_tree()->SetElementIdsForTesting(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); grand_child_layer->layer_tree_impl() @@ -6957,7 +6354,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedLatchToChild) { ->scroll_tree.UpdateScrollOffsetBaseForTesting(child_layer->element_id(), gfx::ScrollOffset(0, 50)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); base::TimeTicks start_time = @@ -7027,43 +6423,13 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { // the scroll doesn't bubble up to the parent layer. gfx::Size surface_size(20, 20); gfx::Size viewport_size(10, 10); - const int kRootLayerId = 1; - const int kPageScaleLayerId = 2; - const int kViewportClipLayerId = 3; - const int kViewportScrollLayerId = 4; - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), kRootLayerId); - std::unique_ptr<LayerImpl> page_scale = - LayerImpl::Create(host_impl_->active_tree(), kPageScaleLayerId); - std::unique_ptr<LayerImpl> root_clip = - LayerImpl::Create(host_impl_->active_tree(), kViewportClipLayerId); - root_clip->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> root_scrolling = - CreateScrollableLayer(kViewportScrollLayerId, surface_size); - root_scrolling->test_properties()->is_container_for_fixed_position_layers = - true; - - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(5, surface_size); - - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(6, surface_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); - - LayerImpl* child_layer = child.get(); - root_scrolling->test_properties()->AddChild(std::move(child)); - root_clip->test_properties()->AddChild(std::move(root_scrolling)); - page_scale->test_properties()->AddChild(std::move(root_clip)); - root_ptr->test_properties()->AddChild(std::move(page_scale)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = kPageScaleLayerId; - viewport_ids.inner_viewport_container = kViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kViewportScrollLayerId; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersNoScrolls(surface_size); + LayerImpl* child_layer = AddScrollableLayer(InnerViewportScrollLayer(), + viewport_size, surface_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, viewport_size, surface_size); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); grand_child_layer->layer_tree_impl() ->property_trees() @@ -7174,30 +6540,18 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) { } // Ensure that layers who's scroll parent is the InnerViewportScrollNode are -// still able to scroll on thte compositor. +// still able to scroll on the compositor. TEST_F(LayerTreeHostImplTest, ChildrenOfInnerScrollNodeCanScrollOnThread) { gfx::Size viewport_size(10, 10); gfx::Size content_size(20, 20); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - - constexpr int kFixedLayerId = 300; + SetupViewportLayersOuterScrolls(viewport_size, content_size); // Simulate adding a "fixed" layer to the tree. { - std::unique_ptr<LayerImpl> fixed_layer = - LayerImpl::Create(host_impl_->active_tree(), kFixedLayerId); + LayerImpl* fixed_layer = AddLayer(); fixed_layer->SetBounds(viewport_size); fixed_layer->SetDrawsContent(true); - content_layer->test_properties()->AddChild(std::move(fixed_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - // This is very hackish but we want to simulate the kind of property tree - // that blink would create where a fixed layer's ScrollNode is parented to - // the inner viewport, rather than the outer. - host_impl_->active_tree() - ->LayerById(kFixedLayerId) - ->SetScrollTreeIndex( - host_impl_->active_tree()->InnerViewportScrollNode()->id); + CopyProperties(InnerViewportScrollLayer(), fixed_layer); } host_impl_->active_tree()->DidBecomeActive(); @@ -7221,8 +6575,7 @@ TEST_F(LayerTreeHostImplTest, ChildrenOfInnerScrollNodeCanScrollOnThread) { // The outer viewport should have scrolled. ASSERT_EQ(scroll_info->scrolls.size(), 1u); EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), - host_impl_->active_tree()->OuterViewportScrollNode()->element_id, + *scroll_info.get(), host_impl_->OuterViewportScrollNode()->element_id, scroll_delta)); } } @@ -7232,26 +6585,14 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { // should be applied to one of its ancestors if possible. gfx::Size viewport_size(10, 10); gfx::Size content_size(20, 20); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - - constexpr int kScrollChildClipId = 300; - constexpr int kScrollChildScrollId = 301; + SetupViewportLayersOuterScrolls(viewport_size, content_size); // Add a scroller whose scroll bounds and scroll container bounds are equal. // Since the max_scroll_offset is 0, scrolls will bubble. - std::unique_ptr<LayerImpl> scroll_child_clip = - LayerImpl::Create(host_impl_->active_tree(), kScrollChildClipId); - std::unique_ptr<LayerImpl> scroll_child = - CreateScrollableLayer(kScrollChildScrollId, gfx::Size(10, 10)); - scroll_child->test_properties()->is_container_for_fixed_position_layers = - true; - scroll_child->SetScrollable(gfx::Size(10, 10)); - - scroll_child_clip->test_properties()->AddChild(std::move(scroll_child)); - content_layer->test_properties()->AddChild(std::move(scroll_child_clip)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* scroll_child_clip = AddContentLayer(); + AddScrollableLayer(scroll_child_clip, gfx::Size(10, 10), gfx::Size(10, 10)); + + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); { @@ -7272,87 +6613,23 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) { // Only the root scroll should have scrolled. ASSERT_EQ(scroll_info->scrolls.size(), 1u); EXPECT_TRUE(ScrollInfoContains( - *scroll_info.get(), - host_impl_->active_tree()->OuterViewportScrollNode()->element_id, + *scroll_info.get(), host_impl_->OuterViewportScrollNode()->element_id, scroll_delta)); } } TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { - const int kRootLayerId = 1; - const int kInnerViewportClipLayerId = 2; - const int kOuterViewportClipLayerId = 7; - const int kInnerViewportScrollLayerId = 3; - const int kOuterViewportScrollLayerId = 8; gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> root_ptr = - LayerImpl::Create(host_impl_->active_tree(), kRootLayerId); - std::unique_ptr<LayerImpl> inner_clip = - LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); - std::unique_ptr<LayerImpl> inner_scroll = - CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); - std::unique_ptr<LayerImpl> outer_clip = - LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId); - std::unique_ptr<LayerImpl> outer_scroll = - CreateScrollableLayer(kOuterViewportScrollLayerId, surface_size); - inner_clip->test_properties()->force_render_surface = true; - inner_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - outer_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - outer_clip->test_properties()->AddChild(std::move(outer_scroll)); - inner_scroll->test_properties()->AddChild(std::move(outer_clip)); - inner_clip->test_properties()->AddChild(std::move(inner_scroll)); - root_ptr->test_properties()->AddChild(std::move(inner_clip)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.outer_viewport_container = kOuterViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - viewport_ids.outer_viewport_scroll = kOuterViewportScrollLayerId; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersNoScrolls(surface_size); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); - // Draw one frame and then immediately rebuild the layer tree to mimic a tree // synchronization. DrawFrame(); - const int kInnerViewportClipLayerId2 = 5; - const int kOuterViewportClipLayerId2 = 9; - const int kInnerViewportScrollLayerId2 = 6; - const int kOuterViewportScrollLayerId2 = 10; - host_impl_->active_tree()->DetachLayers(); - std::unique_ptr<LayerImpl> root_ptr2 = - LayerImpl::Create(host_impl_->active_tree(), 4); - std::unique_ptr<LayerImpl> inner_clip2 = - LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId2); - std::unique_ptr<LayerImpl> inner_scroll2 = - CreateScrollableLayer(kInnerViewportScrollLayerId2, surface_size); - std::unique_ptr<LayerImpl> outer_clip2 = - LayerImpl::Create(host_impl_->active_tree(), kOuterViewportClipLayerId2); - std::unique_ptr<LayerImpl> outer_scroll2 = - CreateScrollableLayer(kOuterViewportScrollLayerId2, surface_size); - inner_scroll2->test_properties()->is_container_for_fixed_position_layers = - true; - outer_scroll2->test_properties()->is_container_for_fixed_position_layers = - true; - outer_clip2->test_properties()->AddChild(std::move(outer_scroll2)); - inner_scroll2->test_properties()->AddChild(std::move(outer_clip2)); - inner_clip2->test_properties()->AddChild(std::move(inner_scroll2)); - inner_clip2->test_properties()->force_render_surface = true; - root_ptr2->test_properties()->AddChild(std::move(inner_clip2)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_ptr2)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - LayerTreeImpl::ViewportLayerIds viewport_ids2; - viewport_ids2.inner_viewport_container = kInnerViewportClipLayerId2; - viewport_ids2.outer_viewport_container = kOuterViewportClipLayerId2; - viewport_ids2.inner_viewport_scroll = kInnerViewportScrollLayerId2; - viewport_ids2.outer_viewport_scroll = kOuterViewportScrollLayerId2; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids2); - host_impl_->active_tree()->DidBecomeActive(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); + SetupViewportLayersNoScrolls(surface_size); // Scrolling should still work even though we did not draw yet. EXPECT_EQ( @@ -7363,7 +6640,8 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { } TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->SetDrawsContent(true); // Rotate the root layer 90 degrees counter-clockwise about its center. @@ -7371,10 +6649,6 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { rotate_transform.Rotate(-90.0); // Set external transform. host_impl_->OnDraw(rotate_transform, gfx::Rect(0, 0, 50, 50), false, false); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll to the right in screen coordinates with a gesture. @@ -7414,43 +6688,35 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) { } TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - int child_clip_layer_id = 6; - int child_layer_id = 7; + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); float child_layer_angle = -20.f; // Create a child layer that is rotated to a non-axis-aligned angle. - std::unique_ptr<LayerImpl> clip_layer = - LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); + // Only allow vertical scrolling. + gfx::Size content_size = scroll_layer->bounds(); + gfx::Size scroll_container_bounds(content_size.width(), + content_size.height() / 2); + LayerImpl* clip_layer = AddLayer(); + clip_layer->SetBounds(scroll_container_bounds); + CopyProperties(scroll_layer, clip_layer); gfx::Transform rotate_transform; rotate_transform.Translate(-50.0, -50.0); rotate_transform.Rotate(child_layer_angle); rotate_transform.Translate(50.0, 50.0); - clip_layer->test_properties()->transform = rotate_transform; - - // Only allow vertical scrolling. - gfx::Size scroll_container_bounds = - gfx::Size(child->bounds().width(), child->bounds().height() / 2); - clip_layer->SetBounds(scroll_container_bounds); - child->SetScrollable(scroll_container_bounds); - child->SetHitTestable(true); + auto& clip_layer_transform_node = CreateTransformNode(clip_layer); // The rotation depends on the layer's transform origin, and the child layer // is a different size than the clip, so make sure the clip layer's origin // lines up over the child. - clip_layer->test_properties()->transform_origin = gfx::Point3F( + clip_layer_transform_node.origin = gfx::Point3F( clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f); - LayerImpl* child_ptr = child.get(); - clip_layer->test_properties()->AddChild(std::move(child)); - // TODO(pdr): Shouldn't clip_layer be scroll_layer's parent? - scroll_layer->test_properties()->AddChild(std::move(clip_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + clip_layer_transform_node.local = rotate_transform; + + LayerImpl* child = + AddScrollableLayer(clip_layer, scroll_container_bounds, content_size); - ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id); + ElementId child_scroll_id = child->element_id(); - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { // Scroll down in screen coordinates with a gesture. @@ -7479,7 +6745,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { } { // Now reset and scroll the same amount horizontally. - SetScrollOffsetDelta(child_ptr, gfx::Vector2dF()); + SetScrollOffsetDelta(child, gfx::Vector2dF()); gfx::Vector2d gesture_scroll_delta(10, 0); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -7507,36 +6773,30 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) { TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { // When scrolling an element with perspective, the distance scrolled // depends on the point at which the scroll begins. - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - int child_clip_layer_id = 6; - int child_layer_id = 7; + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); // Create a child layer that is rotated on its x axis, with perspective. - std::unique_ptr<LayerImpl> clip_layer = - LayerImpl::Create(host_impl_->active_tree(), child_clip_layer_id); - std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(child_layer_id, scroll_layer->bounds()); - LayerImpl* child_ptr = child.get(); + LayerImpl* clip_layer = AddLayer(); + clip_layer->SetBounds(gfx::Size(50, 50)); + CopyProperties(scroll_layer, clip_layer); gfx::Transform perspective_transform; perspective_transform.Translate(-50.0, -50.0); perspective_transform.ApplyPerspectiveDepth(20); perspective_transform.RotateAboutXAxis(45); perspective_transform.Translate(50.0, 50.0); - clip_layer->test_properties()->transform = perspective_transform; - - clip_layer->SetBounds(gfx::Size(child_ptr->bounds().width() / 2, - child_ptr->bounds().height() / 2)); + auto& clip_layer_transform_node = CreateTransformNode(clip_layer); // The transform depends on the layer's transform origin, and the child layer // is a different size than the clip, so make sure the clip layer's origin // lines up over the child. - clip_layer->test_properties()->transform_origin = gfx::Point3F( + clip_layer_transform_node.origin = gfx::Point3F( clip_layer->bounds().width(), clip_layer->bounds().height(), 0.f); - clip_layer->test_properties()->AddChild(std::move(child)); - scroll_layer->test_properties()->AddChild(std::move(clip_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + clip_layer_transform_node.local = perspective_transform; + + LayerImpl* child = AddScrollableLayer(clip_layer, clip_layer->bounds(), + scroll_layer->bounds()); - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); + UpdateDrawProperties(host_impl_->active_tree()); std::unique_ptr<ScrollAndScaleSet> scroll_info; @@ -7562,7 +6822,7 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { // where the previous scroll ended, but the scroll position is reset // for each scroll. for (int i = 0; i < 4; ++i) { - SetScrollOffsetDelta(child_ptr, gfx::Vector2dF()); + SetScrollOffsetDelta(child, gfx::Vector2dF()); DrawFrame(); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -7578,8 +6838,7 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { host_impl_->ScrollEnd(EndState().get()); scroll_info = host_impl_->ProcessScrollDeltas(); - ElementId child_scroll_id = LayerIdToElementIdForTesting(child_layer_id); - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child_scroll_id, + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(), expected_scroll_deltas[i])); // The root scroll layer should not have scrolled, because the input delta @@ -7589,7 +6848,8 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) { } TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); // Scale the layer to twice its normal size. int scale = 2; @@ -7597,10 +6857,6 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) { scale_transform.Scale(scale, scale); // Set external transform above root. host_impl_->OnDraw(scale_transform, gfx::Rect(0, 0, 50, 50), false, false); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - gfx::Size surface_size(50, 50); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); // Scroll down in screen coordinates with a gesture. @@ -7644,33 +6900,23 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) { int width = 332; int height = 20; int scale = 3; - SetupScrollAndContentsLayers(gfx::Size(width, height)); gfx::Size container_bounds = gfx::Size(width * scale - 1, height * scale); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - container_bounds); - host_impl_->active_tree()->InnerViewportScrollLayer()->SetScrollable( - container_bounds); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(container_bounds, gfx::Size(width, height)); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->SetDeviceScaleFactor(scale); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); - LayerImpl* inner_viewport_scroll_layer = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* inner_viewport_scroll_layer = InnerViewportScrollLayer(); EXPECT_EQ(gfx::ScrollOffset(0, 0), inner_viewport_scroll_layer->MaxScrollOffset()); } TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { TestInputHandlerClient scroll_watcher; - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 20)); - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - LayerImpl* clip_layer = - scroll_layer->test_properties()->parent->test_properties()->parent; - clip_layer->SetBounds(gfx::Size(10, 20)); - scroll_layer->SetScrollable(gfx::Size(10, 20)); - scroll_layer->SetHitTestable(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(10, 20), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->BindToClient(&scroll_watcher); @@ -7752,13 +6998,14 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) { // Forces a full tree synchronization and ensures that the scroll delegate // sees the correct size of the new tree. - gfx::Size new_size(42, 24); + gfx::Size new_viewport_size(21, 12); + gfx::Size new_content_size(42, 24); CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), new_size); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), new_viewport_size, + new_content_size, new_content_size); host_impl_->ActivateSyncTree(); - EXPECT_EQ(gfx::SizeF(new_size), scroll_watcher.scrollable_size()); + EXPECT_EQ(gfx::SizeF(new_content_size), scroll_watcher.scrollable_size()); // Tear down the LayerTreeHostImpl before the InputHandlerClient. host_impl_->ReleaseLayerTreeFrameSink(); @@ -7777,13 +7024,8 @@ void CheckLayerScrollDelta(LayerImpl* layer, gfx::Vector2dF scroll_delta) { TEST_F(LayerTreeHostImplTest, ExternalRootLayerScrollOffsetDelegationReflectedInNextDraw) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 20)); - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); - LayerImpl* clip_layer = - scroll_layer->test_properties()->parent->test_properties()->parent; - clip_layer->SetBounds(gfx::Size(10, 20)); - scroll_layer->SetScrollable(gfx::Size(10, 20)); - scroll_layer->SetHitTestable(true); + SetupViewportLayersInnerScrolls(gfx::Size(10, 20), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->SetDrawsContent(true); // Draw first frame to clear any pending draws and check scroll. @@ -7794,7 +7036,8 @@ TEST_F(LayerTreeHostImplTest, // Set external scroll delta on delegate and notify LayerTreeHost. gfx::ScrollOffset scroll_offset(10.f, 10.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f)); + EXPECT_TRUE(host_impl_->active_tree()->needs_update_draw_properties()); // Check scroll delta reflected in layer. TestFrameData frame; @@ -7812,17 +7055,16 @@ TEST_F(LayerTreeHostImplTest, TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { gfx::Size viewport_size(100, 100); gfx::Size content_size(200, 200); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - auto* outer_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - auto* inner_scroll = host_impl_->active_tree()->InnerViewportScrollLayer(); + auto* outer_scroll = OuterViewportScrollLayer(); + auto* inner_scroll = InnerViewportScrollLayer(); ScrollTree& scroll_tree = host_impl_->active_tree()->property_trees()->scroll_tree; ElementId inner_element_id = inner_scroll->element_id(); ElementId outer_element_id = outer_scroll->element_id(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); // Ensure that the scroll offset is interpreted as a content offset so it @@ -7835,9 +7077,8 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { // Disable scrolling the inner viewport. Only the outer should scroll. { ASSERT_FALSE(did_request_redraw_); - inner_scroll->test_properties()->user_scrollable_vertical = false; - inner_scroll->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(inner_scroll)->user_scrollable_vertical = false; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = false; gfx::ScrollOffset scroll_offset(25.f, 30.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7849,18 +7090,17 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { // Reset did_request_redraw_ = false; - inner_scroll->test_properties()->user_scrollable_vertical = true; - inner_scroll->test_properties()->user_scrollable_horizontal = true; - outer_scroll->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0)); + GetScrollNode(inner_scroll)->user_scrollable_vertical = true; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = true; + SetScrollOffset(outer_scroll, gfx::ScrollOffset(0, 0)); } // Disable scrolling the outer viewport. The inner should scroll to its // extent but there should be no bubbling over to the outer viewport. { ASSERT_FALSE(did_request_redraw_); - outer_scroll->test_properties()->user_scrollable_vertical = false; - outer_scroll->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(outer_scroll)->user_scrollable_vertical = false; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = false; gfx::ScrollOffset scroll_offset(120.f, 140.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7872,20 +7112,19 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { // Reset did_request_redraw_ = false; - inner_scroll->test_properties()->user_scrollable_vertical = true; - inner_scroll->test_properties()->user_scrollable_horizontal = true; - inner_scroll->SetCurrentScrollOffset(gfx::ScrollOffset(0, 0)); + GetScrollNode(outer_scroll)->user_scrollable_vertical = true; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = true; + SetScrollOffset(inner_scroll, gfx::ScrollOffset(0, 0)); } // Disable both viewports. No scrolling should take place, no redraw should // be requested. { ASSERT_FALSE(did_request_redraw_); - outer_scroll->test_properties()->user_scrollable_vertical = false; - outer_scroll->test_properties()->user_scrollable_horizontal = false; - inner_scroll->test_properties()->user_scrollable_vertical = false; - inner_scroll->test_properties()->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(inner_scroll)->user_scrollable_vertical = false; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = false; + GetScrollNode(outer_scroll)->user_scrollable_vertical = false; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = false; gfx::ScrollOffset scroll_offset(60.f, 70.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7896,20 +7135,19 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { EXPECT_FALSE(did_request_redraw_); // Reset - inner_scroll->test_properties()->user_scrollable_vertical = true; - inner_scroll->test_properties()->user_scrollable_horizontal = true; - outer_scroll->test_properties()->user_scrollable_vertical = true; - outer_scroll->test_properties()->user_scrollable_horizontal = true; + GetScrollNode(inner_scroll)->user_scrollable_vertical = true; + GetScrollNode(inner_scroll)->user_scrollable_horizontal = true; + GetScrollNode(outer_scroll)->user_scrollable_vertical = true; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = true; } // If the inner is at its extent but the outer cannot scroll, we shouldn't // request a redraw. { ASSERT_FALSE(did_request_redraw_); - outer_scroll->test_properties()->user_scrollable_vertical = false; - outer_scroll->test_properties()->user_scrollable_horizontal = false; - inner_scroll->SetCurrentScrollOffset(gfx::ScrollOffset(50.f, 50.f)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(outer_scroll)->user_scrollable_vertical = false; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = false; + SetScrollOffset(inner_scroll, gfx::ScrollOffset(50.f, 50.f)); gfx::ScrollOffset scroll_offset(60.f, 70.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7920,18 +7158,15 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) { EXPECT_FALSE(did_request_redraw_); // Reset - outer_scroll->test_properties()->user_scrollable_vertical = true; - outer_scroll->test_properties()->user_scrollable_horizontal = true; + GetScrollNode(outer_scroll)->user_scrollable_vertical = true; + GetScrollNode(outer_scroll)->user_scrollable_horizontal = true; } } // The SetSynchronousInputHandlerRootScrollOffset API can be called while there // is no inner viewport set. This test passes if we don't crash. TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetNoViewportCrash) { - host_impl_->active_tree()->ClearViewportLayers(); - host_impl_->active_tree()->DidBecomeActive(); - - auto* inner_scroll = host_impl_->active_tree()->InnerViewportScrollLayer(); + auto* inner_scroll = InnerViewportScrollLayer(); ASSERT_FALSE(inner_scroll); gfx::ScrollOffset scroll_offset(25.f, 30.f); host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset); @@ -7939,10 +7174,8 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetNoViewportCrash) { TEST_F(LayerTreeHostImplTest, OverscrollRoot) { InputHandlerScrollResult scroll_result; - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); @@ -8071,33 +7304,21 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { // Scroll child layers beyond their maximum scroll range and make sure root // overscroll does not accumulate. InputHandlerScrollResult scroll_result; + gfx::Size scroll_container_size(5, 5); gfx::Size surface_size(10, 10); - const int kInnerViewportClipLayerId = 4; - const int kInnerViewportScrollLayerId = 1; - std::unique_ptr<LayerImpl> root_clip = - LayerImpl::Create(host_impl_->active_tree(), kInnerViewportClipLayerId); - root_clip->test_properties()->force_render_surface = true; - - std::unique_ptr<LayerImpl> root = - CreateScrollableLayer(kInnerViewportScrollLayerId, surface_size); - - std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(3, surface_size); - - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(2, surface_size); - LayerImpl* grand_child_layer = grand_child.get(); - child->test_properties()->AddChild(std::move(grand_child)); - - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - host_impl_->active_tree()->SetViewportLayersFromIds(viewport_ids); - - LayerImpl* child_layer = child.get(); - root->test_properties()->AddChild(std::move(child)); - root_clip->test_properties()->AddChild(std::move(root)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* root_clip = SetupDefaultRootLayer(surface_size); + LayerImpl* root = + AddScrollableLayer(root_clip, scroll_container_size, surface_size); + LayerImpl* child_layer = + AddScrollableLayer(root, scroll_container_size, surface_size); + LayerImpl* grand_child_layer = + AddScrollableLayer(child_layer, scroll_container_size, surface_size); + + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.inner_scroll = root->scroll_tree_index(); + host_impl_->active_tree()->SetViewportPropertyIds(viewport_property_ids); + + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->DidBecomeActive(); child_layer->layer_tree_impl() @@ -8109,7 +7330,6 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { ->scroll_tree.UpdateScrollOffsetBaseForTesting( grand_child_layer->element_id(), gfx::ScrollOffset(0, 2)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(surface_size)); DrawFrame(); { gfx::Vector2d scroll_delta(0, -10); @@ -8177,9 +7397,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) { // should be applied to one of its ancestors if possible. Overscroll should // be reflected only when it has bubbled up to the root scrolling layer. InputHandlerScrollResult scroll_result; - SetupScrollAndContentsLayers(gfx::Size(20, 20)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupViewportLayersInnerScrolls(gfx::Size(10, 10), gfx::Size(20, 20)); DrawFrame(); { gfx::Vector2d scroll_delta(0, 8); @@ -8212,16 +7430,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) { LayerTreeSettings settings = DefaultSettings(); CreateHostImpl(settings, CreateLayerTreeFrameSink()); - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(50, 50)); - LayerImpl* clip_layer = - scroll_layer->test_properties()->parent->test_properties()->parent; + SetupViewportLayersNoScrolls(gfx::Size(50, 50)); + UpdateDrawProperties(host_impl_->active_tree()); - clip_layer->SetBounds(gfx::Size(50, 50)); - scroll_layer->SetScrollable(gfx::Size(50, 50)); - scroll_layer->SetHitTestable(true); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); DrawFrame(); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); @@ -8243,13 +7454,7 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { InputHandlerScrollResult scroll_result; gfx::Size viewport_size(100, 100); gfx::Size content_size(200, 200); - LayerImpl* root_scroll_layer = - CreateBasicVirtualViewportLayers(viewport_size, viewport_size); - host_impl_->active_tree()->OuterViewportScrollLayer()->SetBounds( - content_size); - root_scroll_layer->SetBounds(content_size); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); { // Edge glow effect should be applicable only upon reaching Edges @@ -8315,27 +7520,12 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnNonViewportLayers) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* scroll_layer = nullptr; - + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); // Initialization: Add a nested scrolling layer, simulating a scrolling div. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - scroll_layer = scroll.get(); - - content_layer->test_properties()->AddChild(std::move(scroll)); - layer_tree_impl->BuildPropertyTreesForTesting(); - } + LayerImpl* scroll_layer = + AddScrollableLayer(content_layer, content_size, gfx::Size(400, 400)); InputHandlerScrollResult scroll_result; DrawFrame(); @@ -8387,23 +7577,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) { LayerTreeSettings settings = DefaultSettings(); CreateHostImpl(settings, CreateLayerTreeFrameSink()); - const gfx::Size content_size(50, 50); const gfx::Size viewport_size(50, 50); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersNoScrolls(viewport_size); - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->main_thread_scrolling_reasons = + GetScrollNode(InnerViewportScrollLayer())->main_thread_scrolling_reasons = MainThreadScrollingReason::kThreadedScrollingDisabled; - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->main_thread_scrolling_reasons = + GetScrollNode(OuterViewportScrollLayer())->main_thread_scrolling_reasons = MainThreadScrollingReason::kThreadedScrollingDisabled; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); // Overscroll initiated outside layers will be handled by the main thread. @@ -8430,47 +7611,25 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) { TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) { const gfx::Size viewport_size(100, 100); - LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - - CreateBasicVirtualViewportLayers(viewport_size, viewport_size); + SetupViewportLayersNoScrolls(viewport_size); host_impl_->active_tree()->SetTopControlsHeight(10); host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); - - LayerImpl* scroll_layer = nullptr; + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Create a scrolling layer that's parented directly to the inner viewport. // This will test that scrolls that chain up to the inner viewport without // passing through the outer viewport still scroll correctly and affect // browser controls. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollable(viewport_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); + LayerImpl* scroll_layer = AddScrollableLayer( + inner_scroll_layer, viewport_size, gfx::Size(400, 400)); - scroll_layer = scroll.get(); - - inner_scroll_layer->test_properties()->AddChild(std::move(scroll)); - - // Move the outer viewport layer away so that scrolls won't target it. - host_impl_->active_tree() - ->OuterViewportContainerLayer() - ->test_properties() - ->position = gfx::PointF(400, 400); - - layer_tree_impl->BuildPropertyTreesForTesting(); - - float min_page_scale = 1.f, max_page_scale = 4.f; - float page_scale_factor = 2.f; - host_impl_->active_tree()->PushPageScaleFromMainThread( - page_scale_factor, min_page_scale, max_page_scale); - host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - } + float min_page_scale = 1.f, max_page_scale = 4.f; + float page_scale_factor = 2.f; + host_impl_->active_tree()->PushPageScaleFromMainThread( + page_scale_factor, min_page_scale, max_page_scale); + host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor); // Fully scroll the child. { @@ -8523,44 +7682,24 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) { LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); - - LayerImpl* scroll_layer = nullptr; - LayerImpl* child_scroll_layer = nullptr; + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); // Initialization: Add two nested scrolling layers, simulating a scrolling div // with another scrolling div inside it. Set the outer "div" to be the outer // viewport. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(400, 400)); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 13); - scroll2->SetBounds(gfx::Size(500, 500)); - scroll2->SetScrollable(gfx::Size(300, 300)); - scroll2->SetHitTestable(true); - scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); - scroll2->SetDrawsContent(true); - - scroll_layer = scroll.get(); - child_scroll_layer = scroll2.get(); - - scroll->test_properties()->AddChild(std::move(scroll2)); - content_layer->test_properties()->AddChild(std::move(scroll)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); - viewport_ids.inner_viewport_scroll = inner_scroll_layer->id(); - viewport_ids.outer_viewport_scroll = scroll_layer->id(); - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - layer_tree_impl->BuildPropertyTreesForTesting(); - } + LayerImpl* scroll_layer = + AddScrollableLayer(content_layer, content_size, gfx::Size(400, 400)); + GetScrollNode(scroll_layer)->scrolls_outer_viewport = true; + LayerImpl* child_scroll_layer = AddScrollableLayer( + scroll_layer, gfx::Size(300, 300), gfx::Size(500, 500)); + + auto viewport_property_ids = layer_tree_impl->ViewportPropertyIdsForTesting(); + viewport_property_ids.outer_scroll = scroll_layer->scroll_tree_index(); + layer_tree_impl->SetViewportPropertyIds(viewport_property_ids); + UpdateDrawProperties(layer_tree_impl); // Scroll should target the nested scrolling layer in the content and then // chain to the parent scrolling layer which is now set as the outer @@ -8639,6 +7778,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) { scroll_layer->CurrentScrollOffset()); } } + // Test that scrolls chain correctly when a child scroller on the page (e.g. a // scrolling div) is set as the outer viewport but scrolls start from a layer // that's not a descendant of the outer viewport. This happens in the @@ -8649,52 +7789,25 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) { LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); - - LayerImpl* outer_scroll_layer = nullptr; - LayerImpl* sibling_scroll_layer = nullptr; + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); // Initialization: Add a scrolling layer, simulating an ordinary DIV, to be // set as the outer viewport. Add a sibling scrolling layer that isn't a child // of the outer viewport scroll layer. - { - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(gfx::Size(1200, 1200)); - scroll->SetScrollable(content_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - outer_scroll_layer = scroll.get(); + LayerImpl* outer_scroll_layer = + AddScrollableLayer(content_layer, content_size, gfx::Size(1200, 1200)); + GetScrollNode(outer_scroll_layer)->scrolls_outer_viewport = true; + LayerImpl* sibling_scroll_layer = AddScrollableLayer( + content_layer, gfx::Size(600, 600), gfx::Size(1200, 1200)); - content_layer->test_properties()->AddChild(std::move(scroll)); + auto viewport_property_ids = layer_tree_impl->ViewportPropertyIdsForTesting(); + viewport_property_ids.outer_scroll = outer_scroll_layer->scroll_tree_index(); + layer_tree_impl->SetViewportPropertyIds(viewport_property_ids); - // Create the non-descendant. - std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 15); - scroll2->SetBounds(gfx::Size(1200, 1200)); - scroll2->SetScrollable(gfx::Size(600, 600)); - scroll2->SetHitTestable(true); - scroll2->SetElementId(LayerIdToElementIdForTesting(scroll2->id())); - scroll2->SetDrawsContent(true); - - sibling_scroll_layer = scroll2.get(); - - content_layer->test_properties()->AddChild(std::move(scroll2)); - - LayerImpl* inner_container = - host_impl_->active_tree()->InnerViewportContainerLayer(); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); - viewport_ids.inner_viewport_container = inner_container->id(); - viewport_ids.inner_viewport_scroll = inner_scroll_layer->id(); - viewport_ids.outer_viewport_scroll = outer_scroll_layer->id(); - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - layer_tree_impl->BuildPropertyTreesForTesting(); - - ASSERT_EQ(outer_scroll_layer, layer_tree_impl->OuterViewportScrollLayer()); - } + ASSERT_EQ(outer_scroll_layer, + layer_tree_impl->OuterViewportScrollLayerForTesting()); // Scrolls should target the non-descendant scroller. Chaining should not // propagate to the outer viewport scroll layer. @@ -8819,12 +7932,10 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) { CreateHostImpl(settings, CreateLayerTreeFrameSink()); const gfx::Size content_size(50, 50); - const gfx::Size viewport_size(50, 50); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersNoScrolls(content_size); // By default, no main thread scrolling reasons should exist. - LayerImpl* scroll_layer = - host_impl_->active_tree()->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); ScrollNode* scroll_node = host_impl_->active_tree()->property_trees()->scroll_tree.Node( scroll_layer->scroll_tree_index()); @@ -8854,6 +7965,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) { class BlendStateCheckLayer : public LayerImpl { public: + static std::unique_ptr<BlendStateCheckLayer> Create( + LayerTreeImpl* tree_impl, + int id, + viz::ClientResourceProvider* resource_provider) { + return base::WrapUnique( + new BlendStateCheckLayer(tree_impl, id, resource_provider)); + } + BlendStateCheckLayer(LayerTreeImpl* tree_impl, int id, viz::ClientResourceProvider* resource_provider) @@ -8935,93 +8054,63 @@ class BlendStateCheckLayer : public LayerImpl { }; TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { - { - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(false); - root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - } - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); + root->SetDrawsContent(false); - root->test_properties()->AddChild(std::make_unique<BlendStateCheckLayer>( - host_impl_->active_tree(), 2, host_impl_->resource_provider())); - auto* layer1 = - static_cast<BlendStateCheckLayer*>(root->test_properties()->children[0]); - layer1->test_properties()->position = gfx::PointF(2.f, 2.f); - - TestFrameData frame; + auto* layer1 = AddLayer<BlendStateCheckLayer>( + host_impl_->active_tree(), host_impl_->resource_provider()); + CopyProperties(root, layer1); + CreateTransformNode(layer1).post_translation = gfx::Vector2dF(2.f, 2.f); + CreateEffectNode(layer1); // Opaque layer, drawn without blending. layer1->SetContentsOpaque(true); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with translucent content and painting, so drawn with blending. layer1->SetContentsOpaque(false); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with translucent opacity, drawn with blending. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 0.5f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 0.5f); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with translucent opacity and painting, drawn with blending. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 0.5f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 0.5f); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); - layer1->test_properties()->AddChild(std::make_unique<BlendStateCheckLayer>( - host_impl_->active_tree(), 3, host_impl_->resource_provider())); - auto* layer2 = static_cast<BlendStateCheckLayer*>( - layer1->test_properties()->children[0]); - layer2->test_properties()->position = gfx::PointF(4.f, 4.f); + auto* layer2 = AddLayer<BlendStateCheckLayer>( + host_impl_->active_tree(), host_impl_->resource_provider()); + CopyProperties(layer1, layer2); + CreateTransformNode(layer2).post_translation = gfx::Vector2dF(4.f, 4.f); + CreateEffectNode(layer2); // 2 opaque layers, drawn without blending. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); - layer2->test_properties()->opacity = 1.f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 1.f); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Parent layer with translucent content, drawn with blending. // Child layer with opaque content, drawn without blending. @@ -9030,13 +8119,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Parent layer with translucent content but opaque painting, drawn without // blending. @@ -9046,12 +8131,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Parent layer with translucent opacity and opaque content. Since it has a // drawing child, it's drawn to a render surface which carries the opacity, @@ -9059,76 +8141,57 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { // Child layer with opaque content, drawn without blending (parent surface // carries the inherited opacity). layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 0.5f; - layer1->NoteLayerPropertyChanged(); - layer1->test_properties()->force_render_surface = true; + SetOpacity(layer1, 0.5f); + GetEffectNode(layer1)->render_surface_reason = RenderSurfaceReason::kTest; layer1->SetExpectation(false, true, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetExpectation(false, false, layer1); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); - layer1->test_properties()->force_render_surface = false; + GetEffectNode(layer1)->render_surface_reason = RenderSurfaceReason::kNone; // Draw again, but with child non-opaque, to make sure // layer1 not culled. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); - layer2->test_properties()->opacity = 0.5f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 0.5f); layer2->SetExpectation(true, false, layer1); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // A second way of making the child non-opaque. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(false); - layer2->test_properties()->opacity = 1.f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 1.f); layer2->SetExpectation(true, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // And when the layer says its not opaque but is painted opaque, it is not // blended. layer1->SetContentsOpaque(true); - layer1->test_properties()->opacity = 1.f; - layer1->NoteLayerPropertyChanged(); + SetOpacity(layer1, 1.f); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); layer2->SetContentsOpaque(true); - layer2->test_properties()->opacity = 1.f; - layer2->NoteLayerPropertyChanged(); + SetOpacity(layer2, 1.f); layer2->SetExpectation(false, false, root); layer2->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); EXPECT_TRUE(layer2->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents, drawn with blending. layer1->SetContentsOpaque(false); @@ -9137,12 +8200,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents partially culled, drawn with blending. layer1->SetContentsOpaque(false); @@ -9151,12 +8210,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents culled, drawn with blending. layer1->SetContentsOpaque(false); @@ -9165,12 +8220,8 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(true, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); // Layer with partially opaque contents and translucent contents culled, drawn // without blending. @@ -9180,16 +8231,11 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) { layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5)); layer1->SetExpectation(false, false, root); layer1->SetUpdateRect(gfx::Rect(layer1->bounds())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->set_needs_update_draw_properties(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); + DrawFrame(); EXPECT_TRUE(layer1->quads_appended()); - host_impl_->DidDrawAllLayers(frame); } static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) { - host_impl->active_tree()->BuildPropertyTreesForTesting(); host_impl->active_tree()->set_needs_update_draw_properties(); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame)); @@ -9200,40 +8246,40 @@ static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) { TEST_F(LayerTreeHostImplTest, MayContainVideo) { gfx::Size big_size(1000, 1000); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(big_size)); - - int layer_id = 1; - host_impl_->active_tree()->SetRootLayerForTesting( - DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); auto* root = - static_cast<DidDrawCheckLayer*>(*host_impl_->active_tree()->begin()); - - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); - auto* video_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); + SetupRootLayer<DidDrawCheckLayer>(host_impl_->active_tree(), big_size); + auto* video_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); video_layer->set_may_contain_video(true); + CopyProperties(root, video_layer); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get())); // Test with the video layer occluded. - root->test_properties()->AddChild( - DidDrawCheckLayer::Create(host_impl_->active_tree(), layer_id++)); - auto* large_layer = - static_cast<DidDrawCheckLayer*>(root->test_properties()->children.back()); + auto* large_layer = AddLayer<DidDrawCheckLayer>(host_impl_->active_tree()); large_layer->SetBounds(big_size); large_layer->SetContentsOpaque(true); + CopyProperties(root, large_layer); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get())); - // Remove the large layer. - root->test_properties()->RemoveChild(large_layer); + { + // Remove the large layer. + OwnedLayerImplList layers = + host_impl_->active_tree()->DetachLayersKeepingRootLayerForTesting(); + ASSERT_EQ(video_layer, layers[1].get()); + host_impl_->active_tree()->AddLayer(std::move(layers[1])); + } + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get())); // Move the video layer so it goes beyond the root. - video_layer->test_properties()->position = gfx::PointF(100.f, 100.f); + video_layer->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f)); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get())); - video_layer->test_properties()->position = gfx::PointF(0.f, 0.f); + video_layer->SetOffsetToTransformParent(gfx::Vector2dF(0.f, 0.f)); video_layer->NoteLayerPropertyChanged(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get())); } @@ -9253,34 +8299,26 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void SetupActiveTreeLayers() { host_impl_->active_tree()->set_background_color(SK_ColorGRAY); - host_impl_->active_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->force_render_surface = true; - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::make_unique<BlendStateCheckLayer>( - host_impl_->active_tree(), 2, host_impl_->resource_provider())); - child_ = static_cast<BlendStateCheckLayer*>(host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0]); - child_->SetExpectation(false, false, - host_impl_->active_tree()->root_layer_for_testing()); + LayerImpl* root = SetupDefaultRootLayer(viewport_size_); + child_ = AddLayer<BlendStateCheckLayer>(host_impl_->active_tree(), + host_impl_->resource_provider()); + child_->SetExpectation(false, false, root); child_->SetContentsOpaque(true); + CopyProperties(root, child_); + UpdateDrawProperties(host_impl_->active_tree()); } - // Expect no gutter rects. - void TestLayerCoversFullViewport() { - gfx::Rect layer_rect(viewport_size_); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); + void SetLayerGeometry(const gfx::Rect& layer_rect) { child_->SetBounds(layer_rect.size()); child_->SetQuadRect(gfx::Rect(layer_rect.size())); child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + child_->SetOffsetToTransformParent( + gfx::Vector2dF(layer_rect.OffsetFromOrigin())); + } + + // Expect no gutter rects. + void TestLayerCoversFullViewport() { + SetLayerGeometry(gfx::Rect(viewport_size_)); TestFrameData frame; EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); @@ -9295,14 +8333,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { } // Expect fullscreen gutter rect. - void SetUpEmptylayer() { - gfx::Rect layer_rect(0, 0, 0, 0); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); - child_->SetBounds(layer_rect.size()); - child_->SetQuadRect(gfx::Rect(layer_rect.size())); - child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - } + void SetUpEmptylayer() { SetLayerGeometry(gfx::Rect()); } void VerifyEmptyLayerRenderPasses(const viz::RenderPassList& render_passes) { ASSERT_EQ(1u, render_passes.size()); @@ -9316,10 +8347,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void TestEmptyLayer() { SetUpEmptylayer(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - VerifyEmptyLayerRenderPasses(frame.render_passes); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); } void TestEmptyLayerWithOnDraw() { @@ -9333,12 +8361,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { // Expect four surrounding gutter rects. void SetUpLayerInMiddleOfViewport() { - gfx::Rect layer_rect(500, 500, 200, 200); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); - child_->SetBounds(layer_rect.size()); - child_->SetQuadRect(gfx::Rect(layer_rect.size())); - child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetLayerGeometry(gfx::Rect(500, 500, 200, 200)); } void VerifyLayerInMiddleOfViewport(const viz::RenderPassList& render_passes) { @@ -9353,10 +8376,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void TestLayerInMiddleOfViewport() { SetUpLayerInMiddleOfViewport(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - VerifyLayerInMiddleOfViewport(frame.render_passes); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); } void TestLayerInMiddleOfViewportWithOnDraw() { @@ -9370,13 +8390,8 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { // Expect no gutter rects. void SetUpLayerIsLargerThanViewport() { - gfx::Rect layer_rect(viewport_size_.width() + 10, - viewport_size_.height() + 10); - child_->test_properties()->position = gfx::PointF(layer_rect.origin()); - child_->SetBounds(layer_rect.size()); - child_->SetQuadRect(gfx::Rect(layer_rect.size())); - child_->SetQuadVisibleRect(gfx::Rect(layer_rect.size())); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetLayerGeometry( + gfx::Rect(viewport_size_.width() + 10, viewport_size_.height() + 10)); } void VerifyLayerIsLargerThanViewport( @@ -9390,10 +8405,7 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { void TestLayerIsLargerThanViewport() { SetUpLayerIsLargerThanViewport(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - VerifyLayerIsLargerThanViewport(frame.render_passes); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); } void TestLayerIsLargerThanViewportWithOnDraw() { @@ -9427,8 +8439,8 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { } void VerifyQuadsExactlyCoverViewport(const viz::QuadList& quad_list) { - LayerTestCommon::VerifyQuadsExactlyCoverRect( - quad_list, gfx::Rect(DipSizeToPixelSize(viewport_size_))); + VerifyQuadsExactlyCoverRect(quad_list, + gfx::Rect(DipSizeToPixelSize(viewport_size_))); } // Make sure that the texture coordinates match their expectations. @@ -9454,11 +8466,6 @@ class LayerTreeHostImplViewportCoveredTest : public LayerTreeHostImplTest { } } - gfx::Size DipSizeToPixelSize(const gfx::Size& size) { - return gfx::ScaleToRoundedSize( - size, host_impl_->active_tree()->device_scale_factor()); - } - viz::DrawQuad::Material gutter_quad_material_; gfx::Size gutter_texture_size_; gfx::Size viewport_size_; @@ -9471,9 +8478,6 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCovered) { bool software = false; CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); - - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestLayerCoversFullViewport()); EXPECT_SCOPED(TestEmptyLayer()); @@ -9488,8 +8492,6 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) { CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software)); host_impl_->active_tree()->SetDeviceScaleFactor(2.f); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestLayerCoversFullViewport()); EXPECT_SCOPED(TestEmptyLayer()); @@ -9505,8 +8507,6 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ActiveTreeGrowViewportInvalid) { // Pending tree to force active_tree size invalid. Not used otherwise. CreatePendingTree(); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(DipSizeToPixelSize(viewport_size_))); SetupActiveTreeLayers(); EXPECT_SCOPED(TestEmptyLayerWithOnDraw()); @@ -9573,31 +8573,25 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, - AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); + AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr, + nullptr); layer_tree_host_impl->SetVisible(true); layer_tree_host_impl->InitializeFrameSink(layer_tree_frame_sink.get()); layer_tree_host_impl->WillBeginImplFrame( viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2)); - layer_tree_host_impl->active_tree()->SetDeviceViewportRect( - gfx::Rect(500, 500)); - - std::unique_ptr<LayerImpl> root = - FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 1); - root->test_properties()->force_render_surface = true; - std::unique_ptr<LayerImpl> child = - FakeDrawableLayerImpl::Create(layer_tree_host_impl->active_tree(), 2); - child->test_properties()->position = gfx::PointF(12.f, 13.f); + + LayerImpl* root = SetupRootLayer<LayerImpl>( + layer_tree_host_impl->active_tree(), gfx::Size(500, 500)); + LayerImpl* child = AddLayer<LayerImpl>(layer_tree_host_impl->active_tree()); child->SetBounds(gfx::Size(14, 15)); child->SetDrawsContent(true); - root->SetBounds(gfx::Size(500, 500)); - root->SetDrawsContent(true); - root->test_properties()->AddChild(std::move(child)); - layer_tree_host_impl->active_tree()->SetRootLayerForTesting(std::move(root)); - layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(12.f, 13.f)); layer_tree_host_impl->active_tree()->SetLocalSurfaceIdAllocationFromParent( viz::LocalSurfaceIdAllocation( viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)), base::TimeTicks::Now())); + UpdateDrawProperties(layer_tree_host_impl->active_tree()); TestFrameData frame; @@ -9611,18 +8605,8 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { // Second frame, only the damaged area should get swapped. Damage should be // the union of old and new child rects: gfx::Rect(26, 28). - layer_tree_host_impl->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0] - ->test_properties() - ->position = gfx::PointF(); - layer_tree_host_impl->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0] - ->NoteLayerPropertyChanged(); - layer_tree_host_impl->active_tree()->BuildPropertyTreesForTesting(); + child->SetOffsetToTransformParent(gfx::Vector2dF()); + child->NoteLayerPropertyChanged(); EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame)); layer_tree_host_impl->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); @@ -9633,9 +8617,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { layer_tree_host_impl->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10)); // This will damage everything. - layer_tree_host_impl->active_tree() - ->root_layer_for_testing() - ->SetBackgroundColor(SK_ColorBLACK); + root->SetBackgroundColor(SK_ColorBLACK); EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame)); layer_tree_host_impl->DrawLayers(&frame); host_impl_->DidDrawAllLayers(frame); @@ -9648,19 +8630,15 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { } TEST_F(LayerTreeHostImplTest, RootLayerDoesntCreateExtraSurface) { - std::unique_ptr<LayerImpl> root = - FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 1); - std::unique_ptr<LayerImpl> child = - FakeDrawableLayerImpl::Create(host_impl_->active_tree(), 2); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); + LayerImpl* child = AddLayer(); child->SetBounds(gfx::Size(10, 10)); child->SetDrawsContent(true); root->SetBounds(gfx::Size(10, 10)); root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - root->test_properties()->AddChild(std::move(child)); + CopyProperties(root, child); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); TestFrameData frame; @@ -9704,45 +8682,36 @@ TEST_F(LayerTreeHostImplTest, LayersFreeTextures) { FakeLayerTreeFrameSink::Create3d(context_provider)); CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); - std::unique_ptr<LayerImpl> root_layer = - LayerImpl::Create(host_impl_->active_tree(), 1); - root_layer->SetBounds(gfx::Size(10, 10)); - root_layer->test_properties()->force_render_surface = true; + LayerImpl* root_layer = SetupDefaultRootLayer(gfx::Size(10, 10)); scoped_refptr<VideoFrame> softwareFrame = media::VideoFrame::CreateColorFrame( gfx::Size(4, 4), 0x80, 0x80, 0x80, base::TimeDelta()); FakeVideoFrameProvider provider; provider.set_frame(softwareFrame); - std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( - host_impl_->active_tree(), 4, &provider, media::VIDEO_ROTATION_0); + auto* video_layer = AddLayer<VideoLayerImpl>( + host_impl_->active_tree(), &provider, media::VIDEO_ROTATION_0); video_layer->SetBounds(gfx::Size(10, 10)); video_layer->SetDrawsContent(true); - root_layer->test_properties()->AddChild(std::move(video_layer)); + CopyProperties(root_layer, video_layer); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_EQ(0u, sii->shared_image_count()); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); EXPECT_GT(sii->shared_image_count(), 0u); // Kill the layer tree. - host_impl_->active_tree()->DetachLayers(); + ClearLayersAndPropertyTrees(host_impl_->active_tree()); // There should be no textures left in use after. EXPECT_EQ(0u, sii->shared_image_count()); } - TEST_F(LayerTreeHostImplTest, HasTransparentBackground) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - + SetupDefaultRootLayer(gfx::Size(10, 10)); host_impl_->active_tree()->set_background_color(SK_ColorWHITE); + UpdateDrawProperties(host_impl_->active_tree()); // Verify one quad is drawn when transparent background set is not set. TestFrameData frame; @@ -9791,7 +8760,8 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest { return FakeLayerTreeFrameSink::Create3d(); } - void DrawFrameAndTestDamage(const gfx::Rect& expected_damage) { + void DrawFrameAndTestDamage(const gfx::Rect& expected_damage, + const LayerImpl* child) { bool expect_to_draw = !expected_damage.IsEmpty(); TestFrameData frame; @@ -9812,15 +8782,11 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest { // culled. ASSERT_EQ(2u, root_render_pass->quad_list.size()); - LayerImpl* child = host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0]; gfx::Rect expected_child_visible_rect(child->bounds()); EXPECT_EQ(expected_child_visible_rect, root_render_pass->quad_list.front()->visible_rect); - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + LayerImpl* root = root_layer(); gfx::Rect expected_root_visible_rect(root->bounds()); EXPECT_EQ(expected_root_visible_rect, root_render_pass->quad_list.ElementAt(1)->visible_rect); @@ -9832,41 +8798,35 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest { }; TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) { - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); + auto* root = SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(), + gfx::Size(10, 10)); root->SetDrawsContent(true); root->SetBackgroundColor(SK_ColorRED); - root->test_properties()->force_render_surface = true; // Child layer is in the bottom right corner. - std::unique_ptr<SolidColorLayerImpl> child = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 2); - child->test_properties()->position = gfx::PointF(9.f, 9.f); + auto* child = AddLayer<SolidColorLayerImpl>(host_impl_->active_tree()); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetBackgroundColor(SK_ColorRED); - root->test_properties()->AddChild(std::move(child)); + CopyProperties(root, child); + child->SetOffsetToTransformParent(gfx::Vector2dF(9.f, 9.f)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // Draw a frame. In the first frame, the entire viewport should be damaged. gfx::Rect full_frame_damage( host_impl_->active_tree()->GetDeviceViewport().size()); - DrawFrameAndTestDamage(full_frame_damage); + DrawFrameAndTestDamage(full_frame_damage, child); // The second frame has damage that doesn't touch the child layer. Its quads // should still be generated. gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1); - host_impl_->active_tree()->root_layer_for_testing()->SetUpdateRect( - small_damage); - DrawFrameAndTestDamage(small_damage); + root->SetUpdateRect(small_damage); + DrawFrameAndTestDamage(small_damage, child); // The third frame should have no damage, so no quads should be generated. gfx::Rect no_damage; - DrawFrameAndTestDamage(no_damage); + DrawFrameAndTestDamage(no_damage, child); } class GLRendererWithSetupQuadForAntialiasing : public viz::GLRenderer { @@ -9879,59 +8839,39 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { // away quads can end up thinking they need AA. float device_scale_factor = 4.f / 3.f; gfx::Size root_size(2000, 1000); - gfx::Size device_viewport_size = - gfx::ScaleToCeiledSize(root_size, device_scale_factor); - host_impl_->active_tree()->SetDeviceViewportRect( - gfx::Rect(device_viewport_size)); - CreatePendingTree(); host_impl_->pending_tree()->SetDeviceScaleFactor(device_scale_factor); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f / 16.f, 16.f); - std::unique_ptr<LayerImpl> scoped_root = - LayerImpl::Create(host_impl_->pending_tree(), 1); - LayerImpl* root = scoped_root.get(); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), root_size); root->SetNeedsPushProperties(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); - - std::unique_ptr<LayerImpl> scoped_scrolling_layer = - LayerImpl::Create(host_impl_->pending_tree(), 2); - LayerImpl* scrolling_layer = scoped_scrolling_layer.get(); - root->test_properties()->AddChild(std::move(scoped_scrolling_layer)); + gfx::Size content_layer_bounds(100001, 100); + auto* scrolling_layer = + AddScrollableLayer(root, content_layer_bounds, gfx::Size()); scrolling_layer->SetNeedsPushProperties(); - gfx::Size content_layer_bounds(100001, 100); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(content_layer_bounds)); - std::unique_ptr<FakePictureLayerImpl> scoped_content_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 3, raster_source); - LayerImpl* content_layer = scoped_content_layer.get(); - scrolling_layer->test_properties()->AddChild(std::move(scoped_content_layer)); + auto* content_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + CopyProperties(scrolling_layer, content_layer); content_layer->SetBounds(content_layer_bounds); content_layer->SetDrawsContent(true); content_layer->SetNeedsPushProperties(); - root->SetBounds(root_size); + UpdateDrawProperties(host_impl_->pending_tree()); gfx::ScrollOffset scroll_offset(100000, 0); - scrolling_layer->SetScrollable(content_layer_bounds); - scrolling_layer->SetHitTestable(true); - scrolling_layer->SetElementId( - LayerIdToElementIdForTesting(scrolling_layer->id())); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - scrolling_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting( scrolling_layer->element_id(), scroll_offset); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); ASSERT_EQ(1u, host_impl_->active_tree()->GetRenderSurfaceList().size()); TestFrameData frame; @@ -9966,14 +8906,10 @@ class CompositorFrameMetadataTest : public LayerTreeHostImplTest { }; TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { - SetupRootLayerImpl(FakeLayerWithQuads::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - { - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); - } + SetupRootLayer<FakeLayerWithQuads>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); + DrawFrame(); host_impl_->ReclaimResources(std::vector<viz::ReturnedResource>()); host_impl_->DidReceiveCompositorFrameAck(); EXPECT_EQ(acks_received_, 1); @@ -10008,24 +8944,24 @@ TEST_F(LayerTreeHostImplTest, external_transform); // SolidColorLayerImpl will be drawn. - std::unique_ptr<SolidColorLayerImpl> root_layer = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); + auto* root = SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(), + gfx::Size(10, 10)); + root->SetDrawsContent(true); // VideoLayerImpl will not be drawn. FakeVideoFrameProvider provider; - std::unique_ptr<VideoLayerImpl> video_layer = VideoLayerImpl::Create( - host_impl_->active_tree(), 2, &provider, media::VIDEO_ROTATION_0); + LayerImpl* video_layer = AddLayer<VideoLayerImpl>( + host_impl_->active_tree(), &provider, media::VIDEO_ROTATION_0); video_layer->SetBounds(gfx::Size(10, 10)); video_layer->SetDrawsContent(true); - root_layer->test_properties()->AddChild(std::move(video_layer)); - SetupRootLayerImpl(std::move(root_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root, video_layer); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->OnDraw(external_transform, external_viewport, resourceless_software_draw, false); EXPECT_EQ(1u, last_on_draw_frame_->will_draw_layers.size()); - EXPECT_EQ(host_impl_->active_tree()->root_layer_for_testing(), + EXPECT_EQ(host_impl_->active_tree()->root_layer(), last_on_draw_frame_->will_draw_layers[0]); } @@ -10052,7 +8988,8 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) { host_impl_ = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, - AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); + AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr, + nullptr); // Gpu compositing. layer_tree_frame_sink_ = FakeLayerTreeFrameSink::Create3d(); @@ -10130,12 +9067,10 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, RequireHighResAndRedrawWhenVisible) { ASSERT_TRUE(host_impl_->active_tree()); - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); + LayerImpl* root = SetupRootLayer<SolidColorLayerImpl>( + host_impl_->active_tree(), gfx::Size(10, 10)); root->SetBackgroundColor(SK_ColorRED); - SetupRootLayerImpl(std::move(root)); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // RequiresHighResToDraw is set when new output surface is used. EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); @@ -10163,9 +9098,16 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, EXPECT_SCOPED(ExpectFullDamageAndDraw(host_impl_.get())); } -TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { +TEST_F(LayerTreeHostImplTest, RequireHighResAfterMSAAToggles) { + // Create a host impl with MSAA support and a forced sample count of 4. + LayerTreeSettings msaaSettings = DefaultSettings(); + msaaSettings.gpu_rasterization_msaa_sample_count = 4; + EXPECT_TRUE(CreateHostImpl( + msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization( + msaaSettings.gpu_rasterization_msaa_sample_count))); + ASSERT_TRUE(host_impl_->active_tree()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_FALSE(host_impl_->use_msaa()); // RequiresHighResToDraw is set when new output surface is used. EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); @@ -10173,15 +9115,14 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { host_impl_->ResetRequiresHighResToDraw(); host_impl_->SetContentHasSlowPaths(false); - host_impl_->SetHasGpuRasterizationTrigger(false); host_impl_->CommitComplete(); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); - host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); - host_impl_->SetHasGpuRasterizationTrigger(false); + host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); @@ -10189,7 +9130,7 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { host_impl_->ResetRequiresHighResToDraw(); EXPECT_FALSE(host_impl_->RequiresHighResToDraw()); - host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_TRUE(host_impl_->RequiresHighResToDraw()); host_impl_->NotifyReadyToActivate(); @@ -10295,7 +9236,6 @@ TEST_F(LayerTreeHostImplTest, msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -10310,7 +9250,6 @@ TEST_F(LayerTreeHostImplTest, EXPECT_NE(viz::kInvalidResourceId, resource_id); EXPECT_FALSE(host_impl_->EvictedUIResourcesExist()); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -10335,7 +9274,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10354,7 +9292,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10373,7 +9310,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForOopRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10392,7 +9328,6 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) { FakeLayerTreeFrameSink::Create3dForOopRasterization( msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); @@ -10466,30 +9401,26 @@ TEST_P(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) { CreateHostImpl(DefaultSettings(), std::move(layer_tree_frame_sink)); - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - - LayerImpl* root = host_impl_->active_tree()->root_layer_for_testing(); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); struct Helper { std::unique_ptr<viz::CopyOutputResult> unprocessed_result; void OnResult(std::unique_ptr<viz::CopyOutputResult> result) { unprocessed_result = std::move(result); } } helper; - root->test_properties()->copy_requests.push_back( + + GetEffectNode(root)->has_copy_request = true; + GetPropertyTrees(root)->effect_tree.AddCopyRequest( + root->effect_tree_index(), std::make_unique<viz::CopyOutputRequest>( viz::CopyOutputRequest::ResultFormat::RGBA_TEXTURE, base::BindOnce(&Helper::OnResult, base::Unretained(&helper)))); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - host_impl_->DrawLayers(&frame); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); auto* sii = context_provider->SharedImageInterface(); // The CopyOutputResult has a ref on the viz::ContextProvider and a shared // image allocated. - ASSERT_TRUE(helper.unprocessed_result); + EXPECT_TRUE(helper.unprocessed_result); EXPECT_FALSE(context_provider->HasOneRef()); EXPECT_EQ(1u, sii->shared_image_count()); @@ -10509,30 +9440,19 @@ TEST_P(LayerTreeHostImplTestWithRenderer, ShutdownReleasesContext) { TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) { // If we ray cast a scroller that is not on the first layer's ancestor chain, // we should return SCROLL_UNKNOWN. + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); + SetupViewportLayersInnerScrolls(viewport_size, content_size); - int scroll_layer_id = 2; - LayerImpl* scroll_layer = - host_impl_->active_tree()->LayerById(scroll_layer_id); - scroll_layer->SetDrawsContent(true); - scroll_layer->SetHitTestable(true); - - int page_scale_layer_id = 5; - LayerImpl* page_scale_layer = - host_impl_->active_tree()->LayerById(page_scale_layer_id); - - int occluder_layer_id = 6; - std::unique_ptr<LayerImpl> occluder_layer = - LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); + LayerImpl* occluder_layer = AddLayer(); occluder_layer->SetDrawsContent(true); occluder_layer->SetHitTestable(true); occluder_layer->SetBounds(content_size); - occluder_layer->test_properties()->position = gfx::PointF(); // The parent of the occluder is *above* the scroller. - page_scale_layer->test_properties()->AddChild(std::move(occluder_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(root_layer(), occluder_layer); + occluder_layer->SetTransformTreeIndex( + host_impl_->active_tree()->PageScaleTransformNode()->id); DrawFrame(); @@ -10547,37 +9467,25 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { // If we ray cast a scroller this is on the first layer's ancestor chain, but // is not the first scroller we encounter when walking up from the layer, we // should also return SCROLL_UNKNOWN. + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); + SetupViewportLayersInnerScrolls(viewport_size, content_size); - int scroll_layer_id = 2; - LayerImpl* scroll_layer = - host_impl_->active_tree()->LayerById(scroll_layer_id); - scroll_layer->SetDrawsContent(true); - scroll_layer->SetHitTestable(true); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + + LayerImpl* child_scroll_clip = AddLayer(); + CopyProperties(scroll_layer, child_scroll_clip); - int occluder_layer_id = 6; - std::unique_ptr<LayerImpl> occluder_layer = - LayerImpl::Create(host_impl_->active_tree(), occluder_layer_id); + LayerImpl* child_scroll = + AddScrollableLayer(child_scroll_clip, viewport_size, content_size); + child_scroll->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); + + LayerImpl* occluder_layer = AddLayer(); occluder_layer->SetDrawsContent(true); occluder_layer->SetHitTestable(true); occluder_layer->SetBounds(content_size); - occluder_layer->test_properties()->position = gfx::PointF(-10.f, -10.f); - - int child_scroll_clip_layer_id = 7; - std::unique_ptr<LayerImpl> child_scroll_clip = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_clip_layer_id); - - int child_scroll_layer_id = 8; - std::unique_ptr<LayerImpl> child_scroll = - CreateScrollableLayer(child_scroll_layer_id, content_size); - - child_scroll->test_properties()->position = gfx::PointF(10.f, 10.f); - - child_scroll->test_properties()->AddChild(std::move(occluder_layer)); - child_scroll_clip->test_properties()->AddChild(std::move(child_scroll)); - scroll_layer->test_properties()->AddChild(std::move(child_scroll_clip)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(child_scroll, occluder_layer); + occluder_layer->SetOffsetToTransformParent(gfx::Vector2dF(-10.f, -10.f)); DrawFrame(); @@ -10589,21 +9497,15 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { } TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) { + gfx::Size viewport_size(50, 50); gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); - - int scroll_layer_id = 2; - LayerImpl* scroll_layer = - host_impl_->active_tree()->LayerById(scroll_layer_id); + SetupViewportLayersInnerScrolls(viewport_size, content_size); - int child_scroll_layer_id = 7; - std::unique_ptr<LayerImpl> child_scroll = - CreateScrollableLayer(child_scroll_layer_id, content_size); + LayerImpl* scroll_layer = InnerViewportScrollLayer(); + LayerImpl* child_scroll = + AddScrollableLayer(scroll_layer, viewport_size, content_size); child_scroll->SetDrawsContent(false); - scroll_layer->test_properties()->AddChild(std::move(child_scroll)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - DrawFrame(); // We should have scrolled |child_scroll| even though it does not move @@ -10614,111 +9516,23 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) { ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) .thread); - EXPECT_EQ(host_impl_->active_tree()->LayerById(7)->scroll_tree_index(), + EXPECT_EQ(child_scroll->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); } -template <bool commit_to_active_tree> -class LayerTreeHostImplLatencyInfoTest : public LayerTreeHostImplTest { - public: - void SetUp() override { - LayerTreeSettings settings = DefaultSettings(); - settings.commit_to_active_tree = commit_to_active_tree; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); - - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), 1); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - } -}; - -// Make sure LatencyInfo are passed in viz::CompositorFrameMetadata properly in -// the Renderer. This includes components added by LatencyInfoSwapPromise and -// the default LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT. -using LayerTreeHostImplLatencyInfoRendererTest = - LayerTreeHostImplLatencyInfoTest<false>; -TEST_F(LayerTreeHostImplLatencyInfoRendererTest, - LatencyInfoPassedToCompositorFrameMetadataRenderer) { - auto* fake_layer_tree_frame_sink = - static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); - - // The first frame should only have the default BeginFrame component. - TestFrameData frame1; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame1)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame1)); - host_impl_->DidDrawAllLayers(frame1); - - const std::vector<ui::LatencyInfo>& metadata_latency_after1 = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(1u, metadata_latency_after1.size()); - EXPECT_TRUE(metadata_latency_after1[0].FindLatency( - ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after1[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - - // The second frame should have the default BeginFrame component and the - // component attached via LatencyInfoSwapPromise. - ui::LatencyInfo latency_info; - latency_info.set_trace_id(5); - latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); - std::unique_ptr<SwapPromise> swap_promise( - new LatencyInfoSwapPromise(latency_info)); - host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise)); - - TestFrameData frame2; - host_impl_->SetFullViewportDamage(); - host_impl_->SetNeedsRedraw(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame2)); - host_impl_->DidDrawAllLayers(frame2); +// Make sure LatencyInfo carried by LatencyInfoSwapPromise are passed +// in viz::CompositorFrameMetadata. +TEST_F(LayerTreeHostImplTest, LatencyInfoPassedToCompositorFrameMetadata) { + LayerTreeSettings settings = DefaultSettings(); + settings.commit_to_active_tree = false; + CreateHostImpl(settings, CreateLayerTreeFrameSink()); + SetupRootLayer<SolidColorLayerImpl>(host_impl_->active_tree(), + gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); - const std::vector<ui::LatencyInfo>& metadata_latency_after2 = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(2u, metadata_latency_after2.size()); - EXPECT_TRUE(metadata_latency_after2[0].FindLatency( - ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after2[1].FindLatency( - ui::LATENCY_BEGIN_FRAME_RENDERER_COMPOSITOR_COMPONENT, nullptr)); - - // Renderer should also record INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT. - EXPECT_TRUE(metadata_latency_after2[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after2[1].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); -} - -// Make sure LatencyInfo are passed in viz::CompositorFrameMetadata properly in -// the UI. This includes components added by LatencyInfoSwapPromise and -// the default LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT. -using LayerTreeHostImplLatencyInfoUITest = - LayerTreeHostImplLatencyInfoTest<true>; -TEST_F(LayerTreeHostImplLatencyInfoUITest, - LatencyInfoPassedToCompositorFrameMetadataUI) { auto* fake_layer_tree_frame_sink = static_cast<FakeLayerTreeFrameSink*>(host_impl_->layer_tree_frame_sink()); - // The first frame should only have the default BeginFrame component. - TestFrameData frame1; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame1)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame1)); - host_impl_->DidDrawAllLayers(frame1); - - const std::vector<ui::LatencyInfo>& metadata_latency_after1 = - fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(1u, metadata_latency_after1.size()); - EXPECT_TRUE(metadata_latency_after1[0].FindLatency( - ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, nullptr)); - EXPECT_FALSE(metadata_latency_after1[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - - // The second frame should have the default BeginFrame component and the - // component attached via LatencyInfoSwapPromise. ui::LatencyInfo latency_info; latency_info.set_trace_id(5); latency_info.AddLatencyNumber(ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT); @@ -10726,47 +9540,29 @@ TEST_F(LayerTreeHostImplLatencyInfoUITest, new LatencyInfoSwapPromise(latency_info)); host_impl_->active_tree()->QueuePinnedSwapPromise(std::move(swap_promise)); - TestFrameData frame2; host_impl_->SetFullViewportDamage(); host_impl_->SetNeedsRedraw(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame2)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame2)); - host_impl_->DidDrawAllLayers(frame2); + DrawFrame(); - const std::vector<ui::LatencyInfo>& metadata_latency_after2 = + const auto& metadata_latency_after = fake_layer_tree_frame_sink->last_sent_frame()->metadata.latency_info; - EXPECT_EQ(2u, metadata_latency_after2.size()); - EXPECT_TRUE(metadata_latency_after2[0].FindLatency( + EXPECT_EQ(1u, metadata_latency_after.size()); + EXPECT_TRUE(metadata_latency_after[0].FindLatency( ui::INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT, nullptr)); - EXPECT_TRUE(metadata_latency_after2[1].FindLatency( - ui::LATENCY_BEGIN_FRAME_UI_COMPOSITOR_COMPONENT, nullptr)); - - // UI should not record INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT. - EXPECT_FALSE(metadata_latency_after2[0].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); - EXPECT_FALSE(metadata_latency_after2[1].FindLatency( - ui::INPUT_EVENT_LATENCY_RENDERER_SWAP_COMPONENT, nullptr)); } #if defined(OS_ANDROID) TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { - int root_layer_id = 1; - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* root = SetupRootLayer<SolidColorLayerImpl>( + host_impl_->active_tree(), gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); // Plumb the layer-local selection bounds. gfx::Point selection_top(5, 0); gfx::Point selection_bottom(5, 5); LayerSelection selection; selection.start.type = gfx::SelectionBound::CENTER; - selection.start.layer_id = root_layer_id; + selection.start.layer_id = root->id(); selection.start.edge_bottom = selection_bottom; selection.start.edge_top = selection_top; selection.end = selection.start; @@ -10787,16 +9583,9 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) { } TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) { - int root_layer_id = 1; - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); // Plumb the layer-local selection bounds. gfx::Point selection_top(5, 0); @@ -10807,7 +9596,7 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) { selection.start.hidden = true; selection.start.type = gfx::SelectionBound::CENTER; - selection.start.layer_id = root_layer_id; + selection.start.layer_id = root->id(); selection.start.edge_bottom = selection_bottom; selection.start.edge_top = selection_top; selection.end = selection.start; @@ -10833,15 +9622,13 @@ class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { SimpleSwapPromiseMonitor(LayerTreeHost* layer_tree_host, LayerTreeHostImpl* layer_tree_host_impl, int* set_needs_commit_count, - int* set_needs_redraw_count, - int* forward_to_main_count) + int* set_needs_redraw_count) : SwapPromiseMonitor( (layer_tree_host ? layer_tree_host->GetSwapPromiseManager() : nullptr), layer_tree_host_impl), set_needs_commit_count_(set_needs_commit_count), - set_needs_redraw_count_(set_needs_redraw_count), - forward_to_main_count_(forward_to_main_count) {} + set_needs_redraw_count_(set_needs_redraw_count) {} ~SimpleSwapPromiseMonitor() override = default; @@ -10849,30 +9636,23 @@ class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { void OnSetNeedsRedrawOnImpl() override { (*set_needs_redraw_count_)++; } - void OnForwardScrollUpdateToMainThreadOnImpl() override { - (*forward_to_main_count_)++; - } - private: int* set_needs_commit_count_; int* set_needs_redraw_count_; - int* forward_to_main_count_; }; TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { int set_needs_commit_count = 0; int set_needs_redraw_count = 0; - int forward_to_main_count = 0; { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } // Now the monitor is destroyed, SetNeedsRedraw() is no longer being @@ -10880,43 +9660,39 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); // Redraw with damage. host_impl_->SetFullViewportDamage(); host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(2, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); // Redraw without damage. host_impl_->SetNeedsRedraw(); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(3, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } set_needs_commit_count = 0; set_needs_redraw_count = 0; - forward_to_main_count = 0; { std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); // Scrolling normally should not trigger any forwarding. EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -10932,7 +9708,6 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); // Scrolling with a scroll handler should defer the swap to the main // thread. @@ -10950,7 +9725,6 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(2, set_needs_redraw_count); - EXPECT_EQ(1, forward_to_main_count); } } @@ -10971,7 +9745,8 @@ class LayerTreeHostImplWithBrowserControlsTest : public LayerTreeHostImplTest { const int LayerTreeHostImplWithBrowserControlsTest::top_controls_height_ = 50; TEST_F(LayerTreeHostImplWithBrowserControlsTest, NoIdleAnimations) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), @@ -10986,7 +9761,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, NoIdleAnimations) { TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsHeightIsCommitted) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_FALSE(did_request_redraw_); CreatePendingTree(); host_impl_->sync_tree()->SetTopControlsHeight(100); @@ -10996,7 +9771,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsStayFullyVisibleOnHeightChange) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset()); CreatePendingTree(); @@ -11012,7 +9787,8 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsAnimationScheduling) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(), @@ -11025,10 +9801,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, ScrollHandledByBrowserControls) { InputHandlerScrollResult result; - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11101,14 +9877,13 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, WheelUnhandledByBrowserControls) { - SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); host_impl_->active_tree()->set_browser_controls_shrink_blink_size(true); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); - LayerImpl* viewport_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* viewport_layer = InnerViewportScrollLayer(); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -11142,10 +9917,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsAnimationAtOrigin) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 200)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11222,10 +9997,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsAnimationAfterScroll) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); float initial_scroll_offset = 50; @@ -11302,10 +10077,10 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest, BrowserControlsScrollDeltaInOverScroll) { // Verifies that the overscroll delta should not have accumulated in // the browser controls if we do a hide and show without releasing finger. - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200)); + auto* scroll_layer = InnerViewportScrollLayer(); + UpdateDrawProperties(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BrowserControlsState::kBoth, BrowserControlsState::kShown, false); DrawFrame(); @@ -11390,45 +10165,27 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, SetupBrowserControlsAndScrollLayerWithVirtualViewport( viewport_size, viewport_size, root_layer_size); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - LayerImpl* scroll_layer = nullptr; - LayerImpl* clip_layer = nullptr; + LayerImpl* outer_scroll = OuterViewportScrollLayer(); // Initialization: Add a child scrolling layer to the outer scroll layer and // set its scroll layer as the outer viewport. This simulates setting a // scrolling element as the root scroller on the page. - { - std::unique_ptr<LayerImpl> clip = LayerImpl::Create(layer_tree_impl, 10); - clip->SetBounds(root_layer_size); - clip->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); - scroll->SetBounds(scroll_content_size); - scroll->SetScrollable(root_layer_size); - scroll->SetHitTestable(true); - scroll->SetElementId(LayerIdToElementIdForTesting(scroll->id())); - scroll->SetDrawsContent(true); - - scroll_layer = scroll.get(); - clip_layer = clip.get(); - - clip->test_properties()->AddChild(std::move(scroll)); - outer_scroll->test_properties()->AddChild(std::move(clip)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = layer_tree_impl->PageScaleLayer()->id(); - viewport_ids.inner_viewport_container = - layer_tree_impl->InnerViewportContainerLayer()->id(); - viewport_ids.outer_viewport_container = clip_layer->id(); - viewport_ids.inner_viewport_scroll = inner_scroll->id(); - viewport_ids.outer_viewport_scroll = scroll_layer->id(); - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - layer_tree_impl->BuildPropertyTreesForTesting(); - DrawFrame(); - } + LayerImpl* clip_layer = AddLayer(); + clip_layer->SetBounds(root_layer_size); + CopyProperties(outer_scroll, clip_layer); + CreateClipNode(clip_layer); + LayerImpl* scroll_layer = + AddScrollableLayer(clip_layer, root_layer_size, scroll_content_size); + GetScrollNode(scroll_layer)->scrolls_outer_viewport = true; + + auto viewport_property_ids = layer_tree_impl->ViewportPropertyIdsForTesting(); + viewport_property_ids.outer_clip = clip_layer->clip_tree_index(); + viewport_property_ids.outer_scroll = scroll_layer->scroll_tree_index(); + layer_tree_impl->SetViewportPropertyIds(viewport_property_ids); + DrawFrame(); - ASSERT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); + ASSERT_EQ(1.f, layer_tree_impl->CurrentBrowserControlsShownRatio()); // Scrolling should scroll the child content and the browser controls. The // original outer viewport should get no scroll. @@ -11442,100 +10199,22 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll->CurrentScrollOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(100.f, 50.f), scroll_layer->CurrentScrollOffset()); - EXPECT_EQ(0.f, - host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); + EXPECT_EQ(0.f, layer_tree_impl->CurrentBrowserControlsShownRatio()); } } -class LayerTreeHostImplVirtualViewportTest : public LayerTreeHostImplTest { - public: - void SetupVirtualViewportLayers(const gfx::Size& content_size, - const gfx::Size& outer_viewport, - const gfx::Size& inner_viewport) { - LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - const int kOuterViewportClipLayerId = 6; - const int kOuterViewportScrollLayerId = 7; - const int kInnerViewportScrollLayerId = 2; - const int kInnerViewportClipLayerId = 4; - const int kPageScaleLayerId = 5; - - std::unique_ptr<LayerImpl> inner_scroll = - LayerImpl::Create(layer_tree_impl, kInnerViewportScrollLayerId); - inner_scroll->test_properties()->is_container_for_fixed_position_layers = - true; - inner_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - inner_scroll->element_id(), gfx::ScrollOffset()); - - std::unique_ptr<LayerImpl> inner_clip = - LayerImpl::Create(layer_tree_impl, kInnerViewportClipLayerId); - inner_clip->SetBounds(inner_viewport); - - std::unique_ptr<LayerImpl> page_scale = - LayerImpl::Create(layer_tree_impl, kPageScaleLayerId); - - inner_scroll->SetScrollable(inner_viewport); - inner_scroll->SetHitTestable(true); - inner_scroll->SetElementId( - LayerIdToElementIdForTesting(inner_scroll->id())); - inner_scroll->SetBounds(outer_viewport); - inner_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> outer_clip = - LayerImpl::Create(layer_tree_impl, kOuterViewportClipLayerId); - outer_clip->SetBounds(outer_viewport); - outer_clip->test_properties()->is_container_for_fixed_position_layers = - true; - - std::unique_ptr<LayerImpl> outer_scroll = - LayerImpl::Create(layer_tree_impl, kOuterViewportScrollLayerId); - outer_scroll->SetScrollable(outer_viewport); - outer_scroll->SetHitTestable(true); - outer_scroll->SetElementId( - LayerIdToElementIdForTesting(outer_scroll->id())); - outer_scroll->layer_tree_impl() - ->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - outer_scroll->element_id(), gfx::ScrollOffset()); - outer_scroll->SetBounds(content_size); - outer_scroll->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> contents = LayerImpl::Create(layer_tree_impl, 8); - contents->SetDrawsContent(true); - contents->SetBounds(content_size); - contents->test_properties()->position = gfx::PointF(); - - outer_scroll->test_properties()->AddChild(std::move(contents)); - outer_clip->test_properties()->AddChild(std::move(outer_scroll)); - inner_scroll->test_properties()->AddChild(std::move(outer_clip)); - page_scale->test_properties()->AddChild(std::move(inner_scroll)); - inner_clip->test_properties()->AddChild(std::move(page_scale)); - - inner_clip->test_properties()->force_render_surface = true; - layer_tree_impl->SetRootLayerForTesting(std::move(inner_clip)); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = kPageScaleLayerId; - viewport_ids.inner_viewport_container = kInnerViewportClipLayerId; - viewport_ids.outer_viewport_container = kOuterViewportClipLayerId; - viewport_ids.inner_viewport_scroll = kInnerViewportScrollLayerId; - viewport_ids.outer_viewport_scroll = kOuterViewportScrollLayerId; - layer_tree_impl->SetViewportLayersFromIds(viewport_ids); - - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->DidBecomeActive(); - } -}; +using LayerTreeHostImplVirtualViewportTest = LayerTreeHostImplTest; TEST_F(LayerTreeHostImplVirtualViewportTest, RootScrollBothInnerAndOuterLayer) { gfx::Size content_size = gfx::Size(100, 160); gfx::Size outer_viewport = gfx::Size(50, 80); gfx::Size inner_viewport = gfx::Size(25, 40); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DrawFrame(); { @@ -11565,10 +10244,11 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, gfx::Size outer_viewport = gfx::Size(100, 160); gfx::Size inner_viewport = gfx::Size(50, 80); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); DrawFrame(); { @@ -11617,16 +10297,14 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, gfx::Size outer_viewport = gfx::Size(50, 80); gfx::Size inner_viewport = gfx::Size(25, 40); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); - - LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); - std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport); - LayerImpl* child_scroll = child.get(); - outer_scroll->test_properties()->children[0]->test_properties()->AddChild( - std::move(child)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* outer_scroll = OuterViewportScrollLayer(); + LayerImpl* child_scroll = + AddScrollableLayer(outer_scroll, inner_viewport, outer_viewport); + UpdateDrawProperties(host_impl_->active_tree()); DrawFrame(); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -11634,8 +10312,8 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, ->RootScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id, - host_impl_->ViewportMainScrollLayer()->scroll_tree_index()); + EXPECT_EQ(host_impl_->CurrentlyScrollingNode(), + host_impl_->ViewportMainScrollNode()); host_impl_->ScrollEnd(EndState().get()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -11653,12 +10331,12 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, gfx::Size content_size = gfx::Size(100, 160); gfx::Size outer_viewport = gfx::Size(50, 80); gfx::Size inner_viewport = gfx::Size(25, 40); - SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); + SetupViewportLayers(host_impl_->active_tree(), inner_viewport, outer_viewport, + content_size); // Make inner viewport unscrollable. - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); - inner_scroll->test_properties()->user_scrollable_horizontal = false; - inner_scroll->test_properties()->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* inner_scroll = InnerViewportScrollLayer(); + GetScrollNode(inner_scroll)->user_scrollable_horizontal = false; + GetScrollNode(inner_scroll)->user_scrollable_vertical = false; DrawFrame(); @@ -11701,11 +10379,13 @@ TEST_F(LayerTreeHostImplWithImplicitLimitsTest, ImplicitMemoryLimits) { } TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); gfx::Transform external_transform; const gfx::Rect external_viewport(layer_size); const bool resourceless_software_draw = false; - LayerImpl* layer = SetupScrollAndContentsLayers(layer_size); + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + auto* layer = InnerViewportScrollLayer(); layer->SetDrawsContent(true); host_impl_->SetExternalTilePriorityConstraints(external_viewport, @@ -11725,11 +10405,9 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformReflectedInNextDraw) { } TEST_F(LayerTreeHostImplTest, ExternalTransformSetNeedsRedraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform transform_for_tile_priority; const gfx::Transform draw_transform; @@ -11778,11 +10456,9 @@ TEST_F(LayerTreeHostImplTest, OnMemoryPressure) { } TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform draw_transform; const gfx::Rect draw_viewport1(viewport_size); @@ -11813,11 +10489,9 @@ TEST_F(LayerTreeHostImplTest, OnDrawConstraintSetNeedsRedraw) { // This test verifies that the viewport damage rect is the full viewport and not // just part of the viewport in the presence of an external viewport. TEST_F(LayerTreeHostImplTest, FullViewportDamageAfterOnDraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform draw_transform; const gfx::Rect draw_viewport(gfx::Point(5, 5), viewport_size); @@ -11841,11 +10515,9 @@ class ResourcelessSoftwareLayerTreeHostImplTest : public LayerTreeHostImplTest { TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, ResourcelessSoftwareSetNeedsRedraw) { - SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); + SetupDefaultRootLayer(viewport_size); + UpdateDrawProperties(host_impl_->active_tree()); const gfx::Transform draw_transform; const gfx::Rect draw_viewport(viewport_size); @@ -11873,19 +10545,16 @@ TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, TEST_F(ResourcelessSoftwareLayerTreeHostImplTest, ResourcelessSoftwareDrawSkipsUpdateTiles) { const gfx::Size viewport_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); CreatePendingTree(); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(viewport_size)); - std::unique_ptr<FakePictureLayerImpl> layer( - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 11, raster_source)); - layer->SetBounds(viewport_size); - layer->SetDrawsContent(true); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer)); + auto* root = SetupRootLayer<FakePictureLayerImpl>( + host_impl_->pending_tree(), viewport_size, raster_source); + root->SetBounds(viewport_size); + root->SetDrawsContent(true); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); host_impl_->ActivateSyncTree(); const gfx::Transform draw_transform; @@ -11912,25 +10581,19 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, ExternalTileConstraintReflectedInPendingTree) { EXPECT_FALSE(host_impl_->CommitToActiveTree()); const gfx::Size layer_size(100, 100); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_size)); // Set up active and pending tree. CreatePendingTree(); - host_impl_->pending_tree()->SetRootLayerForTesting( - LayerImpl::Create(host_impl_->pending_tree(), 1)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - host_impl_->pending_tree()->UpdateDrawProperties(); - host_impl_->pending_tree() - ->root_layer_for_testing() - ->SetNeedsPushProperties(); + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), layer_size); + UpdateDrawProperties(host_impl_->pending_tree()); + host_impl_->pending_tree()->root_layer()->SetNeedsPushProperties(); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); CreatePendingTree(); - host_impl_->pending_tree()->UpdateDrawProperties(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->pending_tree()); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_FALSE(host_impl_->pending_tree()->needs_update_draw_properties()); EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); @@ -11946,15 +10609,13 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); - SetupScrollAndContentsLayers(layer_size); - LayerImpl* content_layer = host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + LayerImpl* content_layer = AddContentLayer(); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(90, 90)); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_EQ(gfx::Rect(90, 90), content_layer->visible_layer_rect()); gfx::Transform external_transform; @@ -11977,15 +10638,13 @@ TEST_F(LayerTreeHostImplTest, ExternalViewportAffectsVisibleRects) { } TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); - SetupScrollAndContentsLayers(layer_size); - LayerImpl* content_layer = host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + LayerImpl* content_layer = AddContentLayer(); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); EXPECT_EQ(gfx::Rect(50, 50), content_layer->visible_layer_rect()); gfx::Transform external_transform; @@ -12013,25 +10672,18 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsVisibleRects) { } TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { + const gfx::Size viewport_size(50, 50); const gfx::Size layer_size(100, 100); - SetupScrollAndContentsLayers(layer_size); - LayerImpl* content_layer = host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; - content_layer->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 100)); - LayerImpl* test_layer = host_impl_->active_tree()->LayerById(100); - test_layer->test_properties()->force_render_surface = true; - test_layer->SetDrawsContent(true); - test_layer->SetBounds(layer_size); + SetupViewportLayersInnerScrolls(viewport_size, layer_size); + LayerImpl* test_layer = AddContentLayer(); gfx::Transform perspective_transform; perspective_transform.ApplyPerspectiveDepth(2); - test_layer->test_properties()->transform = perspective_transform; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CreateTransformNode(test_layer).local = perspective_transform; + CreateEffectNode(test_layer).render_surface_reason = + RenderSurfaceReason::kTest; host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); EffectNode* node = host_impl_->active_tree()->property_trees()->effect_tree.Node( test_layer->effect_tree_index()); @@ -12067,7 +10719,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { TEST_F(LayerTreeHostImplTest, ScrollAnimated) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12082,21 +10734,19 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { // for LatencyInfo's to be propagated along with the CompositorFrame int set_needs_commit_count = 0; int set_needs_redraw_count = 0; - int forward_to_main_count = 0; std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12124,11 +10774,10 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { // for LatencyInfo's to be propagated along with the CompositorFrame int set_needs_commit_count = 0; int set_needs_redraw_count = 0; - int forward_to_main_count = 0; std::unique_ptr<SimpleSwapPromiseMonitor> swap_promise_monitor( - new SimpleSwapPromiseMonitor( - nullptr, host_impl_.get(), &set_needs_commit_count, - &set_needs_redraw_count, &forward_to_main_count)); + new SimpleSwapPromiseMonitor(nullptr, host_impl_.get(), + &set_needs_commit_count, + &set_needs_redraw_count)); // Update target. EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -12136,7 +10785,6 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { EXPECT_EQ(0, set_needs_commit_count); EXPECT_EQ(1, set_needs_redraw_count); - EXPECT_EQ(0, forward_to_main_count); } host_impl_->DidFinishImplFrame(); @@ -12174,8 +10822,8 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimated) { TEST_F(LayerTreeHostImplTest, ScrollAnimatedWhileZoomed) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* scrolling_layer = host_impl_->InnerViewportScrollLayer(); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* scrolling_layer = InnerViewportScrollLayer(); DrawFrame(); @@ -12246,21 +10894,16 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { // Setup the viewport. const gfx::Size viewport_size = gfx::Size(360, 600); const gfx::Size content_size = gfx::Size(345, 3800); - CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* scroll_layer = host_impl_->OuterViewportScrollLayer(); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + LayerImpl* scroll_layer = OuterViewportScrollLayer(); // Set up the scrollbar and its dimensions. LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); - std::unique_ptr<PaintedScrollbarLayerImpl> scrollbar = - PaintedScrollbarLayerImpl::Create(layer_tree_impl, 99, VERTICAL, false, - true); + auto* scrollbar = AddLayer<PaintedScrollbarLayerImpl>(layer_tree_impl, + VERTICAL, false, true); + SetupScrollbarLayer(scroll_layer, scrollbar); const gfx::Size scrollbar_size = gfx::Size(15, 600); scrollbar->SetBounds(scrollbar_size); - scrollbar->test_properties()->position = gfx::PointF(345, 0); - scrollbar->SetScrollElementId(scroll_layer->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->SetHitTestable(true); - scrollbar->test_properties()->opacity = 1.f; // Set up the thumb dimensions. scrollbar->SetThumbThickness(15); @@ -12274,10 +10917,8 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { scrollbar->SetForwardButtonRect( gfx::Rect(gfx::Point(345, 570), gfx::Size(15, 15))); - // Add the scrollbar to the outer viewport. - scroll_layer->test_properties()->AddChild(std::move(scrollbar)); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - host_impl_->active_tree()->BuildLayerListAndPropertyTreesForTesting(); host_impl_->ScrollBegin(BeginState(gfx::Point(350, 18)).get(), InputHandler::SCROLLBAR); TestInputHandlerClient input_handler_client; @@ -12294,7 +10935,7 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { // MouseDown on the thumb should not produce a scroll. InputHandlerPointerResult result = - host_impl_->MouseDown(gfx::PointF(350, 18)); + host_impl_->MouseDown(gfx::PointF(350, 18), /*shift_modifier*/ false); EXPECT_EQ(result.scroll_offset.y(), 0u); // The first request for a GSU should be processed as expected. @@ -12333,7 +10974,7 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) { TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); EXPECT_EQ( InputHandler::SCROLL_ON_IMPL_THREAD, @@ -12350,7 +10991,7 @@ TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) { TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12391,7 +11032,7 @@ TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) { host_impl_->UpdateAnimationState(true); host_impl_->DidFinishImplFrame(); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12403,7 +11044,7 @@ TEST_F(LayerTreeHostImplTest, AnimatedScrollUpdateTargetBeforeStarting) { TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(50, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12419,7 +11060,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) { base::TimeDelta::FromMilliseconds(100)) .thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12465,7 +11106,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimatedWithDelay) { TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12480,7 +11121,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12535,7 +11176,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); DrawFrame(); @@ -12549,7 +11190,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(0, 50)).thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12609,11 +11250,11 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimated) { TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersOuterScrolls(viewport_size, content_size); + UpdateDrawProperties(host_impl_->active_tree()); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Zoom into the page by a 2X factor float min_page_scale = 1.f, max_page_scale = 4.f; @@ -12707,10 +11348,10 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) { TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimatedUpdate) { const gfx::Size content_size(200, 200); const gfx::Size viewport_size(100, 100); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - LayerImpl* outer_scroll_layer = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll_layer = host_impl_->InnerViewportScrollLayer(); + LayerImpl* outer_scroll_layer = OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = InnerViewportScrollLayer(); // Zoom into the page by a 2X factor float min_page_scale = 1.f, max_page_scale = 4.f; @@ -12767,15 +11408,11 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimatedUpdate) { TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) { const gfx::Size content_size(1000, 1000); const gfx::Size viewport_size(500, 500); - CreateBasicVirtualViewportLayers(viewport_size, content_size); + SetupViewportLayersOuterScrolls(viewport_size, content_size); - host_impl_->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = true; - host_impl_->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); + GetScrollNode(scrolling_layer)->user_scrollable_vertical = true; + GetScrollNode(scrolling_layer)->user_scrollable_horizontal = false; DrawFrame(); @@ -12789,7 +11426,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedNotUserScrollable) { InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(50, 50)).thread); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12852,8 +11488,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) { const gfx::Size new_content_size(750, 750); const gfx::Size viewport_size(500, 500); - LayerImpl* content_layer = - CreateBasicVirtualViewportLayers(viewport_size, old_content_size); + SetupViewportLayersOuterScrolls(viewport_size, old_content_size); + LayerImpl* scrolling_layer = OuterViewportScrollLayer(); + LayerImpl* content_layer = AddContentLayer(); DrawFrame(); @@ -12864,7 +11501,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) { host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(500, 500)); - LayerImpl* scrolling_layer = host_impl_->OuterViewportScrollLayer(); EXPECT_EQ(scrolling_layer->scroll_tree_index(), host_impl_->CurrentlyScrollingNode()->id); @@ -12877,7 +11513,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) { content_layer->SetBounds(new_content_size); scrolling_layer->SetBounds(new_content_size); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + GetScrollNode(scrolling_layer)->bounds = new_content_size; DrawFrame(); @@ -12900,9 +11536,8 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { scoped_refptr<RasterSource> raster_source_with_tiles( FakeRasterSource::CreateFilled(gfx::Size(10, 10))); - std::unique_ptr<FakePictureLayerImpl> layer = - FakePictureLayerImpl::Create(host_impl_->pending_tree(), 11); - layer->SetBounds(gfx::Size(10, 10)); + auto* layer = SetupRootLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(10, 10)); layer->set_gpu_raster_max_texture_size( host_impl_->active_tree()->GetDeviceViewport().size()); layer->SetDrawsContent(true); @@ -12914,18 +11549,14 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) { layer->tilings()->tiling_at(0)->CreateAllTilesForTesting(); layer->tilings()->UpdateTilePriorities(gfx::Rect(gfx::Size(10, 10)), 1.f, 1.0, Occlusion(), true); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(layer)); - auto* root_layer = static_cast<FakePictureLayerImpl*>( - host_impl_->pending_tree()->root_layer_for_testing()); - - root_layer->set_has_valid_tile_priorities(true); + layer->set_has_valid_tile_priorities(true); std::unique_ptr<RasterTilePriorityQueue> non_empty_raster_priority_queue_all = host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL); EXPECT_FALSE(non_empty_raster_priority_queue_all->IsEmpty()); - root_layer->set_has_valid_tile_priorities(false); + layer->set_has_valid_tile_priorities(false); std::unique_ptr<RasterTilePriorityQueue> empty_raster_priority_queue_all = host_impl_->BuildRasterQueue(TreePriority::SAME_PRIORITY_FOR_BOTH_TREES, RasterTilePriorityQueue::Type::ALL); @@ -12939,44 +11570,39 @@ TEST_F(LayerTreeHostImplTest, DidBecomeActive) { LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - std::unique_ptr<FakePictureLayerImpl> pending_layer = - FakePictureLayerImpl::Create(pending_tree, 10); - FakePictureLayerImpl* raw_pending_layer = pending_layer.get(); - pending_tree->SetRootLayerForTesting(std::move(pending_layer)); - ASSERT_EQ(raw_pending_layer, pending_tree->root_layer_for_testing()); + auto* pending_layer = + SetupRootLayer<FakePictureLayerImpl>(pending_tree, gfx::Size(10, 10)); - EXPECT_EQ(0u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(0u, pending_layer->did_become_active_call_count()); pending_tree->DidBecomeActive(); - EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(1u, pending_layer->did_become_active_call_count()); std::unique_ptr<FakePictureLayerImpl> mask_layer = - FakePictureLayerImpl::Create(pending_tree, 11); + FakePictureLayerImpl::Create(pending_tree, next_layer_id_++); FakePictureLayerImpl* raw_mask_layer = mask_layer.get(); - raw_pending_layer->test_properties()->SetMaskLayer(std::move(mask_layer)); - ASSERT_EQ(raw_mask_layer, raw_pending_layer->test_properties()->mask_layer); - pending_tree->BuildPropertyTreesForTesting(); + SetupMaskProperties(pending_layer, raw_mask_layer); + pending_tree->AddLayer(std::move(mask_layer)); - EXPECT_EQ(1u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(1u, pending_layer->did_become_active_call_count()); EXPECT_EQ(0u, raw_mask_layer->did_become_active_call_count()); pending_tree->DidBecomeActive(); - EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(2u, pending_layer->did_become_active_call_count()); EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); - pending_tree->BuildPropertyTreesForTesting(); - - EXPECT_EQ(2u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(2u, pending_layer->did_become_active_call_count()); EXPECT_EQ(1u, raw_mask_layer->did_become_active_call_count()); pending_tree->DidBecomeActive(); - EXPECT_EQ(3u, raw_pending_layer->did_become_active_call_count()); + EXPECT_EQ(3u, pending_layer->did_become_active_call_count()); EXPECT_EQ(2u, raw_mask_layer->did_become_active_call_count()); } TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) { - LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* scroll_layer = InnerViewportScrollLayer(); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); DrawFrame(); - EXPECT_EQ(scroll_layer, host_impl_->InnerViewportScrollLayer()); + EXPECT_EQ(scroll_layer, InnerViewportScrollLayer()); float min_page_scale = 1.f, max_page_scale = 4.f; float page_scale_factor = 1.f; @@ -13223,33 +11849,6 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) { EXPECT_FALSE(controller.did_draw_frame()); } -// Tests that SetHasGpuRasterizationTrigger behaves as expected. -TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusTrigger) { - // Set initial state, before varying GPU rasterization trigger. - host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->SetContentHasSlowPaths(false); - host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, - host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); - host_impl_->NotifyReadyToActivate(); - - // Toggle the trigger on. - host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); - EXPECT_TRUE(host_impl_->use_gpu_rasterization()); - host_impl_->NotifyReadyToActivate(); - - // And off. - host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->CommitComplete(); - EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, - host_impl_->gpu_rasterization_status()); - EXPECT_FALSE(host_impl_->use_gpu_rasterization()); - host_impl_->NotifyReadyToActivate(); -} - // Tests that SetContentHasSlowPaths behaves as expected. TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) { LayerTreeSettings msaaSettings = DefaultSettings(); @@ -13259,7 +11858,6 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) { msaaSettings.gpu_rasterization_msaa_sample_count))); // Set initial state, with slow paths on. - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -13294,7 +11892,6 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(4))); // Set initial state, before varying scale factor. - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13329,7 +11926,6 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusExplicitMSAACount) { msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization( msaaSettings.gpu_rasterization_msaa_sample_count))); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -13349,10 +11945,8 @@ class GpuRasterizationDisabledLayerTreeHostImplTest // Tests that GPU rasterization overrides work as expected. TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest, GpuRasterizationStatusOverrides) { - // GPU rasterization explicitly disabled. LayerTreeSettings settings = DefaultSettings(); EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE, @@ -13363,7 +11957,6 @@ TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest, settings.gpu_rasterization_forced = true; EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d())); - host_impl_->SetHasGpuRasterizationTrigger(false); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON_FORCED, @@ -13394,7 +11987,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // Ensure that without the msaa_is_slow or avoid_stencil_buffers caps // we raster slow paths with msaa. CreateHostImplWithCaps(false, false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, @@ -13405,7 +11997,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // we don't raster slow paths with msaa (we'll still use GPU raster, though). // msaa_is_slow = true, avoid_stencil_buffers = false CreateHostImplWithCaps(true, false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13414,7 +12005,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // msaa_is_slow = false, avoid_stencil_buffers = true CreateHostImplWithCaps(false, true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13423,7 +12013,6 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) { // msaa_is_slow = true, avoid_stencil_buffers = true CreateHostImplWithCaps(true, true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); @@ -13455,7 +12044,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that without non-aa paint and without multisample compatibility, we // raster slow paths with msaa. CreateHostImplWithMultisampleCompatibility(false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(false); host_impl_->CommitComplete(); @@ -13466,7 +12054,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that without non-aa paint and with multisample compatibility, we // raster slow paths with msaa. CreateHostImplWithMultisampleCompatibility(true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(false); host_impl_->CommitComplete(); @@ -13477,7 +12064,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that with non-aa paint and without multisample compatibility, we do // not raster slow paths with msaa. CreateHostImplWithMultisampleCompatibility(false); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(true); host_impl_->CommitComplete(); @@ -13487,7 +12073,6 @@ TEST_F(MsaaCompatibilityLayerTreeHostImplTest, // Ensure that with non-aa paint and with multisample compatibility, we raster // slow paths with msaa. CreateHostImplWithMultisampleCompatibility(true); - host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentHasSlowPaths(true); host_impl_->SetContentHasNonAAPaint(true); host_impl_->CommitComplete(); @@ -13501,45 +12086,44 @@ TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) { // on the active tree. CreatePendingTree(); host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50), + gfx::Size(100, 100), gfx::Size(100, 100)); host_impl_->ActivateSyncTree(); DrawFrame(); CreatePendingTree(); host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f); - LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer(); TransformNode* active_tree_node = - host_impl_->active_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + host_impl_->active_tree()->PageScaleTransformNode(); // SetPageScaleOnActiveTree also updates the factors in property trees. EXPECT_TRUE(active_tree_node->local.IsScale2d()); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d()); EXPECT_EQ(gfx::Point3F(), active_tree_node->origin); - EXPECT_EQ(host_impl_->active_tree()->current_page_scale_factor(), 2.f); + EXPECT_EQ(2.f, host_impl_->active_tree()->current_page_scale_factor()); TransformNode* pending_tree_node = - host_impl_->pending_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + host_impl_->pending_tree()->PageScaleTransformNode(); + // Before pending tree updates draw properties, its properties are still + // based on 1.0 page scale, except for current_page_scale_factor() which is a + // shared data between the active and pending trees. EXPECT_TRUE(pending_tree_node->local.IsIdentity()); EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin); - EXPECT_EQ(host_impl_->pending_tree()->current_page_scale_factor(), 2.f); - - host_impl_->pending_tree()->UpdateDrawProperties(); - pending_tree_node = - host_impl_->pending_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + EXPECT_EQ(2.f, host_impl_->pending_tree()->current_page_scale_factor()); + EXPECT_EQ(1.f, host_impl_->pending_tree() + ->property_trees() + ->transform_tree.page_scale_factor()); + + host_impl_->pending_tree()->set_needs_update_draw_properties(); + UpdateDrawProperties(host_impl_->pending_tree()); + pending_tree_node = host_impl_->pending_tree()->PageScaleTransformNode(); EXPECT_TRUE(pending_tree_node->local.IsScale2d()); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), pending_tree_node->local.Scale2d()); EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->UpdateDrawProperties(); - active_tree_node = - host_impl_->active_tree()->property_trees()->transform_tree.Node( - page_scale_layer->transform_tree_index()); + UpdateDrawProperties(host_impl_->active_tree()); + active_tree_node = host_impl_->active_tree()->PageScaleTransformNode(); EXPECT_TRUE(active_tree_node->local.IsScale2d()); EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d()); EXPECT_EQ(gfx::Point3F(), active_tree_node->origin); @@ -13549,102 +12133,27 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { // Checks that the sublayer scale of a transform node in the subtree of the // page scale layer is updated without a property tree rebuild. host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f); - CreateScrollAndContentsLayers(host_impl_->active_tree(), gfx::Size(100, 100)); - LayerImpl* page_scale_layer = host_impl_->active_tree()->PageScaleLayer(); - page_scale_layer->test_properties()->AddChild( - LayerImpl::Create(host_impl_->active_tree(), 100)); - - LayerImpl* in_subtree_of_page_scale_layer = - host_impl_->active_tree()->LayerById(100); - in_subtree_of_page_scale_layer->test_properties()->force_render_surface = - true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + LayerImpl* in_subtree_of_page_scale_layer = AddLayer(); + CopyProperties(root_layer(), in_subtree_of_page_scale_layer); + in_subtree_of_page_scale_layer->SetTransformTreeIndex( + host_impl_->active_tree()->PageScaleTransformNode()->id); + CreateEffectNode(in_subtree_of_page_scale_layer).render_surface_reason = + RenderSurfaceReason::kTest; DrawFrame(); - EffectNode* node = - host_impl_->active_tree()->property_trees()->effect_tree.Node( - in_subtree_of_page_scale_layer->effect_tree_index()); + EffectNode* node = GetEffectNode(in_subtree_of_page_scale_layer); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f)); host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f); DrawFrame(); - in_subtree_of_page_scale_layer = host_impl_->active_tree()->LayerById(100); - node = host_impl_->active_tree()->property_trees()->effect_tree.Node( - in_subtree_of_page_scale_layer->effect_tree_index()); + node = GetEffectNode(in_subtree_of_page_scale_layer); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); } -TEST_F(LayerTreeHostImplTest, JitterTest) { - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(100, 100)); - - CreatePendingTree(); - CreateScrollAndContentsLayers(host_impl_->pending_tree(), - gfx::Size(100, 100)); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); - - host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - const int scroll = 5; - int accumulated_scroll = 0; - for (int i = 0; i < host_impl_->pending_tree()->kFixedPointHitsThreshold + 1; - ++i) { - host_impl_->ActivateSyncTree(); - host_impl_->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), - InputHandler::TOUCHSCREEN); - host_impl_->ScrollBy( - UpdateState(gfx::Point(), gfx::Vector2dF(0, scroll)).get()); - accumulated_scroll += scroll; - host_impl_->ScrollEnd(EndState().get()); - host_impl_->active_tree()->UpdateDrawProperties(); - - CreatePendingTree(); - host_impl_->pending_tree()->set_source_frame_number(i + 1); - LayerImpl* content_layer = host_impl_->pending_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->children[0]; - // The scroll done on the active tree is undone on the pending tree. - gfx::Transform translate; - translate.Translate(0, accumulated_scroll); - content_layer->test_properties()->transform = translate; - - LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - LayerImpl* last_scrolled_layer = pending_tree->LayerById( - host_impl_->active_tree()->InnerViewportScrollLayer()->id()); - - // When building property trees from impl side, the builder uses the scroll - // offset of layer_impl to initialize the scroll offset in scroll tree: - // scroll_tree.synced_scroll_offset.PushMainToPending( - // layer->CurrentScrollOffset()). - // However, layer_impl does not store scroll_offset, so it is using scroll - // tree's scroll offset to initialize itself. Usually this approach works - // because this is a simple assignment. However if scroll_offset's pending - // delta is not zero, the delta would be counted twice. - // This hacking here is to restore the damaged scroll offset. - gfx::ScrollOffset pending_base = - pending_tree->property_trees() - ->scroll_tree.GetScrollOffsetBaseForTesting( - last_scrolled_layer->element_id()); - pending_tree->BuildPropertyTreesForTesting(); - pending_tree->property_trees() - ->scroll_tree.UpdateScrollOffsetBaseForTesting( - last_scrolled_layer->element_id(), pending_base); - pending_tree->LayerById(content_layer->id())->SetNeedsPushProperties(); - - pending_tree->set_needs_update_draw_properties(); - pending_tree->UpdateDrawProperties(); - float jitter = LayerTreeHostCommon::CalculateLayerJitter(content_layer); - // There should not be any jitter measured till we hit the fixed point hits - // threshold. - float expected_jitter = - (i == pending_tree->kFixedPointHitsThreshold) ? 500 : 0; - EXPECT_EQ(jitter, expected_jitter); - } -} - // Checks that if we lose a GPU raster enabled LayerTreeFrameSink and replace // it with a software LayerTreeFrameSink, LayerTreeHostImpl correctly // re-computes GPU rasterization status. @@ -13658,7 +12167,8 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnLayerTreeFrameSinkChange) { host_impl_ = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, &task_graph_runner_, - AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr); + AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0, nullptr, + nullptr); host_impl_->SetVisible(true); // InitializeFrameSink with a gpu-raster enabled output surface. @@ -13685,48 +12195,29 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( gfx::Size scrollbar_size_1(gfx::Size(15, viewport_size.height())); gfx::Size scrollbar_size_2(gfx::Size(15, child_layer_size.height())); - const int scrollbar_1_id = 10; - const int scrollbar_2_id = 11; - const int child_scroll_id = 13; - CreateHostImpl(settings, CreateLayerTreeFrameSink()); host_impl_->active_tree()->SetDeviceScaleFactor(1); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - CreateScrollAndContentsLayers(host_impl_->active_tree(), content_size); - host_impl_->active_tree()->InnerViewportContainerLayer()->SetBounds( - viewport_size); - LayerImpl* root_scroll = - host_impl_->active_tree()->OuterViewportScrollLayer(); + SetupViewportLayersInnerScrolls(viewport_size, content_size); + LayerImpl* root_scroll = OuterViewportScrollLayer(); if (main_thread_scrolling) { - root_scroll->test_properties()->main_thread_scrolling_reasons = + GetScrollNode(root_scroll)->main_thread_scrolling_reasons = MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; } // scrollbar_1 on root scroll. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_1 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_1_id, VERTICAL, 15, 0, - true, true); - scrollbar_1->SetScrollElementId(root_scroll->element_id()); - scrollbar_1->SetDrawsContent(true); + auto* scrollbar_1 = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + SetupScrollbarLayer(root_scroll, scrollbar_1); scrollbar_1->SetBounds(scrollbar_size_1); TouchActionRegion touch_action_region; touch_action_region.Union(kTouchActionNone, gfx::Rect(scrollbar_size_1)); scrollbar_1->SetTouchActionRegion(touch_action_region); - scrollbar_1->SetCurrentPos(0); - scrollbar_1->test_properties()->position = gfx::PointF(0, 0); - host_impl_->active_tree() - ->InnerViewportContainerLayer() - ->test_properties() - ->AddChild(std::move(scrollbar_1)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); DrawFrame(); - host_impl_->active_tree()->UpdateDrawProperties(); ScrollbarAnimationController* scrollbar_1_animation_controller = host_impl_->ScrollbarAnimationControllerForElementId( @@ -13800,40 +12291,26 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( scrollbar_1_animation_controller->MouseIsOverScrollbarThumb(VERTICAL)); // scrollbar_2 on child. - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_2 = - SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), - scrollbar_2_id, VERTICAL, 15, 0, - true, true); - std::unique_ptr<LayerImpl> child = - LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); - child->test_properties()->position = gfx::PointF(50, 50); - child->SetBounds(child_layer_size); - child->SetDrawsContent(true); - child->SetScrollable(gfx::Size(100, 100)); - child->SetHitTestable(true); - child->SetElementId(LayerIdToElementIdForTesting(child->id())); - ElementId child_element_id = child->element_id(); - + auto* scrollbar_2 = AddLayer<SolidColorScrollbarLayerImpl>( + host_impl_->active_tree(), VERTICAL, 15, 0, true); + LayerImpl* child = + AddScrollableLayer(root_scroll, gfx::Size(100, 100), child_layer_size); + child->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); if (main_thread_scrolling) { - child->test_properties()->main_thread_scrolling_reasons = + GetScrollNode(child)->main_thread_scrolling_reasons = MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; } - scrollbar_2->SetScrollElementId(child_element_id); - scrollbar_2->SetDrawsContent(true); + SetupScrollbarLayer(child, scrollbar_2); scrollbar_2->SetBounds(scrollbar_size_2); - scrollbar_2->SetCurrentPos(0); - scrollbar_2->test_properties()->position = gfx::PointF(0, 0); - - child->test_properties()->AddChild(std::move(scrollbar_2)); - root_scroll->test_properties()->AddChild(std::move(child)); + scrollbar_2->SetOffsetToTransformParent(child->offset_to_transform_parent()); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); host_impl_->active_tree()->UpdateScrollbarGeometries(); host_impl_->active_tree()->DidBecomeActive(); ScrollbarAnimationController* scrollbar_2_animation_controller = - host_impl_->ScrollbarAnimationControllerForElementId(child_element_id); + host_impl_->ScrollbarAnimationControllerForElementId(child->element_id()); EXPECT_TRUE(scrollbar_2_animation_controller); // Mouse goes over scrollbar_2, moves close to scrollbar_2, moves close to @@ -13896,7 +12373,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( animation_task_.Reset(); // Only the MouseMove's location will affect the overlay scrollbar. - host_impl_->MouseDown(gfx::PointF(60, 50)); + host_impl_->MouseDown(gfx::PointF(60, 50), /*shift_modifier*/ false); host_impl_->MouseMoveAt(gfx::Point(60, 50)); host_impl_->MouseUp(gfx::PointF(60, 50)); @@ -13907,14 +12384,14 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates( host_impl_->MouseMoveAt(gfx::Point(40, 150)); animation_task_.Reset(); - host_impl_->MouseDown(gfx::PointF(40, 150)); + host_impl_->MouseDown(gfx::PointF(40, 150), /*shift_modifier*/ false); host_impl_->MouseUp(gfx::PointF(40, 150)); EXPECT_TRUE(animation_task_.is_null()); // Near scrollbar_1, then mouse down and unregister // scrollbar_2_animation_controller, then mouse up should not cause crash. host_impl_->MouseMoveAt(gfx::Point(40, 150)); - host_impl_->MouseDown(gfx::PointF(40, 150)); + host_impl_->MouseDown(gfx::PointF(40, 150), /*shift_modifier*/ false); host_impl_->UnregisterScrollbarAnimationController(root_scroll->element_id()); host_impl_->MouseUp(gfx::PointF(40, 150)); } @@ -13930,7 +12407,7 @@ TEST_F(LayerTreeHostImplTest, } TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { - LayerTreeSettings settings = DefaultSettings(); + LayerTreeSettings settings = LegacySWSettings(); settings.commit_to_active_tree = false; settings.enable_checker_imaging = true; settings.min_image_bytes_to_checker = 512 * 1024; @@ -13966,14 +12443,10 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { // Create the pending tree. host_impl_->BeginCommit(); LayerTreeImpl* pending_tree = host_impl_->pending_tree(); - pending_tree->SetDeviceViewportRect(gfx::Rect(layer_size)); - pending_tree->SetRootLayerForTesting( - FakePictureLayerImpl::CreateWithRasterSource(pending_tree, 1, - raster_source)); - auto* root = static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); - root->SetBounds(layer_size); + auto* root = SetupRootLayer<FakePictureLayerImpl>(pending_tree, layer_size, + raster_source); root->SetDrawsContent(true); - pending_tree->BuildPropertyTreesForTesting(); + UpdateDrawProperties(pending_tree); // Update the decoding state map for the tracker so it knows the correct // decoding preferences for the image. @@ -14004,7 +12477,7 @@ TEST_F(LayerTreeHostImplTest, CheckerImagingTileInvalidation) { // invalidated on the pending tree. host_impl_->InvalidateContentOnImplSide(); pending_tree = host_impl_->pending_tree(); - root = static_cast<FakePictureLayerImpl*>(*pending_tree->begin()); + root = static_cast<FakePictureLayerImpl*>(pending_tree->root_layer()); for (auto* tile : root->tilings()->tiling_at(0)->AllTilesForTesting()) { if (tile->tiling_i_index() < 2 && tile->tiling_j_index() < 2) EXPECT_TRUE(tile->HasRasterTask()); @@ -14043,34 +12516,29 @@ TEST_F(LayerTreeHostImplTest, RasterColorSpaceSoftware) { TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { gfx::Size layer_bounds(500, 500); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds)); CreatePendingTree(); - std::unique_ptr<LayerImpl> scoped_root = - LayerImpl::Create(host_impl_->pending_tree(), 1); - scoped_root->SetBounds(layer_bounds); - LayerImpl* root = scoped_root.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + auto* root = + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), layer_bounds); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(layer_bounds)); - std::unique_ptr<FakePictureLayerImpl> scoped_animated_transform_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 2, raster_source); - scoped_animated_transform_layer->SetBounds(layer_bounds); - scoped_animated_transform_layer->SetDrawsContent(true); + auto* animated_transform_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + animated_transform_layer->SetBounds(layer_bounds); + animated_transform_layer->SetDrawsContent(true); + + host_impl_->pending_tree()->SetElementIdsForTesting(); gfx::Transform singular; singular.Scale3d(6.f, 6.f, 0.f); - scoped_animated_transform_layer->test_properties()->transform = singular; - FakePictureLayerImpl* animated_transform_layer = - scoped_animated_transform_layer.get(); - root->test_properties()->AddChild(std::move(scoped_animated_transform_layer)); + CopyProperties(root, animated_transform_layer); + CreateTransformNode(animated_transform_layer).local = singular; // A layer with a non-invertible transform is not drawn or rasterized. Since // this layer is not rasterized, we shouldn't be creating any tilings for it. - host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_FALSE(animated_transform_layer->HasValidTilePriorities()); EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); - host_impl_->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_FALSE(animated_transform_layer->raster_even_if_not_drawn()); EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 0u); @@ -14078,7 +12546,6 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { // Now add a transform animation to this layer. While we don't drawn layers // with non-invertible transforms, we still raster them if there is a // transform animation. - host_impl_->pending_tree()->SetElementIdsForTesting(); TransformOperations start_transform_operations; start_transform_operations.AppendMatrix(singular); TransformOperations end_transform_operations; @@ -14089,11 +12556,10 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { // The layer is still not drawn, but it will be rasterized. Since the layer is // rasterized, we should be creating tilings for it in UpdateDrawProperties. // However, none of these tiles should be required for activation. - host_impl_->pending_tree()->BuildLayerListAndPropertyTreesForTesting(); - host_impl_->pending_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->pending_tree()); EXPECT_TRUE(animated_transform_layer->raster_even_if_not_drawn()); EXPECT_FALSE(animated_transform_layer->contributes_to_drawn_render_surface()); - EXPECT_EQ(animated_transform_layer->tilings()->num_tilings(), 1u); + ASSERT_EQ(animated_transform_layer->tilings()->num_tilings(), 1u); EXPECT_FALSE(animated_transform_layer->tilings() ->tiling_at(0) ->can_require_tiles_for_activation()); @@ -14101,38 +12567,29 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) { TEST_F(LayerTreeHostImplTest, RasterTilePrioritizationForNonDrawingLayers) { gfx::Size layer_bounds(500, 500); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(layer_bounds)); CreatePendingTree(); - std::unique_ptr<LayerImpl> scoped_root = - LayerImpl::Create(host_impl_->pending_tree(), 1); - scoped_root->SetBounds(layer_bounds); - LayerImpl* root = scoped_root.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_root)); + auto* root = + SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), layer_bounds); + root->SetBounds(layer_bounds); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(layer_bounds)); - std::unique_ptr<FakePictureLayerImpl> scoped_hidden_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 2, raster_source); - scoped_hidden_layer->SetBounds(layer_bounds); - scoped_hidden_layer->SetDrawsContent(true); - scoped_hidden_layer->set_contributes_to_drawn_render_surface(true); - FakePictureLayerImpl* hidden_layer = scoped_hidden_layer.get(); - root->test_properties()->AddChild(std::move(scoped_hidden_layer)); - - std::unique_ptr<FakePictureLayerImpl> scoped_drawing_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 3, raster_source); - scoped_drawing_layer->SetBounds(layer_bounds); - scoped_drawing_layer->SetDrawsContent(true); - scoped_drawing_layer->set_contributes_to_drawn_render_surface(true); - FakePictureLayerImpl* drawing_layer = scoped_drawing_layer.get(); - root->test_properties()->AddChild(std::move(scoped_drawing_layer)); + auto* hidden_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + hidden_layer->SetBounds(layer_bounds); + hidden_layer->SetDrawsContent(true); + hidden_layer->set_contributes_to_drawn_render_surface(true); + CopyProperties(root, hidden_layer); + + auto* drawing_layer = + AddLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), raster_source); + drawing_layer->SetBounds(layer_bounds); + drawing_layer->SetDrawsContent(true); + drawing_layer->set_contributes_to_drawn_render_surface(true); + CopyProperties(root, drawing_layer); gfx::Rect layer_rect(0, 0, 500, 500); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); hidden_layer->tilings()->AddTiling(gfx::AxisTransform2d(), raster_source); PictureLayerTiling* hidden_tiling = hidden_layer->tilings()->tiling_at(0); @@ -14179,19 +12636,13 @@ TEST_F(LayerTreeHostImplTest, DrawAfterDroppingTileResources) { gfx::Size bounds(100, 100); scoped_refptr<FakeRasterSource> raster_source( FakeRasterSource::CreateFilled(bounds)); - { - std::unique_ptr<FakePictureLayerImpl> scoped_layer = - FakePictureLayerImpl::CreateWithRasterSource(host_impl_->pending_tree(), - 1, raster_source); - scoped_layer->SetBounds(bounds); - scoped_layer->SetDrawsContent(true); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(scoped_layer)); - } - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + auto* root = SetupRootLayer<FakePictureLayerImpl>(host_impl_->pending_tree(), + bounds, raster_source); + root->SetDrawsContent(true); host_impl_->ActivateSyncTree(); FakePictureLayerImpl* layer = static_cast<FakePictureLayerImpl*>( - host_impl_->active_tree()->FindActiveTreeLayerById(1)); + host_impl_->active_tree()->FindActiveTreeLayerById(root->id())); DrawFrame(); EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties()); @@ -14213,11 +12664,6 @@ TEST_F(LayerTreeHostImplTest, DrawAfterDroppingTileResources) { TEST_F(LayerTreeHostImplTest, NeedUpdateGpuRasterization) { EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); - host_impl_->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); - host_impl_->CommitComplete(); - EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); - host_impl_->SetContentHasSlowPaths(true); EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting()); host_impl_->CommitComplete(); @@ -14278,7 +12724,7 @@ class TestRenderFrameMetadataObserver : public RenderFrameMetadataObserver { }; TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f); @@ -14319,22 +12765,16 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { // Root "overflow: hidden" properties should be reflected on the outer // viewport scroll layer. { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_horizontal = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_FALSE(metadata.root_overflow_y_hidden); } { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_vertical = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_y_hidden); @@ -14343,15 +12783,9 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { // Re-enable scrollability and verify that overflows are no longer // hidden. { - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = true; - host_impl_->active_tree() - ->OuterViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = true; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_horizontal = true; + host_impl_->OuterViewportScrollNode()->user_scrollable_vertical = true; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_FALSE(metadata.root_overflow_y_hidden); @@ -14360,22 +12794,16 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { // Root "overflow: hidden" properties should also be reflected on the // inner viewport scroll layer. { - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->user_scrollable_horizontal = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_horizontal = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_FALSE(metadata.root_overflow_y_hidden); } { - host_impl_->active_tree() - ->InnerViewportScrollLayer() - ->test_properties() - ->user_scrollable_vertical = false; - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); + host_impl_->OuterViewportScrollNode()->user_scrollable_vertical = false; RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata(); EXPECT_TRUE(metadata.root_overflow_y_hidden); @@ -14423,16 +12851,8 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) { } TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { - const int root_layer_id = 1; - std::unique_ptr<SolidColorLayerImpl> root = - SolidColorLayerImpl::Create(host_impl_->active_tree(), root_layer_id); - root->test_properties()->position = gfx::PointF(); - root->SetBounds(gfx::Size(10, 10)); - root->SetDrawsContent(true); - root->test_properties()->force_render_surface = true; - - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(10, 10)); + UpdateDrawProperties(host_impl_->active_tree()); auto observer = std::make_unique<TestRenderFrameMetadataObserver>(false); auto* observer_ptr = observer.get(); @@ -14441,10 +12861,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { // Trigger a draw-swap sequence. host_impl_->SetNeedsRedraw(); - TestFrameData frame; - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame)); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); // Ensure the selection bounds propagated to the render frame metadata // represent an empty selection. @@ -14463,7 +12880,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { gfx::Point selection_bottom(5, 5); LayerSelection selection; selection.start.type = gfx::SelectionBound::CENTER; - selection.start.layer_id = root_layer_id; + selection.start.layer_id = root->id(); selection.start.edge_bottom = selection_bottom; selection.start.edge_top = selection_top; selection.end = selection.start; @@ -14471,9 +12888,7 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { // Trigger a draw-swap sequence. host_impl_->SetNeedsRedraw(); - EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame)); - EXPECT_TRUE(host_impl_->DrawLayers(&frame)); - host_impl_->DidDrawAllLayers(frame); + DrawFrame(); // Ensure the selection bounds have propagated to the render frame metadata. ASSERT_TRUE(observer_ptr->last_metadata()); @@ -14490,8 +12905,8 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) { // Tests ScrollBy() to see if the method sets the scroll tree's currently // scrolling node and the ScrollState properly. TEST_F(LayerTreeHostImplTest, ScrollByScrollingNode) { - SetupScrollAndContentsLayers(gfx::Size(100, 100)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + UpdateDrawProperties(host_impl_->active_tree()); // Create a ScrollState object with no scrolling element. ScrollStateData scroll_state_data; @@ -14544,8 +12959,8 @@ class HitTestRegionListGeneratingLayerTreeHostImplTest // Enable hit test data generation with the CompositorFrame. LayerTreeSettings new_settings = settings; new_settings.build_hit_test_data = true; - return CreateHostImplWithTaskRunnerProvider( - new_settings, std::move(layer_tree_frame_sink), &task_runner_provider_); + return LayerTreeHostImplTest::CreateHostImpl( + new_settings, std::move(layer_tree_frame_sink)); } }; @@ -14556,22 +12971,18 @@ TEST_F(LayerTreeHostImplTest, DisabledBuildHitTestData) { // Setup surface layers in LayerTreeHostImpl. host_impl_->CreatePendingTree(); host_impl_->ActivateSyncTree(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - std::unique_ptr<SurfaceLayerImpl> surface_child = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); + auto* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - surface_child->test_properties()->position = gfx::PointF(50, 50); surface_child->SetBounds(gfx::Size(100, 100)); surface_child->SetDrawsContent(true); surface_child->SetSurfaceHitTestable(true); - root->test_properties()->AddChild(std::move(surface_child)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); + CopyProperties(root, surface_child); + surface_child->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); @@ -14591,36 +13002,26 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) { // +-----surface_child1 (50, 50), 100x100, Rotate(45) // +---surface_child2 (450, 300), 100x100 // +---overlapping_layer (500, 350), 200x200 - std::unique_ptr<LayerImpl> intermediate_layer = - LayerImpl::Create(host_impl_->active_tree(), 2); - std::unique_ptr<SurfaceLayerImpl> surface_child1 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); - std::unique_ptr<SurfaceLayerImpl> surface_child2 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 4); - std::unique_ptr<LayerImpl> overlapping_layer = - LayerImpl::Create(host_impl_->active_tree(), 5); + auto* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* intermediate_layer = AddLayer(); + auto* surface_child1 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); + auto* surface_child2 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); + auto* overlapping_layer = AddLayer(); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - - intermediate_layer->test_properties()->position = gfx::PointF(200, 300); intermediate_layer->SetBounds(gfx::Size(200, 200)); - surface_child1->test_properties()->position = gfx::PointF(50, 50); surface_child1->SetBounds(gfx::Size(100, 100)); gfx::Transform rotate; rotate.Rotate(45); - surface_child1->test_properties()->transform = rotate; surface_child1->SetDrawsContent(true); surface_child1->SetHitTestable(true); surface_child1->SetSurfaceHitTestable(true); - surface_child2->test_properties()->position = gfx::PointF(450, 300); surface_child2->SetBounds(gfx::Size(100, 100)); surface_child2->SetDrawsContent(true); surface_child2->SetHitTestable(true); surface_child2->SetSurfaceHitTestable(true); - overlapping_layer->test_properties()->position = gfx::PointF(500, 350); overlapping_layer->SetBounds(gfx::Size(200, 200)); overlapping_layer->SetDrawsContent(true); overlapping_layer->SetHitTestable(true); @@ -14634,24 +13035,20 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) { surface_child2->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - intermediate_layer->test_properties()->AddChild(std::move(surface_child1)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(intermediate_layer)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child2)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(overlapping_layer)); + CopyProperties(root, intermediate_layer); + intermediate_layer->SetOffsetToTransformParent(gfx::Vector2dF(200, 300)); + CopyProperties(root, surface_child2); + surface_child2->SetOffsetToTransformParent(gfx::Vector2dF(450, 300)); + CopyProperties(root, overlapping_layer); + overlapping_layer->SetOffsetToTransformParent(gfx::Vector2dF(500, 350)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); + CopyProperties(intermediate_layer, surface_child1); + auto& surface_child1_transform_node = CreateTransformNode(surface_child1); + // The post_translation includes offset of intermediate_layer. + surface_child1_transform_node.post_translation = gfx::Vector2dF(250, 350); + surface_child1_transform_node.local = rotate; + + UpdateDrawProperties(host_impl_->active_tree()); draw_property_utils::ComputeEffects( &host_impl_->active_tree()->property_trees()->effect_tree); @@ -14710,26 +13107,24 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, PointerEvents) { // +---surface_child1 (0, 0), 100x100 // +---overlapping_surface_child2 (50, 50), 100x100, pointer-events: none, // does not generate hit test region - std::unique_ptr<SurfaceLayerImpl> surface_child1 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); - std::unique_ptr<SurfaceLayerImpl> surface_child2 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); + auto* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child1 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); + auto* surface_child2 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - - surface_child1->test_properties()->position = gfx::PointF(0, 0); surface_child1->SetBounds(gfx::Size(100, 100)); surface_child1->SetDrawsContent(true); surface_child1->SetHitTestable(true); surface_child1->SetSurfaceHitTestable(true); surface_child1->SetHasPointerEventsNone(false); + CopyProperties(root, surface_child1); - surface_child2->test_properties()->position = gfx::PointF(50, 50); surface_child2->SetBounds(gfx::Size(100, 100)); surface_child2->SetDrawsContent(true); surface_child2->SetHitTestable(true); surface_child2->SetSurfaceHitTestable(false); surface_child2->SetHasPointerEventsNone(true); + CopyProperties(root, surface_child2); + surface_child2->SetOffsetToTransformParent(gfx::Vector2dF(50, 50)); viz::LocalSurfaceId child_local_surface_id(2, base::UnguessableToken::Create()); @@ -14738,22 +13133,9 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, PointerEvents) { surface_child1->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child1)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child2)); - constexpr gfx::Rect kFrameRect(0, 0, 1024, 768); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); // Generating HitTestRegionList should have been enabled for this test. @@ -14792,12 +13174,9 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, ComplexPage) { // +-Root (1024x768) // +---surface_child (0, 0), 100x100 // +---100x non overlapping layers (110, 110), 1x1 - std::unique_ptr<SurfaceLayerImpl> surface_child = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); - - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - surface_child->test_properties()->position = gfx::PointF(0, 0); surface_child->SetBounds(gfx::Size(100, 100)); surface_child->SetDrawsContent(true); surface_child->SetHitTestable(true); @@ -14811,32 +13190,20 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, ComplexPage) { surface_child->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child)); + CopyProperties(root, surface_child); // Create 101 non overlapping layers. for (size_t i = 0; i <= 100; ++i) { - std::unique_ptr<LayerImpl> layer = - LayerImpl::Create(host_impl_->active_tree(), i + 3); - layer->test_properties()->position = gfx::PointF(110, 110); + LayerImpl* layer = AddLayer(); layer->SetBounds(gfx::Size(1, 1)); layer->SetDrawsContent(true); layer->SetHitTestable(true); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(layer)); + CopyProperties(root, layer); } constexpr gfx::Rect kFrameRect(0, 0, 1024, 768); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); // Generating HitTestRegionList should have been enabled for this test. @@ -14875,17 +13242,17 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, InvalidFrameSinkId) { // +-Root (1024x768) // +---surface_child1 (0, 0), 100x100 // +---surface_child2 (0, 0), 50x50, frame_sink_id = (0, 0) - std::unique_ptr<SurfaceLayerImpl> surface_child1 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 2); + LayerImpl* root = SetupDefaultRootLayer(gfx::Size(1024, 768)); + auto* surface_child1 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(1024, 768)); - surface_child1->test_properties()->position = gfx::PointF(0, 0); surface_child1->SetBounds(gfx::Size(100, 100)); surface_child1->SetDrawsContent(true); surface_child1->SetHitTestable(true); surface_child1->SetSurfaceHitTestable(true); surface_child1->SetHasPointerEventsNone(false); + CopyProperties(root, surface_child1); viz::LocalSurfaceId child_local_surface_id(2, base::UnguessableToken::Create()); @@ -14894,36 +13261,21 @@ TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, InvalidFrameSinkId) { surface_child1->SetRange(viz::SurfaceRange(base::nullopt, child_surface_id), base::nullopt); - std::unique_ptr<SurfaceLayerImpl> surface_child2 = - SurfaceLayerImpl::Create(host_impl_->active_tree(), 3); + auto* surface_child2 = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree()); - surface_child2->test_properties()->position = gfx::PointF(0, 0); surface_child2->SetBounds(gfx::Size(50, 50)); surface_child2->SetDrawsContent(true); surface_child2->SetHitTestable(true); surface_child2->SetSurfaceHitTestable(true); surface_child2->SetHasPointerEventsNone(false); + CopyProperties(root, surface_child2); surface_child2->SetRange(viz::SurfaceRange(base::nullopt, viz::SurfaceId()), base::nullopt); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child1)); - - host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->AddChild(std::move(surface_child2)); - constexpr gfx::Rect kFrameRect(0, 0, 1024, 768); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - host_impl_->active_tree()->UpdateDrawProperties(); + UpdateDrawProperties(host_impl_->active_tree()); base::Optional<viz::HitTestRegionList> hit_test_region_list = host_impl_->BuildHitTestData(); // Generating HitTestRegionList should have been enabled for this test. @@ -14977,7 +13329,8 @@ TEST_F(LayerTreeHostImplTest, ImplThreadPhaseUponImplSideInvalidation) { TEST_F(LayerTreeHostImplTest, SkipOnDrawDoesNotUpdateDrawParams) { EXPECT_TRUE(CreateHostImpl(DefaultSettings(), FakeLayerTreeFrameSink::CreateSoftware())); - LayerImpl* layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); + SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100)); + auto* layer = InnerViewportScrollLayer(); layer->SetDrawsContent(true); gfx::Transform transform; transform.Translate(20, 20); @@ -15008,32 +13361,17 @@ TEST_F(LayerTreeHostImplTest, TouchScrollOnAndroidScrollbar) { gfx::Size scroll_content_size = gfx::Size(360, 3800); gfx::Size scrollbar_size = gfx::Size(15, 600); - host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(viewport_size)); - std::unique_ptr<LayerImpl> root = LayerImpl::Create(layer_tree_impl, 1); - root->SetBounds(viewport_size); - root->test_properties()->position = gfx::PointF(); - - std::unique_ptr<LayerImpl> content = LayerImpl::Create(layer_tree_impl, 2); - content->SetBounds(scroll_content_size); - content->SetScrollable(viewport_size); - content->SetHitTestable(true); - content->SetElementId(LayerIdToElementIdForTesting(content->id())); - content->SetDrawsContent(true); - - std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar = - SolidColorScrollbarLayerImpl::Create(layer_tree_impl, 3, VERTICAL, 10, 0, - false, true); - scrollbar->SetBounds(scrollbar_size); - scrollbar->test_properties()->position = gfx::PointF(345, 0); - scrollbar->SetScrollElementId(content->element_id()); - scrollbar->SetDrawsContent(true); - scrollbar->test_properties()->opacity = 1.f; + LayerImpl* root = SetupDefaultRootLayer(viewport_size); + LayerImpl* content = + AddScrollableLayer(root, viewport_size, scroll_content_size); - root->test_properties()->AddChild(std::move(content)); - root->test_properties()->AddChild(std::move(scrollbar)); + auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>( + layer_tree_impl, VERTICAL, 10, 0, false); + SetupScrollbarLayer(content, scrollbar); + scrollbar->SetBounds(scrollbar_size); + scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0)); - layer_tree_impl->SetRootLayerForTesting(std::move(root)); - layer_tree_impl->BuildPropertyTreesForTesting(); + UpdateDrawProperties(layer_tree_impl); layer_tree_impl->DidBecomeActive(); // Do a scroll over the scrollbar layer as well as the content layer, which @@ -15076,13 +13414,8 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithDirtyPaintWorklets) { // Setup the pending tree with a PictureLayerImpl that will contain // PaintWorklets. host_impl_->CreatePendingTree(); - std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create( - host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK); - PictureLayerImpl* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - - root->SetBounds(gfx::Size(100, 100)); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<PictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(100, 100)); root->SetNeedsPushProperties(); // Add a PaintWorkletInput to the PictureLayerImpl. @@ -15092,8 +13425,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, CommitWithDirtyPaintWorklets) { root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr, nullptr); - host_impl_->pending_tree()->SetElementIdsForTesting(); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); // Since we have dirty PaintWorklets, committing will not cause tile // preparation to happen. Instead, it will be delayed until the callback @@ -15131,13 +13463,8 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, std::make_unique<TestPaintWorkletLayerPainter>()); host_impl_->CreatePendingTree(); - std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create( - host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK); - PictureLayerImpl* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - - root->SetBounds(gfx::Size(100, 100)); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<PictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(100, 100)); root->SetNeedsPushProperties(); // Add some PaintWorklets. @@ -15147,8 +13474,7 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest, root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr, nullptr); - host_impl_->pending_tree()->SetElementIdsForTesting(); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); // Pretend that our worklets were already painted. ASSERT_EQ(root->GetPaintWorkletRecordMap().size(), 1u); @@ -15184,13 +13510,8 @@ TEST_F(ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest, // Setup the pending tree with a PictureLayerImpl that will contain // PaintWorklets. host_impl_->CreatePendingTree(); - std::unique_ptr<PictureLayerImpl> root_owned = PictureLayerImpl::Create( - host_impl_->pending_tree(), 1, Layer::LayerMaskType::NOT_MASK); - PictureLayerImpl* root = root_owned.get(); - host_impl_->pending_tree()->SetRootLayerForTesting(std::move(root_owned)); - - root->SetBounds(gfx::Size(100, 100)); - root->test_properties()->force_render_surface = true; + auto* root = SetupRootLayer<PictureLayerImpl>(host_impl_->pending_tree(), + gfx::Size(100, 100)); root->SetNeedsPushProperties(); // Add a PaintWorkletInput to the PictureLayerImpl. @@ -15200,8 +13521,7 @@ TEST_F(ForceActivateAfterPaintWorkletPaintLayerTreeHostImplTest, root->UpdateRasterSource(raster_source_with_pws, &empty_invalidation, nullptr, nullptr); - host_impl_->pending_tree()->SetElementIdsForTesting(); - host_impl_->pending_tree()->BuildPropertyTreesForTesting(); + UpdateDrawProperties(host_impl_->pending_tree()); // Since we have dirty PaintWorklets, committing will not cause tile // preparation to happen. Instead, it will be delayed until the callback diff --git a/chromium/cc/trees/layer_tree_host_perftest.cc b/chromium/cc/trees/layer_tree_host_perftest.cc index 379d099def3..7d9e9d4f2a9 100644 --- a/chromium/cc/trees/layer_tree_host_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_perftest.cc @@ -27,7 +27,7 @@ #include "components/viz/test/paths.h" #include "gpu/command_buffer/common/mailbox.h" #include "gpu/command_buffer/common/sync_token.h" -#include "testing/perf/perf_test.h" +#include "testing/perf/perf_result_reporter.h" namespace cc { namespace { @@ -99,6 +99,13 @@ class LayerTreeHostPerfTest : public LayerTreeTest { host_impl->SetFullViewportDamage(); } + void SetUpReporter(const std::string& story_name) { + reporter_ = std::make_unique<perf_test::PerfResultReporter>( + "layer_tree_host", story_name); + reporter_->RegisterImportantMetric("_frame_time", "us"); + reporter_->RegisterImportantMetric("_commit_time", "us"); + } + virtual void CleanUpAndEndTest() { EndTest(); } virtual bool CleanUpStarted() { return false; } @@ -106,14 +113,12 @@ class LayerTreeHostPerfTest : public LayerTreeTest { virtual void BuildTree() {} void AfterTest() override { - CHECK(!test_name_.empty()) << "Must SetTestName() before AfterTest()."; - perf_test::PrintResult("layer_tree_host_frame_time", "", test_name_, - draw_timer_.TimePerLap().InMicrosecondsF(), "us", - true); + CHECK(reporter_) << "Must SetUpReporter() before AfterTest()."; + reporter_->AddResult("_frame_time", + draw_timer_.TimePerLap().InMicrosecondsF()); if (measure_commit_cost_) { - perf_test::PrintResult("layer_tree_host_commit_time", "", test_name_, - commit_timer_.TimePerLap().InMicrosecondsF(), "us", - true); + reporter_->AddResult("_commit_time", + commit_timer_.TimePerLap().InMicrosecondsF()); } } @@ -121,7 +126,7 @@ class LayerTreeHostPerfTest : public LayerTreeTest { base::LapTimer draw_timer_; base::LapTimer commit_timer_; - std::string test_name_; + std::unique_ptr<perf_test::PerfResultReporter> reporter_; FakeContentLayerClient fake_content_layer_client_; bool full_damage_each_frame_; bool begin_frame_driven_drawing_; @@ -136,10 +141,6 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { : LayerTreeHostPerfTest() { } - void SetTestName(const std::string& name) { - test_name_ = name; - } - void ReadTestFile(const std::string& name) { base::FilePath test_data_dir; ASSERT_TRUE( @@ -171,7 +172,7 @@ class LayerTreeHostPerfTestJsonReader : public LayerTreeHostPerfTest { #define MAYBE_TenTenSingleThread TenTenSingleThread #endif TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenSingleThread) { - SetTestName("10_10_single_thread"); + SetUpReporter("10_10_single_thread"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::SINGLE_THREADED); } @@ -183,7 +184,7 @@ TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenSingleThread) { #define MAYBE_TenTenThreaded TenTenThreaded #endif TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenThreaded) { - SetTestName("10_10_threaded_impl_side"); + SetUpReporter("10_10_threaded_impl_side"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -192,14 +193,14 @@ TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_TenTenThreaded) { TEST_F(LayerTreeHostPerfTestJsonReader, TenTenSingleThread_FullDamageEachFrame) { full_damage_each_frame_ = true; - SetTestName("10_10_single_thread_full_damage_each_frame"); + SetUpReporter("10_10_single_thread_full_damage_each_frame"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::SINGLE_THREADED); } TEST_F(LayerTreeHostPerfTestJsonReader, TenTenThreaded_FullDamageEachFrame) { full_damage_each_frame_ = true; - SetTestName("10_10_threaded_impl_side_full_damage_each_frame"); + SetUpReporter("10_10_threaded_impl_side_full_damage_each_frame"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -233,14 +234,14 @@ class LayerTreeHostPerfTestLeafInvalidates // Simulates a tab switcher scene with two stacks of 10 tabs each. Invalidate a // property on a leaf layer in the tree every commit. TEST_F(LayerTreeHostPerfTestLeafInvalidates, TenTenSingleThread) { - SetTestName("10_10_single_thread_leaf_invalidates"); + SetUpReporter("10_10_single_thread_leaf_invalidates"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::SINGLE_THREADED); } // Timed out on Android: http://crbug.com/723821 TEST_F(LayerTreeHostPerfTestLeafInvalidates, MAYBE_TenTenThreaded) { - SetTestName("10_10_threaded_impl_side_leaf_invalidates"); + SetUpReporter("10_10_threaded_impl_side_leaf_invalidates"); ReadTestFile("10_10_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -278,7 +279,7 @@ class ScrollingLayerTreePerfTest : public LayerTreeHostPerfTestJsonReader { #define MAYBE_LongScrollablePageSingleThread LongScrollablePageSingleThread #endif TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageSingleThread) { - SetTestName("long_scrollable_page"); + SetUpReporter("long_scrollable_page"); ReadTestFile("long_scrollable_page"); RunTest(CompositorMode::SINGLE_THREADED); } @@ -290,7 +291,7 @@ TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageSingleThread) { #define MAYBE_LongScrollablePageThreaded LongScrollablePageThreaded #endif TEST_F(ScrollingLayerTreePerfTest, MAYBE_LongScrollablePageThreaded) { - SetTestName("long_scrollable_page_threaded_impl_side"); + SetUpReporter("long_scrollable_page_threaded_impl_side"); ReadTestFile("long_scrollable_page"); RunTest(CompositorMode::THREADED); } @@ -382,7 +383,7 @@ class BrowserCompositorInvalidateLayerTreePerfTest TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) { measure_commit_cost_ = true; - SetTestName("dense_layer_tree"); + SetUpReporter("dense_layer_tree"); ReadTestFile("dense_layer_tree"); RunTest(CompositorMode::THREADED); } @@ -397,7 +398,7 @@ TEST_F(BrowserCompositorInvalidateLayerTreePerfTest, DenseBrowserUIThreaded) { TEST_F(LayerTreeHostPerfTestJsonReader, MAYBE_HeavyPageThreaded) { begin_frame_driven_drawing_ = true; measure_commit_cost_ = true; - SetTestName("heavy_page"); + SetUpReporter("heavy_page"); ReadTestFile("heavy_layer_tree"); RunTest(CompositorMode::THREADED); } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc index 6c045aa5ff5..09802cdbac2 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_blending.cc @@ -132,7 +132,6 @@ class LayerTreeHostBlendingPixelTest gfx::Size bounds = layer->bounds(); scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create(); mask->SetIsDrawable(true); - mask->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask->SetBounds(bounds); sk_sp<SkSurface> surface = @@ -224,7 +223,7 @@ class LayerTreeHostBlendingPixelTest scoped_refptr<Layer> background = CreateColorfulBackdropLayer(kRootWidth, kRootHeight); - background->SetIsRootForIsolatedGroup(true); + background->SetForceRenderSurfaceForTesting(true); root->AddChild(background); CreateBlendingColorLayers(kRootWidth, kRootHeight, background.get(), flags); @@ -352,7 +351,7 @@ TEST_P(LayerTreeHostBlendingPixelTest, BlendingWithTransparent) { CreateSolidColorLayer(gfx::Rect(kRootWidth, kRootHeight), kCSSOrange); root->AddChild(background); - background->SetIsRootForIsolatedGroup(true); + background->SetForceRenderSurfaceForTesting(true); // Orange child layers will blend with the green background gfx::Rect child_rect(kRootWidth, kRootHeight); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index b43b7336343..4af1f35d30f 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -138,6 +138,26 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRect) { : base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur.png"))); } +TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterInvalid) { + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(50, 50, 100, 100), kCSSGreen); + scoped_refptr<SolidColorLayer> blur = + CreateSolidColorLayer(gfx::Rect(30, 30, 140, 140), SK_ColorTRANSPARENT); + background->AddChild(green); + background->AddChild(blur); + + // This should be an invalid filter, and result in just the original green. + FilterOperations filters; + filters.Append(FilterOperation::CreateHueRotateFilter(9e99)); + blur->SetBackdropFilters(filters); + + RunPixelTest( + renderer_type(), background, + base::FilePath(FILE_PATH_LITERAL("backdrop_filter_invalid.png"))); +} + TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRadius) { if (renderer_type() == RENDERER_SOFTWARE) { // TODO(989238): Software renderer does not support/implement @@ -280,52 +300,82 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) { base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_outsets.png"))); } -TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) { - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT); +class LayerTreeHostFiltersPixelTestGPULayerList + : public LayerTreeHostFiltersPixelTest { + public: + LayerTreeHostFiltersPixelTestGPULayerList() { SetUseLayerLists(); } - // This verifies that the perspective of the clear layer (with black border) - // does not influence the blending of the green box behind it. Also verifies - // that the blur is correctly clipped inside the transformed clear layer. - scoped_refptr<SolidColorLayer> green = CreateSolidColorLayer( - gfx::Rect(50, 50, 100, 100), kCSSGreen); - scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayerWithBorder( - gfx::Rect(30, 30, 120, 120), SK_ColorTRANSPARENT, 1, SK_ColorBLACK); - background->AddChild(green); - background->AddChild(blur); + void SetupTree() override { + SetInitialRootBounds(gfx::Size(200, 200)); + LayerTreePixelTest::SetupTree(); - background->SetShouldFlattenTransform(false); - background->Set3dSortingContextId(1); - green->SetShouldFlattenTransform(false); - green->Set3dSortingContextId(1); - gfx::Transform background_transform; - background_transform.ApplyPerspectiveDepth(200.0); - background->SetTransform(background_transform); + Layer* root = layer_tree_host()->root_layer(); - blur->SetShouldFlattenTransform(false); - blur->Set3dSortingContextId(1); - for (size_t i = 0; i < blur->children().size(); ++i) - blur->children()[i]->Set3dSortingContextId(1); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorTRANSPARENT); + CopyProperties(root, background.get()); + root->AddChild(background); - gfx::Transform blur_transform; - blur_transform.Translate(55.0, 65.0); - blur_transform.RotateAboutXAxis(85.0); - blur_transform.RotateAboutYAxis(180.0); - blur_transform.RotateAboutZAxis(20.0); - blur_transform.Translate(-60.0, -60.0); - blur->SetTransform(blur_transform); + TransformNode& background_transform_node = + CreateTransformNode(background.get()); + background_transform_node.local.ApplyPerspectiveDepth(200.0); + background_transform_node.flattens_inherited_transform = true; + background_transform_node.sorting_context_id = 1; + + // This verifies that the perspective of the clear layer (with black border) + // does not influence the blending of the green box behind it. Also verifies + // that the blur is correctly clipped inside the transformed clear layer. + scoped_refptr<SolidColorLayer> green = + CreateSolidColorLayer(gfx::Rect(50, 50, 100, 100), kCSSGreen); + CopyProperties(background.get(), green.get()); + root->AddChild(green); + + std::vector<scoped_refptr<SolidColorLayer>> blur_layers; + CreateSolidColorLayerPlusBorders(gfx::Rect(0, 0, 120, 120), + SK_ColorTRANSPARENT, 1, SK_ColorBLACK, + blur_layers); + CopyProperties(background.get(), blur_layers[0].get()); + TransformNode& blur_transform_node = + CreateTransformNode(blur_layers[0].get(), background_transform_node.id); + + blur_transform_node.local.Translate(55.0, 65.0); + blur_transform_node.local.RotateAboutXAxis(85.0); + blur_transform_node.local.RotateAboutYAxis(180.0); + blur_transform_node.local.RotateAboutZAxis(20.0); + blur_transform_node.local.Translate(-60.0, -60.0); + blur_transform_node.flattens_inherited_transform = false; + blur_transform_node.post_translation = gfx::Vector2dF(30, 30); + blur_transform_node.sorting_context_id = 1; + + EffectNode& blur_effect_node = CreateEffectNode(blur_layers[0].get()); - FilterOperations filters; - filters.Append(FilterOperation::CreateBlurFilter( - 2.f, SkBlurImageFilter::kClamp_TileMode)); - blur->SetBackdropFilters(filters); - // TODO(916311): We should be able to set the bounds like this, but the - // resulting output is clipped incorrectly. - // gfx::RRectF - // backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())),0); - // blur->SetBackdropFilterBounds(backdrop_filter_bounds); - blur->ClearBackdropFilterBounds(); + FilterOperations filters; + filters.Append(FilterOperation::CreateBlurFilter( + 2.f, SkBlurImageFilter::kClamp_TileMode)); + blur_effect_node.backdrop_filters = filters; + blur_effect_node.render_surface_reason = + RenderSurfaceReason::kBackdropFilter; + blur_effect_node.closest_ancestor_with_copy_request_id = 1; + + // TODO(916311): We should be able to set the bounds like this, but the + // resulting output is clipped incorrectly. + // gfx::RRectF + // backdrop_filter_bounds(gfx::RectF(gfx::SizeF(blur->bounds())),0); + // blur_effect_node.backdrop_filter_bounds.emplace(backdrop_filter_bounds); + + root->AddChild(blur_layers[0]); + for (unsigned i = 1; i < blur_layers.size(); i++) { + CopyProperties(blur_layers[0].get(), blur_layers[i].get()); + root->AddChild(blur_layers[i]); + } + } +}; +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostFiltersPixelTestGPULayerList, + ::testing::ValuesIn(kRendererTypesGpu)); + +TEST_P(LayerTreeHostFiltersPixelTestGPULayerList, BackdropFilterBlurOffAxis) { #if defined(OS_WIN) || defined(ARCH_CPU_ARM64) #if defined(OS_WIN) // Windows has 116 pixels off by at most 2: crbug.com/225027 @@ -347,8 +397,8 @@ TEST_P(LayerTreeHostFiltersPixelTestGPU, BackdropFilterBlurOffAxis) { small_error_allowed)); #endif - RunPixelTest( - renderer_type(), background, + RunPixelTestWithLayerList( + renderer_type(), base::FilePath(FILE_PATH_LITERAL("backdrop_filter_blur_off_axis_.png")) .InsertBeforeExtensionASCII(GetRendererSuffix())); } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc index ba32c9bdd0c..ad9f2838cf7 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_masks.cc @@ -26,13 +26,6 @@ namespace cc { namespace { -auto CombineWithLayerMaskTypes( - const std::vector<PixelResourceTestCase>& test_cases) { - return ::testing::Combine( - ::testing::ValuesIn(test_cases), - ::testing::Values(Layer::LayerMaskType::SINGLE_TEXTURE_MASK)); -} - // TODO(penghuang): Fix vulkan with one copy or zero copy // https://crbug.com/979703 std::vector<PixelResourceTestCase> const kTestCases = { @@ -52,7 +45,7 @@ using LayerTreeHostMasksPixelTest = ParameterizedPixelResourceTest; INSTANTIATE_TEST_SUITE_P(PixelResourceTest, LayerTreeHostMasksPixelTest, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); class MaskContentLayerClient : public ContentLayerClient { public: @@ -111,7 +104,6 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayer) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); green->SetMaskLayer(mask); pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(true); @@ -164,7 +156,7 @@ class LayerTreeHostMaskPixelTestWithLayerList INSTANTIATE_TEST_SUITE_P(PixelResourceTest, LayerTreeHostMaskPixelTestWithLayerList, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTestWithLayerList, MaskWithEffect) { MaskContentLayerClient client(mask_bounds_); @@ -237,7 +229,7 @@ class LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface INSTANTIATE_TEST_SUITE_P( PixelResourceTest, LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTest_SolidColorEmptyMaskWithEffectAndRenderSurface, Test) { @@ -272,7 +264,7 @@ class LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask INSTANTIATE_TEST_SUITE_P( PixelResourceTest, LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTest_MaskWithEffectNoContentToMask, Test) { MaskContentLayerClient client(mask_bounds_); @@ -297,7 +289,7 @@ class LayerTreeHostMaskPixelTest_ScaledMaskWithEffect INSTANTIATE_TEST_SUITE_P(PixelResourceTest, LayerTreeHostMaskPixelTest_ScaledMaskWithEffect, - CombineWithLayerMaskTypes(kTestCases)); + ::testing::ValuesIn(kTestCases)); TEST_P(LayerTreeHostMaskPixelTest_ScaledMaskWithEffect, Test) { MaskContentLayerClient client(mask_bounds_); @@ -361,7 +353,6 @@ TEST_P(LayerTreeHostMasksPixelTest, ImageMaskOfLayer) { scoped_refptr<PictureImageLayer> mask = PictureImageLayer::Create(); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); mask->SetBounds(mask_bounds); sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(200, 200); @@ -411,7 +402,6 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfClippedLayer) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); green->SetMaskLayer(mask); pixel_comparator_ = @@ -435,7 +425,6 @@ TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerNonExactTextureSize) { scoped_refptr<FakePictureLayer> mask = FakePictureLayer::Create(&client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); mask->set_fixed_tile_size(gfx::Size(173, 135)); green->SetMaskLayer(mask); @@ -537,43 +526,59 @@ class CircleContentLayerClient : public ContentLayerClient { gfx::Size bounds_; }; -using LayerTreeHostMasksForBackdropFiltersPixelTest = - ParameterizedPixelResourceTest; +class LayerTreeHostMasksForBackdropFiltersPixelTest + : public ParameterizedPixelResourceTest { + protected: + LayerTreeHostMasksForBackdropFiltersPixelTest() + : bounds_(100, 100), + picture_client_(bounds_, SK_ColorGREEN, true), + mask_client_(bounds_) { + SetUseLayerLists(); + } -INSTANTIATE_TEST_SUITE_P(PixelResourceTest, - LayerTreeHostMasksForBackdropFiltersPixelTest, - CombineWithLayerMaskTypes(kTestCases)); + // Setup three layers for testing masks: a white background, a green layer, + // and a mask layer with kDstIn blend mode. + void SetupTree() override { + SetInitialRootBounds(bounds_); + ParameterizedPixelResourceTest::SetupTree(); -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, - MaskOfLayerWithBackdropFilter) { - scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorWHITE); + Layer* root = layer_tree_host()->root_layer(); + + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorWHITE); + CopyProperties(root, background.get()); + root->AddChild(background); - gfx::Size picture_bounds(100, 100); - CheckerContentLayerClient picture_client(picture_bounds, SK_ColorGREEN, true); - scoped_refptr<PictureLayer> picture = PictureLayer::Create(&picture_client); - picture->SetBounds(picture_bounds); - picture->SetIsDrawable(true); + scoped_refptr<PictureLayer> picture = + PictureLayer::Create(&picture_client_); + picture->SetBounds(bounds_); + picture->SetIsDrawable(true); + CopyProperties(background.get(), picture.get()); + root->AddChild(picture); - scoped_refptr<SolidColorLayer> blur = CreateSolidColorLayer( - gfx::Rect(100, 100), SK_ColorTRANSPARENT); - background->AddChild(picture); - background->AddChild(blur); + scoped_refptr<SolidColorLayer> blur = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorTRANSPARENT); + CopyProperties(background.get(), blur.get()); + CreateEffectNode(blur.get()) + .backdrop_filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); + root->AddChild(blur); - FilterOperations filters; - filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); - blur->SetBackdropFilters(filters); - blur->ClearBackdropFilterBounds(); + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client_); + SetupMaskProperties(blur.get(), mask.get()); - gfx::Size mask_bounds(100, 100); - CircleContentLayerClient mask_client(mask_bounds); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); - blur->SetMaskLayer(mask); - CHECK_EQ(Layer::LayerMaskType::SINGLE_TEXTURE_MASK, mask->mask_type()); + root->AddChild(mask); + } + const gfx::Size bounds_; + CheckerContentLayerClient picture_client_; + CircleContentLayerClient mask_client_; +}; + +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostMasksForBackdropFiltersPixelTest, + ::testing::ValuesIn(kTestCases)); + +TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, Test) { base::FilePath image_name = (raster_type() == GPU) ? base::FilePath(FILE_PATH_LITERAL("mask_of_backdrop_filter_gpu.png")) @@ -593,10 +598,10 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, large_error_allowed, small_error_allowed); } - RunPixelResourceTest(background, image_name); + RunPixelResourceTestWithLayerList(image_name); } -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, MaskOfLayerWithBlend) { +TEST_P(LayerTreeHostMasksPixelTest, MaskOfLayerWithBlend) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer( gfx::Rect(128, 128), SK_ColorWHITE); @@ -625,7 +630,6 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, MaskOfLayerWithBlend) { scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); mask->SetBounds(mask_bounds); mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); picture_horizontal->SetMaskLayer(mask); float percentage_pixels_large_error = 0.04f; // 0.04%, ~6px / (128*128) @@ -684,9 +688,7 @@ class LayerTreeHostMaskAsBlendingPixelTest public ::testing::WithParamInterface<MaskTestConfig> { public: LayerTreeHostMaskAsBlendingPixelTest() - : LayerTreeHostPixelResourceTest( - GetParam().test_case, - Layer::LayerMaskType::SINGLE_TEXTURE_MASK), + : LayerTreeHostPixelResourceTest(GetParam().test_case), use_antialiasing_(GetParam().flags & kUseAntialiasing), force_shaders_(GetParam().flags & kForceShaders) { float percentage_pixels_error = 0.f; @@ -831,7 +833,6 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, PixelAlignedNoop) { mask_isolation->SetPosition(gfx::PointF(20, 20)); mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -856,7 +857,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, PixelAlignedClippedCircle) { mask_isolation->SetPosition(gfx::PointF(20, 20)); mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); + mask_isolation->SetForceRenderSurfaceForTesting(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -893,7 +894,7 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, mask_isolation->SetPosition(gfx::PointF(20, 20)); mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); + mask_isolation->SetForceRenderSurfaceForTesting(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -934,7 +935,6 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircle) { } mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -981,7 +981,6 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) { } mask_isolation->SetBounds(gfx::Size(350, 250)); mask_isolation->SetMasksToBounds(true); - mask_isolation->SetIsRootForIsolatedGroup(true); root->AddChild(mask_isolation); scoped_refptr<Layer> content = @@ -1013,44 +1012,64 @@ TEST_P(LayerTreeHostMaskAsBlendingPixelTest, RotatedClippedCircleUnderflow) { RunPixelResourceTest(root, image_name); } -TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, - MaskOfLayerWithBackdropFilterAndBlend) { - scoped_refptr<SolidColorLayer> background = - CreateSolidColorLayer(gfx::Rect(128, 128), SK_ColorWHITE); +class LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest + : public ParameterizedPixelResourceTest { + protected: + LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest() + : bounds_(128, 128), + picture_client_vertical_(bounds_, SK_ColorGREEN, true), + picture_client_horizontal_(bounds_, SK_ColorMAGENTA, false), + mask_client_(bounds_) { + SetUseLayerLists(); + } - gfx::Size picture_bounds(128, 128); - CheckerContentLayerClient picture_client_vertical(picture_bounds, - SK_ColorGREEN, true); - scoped_refptr<PictureLayer> picture_vertical = - PictureLayer::Create(&picture_client_vertical); - picture_vertical->SetBounds(picture_bounds); - picture_vertical->SetIsDrawable(true); + void SetupTree() override { + SetInitialRootBounds(bounds_); + ParameterizedPixelResourceTest::SetupTree(); - CheckerContentLayerClient picture_client_horizontal(picture_bounds, - SK_ColorMAGENTA, false); - scoped_refptr<PictureLayer> picture_horizontal = - PictureLayer::Create(&picture_client_horizontal); - picture_horizontal->SetBounds(picture_bounds); - picture_horizontal->SetIsDrawable(true); - picture_horizontal->SetContentsOpaque(false); - picture_horizontal->SetBlendMode(SkBlendMode::kMultiply); + Layer* root = layer_tree_host()->root_layer(); - FilterOperations filters; - filters.Append(FilterOperation::CreateGrayscaleFilter(1.0)); - picture_horizontal->SetBackdropFilters(filters); - picture_horizontal->ClearBackdropFilterBounds(); + scoped_refptr<SolidColorLayer> background = + CreateSolidColorLayer(gfx::Rect(bounds_), SK_ColorWHITE); + CopyProperties(root, background.get()); + root->AddChild(background); - background->AddChild(picture_vertical); - background->AddChild(picture_horizontal); + scoped_refptr<PictureLayer> picture_vertical = + PictureLayer::Create(&picture_client_vertical_); + picture_vertical->SetBounds(bounds_); + picture_vertical->SetIsDrawable(true); + CopyProperties(background.get(), picture_vertical.get()); + root->AddChild(picture_vertical); + + scoped_refptr<PictureLayer> picture_horizontal = + PictureLayer::Create(&picture_client_horizontal_); + picture_horizontal->SetBounds(bounds_); + picture_horizontal->SetIsDrawable(true); + picture_horizontal->SetContentsOpaque(false); + CopyProperties(background.get(), picture_horizontal.get()); + auto& effect_node = CreateEffectNode(picture_horizontal.get()); + effect_node.backdrop_filters.Append( + FilterOperation::CreateGrayscaleFilter(1.0)); + effect_node.blend_mode = SkBlendMode::kMultiply; + root->AddChild(picture_horizontal); + + scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client_); + mask->SetBounds(bounds_); + SetupMaskProperties(picture_horizontal.get(), mask.get()); + root->AddChild(mask); + } - gfx::Size mask_bounds(128, 128); - CircleContentLayerClient mask_client(mask_bounds); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&mask_client); - mask->SetBounds(mask_bounds); - mask->SetIsDrawable(true); - mask->SetLayerMaskType(mask_type_); - picture_horizontal->SetMaskLayer(mask); + const gfx::Size bounds_; + CheckerContentLayerClient picture_client_vertical_; + CheckerContentLayerClient picture_client_horizontal_; + CircleContentLayerClient mask_client_; +}; + +INSTANTIATE_TEST_SUITE_P(PixelResourceTest, + LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest, + ::testing::ValuesIn(kTestCases)); +TEST_P(LayerTreeHostMasksForBackdropFiltersAndBlendPixelTest, Test) { base::FilePath result_path( FILE_PATH_LITERAL("mask_of_backdrop_filter_and_blend_.png")); if (raster_type() != GPU) { @@ -1058,7 +1077,7 @@ TEST_P(LayerTreeHostMasksForBackdropFiltersPixelTest, } else { result_path = result_path.InsertBeforeExtensionASCII(GetRendererSuffix()); } - RunPixelResourceTest(background, result_path); + RunPixelResourceTestWithLayerList(result_path); } } // namespace diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc index 52317bb5fa2..345dc9cab6b 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc @@ -416,7 +416,7 @@ TEST_P(LayerTreeHostReadbackPixelTest, MultipleReadbacksOnLayer) { base::FilePath(FILE_PATH_LITERAL("green.png"))); } -// TODO(crbug.com/963446): Enable these tests for Skia Vulkan using texture +// TODO(crbug.com/971257): Enable these tests for Skia Vulkan using texture // readback. ReadbackTestConfig const kTestConfigs[] = { ReadbackTestConfig{LayerTreeTest::RENDERER_SOFTWARE, READBACK_BITMAP}, diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc index b271f513c0c..4be54575240 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc @@ -11,6 +11,7 @@ #include "cc/layers/solid_color_layer.h" #include "cc/paint/paint_canvas.h" #include "cc/paint/paint_flags.h" +#include "cc/test/fake_scrollbar.h" #include "cc/test/layer_tree_pixel_test.h" #include "cc/test/pixel_comparator.h" #include "cc/trees/layer_tree_impl.h" @@ -38,32 +39,23 @@ class LayerTreeHostScrollbarsPixelTest float device_scale_factor_ = 1.f; }; -class PaintedScrollbar : public Scrollbar { +class PaintedScrollbar : public FakeScrollbar { public: - ~PaintedScrollbar() override = default; - - ScrollbarOrientation Orientation() const override { return VERTICAL; } - bool IsLeftSideVerticalScrollbar() const override { return false; } - gfx::Point Location() const override { return gfx::Point(); } - bool IsOverlay() const override { return false; } - bool HasThumb() const override { return thumb_; } - int ThumbThickness() const override { return rect_.width(); } - int ThumbLength() const override { return rect_.height(); } - gfx::Rect TrackRect() const override { return rect_; } - gfx::Rect BackButtonRect() const override { return rect_; } - gfx::Rect ForwardButtonRect() const override { return rect_; } - float ThumbOpacity() const override { return 1.f; } - bool NeedsPaintPart(ScrollbarPart part) const override { return true; } - bool HasTickmarks() const override { return false; } - void PaintPart(PaintCanvas* canvas, - ScrollbarPart part, - const gfx::Rect& content_rect) override { + explicit PaintedScrollbar(const gfx::Size& size) + : FakeScrollbar(/*paint*/ true, + /*has_thumb*/ false, + HORIZONTAL, + /*is_left_side_vertical_scrollbar*/ false, + /*is_overlay*/ false) { + set_track_rect(gfx::Rect(size)); + } + + void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override { PaintFlags flags; flags.setStyle(PaintFlags::kStroke_Style); flags.setStrokeWidth(SkIntToScalar(paint_scale_)); flags.setColor(color_); - - gfx::Rect inset_rect = content_rect; + gfx::Rect inset_rect = GetPartRect(part); while (!inset_rect.IsEmpty()) { int big = paint_scale_ + 2; int small = paint_scale_; @@ -72,17 +64,12 @@ class PaintedScrollbar : public Scrollbar { inset_rect.Inset(big, big, small, small); } } - bool UsesNinePatchThumbResource() const override { return false; } - gfx::Size NinePatchThumbCanvasSize() const override { return gfx::Size(); } - gfx::Rect NinePatchThumbAperture() const override { return gfx::Rect(); } void set_paint_scale(int scale) { paint_scale_ = scale; } private: int paint_scale_ = 4; - bool thumb_ = false; SkColor color_ = SK_ColorGREEN; - gfx::Rect rect_; }; LayerTreeTest::RendererType const kRendererTypes[] = { @@ -101,7 +88,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, NoScale) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(200, 200)); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); @@ -120,7 +107,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100)); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); @@ -135,7 +122,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, TransformScale) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100)); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); layer->SetIsDrawable(true); @@ -162,7 +149,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) { scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE); - auto scrollbar = std::make_unique<PaintedScrollbar>(); + auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(10, 400)); scrollbar->set_paint_scale(1); scoped_refptr<PaintedScrollbarLayer> layer = PaintedScrollbarLayer::Create(std::move(scrollbar)); @@ -215,18 +202,20 @@ class LayerTreeHostOverlayScrollbarsPixelTest float thickness_scale_; }; -class PaintedOverlayScrollbar : public PaintedScrollbar { +class PaintedOverlayScrollbar : public FakeScrollbar { public: - ~PaintedOverlayScrollbar() override = default; - - int ThumbThickness() const override { return 15; } - int ThumbLength() const override { return 50; } - gfx::Rect TrackRect() const override { return gfx::Rect(0, 0, 15, 400); } - bool HasThumb() const override { return true; } - bool IsOverlay() const override { return true; } - void PaintPart(PaintCanvas* canvas, - ScrollbarPart part, - const gfx::Rect& content_rect) override { + PaintedOverlayScrollbar() + : FakeScrollbar(/*paint*/ true, + /*has_thumb*/ true, + VERTICAL, + /*is_left_side_vertical_scrollbar*/ false, + /*is_overlay*/ true) { + set_thumb_thickness(15); + set_thumb_length(50); + set_track_rect(gfx::Rect(0, 0, 15, 400)); + } + + void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override { // The outside of the rect will be painted with a 1 pixel black, red, then // blue border. The inside will be solid blue. This will allow the test to // ensure that scaling the thumb doesn't scale the border at all. Note @@ -237,8 +226,7 @@ class PaintedOverlayScrollbar : public PaintedScrollbar { flags.setStrokeWidth(SkIntToScalar(1)); flags.setColor(SK_ColorBLACK); - gfx::Rect inset_rect = content_rect; - + gfx::Rect inset_rect = GetPartRect(part); canvas->drawRect(RectToSkRect(inset_rect), flags); flags.setColor(SK_ColorRED); @@ -249,6 +237,7 @@ class PaintedOverlayScrollbar : public PaintedScrollbar { inset_rect.Inset(1, 1); canvas->drawRect(RectToSkRect(inset_rect), flags); } + bool UsesNinePatchThumbResource() const override { return true; } gfx::Size NinePatchThumbCanvasSize() const override { return gfx::Size(7, 7); diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc index 708eefad33a..7b3f854f7f9 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc @@ -24,6 +24,7 @@ class LayerTreeHostSynchronousPixelTest LayerTreePixelTest::InitializeSettings(settings); settings->single_thread_proxy_scheduler = false; settings->gpu_rasterization_forced = gpu_rasterization_forced_; + settings->gpu_rasterization_disabled = !settings->gpu_rasterization_forced; settings->use_zero_copy = use_zero_copy_; } diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index e87aef895c7..8e27a3ef68b 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -45,6 +45,8 @@ class LayerTreeHostTilesPixelTest switch (raster_mode()) { case ONE_COPY: settings->use_zero_copy = false; + settings->gpu_rasterization_disabled = true; + settings->gpu_rasterization_forced = false; break; case GPU: settings->gpu_rasterization_forced = true; diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index aec7ad3b5db..03d02988fce 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -51,9 +51,9 @@ #include "cc/trees/clip_node.h" #include "cc/trees/effect_node.h" #include "cc/trees/frame_rate_counter.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/swap_promise.h" @@ -255,6 +255,32 @@ class LayerTreeHostTestRequestedMainFrame : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestRequestedMainFrame); +class LayerTreeHostTestSchedulingClient : public LayerTreeHostTest { + public: + void BeginTest() override { + PostSetNeedsCommitToMainThread(); + EXPECT_EQ(0, main_frame_scheduled_count_); + EXPECT_EQ(0, main_frame_run_count_); + } + + void DidScheduleBeginMainFrame() override { main_frame_scheduled_count_++; } + void DidRunBeginMainFrame() override { main_frame_run_count_++; } + + void DidBeginMainFrame() override { + EXPECT_EQ(1, main_frame_scheduled_count_); + EXPECT_EQ(1, main_frame_run_count_); + EndTest(); + } + + void AfterTest() override {} + + private: + int main_frame_scheduled_count_ = 0; + int main_frame_run_count_ = 0; +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestSchedulingClient); + class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest { protected: void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -615,13 +641,13 @@ MULTI_THREAD_TEST_F( class LayerTreeHostFreeContextResourcesOnDestroy : public LayerTreeHostContextCacheTest { public: - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, const viz::BeginFrameArgs& args) override { + if (!first_will_begin_impl_frame_) + return; + + first_will_begin_impl_frame_ = false; + // Ensure that our initialization expectations have completed. Mock::VerifyAndClearExpectations(mock_main_context_support_); Mock::VerifyAndClearExpectations(mock_worker_context_support_); @@ -633,6 +659,9 @@ class LayerTreeHostFreeContextResourcesOnDestroy SetAggressivelyFreeResources(true)); EndTest(); } + + private: + bool first_will_begin_impl_frame_ = true; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostFreeContextResourcesOnDestroy); @@ -779,7 +808,7 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - VerifyAfterValues(impl->active_tree()->root_layer_for_testing()); + VerifyAfterValues(impl->active_tree()->root_layer()); } void DidCommitAndDrawFrame() override { @@ -966,13 +995,13 @@ class LayerTreeHostTestPushElementIdToNodeIdMap : public LayerTreeHostTest { switch (layer_tree_host()->SourceFrameNumber()) { case 1: child_->SetForceRenderSurfaceForTesting(true); - child_->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); + // Add a non-fast region to ensure a scroll node is created. + child_->SetNonFastScrollableRegion(Region(gfx::Rect(50, 50, 50, 50))); break; case 2: child_->SetForceRenderSurfaceForTesting(false); - child_->ClearMainThreadScrollingReasons( - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); + // Remove the non-fast region to ensure a scroll node is removed. + child_->SetNonFastScrollableRegion(Region()); break; } } @@ -1129,7 +1158,8 @@ class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest { scoped_refptr<Layer> grand_child_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage); +// TODO(crbug.com/1014263): Disable because this test is flaky. +// SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage); class LayerTreeHostTestLayerListSurfaceDamage : public LayerTreeHostTest { protected: @@ -1644,7 +1674,7 @@ class LayerTreeHostTestPropertyTreesChangedSync : public LayerTreeHostTest { void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { gfx::Transform transform; FilterOperations filters; - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); switch (static_cast<Animations>(index_)) { case OPACITY: index_++; @@ -1750,22 +1780,28 @@ SINGLE_THREAD_TEST_F(LayerTreeHostTestAnimationOpacityMutatedUsingLayerLists); class LayerTreeHostTestAnimationTransformMutatedNotUsingLayerLists : public LayerTreeHostTest { protected: - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; + void SetupTree() override { + root_ = Layer::Create(); + child_ = Layer::Create(); + root_->AddChild(child_); + layer_tree_host()->SetRootLayer(root_); + LayerTreeHostTest::SetupTree(); } void BeginTest() override { - Layer* root = layer_tree_host()->root_layer(); - EXPECT_EQ(gfx::Transform(), root->transform()); + EXPECT_EQ(gfx::Transform(), child_->transform()); gfx::Transform expected_transform; expected_transform.Translate(42, 42); layer_tree_host()->SetElementTransformMutated( - root->element_id(), ElementListType::ACTIVE, expected_transform); + child_->element_id(), ElementListType::ACTIVE, expected_transform); // When not using layer lists, transform is stored on the layer. - EXPECT_EQ(expected_transform, root->transform()); + EXPECT_EQ(expected_transform, child_->transform()); EndTest(); } + + private: + scoped_refptr<Layer> root_; + scoped_refptr<Layer> child_; }; SINGLE_THREAD_TEST_F( @@ -1914,7 +1950,7 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest { void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { EffectTree& effect_tree = impl->sync_tree()->property_trees()->effect_tree; - LayerImpl* root = impl->sync_tree()->root_layer_for_testing(); + LayerImpl* root = impl->sync_tree()->root_layer(); EffectNode* node = effect_tree.Node(root->effect_tree_index()); switch (impl->sync_tree()->source_frame_number()) { case 0: @@ -2151,10 +2187,12 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { void SetupTree() override { scoped_refptr<Layer> root = Layer::Create(); root->SetBounds(gfx::Size(10, 10)); + // child_layer_ is not drawable. child_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_); child_layer_->SetBounds(gfx::Size(10, 10)); mask_layer_ = base::MakeRefCounted<UpdateCountingLayer>(&client_); mask_layer_->SetBounds(gfx::Size(10, 10)); + mask_layer_->SetIsDrawable(true); child_layer_->SetMaskLayer(mask_layer_); root->AddChild(child_layer_); layer_tree_host()->SetRootLayer(root); @@ -2170,8 +2208,8 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { switch (layer_tree_host()->SourceFrameNumber()) { case 1: // Root and mask layer should have the same source frame number as they - // will be in the layer update list but the child is not as it has empty - // bounds. + // will be in the layer update list but the child is not as it doesn't + // draw content. EXPECT_EQ(mask_layer_->update_count(), 1); EXPECT_EQ(child_layer_->update_count(), 0); @@ -2182,17 +2220,21 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { } void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { + auto* mask_surface = + GetRenderSurface(impl->sync_tree()->LayerById(mask_layer_->id())); + auto* root_surface = GetRenderSurface(impl->sync_tree()->root_layer()); + ASSERT_TRUE(mask_surface); switch (index_) { - case 0: + case 0: { index_++; - EXPECT_FALSE( - GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) - ->MaskLayer()); + auto* child_surface = + GetRenderSurface(impl->sync_tree()->LayerById(child_layer_->id())); + EXPECT_EQ(child_surface, mask_surface->render_target()); + EXPECT_NE(child_surface, root_surface); break; + } case 1: - EXPECT_TRUE( - GetRenderSurface(impl->sync_tree()->root_layer_for_testing()) - ->MaskLayer()); + EXPECT_EQ(mask_surface->render_target(), root_surface); EndTest(); break; } @@ -2527,10 +2569,8 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest { } else { gfx::Rect root_damage_rect = frame_data->render_passes.back()->damage_rect; - EXPECT_EQ( - gfx::Rect( - host_impl->active_tree()->root_layer_for_testing()->bounds()), - root_damage_rect); + EXPECT_EQ(gfx::Rect(host_impl->active_tree()->root_layer()->bounds()), + root_damage_rect); EXPECT_EQ(4.f, host_impl->active_tree()->device_scale_factor()); EndTest(); } @@ -2614,10 +2654,8 @@ class LayerTreeHostTestRasterColorSpaceChange : public LayerTreeHostTest { if (!frame_data->has_no_damage) { gfx::Rect root_damage_rect = frame_data->render_passes.back()->damage_rect; - EXPECT_EQ( - gfx::Rect( - host_impl->active_tree()->root_layer_for_testing()->bounds()), - root_damage_rect); + EXPECT_EQ(gfx::Rect(host_impl->active_tree()->root_layer()->bounds()), + root_damage_rect); } return draw_result; @@ -3106,16 +3144,15 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); // from LayerTreeHost to LayerTreeHostImpl in the MT compositor. class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { public: - LayerTreeHostTestStartPageScaleAnimation() = default; + LayerTreeHostTestStartPageScaleAnimation() { SetUseLayerLists(); } void SetupTree() override { LayerTreeHostTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); - scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(&client_); - layer->set_always_update_resources(true); - scroll_layer_ = layer; + scroll_layer_ = FakePictureLayer::Create(&client_); + scroll_layer_->set_always_update_resources(true); scroll_layer_->SetBounds(gfx::Size(2 * root_layer->bounds().width(), 2 * root_layer->bounds().height())); @@ -3169,7 +3206,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { } FakeContentLayerClient client_; - scoped_refptr<Layer> scroll_layer_; + scoped_refptr<FakePictureLayer> scroll_layer_; }; // Single thread proxy does not support impl-side page scale changes. @@ -3177,28 +3214,16 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest { protected: - ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) {} + ViewportDeltasAppliedDuringPinch() : sent_gesture_(false) { + SetUseLayerLists(); + } void SetupTree() override { - scoped_refptr<Layer> root_clip = Layer::Create(); - root_clip->SetBounds(gfx::Size(500, 500)); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - page_scale_layer->SetBounds(gfx::Size(500, 500)); - - scoped_refptr<Layer> pinch = Layer::Create(); - pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollable(gfx::Size(200, 200)); - page_scale_layer->AddChild(pinch); - root_clip->AddChild(page_scale_layer); - - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch; - layer_tree_host()->RegisterViewportLayers(viewport_layers); - layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); - layer_tree_host()->SetRootLayer(root_clip); + SetInitialRootBounds(gfx::Size(200, 200)); LayerTreeHostTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); + SetupViewport(root, gfx::Size(500, 500), gfx::Size(500, 500)); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -3217,7 +3242,8 @@ class ViewportDeltasAppliedDuringPinch : public LayerTreeHostTest { EXPECT_EQ(gfx::ScrollOffset(50, 50), args.inner_delta); EXPECT_EQ(2, args.page_scale_delta); - auto* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer(); + auto* scroll_layer = + layer_tree_host()->InnerViewportScrollLayerForTesting(); EXPECT_EQ(gfx::ScrollOffset(50, 50), scroll_layer->CurrentScrollOffset()); EndTest(); } @@ -3299,8 +3325,8 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers // Device viewport is scaled. EXPECT_EQ(gfx::Rect(60, 60), impl->active_tree()->GetDeviceViewport()); - FakePictureLayerImpl* root = static_cast<FakePictureLayerImpl*>( - impl->active_tree()->root_layer_for_testing()); + FakePictureLayerImpl* root = + static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); FakePictureLayerImpl* child = static_cast<FakePictureLayerImpl*>( impl->active_tree()->LayerById(child_layer_->id())); @@ -3864,10 +3890,10 @@ class LayerTreeHostTestLCDChange : public LayerTreeHostTest { } void DrawLayersOnThread(LayerTreeHostImpl* host_impl) override { - PictureLayerImpl* root_layer = static_cast<PictureLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + PictureLayerImpl* root_layer = + static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer()); bool can_use_lcd_text = - host_impl->active_tree()->root_layer_for_testing()->CanUseLCDText(); + host_impl->active_tree()->root_layer()->CanUseLCDText(); switch (host_impl->active_tree()->source_frame_number()) { case 0: // The first draw. @@ -4456,7 +4482,7 @@ class LayerTreeHostTestImplLayersPushProperties // Make sure the new root is pushed. EXPECT_EQ(1u, static_cast<PushPropertiesCountingLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()) + host_impl->active_tree()->root_layer()) ->push_properties_count()); return; case 4: @@ -4562,7 +4588,7 @@ class LayerTreeHostTestImplLayersPushProperties // Pull the layers that we need from the tree assuming the same structure // as LayerTreeHostTestLayersPushProperties root_impl_ = static_cast<PushPropertiesCountingLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + host_impl->active_tree()->root_layer()); LayerTreeImpl* impl = root_impl_->layer_tree_impl(); if (impl->LayerById(child_->id())) { @@ -4639,8 +4665,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed // avoid causing a second commit to be scheduled. If a property change // is made during this, however, it needs to be pushed in the upcoming // commit. - std::unique_ptr<base::AutoReset<bool>> ignore = - scrollbar_layer_->IgnoreSetNeedsCommit(); + auto ignore = scrollbar_layer_->IgnoreSetNeedsCommit(); scrollbar_layer_->SetBounds(gfx::Size(30, 30)); @@ -5381,45 +5406,26 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { public: LayerTreeHostTestElasticOverscroll() - : scroll_elasticity_helper_(nullptr), num_draws_(0) {} + : scroll_elasticity_helper_(nullptr), num_draws_(0) { + SetUseLayerLists(); + } void InitializeSettings(LayerTreeSettings* settings) override { settings->enable_elastic_overscroll = true; } void SetupTree() override { - root_layer_ = Layer::Create(); - root_layer_->SetBounds(gfx::Size(10, 10)); - - scoped_refptr<Layer> inner_viewport_container_layer = Layer::Create(); - inner_viewport_container_layer->SetBounds(gfx::Size(10, 10)); - scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); - overscroll_elasticity_layer->SetElementId( - LayerIdToElementIdForTesting(overscroll_elasticity_layer->id())); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); - inner_viewport_scroll_layer->SetScrollable( - inner_viewport_container_layer->bounds()); - - root_layer_->AddChild(inner_viewport_container_layer); - inner_viewport_container_layer->AddChild(overscroll_elasticity_layer); - overscroll_elasticity_layer->AddChild(page_scale_layer); - page_scale_layer->AddChild(inner_viewport_scroll_layer); + LayerTreeHostTest::SetupTree(); + root_layer_ = layer_tree_host()->root_layer(); + SetupViewport(root_layer_, root_layer_->bounds(), root_layer_->bounds()); scoped_refptr<Layer> content_layer = FakePictureLayer::Create(&client_); content_layer_id_ = content_layer->id(); content_layer->SetBounds(gfx::Size(10, 10)); - inner_viewport_scroll_layer->AddChild(content_layer); + CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(), + content_layer.get()); + root_layer_->AddChild(content_layer); - layer_tree_host()->SetRootLayer(root_layer_); - ViewportLayers viewport_layers; - viewport_layers.overscroll_elasticity_element_id = - overscroll_elasticity_layer->element_id(); - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = inner_viewport_container_layer; - viewport_layers.inner_viewport_scroll = inner_viewport_scroll_layer; - layer_tree_host()->RegisterViewportLayers(viewport_layers); - LayerTreeHostTest::SetupTree(); client_.set_bounds(content_layer->bounds()); } @@ -5468,7 +5474,7 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { private: FakeContentLayerClient client_; - scoped_refptr<Layer> root_layer_; + Layer* root_layer_; ScrollElasticityHelper* scroll_elasticity_helper_; int content_layer_id_; int num_draws_; @@ -5972,10 +5978,6 @@ class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { ADD_FAILURE() << "Should not get called on main thread."; } - void OnForwardScrollUpdateToMainThreadOnImpl() override { - ADD_FAILURE() << "Should not get called on main thread."; - } - private: int* set_needs_commit_count_; }; @@ -6155,13 +6157,6 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Setting gpu rasterization trigger does not enable gpu rasterization. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - PostSetNeedsCommitToMainThread(); } @@ -6170,6 +6165,7 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { @@ -6177,6 +6173,7 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); EndTest(); } @@ -6187,57 +6184,12 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest { MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationDefault); -class LayerTreeHostTestEmptyLayerGpuRasterization : public LayerTreeHostTest { +class LayerTreeHostWithGpuRasterizationSupportedTest + : public LayerTreeHostTest { protected: - void SetupTree() override { - LayerTreeHostTest::SetupTree(); - - std::unique_ptr<FakeRecordingSource> recording_source( - new FakeRecordingSource); - recording_source_ = recording_source.get(); - - scoped_refptr<FakePictureLayer> layer = - FakePictureLayer::CreateWithRecordingSource( - &layer_client_, std::move(recording_source)); - layer_ = layer.get(); - layer->SetBounds(gfx::Size()); - layer->SetIsDrawable(true); - layer_tree_host()->root_layer()->AddChild(layer); - layer_client_.set_bounds(layer->bounds()); - } - - void BeginTest() override { - // Setting gpu rasterization trigger does not enable gpu rasterization. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - - PostSetNeedsCommitToMainThread(); - } - - void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_FALSE(layer_->HasSlowPaths()); - - EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization()); - EXPECT_FALSE(host_impl->use_gpu_rasterization()); - } - - void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { - EXPECT_FALSE(layer_->HasSlowPaths()); - - EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); - EXPECT_FALSE(host_impl->use_gpu_rasterization()); - EndTest(); + void InitializeSettings(LayerTreeSettings* settings) override { + settings->gpu_rasterization_msaa_sample_count = 4; } - - FakeContentLayerClient layer_client_; - FakePictureLayer* layer_; - FakeRecordingSource* recording_source_; -}; - -MULTI_THREAD_TEST_F(LayerTreeHostTestEmptyLayerGpuRasterization); - -class LayerTreeHostWithGpuRasterizationTest : public LayerTreeHostTest { - protected: std::unique_ptr<TestLayerTreeFrameSink> CreateLayerTreeFrameSink( const viz::RendererSettings& renderer_settings, double refresh_rate, @@ -6282,20 +6234,36 @@ class LayerTreeHostWithGpuRasterizationTest : public LayerTreeHostTest { }; class LayerTreeHostTestGpuRasterizationEnabled - : public LayerTreeHostWithGpuRasterizationTest { + : public LayerTreeHostWithGpuRasterizationSupportedTest { protected: - void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(layer_->HasSlowPaths()); + EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(layer_->HasSlowPaths()); + EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_msaa()); + EndTest(); + } +}; - // Gpu rasterization trigger is relevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); - // Content-based veto is relevant as well. +class LayerTreeHostTestGpuRasterizationEnabledWithMSAA + : public LayerTreeHostWithGpuRasterizationSupportedTest { + protected: + void BeginTest() override { + // Content-based MSAA trigger. layer_->set_force_content_has_slow_paths(true); - // Veto will take effect when layers are updated. + // MSAA trigger will take effect when layers are updated. // The results will be verified after commit is completed below. // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. @@ -6309,6 +6277,7 @@ class LayerTreeHostTestGpuRasterizationEnabled EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_msaa()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { @@ -6316,31 +6285,25 @@ class LayerTreeHostTestGpuRasterizationEnabled EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization()); EXPECT_TRUE(host_impl->use_gpu_rasterization()); + EXPECT_TRUE(host_impl->use_msaa()); EndTest(); } }; -MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabledWithMSAA); -class LayerTreeHostTestGpuRasterizationReenabled - : public LayerTreeHostWithGpuRasterizationTest { +class LayerTreeHostTestGpuRasterizationMSAAReenabled + : public LayerTreeHostWithGpuRasterizationSupportedTest { protected: void InitializeSettings(LayerTreeSettings* settings) override { settings->gpu_rasterization_msaa_sample_count = 4; } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Gpu rasterization trigger is relevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Content-based veto is relevant as well. + // Content-based MSAA trigger is relevant. layer_->set_force_content_has_slow_paths(true); - // Veto will take effect when layers are updated. + // MSAA trigger will take effect when layers are updated. // The results will be verified after commit is completed below. // Since we are manually marking the source as containing slow paths, // make sure that the layer gets a chance to update. @@ -6380,23 +6343,16 @@ class LayerTreeHostTestGpuRasterizationReenabled bool expected_use_msaa_ = true; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationReenabled); +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationMSAAReenabled); class LayerTreeHostTestGpuRasterizationNonAASticky - : public LayerTreeHostWithGpuRasterizationTest { + : public LayerTreeHostWithGpuRasterizationSupportedTest { protected: void InitializeSettings(LayerTreeSettings* settings) override { settings->gpu_rasterization_msaa_sample_count = 4; } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Gpu rasterization trigger is relevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - // Start without slow paths, but no non-aa paint. layer_->set_force_content_has_slow_paths(true); layer_->set_force_content_has_non_aa_paint(false); @@ -6461,14 +6417,7 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { } void BeginTest() override { - // Verify default value. - EXPECT_FALSE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // With gpu rasterization forced, gpu rasterization trigger is irrelevant. - layer_tree_host()->SetHasGpuRasterizationTrigger(true); - EXPECT_TRUE(layer_tree_host()->has_gpu_rasterization_trigger()); - - // Content-based veto is irrelevant as well. + // Content-based MSAA trigger is irrelevant as well. layer_->set_force_content_has_slow_paths(true); // Veto will take effect when layers are updated. @@ -6502,6 +6451,29 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationForced); +class LayerTreeHostTestGpuRasterizationSupportedButDisabled + : public LayerTreeHostWithGpuRasterizationSupportedTest { + protected: + void InitializeSettings(LayerTreeSettings* settings) override { + settings->gpu_rasterization_disabled = true; + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(host_impl->sync_tree()->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_gpu_rasterization()); + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization()); + EXPECT_FALSE(host_impl->use_gpu_rasterization()); + EndTest(); + } +}; + +MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationSupportedButDisabled); + class LayerTreeHostTestWillBeginImplFrameHasDidFinishImplFrame : public LayerTreeHostTest { public: @@ -6890,23 +6862,19 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { protected: LayerTreeHostTestCrispUpAfterPinchEnds() : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::SIGNALED) {} + base::WaitableEvent::InitialState::SIGNALED) { + SetUseLayerLists(); + } void SetupTree() override { frame_ = 1; posted_ = false; client_.set_fill_with_nonsolid_color(true); - scoped_refptr<Layer> root_clip = Layer::Create(); - root_clip->SetBounds(gfx::Size(500, 500)); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - page_scale_layer->SetBounds(gfx::Size(500, 500)); - - scoped_refptr<Layer> pinch = Layer::Create(); - pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollable(gfx::Size(500, 500)); - page_scale_layer->AddChild(pinch); - root_clip->AddChild(page_scale_layer); + SetInitialRootBounds(gfx::Size(500, 500)); + LayerTreeHostTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); + SetupViewport(root, root->bounds(), root->bounds()); std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); recording->SetPlaybackAllowedEvent(&playback_allowed_event_); @@ -6917,17 +6885,12 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { layer->SetContentsOpaque(true); // Avoid LCD text on the layer so we don't cause extra commits when we // pinch. - pinch->AddChild(layer); + CopyProperties(layer_tree_host()->InnerViewportScrollLayerForTesting(), + layer.get()); + root->AddChild(layer); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch; - layer_tree_host()->RegisterViewportLayers(viewport_layers); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); - layer_tree_host()->SetRootLayer(root_clip); - LayerTreeHostTest::SetupTree(); - client_.set_bounds(root_clip->bounds()); + client_.set_bounds(root->bounds()); } // Returns the delta scale of all quads in the frame's root pass from their @@ -7194,23 +7157,20 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles protected: LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles() : playback_allowed_event_(base::WaitableEvent::ResetPolicy::MANUAL, - base::WaitableEvent::InitialState::SIGNALED) {} + base::WaitableEvent::InitialState::SIGNALED) { + SetUseLayerLists(); + } void SetupTree() override { step_ = 1; continuous_draws_ = 0; client_.set_fill_with_nonsolid_color(true); - scoped_refptr<Layer> root_clip = Layer::Create(); - root_clip->SetBounds(gfx::Size(500, 500)); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - page_scale_layer->SetBounds(gfx::Size(500, 500)); + SetInitialRootBounds(gfx::Size(500, 500)); + LayerTreeHostTest::SetupTree(); - scoped_refptr<Layer> pinch = Layer::Create(); - pinch->SetBounds(gfx::Size(500, 500)); - pinch->SetScrollable(gfx::Size(500, 500)); - page_scale_layer->AddChild(pinch); - root_clip->AddChild(page_scale_layer); + Layer* root = layer_tree_host()->root_layer(); + SetupViewport(root, root->bounds(), root->bounds()); std::unique_ptr<FakeRecordingSource> recording(new FakeRecordingSource); recording->SetPlaybackAllowedEvent(&playback_allowed_event_); @@ -7219,19 +7179,12 @@ class LayerTreeHostTestContinuousDrawWhenCreatingVisibleTiles std::move(recording)); layer->SetBounds(gfx::Size(500, 500)); layer->SetContentsOpaque(true); - // Avoid LCD text on the layer so we don't cause extra commits when we - // pinch. - pinch->AddChild(layer); + CopyProperties(layer_tree_host()->InnerViewportScrollLayerForTesting(), + layer.get()); + root->AddChild(layer); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch; - layer_tree_host()->RegisterViewportLayers(viewport_layers); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); - layer_tree_host()->SetRootLayer(root_clip); - LayerTreeHostTest::SetupTree(); - client_.set_bounds(root_clip->bounds()); + client_.set_bounds(root->bounds()); } // Returns the delta scale of all quads in the frame's root pass from their @@ -7564,41 +7517,33 @@ class LayerTreeHostTestUpdateCopyRequests : public LayerTreeHostTest { SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateCopyRequests); class LayerTreeTestPageScaleFlags : public LayerTreeTest { + public: + LayerTreeTestPageScaleFlags() { SetUseLayerLists(); } + protected: void SetupTree() override { // -root // -pre page scale - // -page scale - // -inner viewport scroll - // -page scale grandchild + // -viewport layers // -post page scale - scoped_refptr<Layer> root = Layer::Create(); - scoped_refptr<Layer> pre_page_scale = Layer::Create(); - scoped_refptr<Layer> page_scale = Layer::Create(); - scoped_refptr<Layer> inner_viewport_scroll = Layer::Create(); - scoped_refptr<Layer> page_scale_grandchild = Layer::Create(); - scoped_refptr<Layer> post_page_scale = Layer::Create(); + LayerTreeTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); + scoped_refptr<Layer> pre_page_scale = Layer::Create(); + CopyProperties(root, pre_page_scale.get()); root->AddChild(pre_page_scale); - root->AddChild(page_scale); - root->AddChild(post_page_scale); - page_scale->AddChild(inner_viewport_scroll); - inner_viewport_scroll->AddChild(page_scale_grandchild); + SetupViewport(root, root->bounds(), root->bounds()); - layer_tree_host()->SetRootLayer(root); - LayerTreeTest::SetupTree(); - - ViewportLayers viewport_layers; - viewport_layers.inner_viewport_container = root; - viewport_layers.page_scale = page_scale; - viewport_layers.inner_viewport_scroll = inner_viewport_scroll; - layer_tree_host()->RegisterViewportLayers(viewport_layers); + scoped_refptr<Layer> post_page_scale = Layer::Create(); + CopyProperties(root, post_page_scale.get()); + root->AddChild(post_page_scale); - affected_by_page_scale_.push_back(page_scale->id()); - affected_by_page_scale_.push_back(inner_viewport_scroll->id()); - affected_by_page_scale_.push_back(page_scale_grandchild->id()); + affected_by_page_scale_.push_back( + layer_tree_host()->InnerViewportScrollLayerForTesting()->id()); + affected_by_page_scale_.push_back( + layer_tree_host()->OuterViewportScrollLayerForTesting()->id()); not_affected_by_page_scale_.push_back(root->id()); not_affected_by_page_scale_.push_back(pre_page_scale->id()); @@ -7608,14 +7553,12 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { void BeginTest() override { PostSetNeedsCommitToMainThread(); } void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { - LayerTreeHostCommon::CallFunctionForEveryLayer( - host_impl->sync_tree(), [this](LayerImpl* layer) { - const std::vector<int>& list = - layer->IsAffectedByPageScale() - ? this->affected_by_page_scale_ - : this->not_affected_by_page_scale_; - EXPECT_TRUE(base::Contains(list, layer->id())); - }); + for (auto* layer : *host_impl->sync_tree()) { + const std::vector<int>& list = layer->IsAffectedByPageScale() + ? this->affected_by_page_scale_ + : this->not_affected_by_page_scale_; + EXPECT_TRUE(base::Contains(list, layer->id())); + } EndTest(); } @@ -8278,8 +8221,8 @@ class LayerTreeHostTestImageAnimation : public LayerTreeHostTest { void WillPrepareToDrawOnThread(LayerTreeHostImpl* host_impl) override { gfx::Rect image_rect(-1, -1, 502, 502); - auto* layer = static_cast<PictureLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + auto* layer = + static_cast<PictureLayerImpl*>(host_impl->active_tree()->root_layer()); switch (++draw_count_) { case 1: // First draw, everything is invalid. @@ -8816,6 +8759,8 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestPartialTileDamage); class LayerTreeHostTopControlsDeltaTriggersViewportUpdate : public LayerTreeHostTest { public: + LayerTreeHostTopControlsDeltaTriggersViewportUpdate() { SetUseLayerLists(); } + void BeginTest() override { PostSetNeedsCommitToMainThread(); } void SetupTree() override { @@ -8824,6 +8769,7 @@ class LayerTreeHostTopControlsDeltaTriggersViewportUpdate // Set up scrollable root. root_layer->SetBounds(gfx::Size(100, 100)); SetupViewport(root_layer, gfx::Size(50, 50), root_layer->bounds()); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f); // Set browser controls to be partially shown. layer_tree_host()->SetBrowserControlsHeight(kTopControlsHeight, 0.0f, true /* shrink */); diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index 56bd3ff896d..a21e88e65bb 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -352,7 +352,7 @@ class LayerTreeHostAnimationTestAddKeyframeModelWithTimingFunction base::TimeTicks monotonic_time) override { // TODO(ajuma): This test only checks the active tree. Add checks for // pending tree too. - if (!host_impl->active_tree()->root_layer_for_testing()) + if (!host_impl->active_tree()->root_layer()) return; // Wait for the commit with the animation to happen. @@ -1155,7 +1155,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval if (!host_impl->pending_tree()) return false; - if (!host_impl->active_tree()->root_layer_for_testing()) + if (!host_impl->active_tree()->root_layer()) return false; scoped_refptr<AnimationTimeline> timeline_impl = @@ -2349,11 +2349,11 @@ class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->pending_tree()->source_frame_number() <= 1) { EXPECT_TRUE(host_impl->pending_tree() - ->root_layer_for_testing() + ->root_layer() ->screen_space_transform_is_animating()); } else { EXPECT_FALSE(host_impl->pending_tree() - ->root_layer_for_testing() + ->root_layer() ->screen_space_transform_is_animating()); } } @@ -2373,7 +2373,7 @@ class LayerTreeHostAnimationTestSetPotentiallyAnimatingOnLacDestruction DrawResult draw_result) override { const bool screen_space_transform_is_animating = host_impl->active_tree() - ->root_layer_for_testing() + ->root_layer() ->screen_space_transform_is_animating(); // Check that screen_space_transform_is_animating changes only once. diff --git a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc index 28655847535..f841b4c7826 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_checkerimaging.cc @@ -120,7 +120,7 @@ class LayerTreeHostCheckerImagingTestMergeWithMainFrame case 2: { // Ensure that the expected tiles are invalidated on the sync tree. PictureLayerImpl* sync_layer_impl = static_cast<PictureLayerImpl*>( - host_impl->sync_tree()->root_layer_for_testing()); + host_impl->sync_tree()->root_layer()); PictureLayerTiling* sync_tiling = sync_layer_impl->picture_layer_tiling_set() ->FindTilingWithResolution(TileResolution::HIGH_RESOLUTION); @@ -180,8 +180,8 @@ class LayerTreeHostCheckerImagingTestImplSideTree EXPECT_EQ(host_impl->sync_tree()->source_frame_number(), 0); // Ensure that the expected tiles are invalidated on the sync tree. - PictureLayerImpl* sync_layer_impl = static_cast<PictureLayerImpl*>( - host_impl->sync_tree()->root_layer_for_testing()); + PictureLayerImpl* sync_layer_impl = + static_cast<PictureLayerImpl*>(host_impl->sync_tree()->root_layer()); PictureLayerTiling* sync_tiling = sync_layer_impl->picture_layer_tiling_set()->FindTilingWithResolution( TileResolution::HIGH_RESOLUTION); diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc index 55bb0a7b7af..f2b8bba821c 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_context.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc @@ -750,8 +750,8 @@ class LayerTreeHostContextTestLostContextAndEvictTextures } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - FakePictureLayerImpl* picture_impl = static_cast<FakePictureLayerImpl*>( - impl->active_tree()->root_layer_for_testing()); + FakePictureLayerImpl* picture_impl = + static_cast<FakePictureLayerImpl*>(impl->active_tree()->root_layer()); EXPECT_TRUE(picture_impl->HighResTiling() ->TileAt(0, 0) ->draw_info() @@ -829,7 +829,7 @@ class LayerTreeHostContextTestLayersNotified : public LayerTreeHostContextTest { // fail before second activation. if (num_commits_ >= 2) { root_picture = static_cast<FakePictureLayerImpl*>( - host_impl->active_tree()->root_layer_for_testing()); + host_impl->active_tree()->root_layer()); child_picture = static_cast<FakePictureLayerImpl*>( host_impl->active_tree()->LayerById(child_->id())); grandchild_picture = static_cast<FakePictureLayerImpl*>( @@ -984,7 +984,8 @@ class LayerTreeHostContextTestDontUseLostResources scoped_refptr<PaintedScrollbarLayer> scrollbar = PaintedScrollbarLayer::Create( - std::unique_ptr<Scrollbar>(new FakeScrollbar), layer->element_id()); + std::unique_ptr<Scrollbar>(new FakeScrollbar)); + scrollbar->SetScrollElementId(layer->element_id()); scrollbar->SetBounds(gfx::Size(10, 10)); scrollbar->SetIsDrawable(true); root->AddChild(scrollbar); diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index 2545887eddb..2d3bc04e847 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -1319,7 +1319,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - LayerImpl* root = host_impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = host_impl->active_tree()->root_layer(); LayerImpl* child = host_impl->active_tree()->LayerById(child_->id()); bool saw_root = false; diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index 945d4e9c32e..a61d2ea77d2 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -56,7 +56,7 @@ class LayerTreeHostDamageTestSetNeedsRedraw EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -118,7 +118,7 @@ class LayerTreeHostDamageTestSetViewportRectAndScale EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -258,7 +258,7 @@ class LayerTreeHostDamageTestForcedFullDamage : public LayerTreeHostDamageTest { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(host_impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -378,7 +378,7 @@ class LayerTreeHostDamageTestScrollbarDoesDamage DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(host_impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); @@ -464,7 +464,7 @@ class LayerTreeHostDamageTestScrollbarCommitDoesNoDamage DrawResult draw_result) override { EXPECT_EQ(DRAW_SUCCESS, draw_result); RenderSurfaceImpl* root_surface = - GetRenderSurface(host_impl->active_tree()->root_layer_for_testing()); + GetRenderSurface(host_impl->active_tree()->root_layer()); gfx::Rect root_damage; EXPECT_TRUE( root_surface->damage_tracker()->GetDamageRectIfValid(&root_damage)); diff --git a/chromium/cc/trees/layer_tree_host_unittest_masks.cc b/chromium/cc/trees/layer_tree_host_unittest_masks.cc index 3a2edb4e411..ca119f3aa82 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_masks.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_masks.cc @@ -22,7 +22,9 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin // the surface bounds to be larger. It also has a parent that clips the // masked layer and its surface. - scoped_refptr<Layer> root = Layer::Create(); + SetInitialRootBounds(gfx::Size(100, 100)); + LayerTreeTest::SetupTree(); + Layer* root = layer_tree_host()->root_layer(); scoped_refptr<FakePictureLayer> content_layer = FakePictureLayer::Create(&client_); @@ -42,27 +44,30 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin &client_, std::move(recording_source)); content_layer->SetMaskLayer(mask_layer); - gfx::Size root_size(100, 100); - root->SetBounds(root_size); - gfx::Size layer_size(100, 100); content_layer->SetBounds(layer_size); gfx::Size mask_size(100, 100); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask_layer_id_ = mask_layer->id(); - layer_tree_host()->SetRootLayer(root); - LayerTreeTest::SetupTree(); - scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create(); - outer_viewport_scroll_layer->SetBounds(layer_size); - SetupViewport(root.get(), outer_viewport_scroll_layer, gfx::Size(50, 50)); - layer_tree_host()->outer_viewport_container_layer()->SetMasksToBounds(true); - outer_viewport_scroll_layer->AddChild(content_layer); + scoped_refptr<Layer> clip_layer = Layer::Create(); + clip_layer->SetBounds(gfx::Size(50, 50)); + clip_layer->SetMasksToBounds(true); + + scoped_refptr<Layer> scroll_layer = Layer::Create(); + scroll_layer->SetBounds(layer_size); + scroll_layer->SetScrollable(gfx::Size(50, 50)); + scroll_layer->SetMasksToBounds(true); + scroll_layer->SetElementId( + LayerIdToElementIdForTesting(scroll_layer->id())); + + root->AddChild(clip_layer); + clip_layer->AddChild(scroll_layer); + scroll_layer->AddChild(content_layer); client_.set_bounds(root->bounds()); - outer_viewport_scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); + scroll_layer->SetScrollOffset(gfx::ScrollOffset(50, 50)); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -70,7 +75,7 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -85,11 +90,13 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( render_pass_quad->shared_quad_state->quad_to_target_transform, render_pass_quad->rect); - EXPECT_EQ(gfx::Rect(0, 0, 50, 50).ToString(), - rect_in_target_space.ToString()); - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(50.f, 50.f, 50.f, 50.f), 1.f / 100.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50), rect_in_target_space); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -101,6 +108,88 @@ class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOrigin); +class LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList + : public LayerTreeTest { + protected: + LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList() { + SetUseLayerLists(); + } + + void SetupTree() override { + // The masked layer has bounds 50x50, but it has a child that causes + // the surface bounds to be larger. It also has a parent that clips the + // masked layer and its surface. + + SetInitialRootBounds(gfx::Size(100, 100)); + LayerTreeTest::SetupTree(); + + Layer* root = layer_tree_host()->root_layer(); + + gfx::Size layer_size(100, 100); + SetupViewport(root, gfx::Size(50, 50), layer_size); + + auto* scroll = layer_tree_host()->OuterViewportScrollLayerForTesting(); + SetScrollOffset(scroll, gfx::ScrollOffset(50, 50)); + + client_.set_bounds(root->bounds()); + auto content_layer = FakePictureLayer::Create(&client_); + content_layer->SetBounds(layer_size); + CopyProperties(scroll, content_layer.get()); + root->AddChild(content_layer); + + std::unique_ptr<RecordingSource> recording_source = + FakeRecordingSource::CreateFilledRecordingSource(gfx::Size(100, 100)); + PaintFlags paint1, paint2; + static_cast<FakeRecordingSource*>(recording_source.get()) + ->add_draw_rect_with_flags(gfx::Rect(0, 0, 100, 90), paint1); + static_cast<FakeRecordingSource*>(recording_source.get()) + ->add_draw_rect_with_flags(gfx::Rect(0, 90, 100, 10), paint2); + client_.set_fill_with_nonsolid_color(true); + static_cast<FakeRecordingSource*>(recording_source.get())->Rerecord(); + + auto mask_layer = FakePictureLayer::CreateWithRecordingSource( + &client_, std::move(recording_source)); + SetupMaskProperties(content_layer.get(), mask_layer.get()); + root->AddChild(mask_layer); + + mask_layer_id_ = mask_layer->id(); + } + + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, + LayerTreeHostImpl::FrameData* frame_data, + DrawResult draw_result) override { + EXPECT_EQ(1u, frame_data->render_passes.size()); + viz::RenderPass* pass = frame_data->render_passes.back().get(); + EXPECT_EQ(3u, pass->quad_list.size()); + + // There's a solid color quad under everything. + EXPECT_EQ(viz::DrawQuad::Material::kSolidColor, + pass->quad_list.back()->material); + + EXPECT_EQ(viz::DrawQuad::Material::kTiledContent, + pass->quad_list.ElementAt(1)->material); + + auto* mask_quad = pass->quad_list.front(); + EXPECT_EQ(viz::DrawQuad::Material::kTiledContent, mask_quad->material); + gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( + mask_quad->shared_quad_state->quad_to_target_transform, + mask_quad->rect); + EXPECT_EQ(gfx::Rect(0, 0, 50, 50), rect_in_target_space); + // We use kDstIn blend mode for mask. + EXPECT_EQ(SkBlendMode::kDstIn, mask_quad->shared_quad_state->blend_mode); + EndTest(); + return draw_result; + } + + int mask_layer_id_; + FakeContentLayerClient client_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F( + LayerTreeTestMaskLayerForSurfaceWithContentRectNotAtOriginWithLayerList); + class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { protected: void SetupTree() override { @@ -156,7 +245,6 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { gfx::Size mask_size(50, 50); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask_layer_id_ = mask_layer->id(); layer_tree_host()->SetRootLayer(root); @@ -169,7 +257,7 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -187,13 +275,12 @@ class LayerTreeTestMaskLayerForSurfaceWithClippedLayer : public LayerTreeTest { render_pass_quad->rect); EXPECT_EQ(gfx::Rect(20, 10, 10, 20).ToString(), rect_in_target_space.ToString()); - // The masked layer is 50x50, but the surface size is 10x20. So the texture - // coords in the mask are scaled by 10/50 and 20/50. - // The surface is clipped to (20,10) so the mask texture coords are offset - // by 20/50 and 10/50 - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -265,7 +352,6 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale gfx::Size mask_size(50, 50); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); // Setting will change transform on mask layer will make it not adjust // raster scale, which will remain 1. This means the mask_layer and render // surface will have a scale of 2 during draw time. @@ -282,7 +368,7 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -306,13 +392,12 @@ class LayerTreeTestMaskLayerForSurfaceWithDifferentScale render_pass_quad->visible_rect); EXPECT_EQ(gfx::Rect(20, 10, 20, 40).ToString(), visible_rect_in_target_space.ToString()); - // The masked layer is 50x50, but the surface size is 10x20. So the texture - // coords in the mask are scaled by 10/50 and 20/50. - // The surface is clipped to (20,10) so the mask texture coords are offset - // by 20/50 and 10/50 - EXPECT_EQ(gfx::ScaleRect(gfx::RectF(20.f, 10.f, 10.f, 20.f), 1.f / 50.f) - .ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } @@ -368,9 +453,7 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { scaling_layer->SetTransform(scale); content_layer->SetBounds(scaling_layer_size); - mask_layer->SetBounds(scaling_layer_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); layer_tree_host()->SetRootLayer(root); LayerTreeTest::SetupTree(); @@ -382,7 +465,7 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -397,22 +480,25 @@ class LayerTreeTestMaskLayerWithScaling : public LayerTreeTest { gfx::Rect rect_in_target_space = MathUtil::MapEnclosingClippedRect( render_pass_quad->shared_quad_state->quad_to_target_transform, render_pass_quad->rect); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); + switch (host_impl->active_tree()->source_frame_number()) { case 0: // Check that the tree scaling is correctly taken into account for the // mask, that should fully map onto the quad. EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), rect_in_target_space.ToString()); - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); break; case 1: // Applying a DSF should change the render surface size, but won't // affect which part of the mask is used. EXPECT_EQ(gfx::Rect(0, 0, 200, 200).ToString(), rect_in_target_space.ToString()); - EXPECT_EQ(gfx::RectF(0.f, 0.f, 1.f, 1.f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); EndTest(); break; } @@ -471,7 +557,6 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { gfx::Size mask_size(100, 100); gfx::Size mask_texture_size(120, 150); mask_layer->SetBounds(mask_size); - mask_layer->SetLayerMaskType(Layer::LayerMaskType::SINGLE_TEXTURE_MASK); mask_layer->set_fixed_tile_size(mask_texture_size); layer_tree_host()->SetRootLayer(root); @@ -484,7 +569,7 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame_data, DrawResult draw_result) override { - EXPECT_EQ(2u, frame_data->render_passes.size()); + EXPECT_EQ(3u, frame_data->render_passes.size()); viz::RenderPass* root_pass = frame_data->render_passes.back().get(); EXPECT_EQ(2u, root_pass->quad_list.size()); @@ -499,9 +584,12 @@ class LayerTreeTestMaskWithNonExactTextureSize : public LayerTreeTest { viz::RenderPassDrawQuad::MaterialCast(root_pass->quad_list.front()); EXPECT_EQ(gfx::Rect(0, 0, 100, 100).ToString(), render_pass_quad->rect.ToString()); - // The mask layer is 100x100, but is backed by a 120x150 image. - EXPECT_EQ(gfx::RectF(0.0f, 0.0f, 100.f / 120.0f, 100.f / 150.0f).ToString(), - render_pass_quad->mask_uv_rect.ToString()); + + // We use kDstIn blend mode instead of the mask feature of RenderPass. + EXPECT_EQ(gfx::RectF(), render_pass_quad->mask_uv_rect); + viz::RenderPass* mask_pass = frame_data->render_passes[1].get(); + EXPECT_EQ(SkBlendMode::kDstIn, + mask_pass->quad_list.front()->shared_quad_state->blend_mode); EndTest(); return draw_result; } diff --git a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc index 244eb6f2861..e54c35ac2cf 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_occlusion.cc @@ -49,7 +49,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnLayer void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); // Verify the draw properties are valid. @@ -103,7 +103,7 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnSurface void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); RenderSurfaceImpl* surface = GetRenderSurface(child); @@ -148,10 +148,10 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask make_surface_bigger->SetIsDrawable(true); child_->AddChild(make_surface_bigger); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); - mask->SetBounds(gfx::Size(30, 40)); - mask->SetIsDrawable(true); - child_->SetMaskLayer(mask); + mask_ = PictureLayer::Create(&client_); + mask_->SetBounds(gfx::Size(30, 40)); + mask_->SetIsDrawable(true); + child_->SetMaskLayer(mask_); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 12)); @@ -168,30 +168,44 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnMask void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* root = impl->active_tree()->root_layer(); LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - RenderSurfaceImpl* surface = GetRenderSurface(child); - LayerImpl* mask = surface->MaskLayer(); + RenderSurfaceImpl* child_surface = GetRenderSurface(child); + LayerImpl* mask = impl->active_tree()->LayerById(mask_->id()); + RenderSurfaceImpl* mask_surface = GetRenderSurface(mask); // Verify the draw properties are valid. EXPECT_TRUE(root->contributes_to_drawn_render_surface()); EXPECT_TRUE(child->contributes_to_drawn_render_surface()); - EXPECT_TRUE(GetRenderSurface(child)); - EXPECT_EQ(GetRenderSurface(child), child->render_target()); + EXPECT_TRUE(mask->contributes_to_drawn_render_surface()); + EXPECT_TRUE(child_surface); + EXPECT_EQ(child_surface, child->render_target()); - gfx::Transform transform = surface->draw_transform(); + gfx::Transform transform = child_surface->draw_transform(); transform.PreconcatTransform(child->DrawTransform()); + EXPECT_OCCLUSION_EQ( + Occlusion(transform, SimpleEnclosedRegion(), + SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))), + child_surface->occlusion_in_content_space()); + // Mask layer has its own transform and render surface in layer tree mode. + EXPECT_NE(child_surface, mask_surface); EXPECT_OCCLUSION_EQ( Occlusion(transform, SimpleEnclosedRegion(), SimpleEnclosedRegion(gfx::Rect(13, 9, 10, 11))), - mask->draw_properties().occlusion_in_content_space); + mask_surface->occlusion_in_content_space()); + + EXPECT_OCCLUSION_EQ(Occlusion(gfx::Transform(), + SimpleEnclosedRegion(gfx::Rect(3, 4, 10, 10)), + SimpleEnclosedRegion()), + mask->draw_properties().occlusion_in_content_space); EndTest(); } private: FakeContentLayerClient client_; scoped_refptr<Layer> child_; + scoped_refptr<PictureLayer> mask_; }; SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostOcclusionTestDrawPropertiesOnMask); @@ -208,21 +222,21 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask gfx::Transform scale; scale.Scale(2, 2); - child_ = Layer::Create(); - child_->SetBounds(gfx::Size(30, 40)); - child_->SetTransform(scale); - root->AddChild(child_); + scoped_refptr<Layer> child = Layer::Create(); + child->SetBounds(gfx::Size(30, 40)); + child->SetTransform(scale); + root->AddChild(child); scoped_refptr<Layer> grand_child = Layer::Create(); grand_child->SetBounds(gfx::Size(100, 100)); grand_child->SetPosition(gfx::PointF(-10.f, -15.f)); grand_child->SetIsDrawable(true); - child_->AddChild(grand_child); + child->AddChild(grand_child); - scoped_refptr<PictureLayer> mask = PictureLayer::Create(&client_); - mask->SetBounds(gfx::Size(30, 40)); - mask->SetIsDrawable(true); - child_->SetMaskLayer(mask); + mask_ = PictureLayer::Create(&client_); + mask_->SetBounds(gfx::Size(30, 40)); + mask_->SetIsDrawable(true); + child->SetMaskLayer(mask_); scoped_refptr<Layer> child2 = Layer::Create(); child2->SetBounds(gfx::Size(10, 11)); @@ -239,22 +253,21 @@ class LayerTreeHostOcclusionTestDrawPropertiesOnScaledMask void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* child = impl->active_tree()->LayerById(child_->id()); - LayerImpl* mask = GetRenderSurface(child)->MaskLayer(); + LayerImpl* mask = impl->active_tree()->LayerById(mask_->id()); gfx::Transform scale; scale.Scale(2, 2); EXPECT_OCCLUSION_EQ( - Occlusion(scale, SimpleEnclosedRegion(), - SimpleEnclosedRegion(gfx::Rect(13, 15, 10, 11))), + Occlusion(scale, SimpleEnclosedRegion(gfx::Rect(13, 15, 10, 11)), + SimpleEnclosedRegion()), mask->draw_properties().occlusion_in_content_space); EndTest(); } private: FakeContentLayerClient client_; - scoped_refptr<Layer> child_; + scoped_refptr<PictureLayer> mask_; }; SINGLE_AND_MULTI_THREAD_TEST_F( diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index 445a2630c50..8b6af53dba0 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -77,7 +77,7 @@ class LayerTreeHostPictureTestTwinLayer } void WillActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* active_root_impl = impl->active_tree()->root_layer_for_testing(); + LayerImpl* active_root_impl = impl->active_tree()->root_layer(); int picture_id = impl->active_tree()->source_frame_number() < 2 ? picture_id1_ : picture_id2_; @@ -293,7 +293,7 @@ class LayerTreeHostPictureTestChangeLiveTilesRectWithRecycleTree PictureLayerTiling* tiling = picture_impl->HighResTiling(); int num_tiles_y = tiling->TilingDataForTesting().num_tiles_y(); - if (!impl->active_tree()->root_layer_for_testing()) { + if (!impl->active_tree()->root_layer()) { // If active tree doesn't have the layer, then pending tree should have // all needed tiles. EXPECT_TRUE(tiling->TileAt(0, 0)); @@ -420,11 +420,6 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale picture_->SetBounds(gfx::Size(100, 100)); pinch_->AddChild(picture_); - ViewportLayers viewport_layers; - viewport_layers.page_scale = page_scale_layer; - viewport_layers.inner_viewport_container = root_clip; - viewport_layers.inner_viewport_scroll = pinch_; - layer_tree_host()->RegisterViewportLayers(viewport_layers); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 4.f); layer_tree_host()->SetRootLayer(root_clip); LayerTreeHostPictureTest::SetupTree(); diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc index 457b2d1e9b1..f9ff5d0f499 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc @@ -7,6 +7,7 @@ #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_picture_layer.h" #include "cc/test/layer_tree_test.h" +#include "cc/trees/layer_tree_impl.h" #include "cc/trees/proxy_impl.h" #include "cc/trees/proxy_main.h" @@ -82,11 +83,6 @@ class LayerTreeHostProxyTestSetNeedsAnimate : public LayerTreeHostProxyTest { LayerTreeHostProxyTestSetNeedsAnimate& operator=( const LayerTreeHostProxyTestSetNeedsAnimate&) = delete; - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - void BeginTest() override { EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); @@ -102,10 +98,6 @@ class LayerTreeHostProxyTestSetNeedsAnimate : public LayerTreeHostProxyTest { GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->current_pipeline_stage()); - } - - void DidCommit() override { - EXPECT_EQ(0, update_check_layer()->update_count()); EndTest(); } }; @@ -160,14 +152,12 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating& operator=( const LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating&) = delete; - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - - void BeginTest() override { proxy()->SetNeedsAnimate(); } + void BeginTest() override {} void WillBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 1) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::ANIMATE_PIPELINE_STAGE, @@ -184,6 +174,9 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating } void DidBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 2) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, @@ -191,8 +184,19 @@ class LayerTreeHostProxyTestSetNeedsUpdateLayersWhileAnimating } void DidCommit() override { - EXPECT_EQ(1, update_check_layer()->update_count()); - EndTest(); + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + EXPECT_EQ(1, update_check_layer()->update_count()); + + // Wait until the first frame is committed and we enter the desired + // state to start the test. + proxy()->SetNeedsAnimate(); + break; + case 2: + EXPECT_EQ(2, update_check_layer()->update_count()); + EndTest(); + break; + } } }; @@ -209,14 +213,12 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating LayerTreeHostProxyTestSetNeedsCommitWhileAnimating& operator=( const LayerTreeHostProxyTestSetNeedsCommitWhileAnimating&) = delete; - void InitializeSettings(LayerTreeSettings* settings) override { - // TODO(crbug.com/985009): Fix test with surface sync enabled. - settings->enable_surface_synchronization = false; - } - - void BeginTest() override { proxy()->SetNeedsAnimate(); } + void BeginTest() override {} void WillBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 1) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::ANIMATE_PIPELINE_STAGE, @@ -233,6 +235,9 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating } void DidBeginMainFrame() override { + if (layer_tree_host()->SourceFrameNumber() != 2) + return; + EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, GetProxyMain()->max_requested_pipeline_stage()); EXPECT_EQ(ProxyMain::NO_PIPELINE_STAGE, @@ -240,8 +245,19 @@ class LayerTreeHostProxyTestSetNeedsCommitWhileAnimating } void DidCommit() override { - EXPECT_EQ(1, update_check_layer()->update_count()); - EndTest(); + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + EXPECT_EQ(1, update_check_layer()->update_count()); + + // Wait until the first frame is committed and we enter the desired + // state to start the test. + proxy()->SetNeedsAnimate(); + break; + case 2: + EXPECT_EQ(2, update_check_layer()->update_count()); + EndTest(); + break; + } } }; diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index 451a33763d6..6f6915ee368 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -27,7 +27,6 @@ #include "cc/test/test_ukm_recorder_factory.h" #include "cc/trees/clip_node.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" @@ -75,6 +74,8 @@ static ScrollTree* ScrollTreeForLayer(LayerImpl* layer_impl) { class LayerTreeHostScrollTest : public LayerTreeTest { protected: + LayerTreeHostScrollTest() { SetUseLayerLists(); } + void SetupTree() override { LayerTreeTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); @@ -84,31 +85,45 @@ class LayerTreeHostScrollTest : public LayerTreeTest { root_layer->bounds().height() + 100); SetupViewport(root_layer, root_layer->bounds(), scroll_layer_bounds); + layer_tree_host() + ->OuterViewportScrollLayerForTesting() + ->set_did_scroll_callback(base::BindRepeating( + &LayerTreeHostScrollTest::DidScrollOuterViewport, + base::Unretained(this))); + } + + // This is set as did_scroll_callback of scroll layers to automatically + // synchronize scroll delta from impl-side, which simulates cc client (e.g. + // Blink) behavior when handling impl-side scrolls. + void SyncScrollFromImpl(const gfx::ScrollOffset& scroll_offset, + const ElementId& element_id) { + SetScrollOffset(layer_tree_host()->LayerByElementId(element_id), + scroll_offset); } + + virtual void DidScrollOuterViewport(const gfx::ScrollOffset& scroll_offset, + const ElementId& element_id) { + SyncScrollFromImpl(scroll_offset, element_id); + num_outer_viewport_scrolls_++; + } + + int num_outer_viewport_scrolls_ = 0; }; class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { public: LayerTreeHostScrollTestScrollSimple() - : initial_scroll_(10, 20), - second_scroll_(40, 5), - scroll_amount_(2, -1), - num_scrolls_(0) {} + : initial_scroll_(10, 20), second_scroll_(40, 5), scroll_amount_(2, -1) {} void BeginTest() override { - outer_viewport_container_layer_id_ = - layer_tree_host()->outer_viewport_container_layer()->id(); - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestScrollSimple::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); if (!layer_tree_host()->SourceFrameNumber()) { EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); } else { @@ -117,13 +132,14 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { scroll_layer->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - scroll_layer->SetScrollOffset(second_scroll_); + SetScrollOffset(scroll_layer, second_scroll_); } } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root = impl->active_tree()->root_layer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); scroll_layer->SetBounds( @@ -148,18 +164,12 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - - void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: gfx::ScrollOffset initial_scroll_; gfx::ScrollOffset second_scroll_; gfx::Vector2dF scroll_amount_; - int num_scrolls_; - int outer_viewport_container_layer_id_; }; MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple); @@ -168,14 +178,11 @@ class LayerTreeHostScrollTestScrollMultipleRedraw : public LayerTreeHostScrollTest { public: LayerTreeHostScrollTestScrollMultipleRedraw() - : initial_scroll_(40, 10), scroll_amount_(-3, 17), num_scrolls_(0) {} + : initial_scroll_(40, 10), scroll_amount_(-3, 17) {} void BeginTest() override { - scroll_layer_ = layer_tree_host()->outer_viewport_scroll_layer(); - scroll_layer_->SetScrollOffset(initial_scroll_); - scroll_layer_->set_did_scroll_callback(base::BindRepeating( - &LayerTreeHostScrollTestScrollMultipleRedraw::DidScrollOuterViewport, - base::Unretained(this))); + scroll_layer_ = layer_tree_host()->OuterViewportScrollLayerForTesting(); + SetScrollOffset(scroll_layer_.get(), initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -227,16 +234,11 @@ class LayerTreeHostScrollTestScrollMultipleRedraw } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - - void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: gfx::ScrollOffset initial_scroll_; gfx::Vector2dF scroll_amount_; - int num_scrolls_; scoped_refptr<Layer> scroll_layer_; }; @@ -254,16 +256,11 @@ class LayerTreeHostScrollTestScrollAbortedCommit num_did_begin_main_frames_(0), num_will_commits_(0), num_did_commits_(0), - num_impl_commits_(0), - num_impl_scrolls_(0) {} + num_impl_commits_(0) {} void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestScrollAbortedCommit::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -271,18 +268,19 @@ class LayerTreeHostScrollTestScrollAbortedCommit LayerTreeHostScrollTest::SetupTree(); gfx::Size scroll_layer_bounds(200, 200); - layer_tree_host()->outer_viewport_scroll_layer()->SetBounds( + layer_tree_host()->OuterViewportScrollLayerForTesting()->SetBounds( scroll_layer_bounds); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } void WillBeginMainFrame() override { num_will_begin_main_frames_++; - Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* root_scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (num_will_begin_main_frames_) { case 1: // This will not be aborted because of the initial prop changes. - EXPECT_EQ(0, num_impl_scrolls_); + EXPECT_EQ(0, num_outer_viewport_scrolls_); EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->CurrentScrollOffset()); @@ -291,7 +289,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit case 2: // This commit will be aborted, and another commit will be // initiated from the redraw. - EXPECT_EQ(1, num_impl_scrolls_); + EXPECT_EQ(1, num_outer_viewport_scrolls_); EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_), @@ -301,7 +299,7 @@ class LayerTreeHostScrollTestScrollAbortedCommit break; case 3: // This commit will not be aborted because of the scroll change. - EXPECT_EQ(2, num_impl_scrolls_); + EXPECT_EQ(2, num_outer_viewport_scrolls_); // The source frame number still increases even with the abort. EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta( @@ -309,12 +307,14 @@ class LayerTreeHostScrollTestScrollAbortedCommit root_scroll_layer->CurrentScrollOffset()); EXPECT_EQ(impl_scale_ * impl_scale_, layer_tree_host()->page_scale_factor()); - root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta( - root_scroll_layer->CurrentScrollOffset(), second_main_scroll_)); + SetScrollOffset( + root_scroll_layer, + gfx::ScrollOffsetWithDelta(root_scroll_layer->CurrentScrollOffset(), + second_main_scroll_)); break; case 4: // This commit will also be aborted. - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber()); gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; @@ -338,7 +338,8 @@ class LayerTreeHostScrollTestScrollAbortedCommit } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); if (impl->active_tree()->source_frame_number() == 0 && impl->SourceAnimationFrameNumberForTesting() == 1) { @@ -412,12 +413,8 @@ class LayerTreeHostScrollTestScrollAbortedCommit } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_impl_scrolls_++; - } - void AfterTest() override { - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); // Verify that the embedder sees aborted commits as real commits. EXPECT_EQ(4, num_will_begin_main_frames_); EXPECT_EQ(4, num_did_begin_main_frames_); @@ -437,7 +434,6 @@ class LayerTreeHostScrollTestScrollAbortedCommit int num_will_commits_; int num_did_commits_; int num_impl_commits_; - int num_impl_scrolls_; }; MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollAbortedCommit); @@ -454,7 +450,8 @@ class LayerTreeHostScrollTestFractionalScroll : public LayerTreeHostScrollTest { void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); // Check that a fractional scroll delta is correctly accumulated over // multiple commits. @@ -504,20 +501,41 @@ class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest { void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); - layer_tree_host() - ->outer_viewport_container_layer() - ->SetForceRenderSurfaceForTesting(true); - gfx::Transform translate; - translate.Translate(0.25f, 0.f); - layer_tree_host()->outer_viewport_container_layer()->SetTransform( - translate); + + scoped_refptr<Layer> container = Layer::Create(); + container->SetBounds(gfx::Size(100, 100)); + CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(), + container.get()); + CreateTransformNode(container.get()).post_translation = + gfx::Vector2dF(0.25, 0); + CreateEffectNode(container.get()).render_surface_reason = + RenderSurfaceReason::kTest; + layer_tree_host()->root_layer()->AddChild(container); + + scroll_layer_ = Layer::Create(); + scroll_layer_->SetBounds(gfx::Size(200, 200)); + scroll_layer_->SetScrollable(gfx::Size(100, 100)); + scroll_layer_->SetIsDrawable(true); + scroll_layer_->SetElementId( + LayerIdToElementIdForTesting(scroll_layer_->id())); + CopyProperties(container.get(), scroll_layer_.get()); + CreateTransformNode(scroll_layer_.get()); + CreateScrollNode(scroll_layer_.get()); + layer_tree_host()->root_layer()->AddChild(scroll_layer_); + + scroll_layer_->set_did_scroll_callback(base::BindRepeating( + &LayerTreeHostScrollTestScrollSnapping::SyncScrollFromImpl, + base::Unretained(this))); + layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->LayerById(scroll_layer_->id()); + gfx::Transform translate; // Check that screen space transform of the scrollable layer is correctly @@ -545,6 +563,7 @@ class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest { } private: + scoped_refptr<Layer> scroll_layer_; gfx::Vector2dF scroll_amount_; }; @@ -555,25 +574,17 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { LayerTreeHostScrollTestCaseWithChild() : initial_offset_(10, 20), javascript_scroll_(40, 5), - scroll_amount_(2, -1), - num_scrolls_(0) {} + scroll_amount_(2, -1) {} void SetupTree() override { SetInitialDeviceScaleFactor(device_scale_factor_); SetInitialRootBounds(gfx::Size(10, 10)); LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); + Layer* root_scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); - root_scroll_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); - root_scroll_layer_->SetElementId( - LayerIdToElementIdForTesting(root_scroll_layer_->id())); - root_scroll_layer_->SetBounds(gfx::Size(110, 110)); - root_scroll_layer_->SetPosition(gfx::PointF()); - root_scroll_layer_->SetIsDrawable(true); - - SetupViewport(root_layer, root_scroll_layer_, root_layer->bounds()); - - child_layer_ = FakePictureLayer::Create(&fake_content_layer_client_); + child_layer_ = Layer::Create(); child_layer_->set_did_scroll_callback( base::BindRepeating(&LayerTreeHostScrollTestCaseWithChild::DidScroll, base::Unretained(this))); @@ -581,14 +592,15 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { LayerIdToElementIdForTesting(child_layer_->id())); child_layer_->SetBounds(gfx::Size(110, 110)); + gfx::Vector2dF child_layer_offset; + // Adjust the child layer horizontally so that scrolls will never hit it. if (scroll_child_layer_) { // Scrolls on the child layer will happen at 5, 5. If they are treated // like device pixels, and device scale factor is 2, then they will // be considered at 2.5, 2.5 in logical pixels, and will miss this layer. - child_layer_->SetPosition(gfx::PointF(5.f, 5.f)); + child_layer_offset = gfx::Vector2dF(5.f, 5.f); } else { - // Adjust the child layer horizontally so that scrolls will never hit it. - child_layer_->SetPosition(gfx::PointF(60.f, 5.f)); + child_layer_offset = gfx::Vector2dF(60.f, 5.f); } child_layer_->SetIsDrawable(true); @@ -596,24 +608,23 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { child_layer_->SetHitTestable(true); child_layer_->SetElementId( LayerIdToElementIdForTesting(child_layer_->id())); - child_layer_->SetBounds(root_scroll_layer_->bounds()); - root_scroll_layer_->AddChild(child_layer_); + child_layer_->SetBounds(root_scroll_layer->bounds()); + root_layer->AddChild(child_layer_); + + CopyProperties(root_scroll_layer, child_layer_.get()); + CreateTransformNode(child_layer_.get()).post_translation = + child_layer_offset; + CreateScrollNode(child_layer_.get()); if (scroll_child_layer_) { - expected_scroll_layer_ = child_layer_; - expected_no_scroll_layer_ = root_scroll_layer_; + expected_scroll_layer_ = child_layer_.get(); + expected_no_scroll_layer_ = root_scroll_layer; } else { - expected_scroll_layer_ = root_scroll_layer_; - expected_no_scroll_layer_ = child_layer_; + expected_scroll_layer_ = root_scroll_layer; + expected_no_scroll_layer_ = child_layer_.get(); } - expected_scroll_layer_->SetScrollOffset(initial_offset_); - fake_content_layer_client_.set_bounds(root_layer->bounds()); - - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestCaseWithChild::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(expected_scroll_layer_, initial_offset_); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -627,15 +638,12 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { } void DidScroll(const gfx::ScrollOffset& offset, const ElementId& element_id) { + SyncScrollFromImpl(offset, element_id); final_scroll_offset_ = expected_scroll_layer_->CurrentScrollOffset(); EXPECT_VECTOR_EQ(offset, final_scroll_offset_); EXPECT_EQ(element_id, expected_scroll_layer_->element_id()); } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - void UpdateLayerTreeHost() override { EXPECT_VECTOR_EQ(gfx::Vector2d(), expected_no_scroll_layer_->CurrentScrollOffset()); @@ -651,7 +659,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { expected_scroll_layer_->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - expected_scroll_layer_->SetScrollOffset(javascript_scroll_); + SetScrollOffset(expected_scroll_layer_, javascript_scroll_); break; case 2: EXPECT_VECTOR_EQ( @@ -662,12 +670,13 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* inner_scroll = impl->InnerViewportScrollLayer(); - FakePictureLayerImpl* root_scroll_layer_impl = - static_cast<FakePictureLayerImpl*>(impl->OuterViewportScrollLayer()); - FakePictureLayerImpl* child_layer_impl = static_cast<FakePictureLayerImpl*>( + LayerImpl* inner_scroll = + impl->active_tree()->InnerViewportScrollLayerForTesting(); + LayerImpl* root_scroll_layer_impl = + impl->active_tree()->OuterViewportScrollLayerForTesting(); + LayerImpl* child_layer_impl = root_scroll_layer_impl->layer_tree_impl()->LayerById( - child_layer_->id())); + child_layer_->id()); LayerImpl* expected_scroll_layer_impl = nullptr; LayerImpl* expected_no_scroll_layer_impl = nullptr; @@ -690,8 +699,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { // GESTURE scroll on impl thread. Also tests that the last scrolled // layer id is stored even after the scrolling ends. gfx::Point scroll_point = gfx::ToCeiledPoint( - expected_scroll_layer_impl->test_properties()->position - - gfx::Vector2dF(0.5f, 0.5f)); + gfx::PointF(-0.5f, -0.5f) + + GetTransformNode(expected_scroll_layer_impl)->post_translation); InputHandler::ScrollStatus status = impl->ScrollBegin( BeginState(scroll_point).get(), InputHandler::TOUCHSCREEN); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); @@ -715,8 +724,8 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { case 1: { // WHEEL scroll on impl thread. gfx::Point scroll_point = gfx::ToCeiledPoint( - expected_scroll_layer_impl->test_properties()->position + - gfx::Vector2dF(0.5f, 0.5f)); + gfx::PointF(0.5f, 0.5f) + + GetTransformNode(expected_scroll_layer_impl)->post_translation); InputHandler::ScrollStatus status = impl->ScrollBegin( BeginState(scroll_point).get(), InputHandler::WHEEL); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread); @@ -749,12 +758,12 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { void AfterTest() override { if (scroll_child_layer_) { - EXPECT_EQ(0, num_scrolls_); + EXPECT_EQ(0, num_outer_viewport_scrolls_); EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_), final_scroll_offset_); } else { - EXPECT_EQ(2, num_scrolls_); + EXPECT_EQ(2, num_outer_viewport_scrolls_); EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_); } } @@ -766,15 +775,11 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest { gfx::ScrollOffset initial_offset_; gfx::ScrollOffset javascript_scroll_; gfx::Vector2d scroll_amount_; - int num_scrolls_; gfx::ScrollOffset final_scroll_offset_; - FakeContentLayerClient fake_content_layer_client_; - - scoped_refptr<Layer> root_scroll_layer_; scoped_refptr<Layer> child_layer_; - scoped_refptr<Layer> expected_scroll_layer_; - scoped_refptr<Layer> expected_no_scroll_layer_; + Layer* expected_scroll_layer_; + Layer* expected_no_scroll_layer_; }; TEST_F(LayerTreeHostScrollTestCaseWithChild, DeviceScaleFactor1_ScrollChild) { @@ -822,8 +827,7 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { : initial_scroll_(10, 20), main_thread_scroll_(40, 5), impl_thread_scroll1_(2, -1), - impl_thread_scroll2_(-3, 10), - num_scrolls_(0) {} + impl_thread_scroll2_(-3, 10) {} void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); @@ -831,17 +835,14 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { } void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestSimple::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); if (!layer_tree_host()->SourceFrameNumber()) { EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); } else { @@ -851,7 +852,8 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { // Pretend like Javascript updated the scroll position itself with a // change of main_thread_scroll. - scroll_layer->SetScrollOffset( + SetScrollOffset( + scroll_layer, gfx::ScrollOffsetWithDelta( initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_)); } @@ -868,8 +870,9 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { if (impl->pending_tree()) impl->SetNeedsRedraw(); - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root = impl->active_tree()->root_layer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); LayerImpl* pending_root = impl->active_tree()->FindPendingTreeLayerById(root->id()); @@ -903,7 +906,7 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { ScrollDelta(scroll_layer)); LayerImpl* pending_scroll_layer = - impl->pending_tree()->OuterViewportScrollLayer(); + impl->pending_tree()->OuterViewportScrollLayerForTesting(); EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta( initial_scroll_, main_thread_scroll_ + impl_thread_scroll1_), @@ -927,18 +930,13 @@ class LayerTreeHostScrollTestSimple : public LayerTreeHostScrollTest { } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - - void AfterTest() override { EXPECT_EQ(1, num_scrolls_); } + void AfterTest() override { EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: gfx::ScrollOffset initial_scroll_; gfx::Vector2dF main_thread_scroll_; gfx::Vector2dF impl_thread_scroll1_; gfx::Vector2dF impl_thread_scroll2_; - int num_scrolls_; }; // This tests scrolling on the impl side which is only possible with a thread. @@ -959,13 +957,14 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { } void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void WillCommit() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (layer_tree_host()->SourceFrameNumber()) { case 0: EXPECT_TRUE(base::Contains( @@ -986,8 +985,9 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { void BeginCommitOnThread(LayerTreeHostImpl* impl) override { // Scroll after the 2nd commit has started. if (impl->active_tree()->source_frame_number() == 0) { - LayerImpl* active_root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* active_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* active_root = impl->active_tree()->root_layer(); + LayerImpl* active_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); ASSERT_TRUE(active_root); ASSERT_TRUE(active_scroll_layer); active_scroll_layer->ScrollBy(impl_thread_scroll_); @@ -998,12 +998,13 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { void CommitCompleteOnThread(LayerTreeHostImpl* impl) override { // We force a second draw here of the first commit before activating // the second commit. - LayerImpl* active_root = impl->active_tree()->root_layer_for_testing(); + LayerImpl* active_root = impl->active_tree()->root_layer(); LayerImpl* active_scroll_layer = - active_root ? impl->OuterViewportScrollLayer() : nullptr; - LayerImpl* pending_root = impl->pending_tree()->root_layer_for_testing(); + active_root ? impl->active_tree()->OuterViewportScrollLayerForTesting() + : nullptr; + LayerImpl* pending_root = impl->pending_tree()->root_layer(); LayerImpl* pending_scroll_layer = - impl->pending_tree()->OuterViewportScrollLayer(); + impl->pending_tree()->OuterViewportScrollLayerForTesting(); ASSERT_TRUE(pending_root); ASSERT_TRUE(pending_scroll_layer); @@ -1048,7 +1049,8 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { if (!impl->pending_tree()) return; - LayerImpl* scroll_layer = impl->pending_tree()->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->pending_tree()->OuterViewportScrollLayerForTesting(); gfx::ScrollOffset scroll_offset = scroll_layer->CurrentScrollOffset(); int transform_index = scroll_layer->transform_tree_index(); gfx::ScrollOffset transform_tree_scroll_offset = @@ -1063,7 +1065,8 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest { if (impl->pending_tree()) impl->SetNeedsRedraw(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: @@ -1108,10 +1111,6 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset public: LayerTreeHostScrollTestScrollZeroMaxScrollOffset() = default; - void InitializeSettings(LayerTreeSettings* settings) override { - settings->use_layer_lists = true; - } - void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); @@ -1123,11 +1122,11 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset scroller_->SetHitTestable(true); scroller_->SetScrollable(layer_tree_host()->root_layer()->bounds()); scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id())); - CopyProperties(layer_tree_host()->outer_viewport_scroll_layer(), + CopyProperties(layer_tree_host()->OuterViewportScrollLayerForTesting(), scroller_.get()); CreateTransformNode(scroller_.get()); CreateScrollNode(scroller_.get()); - layer_tree_host()->outer_viewport_scroll_layer()->AddChild(scroller_.get()); + layer_tree_host()->root_layer()->AddChild(scroller_.get()); } void BeginTest() override { @@ -1202,11 +1201,12 @@ class LayerTreeHostScrollTestScrollNonDrawnLayer void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); - layer_tree_host()->outer_viewport_scroll_layer()->SetIsDrawable(false); - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - gfx::ScrollOffset(20.f, 20.f)); + layer_tree_host()->OuterViewportScrollLayerForTesting()->SetIsDrawable( + false); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + gfx::ScrollOffset(20.f, 20.f)); layer_tree_host() - ->outer_viewport_scroll_layer() + ->OuterViewportScrollLayerForTesting() ->SetNonFastScrollableRegion(gfx::Rect(20, 20, 20, 20)); } @@ -1235,21 +1235,24 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollNonDrawnLayer); class LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent : public LayerTreeHostScrollTest { public: - LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent() = default; + LayerTreeHostScrollTestImplScrollUnderMainThreadScrollingParent() { + SetUseLayerLists(); + } void BeginTest() override { PostSetNeedsCommitToMainThread(); } void SetupTree() override { LayerTreeHostScrollTest::SetupTree(); - layer_tree_host() - ->inner_viewport_scroll_layer() - ->AddMainThreadScrollingReasons( - MainThreadScrollingReason::kScrollbarScrolling); + GetScrollNode(layer_tree_host()->InnerViewportScrollLayerForTesting()) + ->main_thread_scrolling_reasons = + MainThreadScrollingReason::kScrollbarScrolling; } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* inner_scroll_layer = impl->InnerViewportScrollLayer(); - LayerImpl* outer_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* inner_scroll_layer = + impl->active_tree()->InnerViewportScrollLayerForTesting(); + LayerImpl* outer_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); ScrollTree& scroll_tree = impl->active_tree()->property_trees()->scroll_tree; @@ -1336,14 +1339,10 @@ class LayerTreeHostScrollTestLayerStructureChange : scroll_destroy_whole_tree_(false) {} void SetupTree() override { - LayerTreeTest::SetupTree(); + LayerTreeHostScrollTest::SetupTree(); Layer* root_layer = layer_tree_host()->root_layer(); - root_layer->SetBounds(gfx::Size(10, 10)); - - SetupViewport(root_layer, root_layer->bounds(), root_layer->bounds()); - Layer* outer_scroll_layer = - layer_tree_host()->outer_viewport_scroll_layer(); + layer_tree_host()->OuterViewportScrollLayerForTesting(); Layer* root_scroll_layer = CreateScrollLayer(outer_scroll_layer, &root_scroll_layer_client_); @@ -1381,8 +1380,10 @@ class LayerTreeHostScrollTestLayerStructureChange virtual void DidScroll(Layer* layer) { if (scroll_destroy_whole_tree_) { - layer_tree_host()->RegisterViewportLayers(ViewportLayers()); layer_tree_host()->SetRootLayer(nullptr); + layer_tree_host()->property_trees()->clear(); + layer_tree_host()->RegisterViewportPropertyIds( + LayerTreeHost::ViewportPropertyIds()); EndTest(); return; } @@ -1402,7 +1403,6 @@ class LayerTreeHostScrollTestLayerStructureChange Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) { scoped_refptr<PictureLayer> scroll_layer = PictureLayer::Create(&fake_content_layer_client_); - scroll_layer->SetPosition(gfx::PointF()); scroll_layer->SetIsDrawable(true); scroll_layer->SetScrollable(parent->bounds()); scroll_layer->SetHitTestable(true); @@ -1414,7 +1414,12 @@ class LayerTreeHostScrollTestLayerStructureChange &FakeLayerScrollClient::DidScroll, base::Unretained(client))); client->owner_ = this; client->layer_ = scroll_layer.get(); - parent->AddChild(scroll_layer); + + CopyProperties(parent, scroll_layer.get()); + CreateTransformNode(scroll_layer.get()); + CreateScrollNode(scroll_layer.get()); + layer_tree_host()->root_layer()->AddChild(scroll_layer); + return scroll_layer.get(); } @@ -1456,22 +1461,16 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { second_scroll_(40, 5), third_scroll_(20, 10), scroll_amount_(2, -1), - num_commits_(0), - num_scrolls_(0) {} + num_commits_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { + LayerTreeHostScrollTest::InitializeSettings(settings); settings->main_frame_before_activation_enabled = true; } void BeginTest() override { - outer_viewport_container_layer_id_ = - layer_tree_host()->outer_viewport_container_layer()->id(); - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating( - &LayerTreeHostScrollTestScrollMFBA::DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -1492,7 +1491,8 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (layer_tree_host()->SourceFrameNumber()) { case 0: EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); @@ -1502,20 +1502,21 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_), scroll_layer->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - scroll_layer->SetScrollOffset(second_scroll_); + SetScrollOffset(scroll_layer, second_scroll_); break; case 2: // Third frame does not see a scroll delta because we only did one // scroll for the second and third frames. EXPECT_VECTOR_EQ(second_scroll_, scroll_layer->CurrentScrollOffset()); // Pretend like Javascript updated the scroll position itself. - scroll_layer->SetScrollOffset(third_scroll_); + SetScrollOffset(scroll_layer, third_scroll_); break; } } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: EXPECT_VECTOR_EQ(gfx::Vector2d(), ScrollDelta(scroll_layer)); @@ -1546,19 +1547,16 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { } } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_scrolls_++; - } - void AfterTest() override { EXPECT_EQ(3, num_commits_); - EXPECT_EQ(1, num_scrolls_); + EXPECT_EQ(1, num_outer_viewport_scrolls_); } private: void Scroll(LayerTreeHostImpl* impl) { - LayerImpl* root = impl->active_tree()->root_layer_for_testing(); - LayerImpl* scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root = impl->active_tree()->root_layer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); scroll_layer->SetBounds( gfx::Size(root->bounds().width() + 100, root->bounds().height() + 100)); @@ -1570,8 +1568,6 @@ class LayerTreeHostScrollTestScrollMFBA : public LayerTreeHostScrollTest { gfx::ScrollOffset third_scroll_; gfx::Vector2dF scroll_amount_; int num_commits_; - int num_scrolls_; - int outer_viewport_container_layer_id_; }; MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollMFBA); @@ -1589,20 +1585,16 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA num_did_commits_(0), num_impl_commits_(0), num_aborted_commits_(0), - num_impl_scrolls_(0), num_draws_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { + LayerTreeHostScrollTest::InitializeSettings(settings); settings->main_frame_before_activation_enabled = true; } void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating(&LayerTreeHostScrollTestScrollAbortedCommitMFBA:: - DidScrollOuterViewport, - base::Unretained(this))); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } @@ -1610,35 +1602,38 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA LayerTreeHostScrollTest::SetupTree(); gfx::Size scroll_layer_bounds(200, 200); - layer_tree_host()->outer_viewport_scroll_layer()->SetBounds( + layer_tree_host()->OuterViewportScrollLayerForTesting()->SetBounds( scroll_layer_bounds); layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.01f, 100.f); } void WillBeginMainFrame() override { num_will_begin_main_frames_++; - Layer* root_scroll_layer = layer_tree_host()->outer_viewport_scroll_layer(); + Layer* root_scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); switch (num_will_begin_main_frames_) { case 1: // This will not be aborted because of the initial prop changes. - EXPECT_EQ(0, num_impl_scrolls_); + EXPECT_EQ(0, num_outer_viewport_scrolls_); EXPECT_EQ(0, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ(initial_scroll_, root_scroll_layer->CurrentScrollOffset()); break; case 2: // This commit will not be aborted because of the scroll change. - EXPECT_EQ(1, num_impl_scrolls_); + EXPECT_EQ(1, num_outer_viewport_scrolls_); EXPECT_EQ(1, layer_tree_host()->SourceFrameNumber()); EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, impl_scroll_), root_scroll_layer->CurrentScrollOffset()); - root_scroll_layer->SetScrollOffset(gfx::ScrollOffsetWithDelta( - root_scroll_layer->CurrentScrollOffset(), second_main_scroll_)); + SetScrollOffset( + root_scroll_layer, + gfx::ScrollOffsetWithDelta(root_scroll_layer->CurrentScrollOffset(), + second_main_scroll_)); break; case 3: { // This commit will be aborted. - EXPECT_EQ(2, num_impl_scrolls_); + EXPECT_EQ(2, num_outer_viewport_scrolls_); // The source frame number still increases even with the abort. EXPECT_EQ(2, layer_tree_host()->SourceFrameNumber()); gfx::Vector2dF delta = @@ -1649,7 +1644,7 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA } case 4: { // This commit will also be aborted. - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); EXPECT_EQ(3, layer_tree_host()->SourceFrameNumber()); gfx::Vector2dF delta = impl_scroll_ + impl_scroll_ + impl_scroll_ + second_main_scroll_; @@ -1696,7 +1691,8 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA } void DrawLayersOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* root_scroll_layer = impl->OuterViewportScrollLayer(); + LayerImpl* root_scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: { switch (num_impl_commits_) { @@ -1768,12 +1764,8 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA num_draws_++; } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { - num_impl_scrolls_++; - } - void AfterTest() override { - EXPECT_EQ(3, num_impl_scrolls_); + EXPECT_EQ(3, num_outer_viewport_scrolls_); // Verify that the embedder sees aborted commits as real commits. EXPECT_EQ(4, num_will_begin_main_frames_); EXPECT_EQ(4, num_did_begin_main_frames_); @@ -1797,7 +1789,6 @@ class LayerTreeHostScrollTestScrollAbortedCommitMFBA int num_did_commits_; int num_impl_commits_; int num_aborted_commits_; - int num_impl_scrolls_; int num_draws_; }; @@ -1832,6 +1823,7 @@ class LayerTreeHostScrollTestElasticOverscroll num_begin_main_frames_main_thread_(0) {} void InitializeSettings(LayerTreeSettings* settings) override { + LayerTreeHostScrollTest::InitializeSettings(settings); settings->enable_elastic_overscroll = true; } @@ -1985,52 +1977,44 @@ class LayerTreeHostScrollTestPropertyTreeUpdate : initial_scroll_(10, 20), second_scroll_(0, 0) {} void BeginTest() override { - layer_tree_host()->inner_viewport_scroll_layer()->SetScrollOffset( - initial_scroll_); - layer_tree_host()->inner_viewport_scroll_layer()->SetBounds( - gfx::Size(100, 100)); + SetScrollOffset(layer_tree_host()->OuterViewportScrollLayerForTesting(), + initial_scroll_); PostSetNeedsCommitToMainThread(); } void UpdateLayerTreeHost() override { - Layer* scroll_layer = layer_tree_host()->inner_viewport_scroll_layer(); + Layer* scroll_layer = + layer_tree_host()->OuterViewportScrollLayerForTesting(); if (layer_tree_host()->SourceFrameNumber() == 0) { EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->CurrentScrollOffset()); } else { EXPECT_VECTOR_EQ( gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_), scroll_layer->CurrentScrollOffset()); - scroll_layer->SetScrollOffset(second_scroll_); - scroll_layer->SetOpacity(0.5f); + SetScrollOffset(scroll_layer, second_scroll_); + SetOpacity(scroll_layer, 0.5f); } } void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { - LayerImpl* scroll_layer = impl->InnerViewportScrollLayer(); + LayerImpl* scroll_layer = + impl->active_tree()->OuterViewportScrollLayerForTesting(); switch (impl->active_tree()->source_frame_number()) { case 0: EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( scroll_layer->element_id())); - EXPECT_VECTOR_EQ( - initial_scroll_, - scroll_layer->layer_tree_impl() - ->property_trees() - ->transform_tree.Node(scroll_layer->transform_tree_index()) - ->scroll_offset); + EXPECT_VECTOR_EQ(initial_scroll_, + GetTransformNode(scroll_layer)->scroll_offset); PostSetNeedsCommitToMainThread(); break; case 1: EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer) ->GetScrollOffsetBaseForTesting( scroll_layer->element_id())); - EXPECT_VECTOR_EQ( - second_scroll_, - scroll_layer->layer_tree_impl() - ->property_trees() - ->transform_tree.Node(scroll_layer->transform_tree_index()) - ->scroll_offset); + EXPECT_VECTOR_EQ(second_scroll_, + GetTransformNode(scroll_layer)->scroll_offset); EndTest(); break; } @@ -2047,14 +2031,13 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestPropertyTreeUpdate); class LayerTreeHostScrollTestImplSideInvalidation : public LayerTreeHostScrollTest { void BeginTest() override { - layer_tree_host()->outer_viewport_scroll_layer()->set_did_scroll_callback( - base::BindRepeating(&LayerTreeHostScrollTestImplSideInvalidation:: - DidScrollOuterViewport, - base::Unretained(this))); PostSetNeedsCommitToMainThread(); } - void DidScrollOuterViewport(const gfx::ScrollOffset&, const ElementId&) { + void DidScrollOuterViewport(const gfx::ScrollOffset& offset, + const ElementId& element_id) override { + LayerTreeHostScrollTest::DidScrollOuterViewport(offset, element_id); + // Defer responding to the main frame until an impl-side pending tree is // created for the invalidation request. { @@ -2073,10 +2056,11 @@ class LayerTreeHostScrollTestImplSideInvalidation // second case on activation, so add a delta from the main thread that // takes us to the final value. Layer* outer_viewport_layer = - layer_tree_host()->outer_viewport_scroll_layer(); + layer_tree_host()->OuterViewportScrollLayerForTesting(); gfx::ScrollOffset delta_to_send = outer_viewport_offsets_[2] - outer_viewport_offsets_[1]; - outer_viewport_layer->SetScrollOffset( + SetScrollOffset( + outer_viewport_layer, outer_viewport_layer->CurrentScrollOffset() + delta_to_send); } break; case 2: @@ -2105,7 +2089,7 @@ class LayerTreeHostScrollTestImplSideInvalidation return; LayerImpl* scroll_layer = - host_impl->pending_tree()->OuterViewportScrollLayer(); + host_impl->pending_tree()->OuterViewportScrollLayerForTesting(); gfx::ScrollOffset scroll_offset = scroll_layer->CurrentScrollOffset(); int transform_index = scroll_layer->transform_tree_index(); gfx::ScrollOffset transform_tree_scroll_offset = @@ -2134,7 +2118,7 @@ class LayerTreeHostScrollTestImplSideInvalidation // Add some more delta to the active tree state of the scroll offset and // a commit to send this additional delta to the main thread. host_impl->active_tree() - ->OuterViewportScrollLayer() + ->OuterViewportScrollLayerForTesting() ->SetCurrentScrollOffset(outer_viewport_offsets_[1]); host_impl->SetNeedsCommit(); @@ -2156,9 +2140,10 @@ class LayerTreeHostScrollTestImplSideInvalidation CommitEarlyOutReason reason) override { EXPECT_EQ(CommitEarlyOutReason::FINISHED_NO_UPDATES, reason); EXPECT_EQ(3, num_of_main_frames_); - EXPECT_EQ(outer_viewport_offsets_[2], host_impl->active_tree() - ->OuterViewportScrollLayer() - ->CurrentScrollOffset()); + EXPECT_EQ(outer_viewport_offsets_[2], + host_impl->active_tree() + ->OuterViewportScrollLayerForTesting() + ->CurrentScrollOffset()); } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { @@ -2167,7 +2152,7 @@ class LayerTreeHostScrollTestImplSideInvalidation // Now that we have the active tree, scroll a layer and ask for a commit // to send a BeginMainFrame with the scroll delta to the main thread. host_impl->active_tree() - ->OuterViewportScrollLayer() + ->OuterViewportScrollLayerForTesting() ->SetCurrentScrollOffset(outer_viewport_offsets_[0]); host_impl->SetNeedsCommit(); break; @@ -2176,16 +2161,17 @@ class LayerTreeHostScrollTestImplSideInvalidation // frame number on the active tree remains unchanged, and the scroll // offset on the active tree should also remain unchanged. EXPECT_EQ(0, host_impl->active_tree()->source_frame_number()); - EXPECT_EQ(outer_viewport_offsets_[1], host_impl->active_tree() - ->OuterViewportScrollLayer() - ->CurrentScrollOffset()); + EXPECT_EQ(outer_viewport_offsets_[1], + host_impl->active_tree() + ->OuterViewportScrollLayerForTesting() + ->CurrentScrollOffset()); break; case 3: // The third activation is from a commit. The scroll offset on the // active tree should include deltas sent from the main thread. EXPECT_EQ(host_impl->active_tree()->source_frame_number(), 1); EXPECT_EQ(host_impl->active_tree() - ->OuterViewportScrollLayer() + ->OuterViewportScrollLayerForTesting() ->CurrentScrollOffset(), outer_viewport_offsets_[2]); break; @@ -2193,9 +2179,10 @@ class LayerTreeHostScrollTestImplSideInvalidation // The fourth activation is from an impl-side pending tree, which should // leave the scroll offset unchanged. EXPECT_EQ(1, host_impl->active_tree()->source_frame_number()); - EXPECT_EQ(outer_viewport_offsets_[2], host_impl->active_tree() - ->OuterViewportScrollLayer() - ->CurrentScrollOffset()); + EXPECT_EQ(outer_viewport_offsets_[2], + host_impl->active_tree() + ->OuterViewportScrollLayerForTesting() + ->CurrentScrollOffset()); EndTest(); break; default: diff --git a/chromium/cc/trees/layer_tree_host_unittest_video.cc b/chromium/cc/trees/layer_tree_host_unittest_video.cc index c379af6ddce..f69dc76d788 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_video.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_video.cc @@ -48,7 +48,7 @@ class LayerTreeHostVideoTestSetNeedsDisplay DrawResult PrepareToDrawOnThread(LayerTreeHostImpl* host_impl, LayerTreeHostImpl::FrameData* frame, DrawResult draw_result) override { - LayerImpl* root_layer = host_impl->active_tree()->root_layer_for_testing(); + LayerImpl* root_layer = host_impl->active_tree()->root_layer(); RenderSurfaceImpl* root_surface = GetRenderSurface(root_layer); gfx::Rect damage_rect; EXPECT_TRUE( diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index 1bb42de1429..27812c1d31e 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -31,7 +31,6 @@ #include "cc/layers/effect_tree_layer_list_iterator.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer.h" -#include "cc/layers/layer_list_iterator.h" #include "cc/layers/render_surface_impl.h" #include "cc/layers/scrollbar_layer_impl_base.h" #include "cc/resources/ui_resource_request.h" @@ -39,12 +38,10 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_frame_sink.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/occlusion_tracker.h" #include "cc/trees/property_tree.h" -#include "cc/trees/property_tree_builder.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" #include "components/viz/common/traced_value.h" @@ -61,31 +58,33 @@ namespace { class ViewportAnchor { public: ViewportAnchor(ScrollNode* inner_scroll, - LayerImpl* outer_scroll, + ScrollNode* outer_scroll, LayerTreeImpl* tree_impl) : inner_(inner_scroll), outer_(outer_scroll), tree_impl_(tree_impl) { viewport_in_content_coordinates_ = scroll_tree().current_scroll_offset(inner_->element_id); - if (outer_) - viewport_in_content_coordinates_ += outer_->CurrentScrollOffset(); + if (outer_) { + viewport_in_content_coordinates_ += + scroll_tree().current_scroll_offset(outer_->element_id); + } } void ResetViewportToAnchoredPosition() { DCHECK(outer_); scroll_tree().ClampScrollToMaxScrollOffset(inner_, tree_impl_); - outer_->ClampScrollToMaxScrollOffset(); + scroll_tree().ClampScrollToMaxScrollOffset(outer_, tree_impl_); gfx::ScrollOffset viewport_location = scroll_tree().current_scroll_offset(inner_->element_id) + - outer_->CurrentScrollOffset(); + scroll_tree().current_scroll_offset(outer_->element_id); gfx::Vector2dF delta = viewport_in_content_coordinates_.DeltaFrom(viewport_location); delta = scroll_tree().ScrollBy(inner_, delta, tree_impl_); - outer_->ScrollBy(delta); + scroll_tree().ScrollBy(outer_, delta, tree_impl_); } private: @@ -94,7 +93,7 @@ class ViewportAnchor { } ScrollNode* inner_; - LayerImpl* outer_; + ScrollNode* outer_; LayerTreeImpl* tree_impl_; gfx::ScrollOffset viewport_in_content_coordinates_; }; @@ -123,7 +122,6 @@ LayerTreeImpl::LayerTreeImpl( : host_impl_(host_impl), source_frame_number_(-1), is_first_frame_after_commit_tracker_(-1), - root_layer_for_testing_(nullptr), hud_layer_(nullptr), background_color_(0), last_scrolled_scroll_node_index_(ScrollTree::kInvalidNodeId), @@ -134,7 +132,6 @@ LayerTreeImpl::LayerTreeImpl( device_scale_factor_(1.f), painted_device_scale_factor_(1.f), elastic_overscroll_(elastic_overscroll), - layers_(new OwnedLayerImplList), needs_update_draw_properties_(true), scrollbar_geometries_need_update_(false), needs_full_tree_sync_(true), @@ -155,7 +152,6 @@ LayerTreeImpl::~LayerTreeImpl() { // Need to explicitly clear the tree prior to destroying this so that // the LayerTreeImpl pointer is still valid in the LayerImpl dtor. DCHECK(LayerListIsEmpty()); - DCHECK(layers_->empty()); } void LayerTreeImpl::Shutdown() { @@ -166,42 +162,23 @@ void LayerTreeImpl::Shutdown() { } void LayerTreeImpl::ReleaseResources() { -#if DCHECK_IS_ON() - // These DCHECKs catch tests that add layers to the tree but fail to build the - // layer list afterward. - LayerListIterator<LayerImpl> it(root_layer_for_testing_); - size_t i = 0; - for (; it != LayerListIterator<LayerImpl>(nullptr); ++it, ++i) { - DCHECK_LT(i, layer_list_.size()); - DCHECK_EQ(layer_list_[i], *it); - } -#endif - - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->ReleaseResources(); }); - } + for (auto* layer : *this) + layer->ReleaseResources(); } void LayerTreeImpl::OnPurgeMemory() { - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->OnPurgeMemory(); }); - } + for (auto* layer : *this) + layer->OnPurgeMemory(); } void LayerTreeImpl::ReleaseTileResources() { - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->ReleaseTileResources(); }); - } + for (auto* layer : *this) + layer->ReleaseTileResources(); } void LayerTreeImpl::RecreateTileResources() { - if (!LayerListIsEmpty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->RecreateTileResources(); }); - } + for (auto* layer : *this) + layer->RecreateTileResources(); } void LayerTreeImpl::DidUpdateScrollOffset(ElementId id) { @@ -269,23 +246,27 @@ void LayerTreeImpl::UpdateScrollbarGeometries() { scroll_node->scrolls_outer_viewport; if (is_viewport_scrollbar) { gfx::SizeF viewport_bounds(bounds_size); - if (scroll_node->scrolls_inner_viewport && OuterViewportScrollLayer()) { - // Add offset and bounds contribution of outer viewport. - current_offset += OuterViewportScrollLayer()->CurrentScrollOffset(); - gfx::SizeF outer_viewport_bounds(scroll_tree.container_bounds( - OuterViewportScrollLayer()->scroll_tree_index())); - viewport_bounds.SetToMin(outer_viewport_bounds); - - // The scrolling size is only determined by the outer viewport. - scroll_node = scroll_tree.FindNodeFromElementId( - OuterViewportScrollLayer()->element_id()); - scrolling_size = gfx::SizeF(scroll_node->bounds); + if (scroll_node->scrolls_inner_viewport) { + DCHECK_EQ(scroll_node, InnerViewportScrollNode()); + if (auto* outer_scroll_node = OuterViewportScrollNode()) { + // Add offset and bounds contribution of outer viewport. + current_offset += + scroll_tree.current_scroll_offset(outer_scroll_node->element_id); + gfx::SizeF outer_viewport_bounds( + scroll_tree.container_bounds(outer_scroll_node->id)); + viewport_bounds.SetToMin(outer_viewport_bounds); + // The scrolling size is only determined by the outer viewport. + scrolling_size = gfx::SizeF(outer_scroll_node->bounds); + } } else { + DCHECK_EQ(scroll_node, OuterViewportScrollNode()); + auto* inner_scroll_node = InnerViewportScrollNode(); + DCHECK(inner_scroll_node); // Add offset and bounds contribution of inner viewport. - current_offset += scroll_tree.current_scroll_offset( - InnerViewportScrollNode()->element_id); + current_offset += + scroll_tree.current_scroll_offset(inner_scroll_node->element_id); gfx::SizeF inner_viewport_bounds( - scroll_tree.container_bounds(InnerViewportScrollNode()->id)); + scroll_tree.container_bounds(inner_scroll_node->id)); viewport_bounds.SetToMin(inner_viewport_bounds); } viewport_bounds.Scale(1 / current_page_scale_factor()); @@ -322,14 +303,9 @@ bool LayerTreeImpl::LayerListIsEmpty() const { } void LayerTreeImpl::SetRootLayerForTesting(std::unique_ptr<LayerImpl> layer) { - if (root_layer_for_testing_ && layer.get() != root_layer_for_testing_) - RemoveLayer(root_layer_for_testing_->id()); - root_layer_for_testing_ = layer.get(); - ClearLayerList(); - if (layer) { + DetachLayers(); + if (layer) AddLayer(std::move(layer)); - BuildLayerListForTesting(); - } host_impl_->OnCanDrawStateChangedForTree(); } @@ -337,22 +313,6 @@ void LayerTreeImpl::OnCanDrawStateChangedForTree() { host_impl_->OnCanDrawStateChangedForTree(); } -void LayerTreeImpl::AddToLayerList(LayerImpl* layer) { - layer_list_.push_back(layer); -} - -void LayerTreeImpl::ClearLayerList() { - layer_list_.clear(); -} - -void LayerTreeImpl::BuildLayerListForTesting() { - ClearLayerList(); - LayerListIterator<LayerImpl> it(root_layer_for_testing_); - for (; it != LayerListIterator<LayerImpl>(nullptr); ++it) { - AddToLayerList(*it); - } -} - void LayerTreeImpl::InvalidateRegionForImages( const PaintImageIdFlatSet& images_to_invalidate) { TRACE_EVENT_BEGIN1("cc", "LayerTreeImpl::InvalidateRegionForImages", @@ -392,7 +352,7 @@ void LayerTreeImpl::UpdateViewportContainerSizes() { if (!InnerViewportScrollNode()) return; - ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollLayer(), + ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollNode(), this); // Top/bottom controls always share the same shown ratio. @@ -424,34 +384,23 @@ void LayerTreeImpl::UpdateViewportContainerSizes() { property_trees->SetInnerViewportContainerBoundsDelta(bounds_delta); - ClipNode* inner_clip_node = property_trees->clip_tree.Node( - InnerViewportScrollLayer()->clip_tree_index()); - inner_clip_node->clip.set_height( - InnerViewportScrollNode()->container_bounds.height() + bounds_delta.y()); - // Adjust the outer viewport container as well, since adjusting only the // inner may cause its bounds to exceed those of the outer, causing scroll // clamping. - if (OuterViewportScrollNode()) { + if (auto* outer_scroll = OuterViewportScrollNode()) { gfx::Vector2dF scaled_bounds_delta = gfx::ScaleVector2d(bounds_delta, 1.f / min_page_scale_factor()); property_trees->SetOuterViewportContainerBoundsDelta(scaled_bounds_delta); - property_trees->SetInnerViewportScrollBoundsDelta(scaled_bounds_delta); - - ClipNode* outer_clip_node = property_trees->clip_tree.Node( - OuterViewportScrollLayer()->clip_tree_index()); - - float adjusted_container_height = - OuterViewportScrollNode()->container_bounds.height() + - scaled_bounds_delta.y(); - outer_clip_node->clip.set_height(adjusted_container_height); - - // Expand all clips between the outer viewport and the inner viewport. - auto* outer_ancestor = property_trees->clip_tree.parent(outer_clip_node); - while (outer_ancestor && outer_ancestor != inner_clip_node) { - outer_ancestor->clip.Union(outer_clip_node->clip); - outer_ancestor = property_trees->clip_tree.parent(outer_ancestor); + // outer_viewport_container_bounds_delta and + // inner_viewport_scroll_bounds_delta are the same thing. + DCHECK_EQ(scaled_bounds_delta, + property_trees->inner_viewport_scroll_bounds_delta()); + + if (auto* outer_clip_node = OuterViewportClipNode()) { + float adjusted_container_height = + outer_scroll->container_bounds.height() + scaled_bounds_delta.y(); + outer_clip_node->clip.set_height(adjusted_container_height); } anchor.ResetViewportToAnchoredPosition(); @@ -465,59 +414,48 @@ void LayerTreeImpl::UpdateViewportContainerSizes() { // delta. SetScrollbarGeometriesNeedUpdate(); set_needs_update_draw_properties(); - - // For pre-BlinkGenPropertyTrees mode, we need to ensure the layers are - // appropriately updated. - if (!settings().use_layer_lists) { - if (OuterViewportContainerLayer()) - OuterViewportContainerLayer()->NoteLayerPropertyChanged(); - if (InnerViewportScrollLayer()) - InnerViewportScrollLayer()->NoteLayerPropertyChanged(); - if (OuterViewportScrollLayer()) - OuterViewportScrollLayer()->NoteLayerPropertyChanged(); - } } bool LayerTreeImpl::IsRootLayer(const LayerImpl* layer) const { - return layer_list_.empty() ? false : layer_list_[0] == layer; + return !layer_list_.empty() && layer_list_[0].get() == layer; } gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const { gfx::ScrollOffset offset; - auto& scroll_tree = property_trees()->scroll_tree; + const auto& scroll_tree = property_trees()->scroll_tree; - if (InnerViewportScrollNode()) { - offset += scroll_tree.current_scroll_offset( - InnerViewportScrollNode()->element_id); - } + if (auto* inner_scroll = InnerViewportScrollNode()) + offset += scroll_tree.current_scroll_offset(inner_scroll->element_id); - if (OuterViewportScrollLayer()) - offset += OuterViewportScrollLayer()->CurrentScrollOffset(); + if (auto* outer_scroll = OuterViewportScrollNode()) + offset += scroll_tree.current_scroll_offset(outer_scroll->element_id); return offset; } gfx::ScrollOffset LayerTreeImpl::TotalMaxScrollOffset() const { gfx::ScrollOffset offset; - const ScrollTree& scroll_tree = property_trees()->scroll_tree; + const auto& scroll_tree = property_trees()->scroll_tree; - if (auto* inner_node = InnerViewportScrollNode()) - offset += scroll_tree.MaxScrollOffset(inner_node->id); + if (viewport_property_ids_.inner_scroll != ScrollTree::kInvalidNodeId) + offset += scroll_tree.MaxScrollOffset(viewport_property_ids_.inner_scroll); - if (auto* outer_node = OuterViewportScrollNode()) - offset += scroll_tree.MaxScrollOffset(outer_node->id); + if (viewport_property_ids_.outer_scroll != ScrollTree::kInvalidNodeId) + offset += scroll_tree.MaxScrollOffset(viewport_property_ids_.outer_scroll); return offset; } -std::unique_ptr<OwnedLayerImplList> LayerTreeImpl::DetachLayers() { - root_layer_for_testing_ = nullptr; - layer_list_.clear(); +OwnedLayerImplList LayerTreeImpl::DetachLayers() { render_surface_list_.clear(); set_needs_update_draw_properties(); - std::unique_ptr<OwnedLayerImplList> ret = std::move(layers_); - layers_.reset(new OwnedLayerImplList); - return ret; + return std::move(layer_list_); +} + +OwnedLayerImplList LayerTreeImpl::DetachLayersKeepingRootLayerForTesting() { + auto layers = DetachLayers(); + SetRootLayerForTesting(std::move(layers[0])); + return layers; } void LayerTreeImpl::SetPropertyTrees(PropertyTrees* property_trees) { @@ -594,18 +532,10 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->PassSwapPromises(std::move(swap_promise_list_)); swap_promise_list_.clear(); - target_tree->set_browser_controls_shrink_blink_size( - browser_controls_shrink_blink_size_); - target_tree->SetTopControlsHeight(top_controls_height_); - target_tree->SetBottomControlsHeight(bottom_controls_height_); - target_tree->PushBrowserControls(nullptr); - - target_tree->set_overscroll_behavior(overscroll_behavior_); - // The page scale factor update can affect scrolling which requires that // these ids are set, so this must be before PushPageScaleFactorAndLimits. - target_tree->SetViewportLayersFromIds(viewport_layer_ids_); - target_tree->set_viewport_property_ids(viewport_property_ids_); + // Setting browser controls below also needs viewport scroll properties. + target_tree->SetViewportPropertyIds(viewport_property_ids_); // Active tree already shares the page_scale_factor object with pending // tree so only the limits need to be provided. @@ -613,6 +543,14 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { max_page_scale_factor()); target_tree->SetExternalPageScaleFactor(external_page_scale_factor_); + target_tree->set_browser_controls_shrink_blink_size( + browser_controls_shrink_blink_size_); + target_tree->SetTopControlsHeight(top_controls_height_); + target_tree->SetBottomControlsHeight(bottom_controls_height_); + target_tree->PushBrowserControls(nullptr); + + target_tree->set_overscroll_behavior(overscroll_behavior_); + target_tree->SetRasterColorSpace(raster_color_space_id_, raster_color_space_); target_tree->elastic_overscroll()->PushPendingToActive(); @@ -664,12 +602,12 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { } void LayerTreeImpl::HandleTickmarksVisibilityChange() { - if (!host_impl_->ViewportMainScrollLayer()) + if (!host_impl_->ViewportMainScrollNode()) return; ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( - OuterViewportScrollLayer()->element_id()); + host_impl_->ViewportMainScrollNode()->element_id); if (!controller) return; @@ -687,10 +625,9 @@ void LayerTreeImpl::HandleTickmarksVisibilityChange() { } void LayerTreeImpl::HandleScrollbarShowRequestsFromMain() { - LayerTreeHostCommon::CallFunctionForEveryLayer(this, [this]( - LayerImpl* layer) { + for (auto* layer : *this) { if (!layer->needs_show_scrollbars()) - return; + continue; ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( layer->element_id()); @@ -698,7 +635,7 @@ void LayerTreeImpl::HandleScrollbarShowRequestsFromMain() { controller->DidRequestShowFromMainThread(); layer->set_needs_show_scrollbars(false); } - }); + } } void LayerTreeImpl::MoveChangeTrackingToLayers() { @@ -723,30 +660,6 @@ void LayerTreeImpl::ForceRecalculateRasterScales() { layer->ResetRasterScale(); } -LayerImplList::const_iterator LayerTreeImpl::begin() const { - return layer_list_.cbegin(); -} - -LayerImplList::const_iterator LayerTreeImpl::end() const { - return layer_list_.cend(); -} - -LayerImplList::const_reverse_iterator LayerTreeImpl::rbegin() const { - return layer_list_.crbegin(); -} - -LayerImplList::const_reverse_iterator LayerTreeImpl::rend() const { - return layer_list_.crend(); -} - -LayerImplList::reverse_iterator LayerTreeImpl::rbegin() { - return layer_list_.rbegin(); -} - -LayerImplList::reverse_iterator LayerTreeImpl::rend() { - return layer_list_.rend(); -} - bool LayerTreeImpl::IsElementInPropertyTree(ElementId element_id) const { return property_trees()->HasElement(element_id); } @@ -857,6 +770,18 @@ LayerTreeImpl::TakePresentationCallbacks() { return callbacks; } +LayerImpl* LayerTreeImpl::InnerViewportScrollLayerForTesting() const { + if (auto* scroll_node = InnerViewportScrollNode()) + return LayerByElementId(scroll_node->element_id); + return nullptr; +} + +LayerImpl* LayerTreeImpl::OuterViewportScrollLayerForTesting() const { + if (auto* scroll_node = OuterViewportScrollNode()) + return LayerByElementId(scroll_node->element_id); + return nullptr; +} + ScrollNode* LayerTreeImpl::CurrentlyScrollingNode() { DCHECK(IsActiveTree()); return property_trees_.scroll_tree.CurrentlyScrollingNode(); @@ -1005,26 +930,11 @@ void LayerTreeImpl::UpdateTransformAnimation(ElementId element_id, } } -TransformNode* LayerTreeImpl::PageScaleTransformNode() { - auto* page_scale = PageScaleLayer(); - if (!page_scale) { - // TODO(crbug.com/909750): Check all other callers of PageScaleLayer() and - // switch to viewport_property_ids_.page_scale_transform if needed. - return property_trees()->transform_tree.Node( - viewport_property_ids_.page_scale_transform); - } - - return property_trees()->transform_tree.Node( - page_scale->transform_tree_index()); -} - void LayerTreeImpl::UpdatePageScaleNode() { if (!PageScaleTransformNode()) { DCHECK(layer_list_.empty() || current_page_scale_factor() == 1); return; } - - DCHECK(!IsRootLayer(PageScaleLayer())); draw_property_utils::UpdatePageScaleFactor( property_trees(), PageScaleTransformNode(), current_page_scale_factor()); } @@ -1178,10 +1088,10 @@ void LayerTreeImpl::DidUpdatePageScale() { host_impl_->FlashAllScrollbars(true); return; } - if (host_impl_->ViewportMainScrollLayer()) { + if (auto* scroll_node = host_impl_->ViewportMainScrollNode()) { if (ScrollbarAnimationController* controller = host_impl_->ScrollbarAnimationControllerForElementId( - OuterViewportScrollLayer()->element_id())) + scroll_node->element_id)) controller->DidScrollUpdate(); } } @@ -1275,14 +1185,14 @@ gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const { } gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const { - LayerImpl* root_scroll_layer = OuterViewportScrollLayer() - ? OuterViewportScrollLayer() - : InnerViewportScrollLayer(); - if (!root_scroll_layer) + const ScrollNode* root_scroll_node = OuterViewportScrollNode(); + if (!root_scroll_node) + root_scroll_node = InnerViewportScrollNode(); + if (!root_scroll_node) return gfx::Rect(); return MathUtil::MapEnclosingClippedRect( - root_scroll_layer->ScreenSpaceTransform(), - gfx::Rect(root_scroll_layer->bounds())); + property_trees()->transform_tree.ToScreen(root_scroll_node->transform_id), + gfx::Rect(root_scroll_node->bounds)); } void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { @@ -1298,61 +1208,54 @@ void LayerTreeImpl::ApplySentScrollAndScaleDeltasFromAbortedCommit() { property_trees()->scroll_tree.ApplySentScrollDeltasFromAbortedCommit(); } -void LayerTreeImpl::SetViewportLayersFromIds(const ViewportLayerIds& ids) { - if (viewport_layer_ids_ == ids) - return; +void LayerTreeImpl::SetViewportPropertyIds(const ViewportPropertyIds& ids) { + viewport_property_ids_ = ids; + // Outer viewport properties exist only if inner viewport property exists. + DCHECK(ids.inner_scroll != ScrollTree::kInvalidNodeId || + (ids.outer_scroll == ScrollTree::kInvalidNodeId && + ids.outer_clip == ClipTree::kInvalidNodeId)); - viewport_layer_ids_ = ids; + if (auto* inner_scroll = InnerViewportScrollNode()) { + if (auto* inner_scroll_layer = LayerByElementId(inner_scroll->element_id)) + inner_scroll_layer->set_is_inner_viewport_scroll_layer(); + } +} - // Set the viewport layer types. - if (auto* inner_container = InnerViewportContainerLayer()) - inner_container->SetViewportLayerType(INNER_VIEWPORT_CONTAINER); - if (auto* inner_scroll = InnerViewportScrollLayer()) - inner_scroll->SetViewportLayerType(INNER_VIEWPORT_SCROLL); - if (auto* outer_container = OuterViewportContainerLayer()) - outer_container->SetViewportLayerType(OUTER_VIEWPORT_CONTAINER); - if (auto* outer_scroll = OuterViewportScrollLayer()) - outer_scroll->SetViewportLayerType(OUTER_VIEWPORT_SCROLL); +const TransformNode* LayerTreeImpl::OverscrollElasticityTransformNode() const { + return property_trees()->transform_tree.Node( + viewport_property_ids_.overscroll_elasticity_transform); } -void LayerTreeImpl::ClearViewportLayers() { - SetViewportLayersFromIds(ViewportLayerIds()); +const TransformNode* LayerTreeImpl::PageScaleTransformNode() const { + return property_trees()->transform_tree.Node( + viewport_property_ids_.page_scale_transform); } const ScrollNode* LayerTreeImpl::InnerViewportScrollNode() const { - auto* inner_scroll = InnerViewportScrollLayer(); - if (!inner_scroll) { - // TODO(crbug.com/909750): Check all other callers of - // InnerViewportScrollLayer() and switch to - // viewport_property_ids_.inner_scroll if needed. - return property_trees()->scroll_tree.Node( - viewport_property_ids_.inner_scroll); - } - return property_trees()->scroll_tree.Node(inner_scroll->scroll_tree_index()); + return property_trees()->scroll_tree.Node( + viewport_property_ids_.inner_scroll); +} + +const ClipNode* LayerTreeImpl::OuterViewportClipNode() const { + return property_trees()->clip_tree.Node(viewport_property_ids_.outer_clip); } const ScrollNode* LayerTreeImpl::OuterViewportScrollNode() const { - if (!OuterViewportScrollLayer()) - return nullptr; return property_trees()->scroll_tree.Node( - OuterViewportScrollLayer()->scroll_tree_index()); + viewport_property_ids_.outer_scroll); } // For unit tests, we use the layer's id as its element id. -static void SetElementIdForTesting(LayerImpl* layer) { - layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); -} - void LayerTreeImpl::SetElementIdsForTesting() { - LayerListIterator<LayerImpl> it(root_layer_for_testing_); - for (; it != LayerListIterator<LayerImpl>(nullptr); ++it) { - if (!it->element_id()) - SetElementIdForTesting(*it); + for (auto* layer : *this) { + if (!layer->element_id()) + layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); } } bool LayerTreeImpl::UpdateDrawProperties( - bool update_image_animation_controller) { + bool update_image_animation_controller, + LayerImplList* output_update_layer_list_for_testing) { if (!needs_update_draw_properties_) return true; @@ -1388,14 +1291,9 @@ bool LayerTreeImpl::UpdateDrawProperties( // We verify visible rect calculations whenever we verify clip tree // calculations except when this function is explicitly passed a flag asking // us to skip it. - LayerTreeHostCommon::CalcDrawPropsImplInputs inputs( - layer_list_[0], GetDeviceViewport(), host_impl_->DrawTransform(), - device_scale_factor(), current_page_scale_factor(), PageScaleLayer(), - InnerViewportScrollLayer(), OuterViewportScrollLayer(), - elastic_overscroll()->Current(IsActiveTree()), - OverscrollElasticityElementId(), max_texture_size(), - &render_surface_list_, &property_trees_, PageScaleTransformNode()); - LayerTreeHostCommon::CalculateDrawProperties(&inputs); + draw_property_utils::CalculateDrawProperties( + this, &render_surface_list_, output_update_layer_list_for_testing); + if (const char* client_name = GetClientNameForMetrics()) { UMA_HISTOGRAM_COUNTS_1M( base::StringPrintf( @@ -1450,14 +1348,6 @@ bool LayerTreeImpl::UpdateDrawProperties( occlusion_tracker.GetCurrentOcclusionForContributingSurface( draw_transform); render_surface->set_occlusion_in_content_space(occlusion); - // Masks are used to draw the contributing surface, so should have - // the same occlusion as the surface (nothing inside the surface - // occludes them). - if (LayerImpl* mask = render_surface->MaskLayer()) { - mask->draw_properties().occlusion_in_content_space = - occlusion_tracker.GetCurrentOcclusionForContributingSurface( - draw_transform * render_surface->SurfaceScale()); - } } occlusion_tracker.LeaveLayer(it); @@ -1514,24 +1404,6 @@ void LayerTreeImpl::UpdateCanUseLCDText() { DidModifyTilePriorities(); } -void LayerTreeImpl::BuildLayerListAndPropertyTreesForTesting() { - BuildLayerListForTesting(); - BuildPropertyTreesForTesting(); -} - -void LayerTreeImpl::BuildPropertyTreesForTesting() { - SetElementIdsForTesting(); - property_trees_.needs_rebuild = true; - PropertyTreeBuilder::BuildPropertyTrees( - layer_list_[0], PageScaleLayer(), InnerViewportScrollLayer(), - OuterViewportScrollLayer(), OverscrollElasticityElementId(), - elastic_overscroll()->Current(IsActiveTree()), - current_page_scale_factor(), device_scale_factor(), - gfx::Rect(GetDeviceViewport().size()), host_impl_->DrawTransform(), - &property_trees_); - host_impl_->UpdateElements(GetElementTypeForAnimation()); -} - const RenderSurfaceList& LayerTreeImpl::GetRenderSurfaceList() const { // If this assert triggers, then the list is dirty. DCHECK(!needs_update_draw_properties_); @@ -1546,8 +1418,9 @@ const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const { } gfx::SizeF LayerTreeImpl::ScrollableSize() const { - auto* scroll_node = OuterViewportScrollNode() ? OuterViewportScrollNode() - : InnerViewportScrollNode(); + auto* scroll_node = OuterViewportScrollNode(); + if (!scroll_node) + scroll_node = InnerViewportScrollNode(); if (!scroll_node) return gfx::SizeF(); const auto& scroll_tree = property_trees()->scroll_tree; @@ -1564,11 +1437,11 @@ LayerImpl* LayerTreeImpl::LayerById(int id) const { // TODO(masonfreed): If this shows up on profiles, this could use // a layer_element_map_ approach similar to LayerById(). LayerImpl* LayerTreeImpl::LayerByElementId(ElementId element_id) const { - auto it = std::find_if(layer_list_.rbegin(), layer_list_.rend(), - [&element_id](LayerImpl* layer_impl) { - return layer_impl->element_id() == element_id; - }); - if (it == layer_list_.rend()) + auto it = + std::find_if(rbegin(), rend(), [&element_id](LayerImpl* layer_impl) { + return layer_impl->element_id() == element_id; + }); + if (it == rend()) return nullptr; return *it; } @@ -1618,26 +1491,13 @@ void LayerTreeImpl::UnregisterLayer(LayerImpl* layer) { layer_id_map_.erase(layer->id()); } -// These manage ownership of the LayerImpl. void LayerTreeImpl::AddLayer(std::unique_ptr<LayerImpl> layer) { - DCHECK(!base::Contains(*layers_, layer)); DCHECK(layer); - layers_->push_back(std::move(layer)); + DCHECK(!base::Contains(layer_list_, layer)); + layer_list_.push_back(std::move(layer)); set_needs_update_draw_properties(); } -std::unique_ptr<LayerImpl> LayerTreeImpl::RemoveLayer(int id) { - for (auto it = layers_->begin(); it != layers_->end(); ++it) { - if ((*it) && (*it)->id() != id) - continue; - std::unique_ptr<LayerImpl> ret = std::move(*it); - set_needs_update_draw_properties(); - layers_->erase(it); - return ret; - } - return nullptr; -} - size_t LayerTreeImpl::NumLayers() { return layer_id_map_.size(); } @@ -1652,10 +1512,8 @@ void LayerTreeImpl::DidBecomeActive() { // if we were in a good state. host_impl_->ResetRequiresHighResToDraw(); - if (!layer_list_.empty()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - this, [](LayerImpl* layer) { layer->DidBecomeActive(); }); - } + for (auto* layer : *this) + layer->DidBecomeActive(); for (const auto& swap_promise : swap_promise_list_) swap_promise->DidActivate(); @@ -1820,11 +1678,10 @@ void LayerTreeImpl::SetNeedsRedraw() { void LayerTreeImpl::GetAllPrioritizedTilesForTracing( std::vector<PrioritizedTile>* prioritized_tiles) const { - for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) { - LayerImpl* layer_impl = *it; - if (!layer_impl->contributes_to_drawn_render_surface()) + for (auto* layer : base::Reversed(*this)) { + if (!layer->contributes_to_drawn_render_surface()) continue; - layer_impl->GetAllPrioritizedTilesForTracing(prioritized_tiles); + layer->GetAllPrioritizedTilesForTracing(prioritized_tiles); } } @@ -1834,10 +1691,10 @@ void LayerTreeImpl::AsValueInto(base::trace_event::TracedValue* state) const { state->SetInteger("source_frame_number", source_frame_number_); state->BeginArray("render_surface_layer_list"); - for (auto it = layer_list_.rbegin(); it != layer_list_.rend(); ++it) { - if (!(*it)->contributes_to_drawn_render_surface()) + for (auto* layer : base::Reversed(*this)) { + if (layer->contributes_to_drawn_render_surface()) continue; - viz::TracedValue::AppendIDRef(*it, state); + viz::TracedValue::AppendIDRef(layer, state); } state->EndArray(); @@ -2245,11 +2102,12 @@ static void FindClosestMatchingLayer(const gfx::PointF& screen_space_point, float distance_to_intersection = 0.f; bool hit = false; - if (layer->Is3dSorted()) + if (layer->Is3dSorted()) { hit = PointHitsLayer(layer, screen_space_point, &distance_to_intersection); - else + } else { hit = PointHitsLayer(layer, screen_space_point, nullptr); + } if (!hit) continue; @@ -2287,7 +2145,7 @@ LayerImpl* LayerTreeImpl::FindFirstScrollingLayerOrScrollbarThatIsHitByPoint( return nullptr; FindClosestMatchingLayerState state; - LayerImpl* root_layer = layer_list_[0]; + LayerImpl* root_layer = layer_list_[0].get(); FindClosestMatchingLayer(screen_space_point, root_layer, HitTestScrollingLayerOrScrollbarFunctor(), &state); return state.closest_match; @@ -2304,7 +2162,7 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPoint( if (!UpdateDrawProperties()) return nullptr; FindClosestMatchingLayerState state; - FindClosestMatchingLayer(screen_space_point, layer_list_[0], + FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), HitTestVisibleScrollableOrTouchableFunctor(), &state); return state.closest_match; @@ -2337,7 +2195,8 @@ LayerImpl* LayerTreeImpl::FindLayerThatIsHitByPointInEventHandlerRegion( if (!UpdateDrawProperties()) return nullptr; FindClosestMatchingLayerState state; - FindClosestMatchingLayer(screen_space_point, layer_list_[0], func, &state); + FindClosestMatchingLayer(screen_space_point, layer_list_[0].get(), func, + &state); return state.closest_match; } @@ -2506,7 +2365,7 @@ bool LayerTreeImpl::TakeForceSendMetadataRequest() { void LayerTreeImpl::ResetAllChangeTracking() { layers_that_should_push_properties_.clear(); // Iterate over all layers, including masks. - for (auto& layer : *layers_) + for (auto* layer : *this) layer->ResetChangeTracking(); property_trees_.ResetAllChangeTracking(); } @@ -2524,18 +2383,4 @@ std::string LayerTreeImpl::LayerListAsJson() const { return str; } -std::string LayerTreeImpl::LayerTreeAsJson() const { - std::string str; - if (root_layer_for_testing_) { - std::unique_ptr<base::Value> json( - root_layer_for_testing_->LayerTreeAsJson()); - base::JSONWriter::WriteWithOptions( - *json, - base::JSONWriter::OPTIONS_OMIT_DOUBLE_TYPE_PRESERVATION | - base::JSONWriter::OPTIONS_PRETTY_PRINT, - &str); - } - return str; -} - } // namespace cc diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index 666701c4360..7cb74373eba 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -162,15 +162,17 @@ class CC_EXPORT LayerTreeImpl { // Other public methods // --------------------------------------------------------------------------- - LayerImpl* root_layer_for_testing() { - return layer_list_.empty() ? nullptr : layer_list_[0]; + LayerImpl* root_layer() { + return layer_list_.empty() ? nullptr : layer_list_[0].get(); } const RenderSurfaceImpl* RootRenderSurface() const; bool LayerListIsEmpty() const; void SetRootLayerForTesting(std::unique_ptr<LayerImpl>); void OnCanDrawStateChangedForTree(); bool IsRootLayer(const LayerImpl* layer) const; - std::unique_ptr<OwnedLayerImplList> DetachLayers(); + + OwnedLayerImplList DetachLayers(); + OwnedLayerImplList DetachLayersKeepingRootLayerForTesting(); void SetPropertyTrees(PropertyTrees* property_trees); PropertyTrees* property_trees() { @@ -189,12 +191,36 @@ class CC_EXPORT LayerTreeImpl { void ForceRecalculateRasterScales(); - LayerImplList::const_iterator begin() const; - LayerImplList::const_iterator end() const; - LayerImplList::const_reverse_iterator rbegin() const; - LayerImplList::const_reverse_iterator rend() const; - LayerImplList::reverse_iterator rbegin(); - LayerImplList::reverse_iterator rend(); + // Adapts an iterator of std::unique_ptr<LayerImpl> to an iterator of + // LayerImpl*. + template <typename Iterator> + class IteratorAdapter + : public std::iterator<std::forward_iterator_tag, LayerImpl*> { + public: + explicit IteratorAdapter(Iterator it) : it_(it) {} + bool operator==(IteratorAdapter o) const { return it_ == o.it_; } + bool operator!=(IteratorAdapter o) const { return !(*this == o); } + LayerImpl* operator*() const { return it_->get(); } + LayerImpl* operator->() const { return it_->get(); } + IteratorAdapter& operator++() { + ++it_; + return *this; + } + + private: + Iterator it_; + }; + using const_iterator = IteratorAdapter<OwnedLayerImplList::const_iterator>; + using const_reverse_iterator = + IteratorAdapter<OwnedLayerImplList::const_reverse_iterator>; + const_iterator begin() const { return const_iterator(layer_list_.cbegin()); } + const_iterator end() const { return const_iterator(layer_list_.cend()); } + const_reverse_iterator rbegin() const { + return const_reverse_iterator(layer_list_.crbegin()); + } + const_reverse_iterator rend() const { + return const_reverse_iterator(layer_list_.crend()); + } void SetTransformMutated(ElementId element_id, const gfx::Transform& transform); @@ -251,66 +277,47 @@ class CC_EXPORT LayerTreeImpl { return !presentation_callbacks_.empty(); } - ScrollNode* CurrentlyScrollingNode(); - const ScrollNode* CurrentlyScrollingNode() const; - int LastScrolledScrollNodeIndex() const; - void SetCurrentlyScrollingNode(const ScrollNode* node); - void ClearCurrentlyScrollingNode(); + using ViewportPropertyIds = LayerTreeHost::ViewportPropertyIds; + void SetViewportPropertyIds(const ViewportPropertyIds& ids); - struct ViewportLayerIds { - ElementId overscroll_elasticity_element_id; - int page_scale = Layer::INVALID_ID; - int inner_viewport_container = Layer::INVALID_ID; - int outer_viewport_container = Layer::INVALID_ID; - int inner_viewport_scroll = Layer::INVALID_ID; - int outer_viewport_scroll = Layer::INVALID_ID; - - bool operator==(const ViewportLayerIds& other) { - return overscroll_elasticity_element_id == - other.overscroll_elasticity_element_id && - page_scale == other.page_scale && - inner_viewport_container == other.inner_viewport_container && - outer_viewport_container == other.outer_viewport_container && - inner_viewport_scroll == other.inner_viewport_scroll && - outer_viewport_scroll == other.outer_viewport_scroll; - } - }; - void SetViewportLayersFromIds(const ViewportLayerIds& viewport_layer_ids); - void ClearViewportLayers(); - ElementId OverscrollElasticityElementId() const { - return viewport_layer_ids_.overscroll_elasticity_element_id; - } - LayerImpl* PageScaleLayer() const { - return LayerById(viewport_layer_ids_.page_scale); - } - LayerImpl* InnerViewportContainerLayer() const { - return LayerById(viewport_layer_ids_.inner_viewport_container); - } - LayerImpl* OuterViewportContainerLayer() const { - return LayerById(viewport_layer_ids_.outer_viewport_container); - } - LayerImpl* InnerViewportScrollLayer() const { - return LayerById(viewport_layer_ids_.inner_viewport_scroll); + const TransformNode* OverscrollElasticityTransformNode() const; + TransformNode* OverscrollElasticityTransformNode() { + return const_cast<TransformNode*>( + const_cast<const LayerTreeImpl*>(this) + ->OverscrollElasticityTransformNode()); } - LayerImpl* OuterViewportScrollLayer() const { - return LayerById(viewport_layer_ids_.outer_viewport_scroll); + const TransformNode* PageScaleTransformNode() const; + TransformNode* PageScaleTransformNode() { + return const_cast<TransformNode*>( + const_cast<const LayerTreeImpl*>(this)->PageScaleTransformNode()); } - const ScrollNode* InnerViewportScrollNode() const; ScrollNode* InnerViewportScrollNode() { return const_cast<ScrollNode*>( const_cast<const LayerTreeImpl*>(this)->InnerViewportScrollNode()); } + const ClipNode* OuterViewportClipNode() const; + ClipNode* OuterViewportClipNode() { + return const_cast<ClipNode*>( + const_cast<const LayerTreeImpl*>(this)->OuterViewportClipNode()); + } const ScrollNode* OuterViewportScrollNode() const; ScrollNode* OuterViewportScrollNode() { return const_cast<ScrollNode*>( const_cast<const LayerTreeImpl*>(this)->OuterViewportScrollNode()); } - void set_viewport_property_ids( - const LayerTreeHost::ViewportPropertyIds& ids) { - viewport_property_ids_ = ids; + LayerTreeHost::ViewportPropertyIds ViewportPropertyIdsForTesting() const { + return viewport_property_ids_; } + LayerImpl* InnerViewportScrollLayerForTesting() const; + LayerImpl* OuterViewportScrollLayerForTesting() const; + + ScrollNode* CurrentlyScrollingNode(); + const ScrollNode* CurrentlyScrollingNode() const; + int LastScrolledScrollNodeIndex() const; + void SetCurrentlyScrollingNode(const ScrollNode* node); + void ClearCurrentlyScrollingNode(); void ApplySentScrollAndScaleDeltasFromAbortedCommit(); @@ -408,16 +415,19 @@ class CC_EXPORT LayerTreeImpl { const SyncedBrowserControls* top_controls_shown_ratio() const { return top_controls_shown_ratio_.get(); } + gfx::Vector2dF current_elastic_overscroll() const { + return elastic_overscroll()->Current(IsActiveTree()); + } void SetElementIdsForTesting(); // Updates draw properties and render surface layer list, as well as tile // priorities. Returns false if it was unable to update. Updating lcd // text may cause invalidations, so should only be done after a commit. - bool UpdateDrawProperties(bool update_image_animation_controller = true); + bool UpdateDrawProperties( + bool update_image_animation_controller = true, + LayerImplList* output_update_layer_list_for_testing = nullptr); void UpdateCanUseLCDText(); - void BuildPropertyTreesForTesting(); - void BuildLayerListAndPropertyTreesForTesting(); void set_needs_update_draw_properties() { needs_update_draw_properties_ = true; @@ -462,8 +472,6 @@ class CC_EXPORT LayerTreeImpl { LayerImpl* ScrollableLayerByElementId(ElementId element_id) const; bool IsElementInPropertyTree(ElementId element_id) const; - void AddToElementPropertyTreeList(ElementId element_id); - void RemoveFromElementPropertyTreeList(ElementId element_id); void AddToElementLayerList(ElementId element_id, LayerImpl* layer); void RemoveFromElementLayerList(ElementId element_id); @@ -484,9 +492,8 @@ class CC_EXPORT LayerTreeImpl { void RegisterLayer(LayerImpl* layer); void UnregisterLayer(LayerImpl* layer); - // These manage ownership of the LayerImpl. + // Append a layer to the list. void AddLayer(std::unique_ptr<LayerImpl> layer); - std::unique_ptr<LayerImpl> RemoveLayer(int id); size_t NumLayers(); @@ -646,12 +653,6 @@ class CC_EXPORT LayerTreeImpl { void ResetAllChangeTracking(); - void AddToLayerList(LayerImpl* layer); - - void ClearLayerList(); - - void BuildLayerListForTesting(); - void HandleTickmarksVisibilityChange(); void HandleScrollbarShowRequestsFromMain(); @@ -663,14 +664,15 @@ class CC_EXPORT LayerTreeImpl { LayerTreeLifecycle& lifecycle() { return lifecycle_; } std::string LayerListAsJson() const; - // TODO(pdr): This should be removed because there is no longer a tree - // of layers, only a list. - std::string LayerTreeAsJson() const; AnimatedPaintWorkletTracker& paint_worklet_tracker() { return host_impl_->paint_worklet_tracker(); } + const gfx::Transform& DrawTransform() const { + return host_impl_->DrawTransform(); + } + protected: float ClampPageScaleFactorToLimits(float page_scale_factor) const; void PushPageScaleFactorAndLimits(const float* page_scale_factor, @@ -685,7 +687,6 @@ class CC_EXPORT LayerTreeImpl { private: friend class LayerTreeHost; - TransformNode* PageScaleTransformNode(); void UpdatePageScaleNode(); ElementListType GetElementTypeForAnimation() const; @@ -698,14 +699,12 @@ class CC_EXPORT LayerTreeImpl { LayerTreeHostImpl* host_impl_; int source_frame_number_; int is_first_frame_after_commit_tracker_; - LayerImpl* root_layer_for_testing_; HeadsUpDisplayLayerImpl* hud_layer_; PropertyTrees property_trees_; SkColor background_color_; int last_scrolled_scroll_node_index_; - ViewportLayerIds viewport_layer_ids_; LayerTreeHost::ViewportPropertyIds viewport_property_ids_; LayerSelection selection_; @@ -728,9 +727,13 @@ class CC_EXPORT LayerTreeImpl { scoped_refptr<SyncedElasticOverscroll> elastic_overscroll_; - std::unique_ptr<OwnedLayerImplList> layers_; + // TODO(wangxianzhu): Combine layers_ and layer_list_ when we remove + // support of mask layers. + + OwnedLayerImplList layer_list_; + // Maps from layer id to layer. LayerImplMap layer_id_map_; - LayerImplList layer_list_; + // Set of layers that need to push properties. base::flat_set<LayerImpl*> layers_that_should_push_properties_; diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 4b2a48a7594..bdfe90cb9bc 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -8,10 +8,9 @@ #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/fake_raster_source.h" #include "cc/test/geometry_test_utils.h" -#include "cc/test/layer_test_common.h" +#include "cc/test/layer_tree_impl_test_base.h" #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,23 +18,20 @@ namespace cc { namespace { -class LayerTreeImplTest : public LayerTestCommon::LayerImplTest, - public testing::Test { +class LayerTreeImplTest : public LayerTreeImplTestBase, public testing::Test { public: - explicit LayerTreeImplTest( - const LayerTreeSettings& settings = LayerListSettings()) - : LayerImplTest(settings) {} + LayerTreeImplTest() = default; + explicit LayerTreeImplTest(const LayerTreeSettings& settings) + : LayerTreeImplTestBase(settings) {} void SetUp() override { root_layer()->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(root_layer()); UpdateDrawProperties(host_impl().active_tree()); } FakeLayerTreeHostImpl& host_impl() const { - return *LayerImplTest::host_impl(); + return *LayerTreeImplTestBase::host_impl(); } - LayerImpl* root_layer() { return root_layer_for_testing(); } const RenderSurfaceList& GetRenderSurfaceList() const { return host_impl().active_tree()->GetRenderSurfaceList(); @@ -108,14 +104,6 @@ class LayerTreeImplTest : public LayerTestCommon::LayerImplTest, LayerImpl* top_ = nullptr; LayerImpl* left_child_ = nullptr; LayerImpl* right_child_ = nullptr; - - private: - RenderSurfaceList render_surface_list_impl_; -}; - -class LayerTreeImplTestWithLayerLists : public LayerTreeImplTest { - public: - LayerTreeImplTestWithLayerLists() : LayerTreeImplTest(LayerListSettings()) {} }; TEST_F(LayerTreeImplTest, HitTestingForSingleLayer) { @@ -699,7 +687,6 @@ TEST_F(LayerTreeImplTest, HitTestingForNonClippingIntermediateLayer) { intermediate_layer->SetBounds(gfx::Size(50, 50)); // Sanity check the intermediate layer should not clip. ASSERT_FALSE(intermediate_layer->masks_to_bounds()); - ASSERT_FALSE(intermediate_layer->test_properties()->mask_layer); CopyProperties(root, intermediate_layer); // this layer is positioned, and hit testing should correctly know where the // layer is located. @@ -973,13 +960,13 @@ TEST_F(LayerTreeImplTest, HitTestingForMultipleLayersAtVaryingDepths) { EXPECT_EQ(grand_child1, result_layer); } -TEST_F(LayerTreeImplTestWithLayerLists, HitTestingRespectsClipParents) { +TEST_F(LayerTreeImplTest, HitTestingRespectsClipParents) { LayerImpl* root = root_layer(); root->SetBounds(gfx::Size(100, 100)); root->SetDrawsContent(true); root->SetHitTestable(true); - LayerImpl* child = AddChildToRoot<LayerImpl>(); + LayerImpl* child = AddLayer<LayerImpl>(); child->SetBounds(gfx::Size(1, 1)); child->SetDrawsContent(true); child->SetHitTestable(true); @@ -987,14 +974,14 @@ TEST_F(LayerTreeImplTestWithLayerLists, HitTestingRespectsClipParents) { child->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f)); CreateClipNode(child); - LayerImpl* scroll_child = AddChildToRoot<LayerImpl>(); + LayerImpl* scroll_child = AddLayer<LayerImpl>(); scroll_child->SetBounds(gfx::Size(200, 200)); scroll_child->SetDrawsContent(true); scroll_child->SetHitTestable(true); CopyProperties(root, scroll_child); scroll_child->SetClipTreeIndex(child->clip_tree_index()); - LayerImpl* grand_child = AddChildToRoot<LayerImpl>(); + LayerImpl* grand_child = AddLayer<LayerImpl>(); grand_child->SetBounds(gfx::Size(200, 200)); grand_child->SetDrawsContent(true); grand_child->SetHitTestable(true); @@ -1361,9 +1348,10 @@ TEST_F(LayerTreeImplTest, gfx::Rect(scaled_bounds_for_root)); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale_layer->id(); - host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale_layer->transform_tree_index(); + host_impl().active_tree()->SetViewportPropertyIds(viewport_property_ids); host_impl().active_tree()->PushPageScaleFromMainThread( page_scale_factor, page_scale_factor, max_page_scale_factor); host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); @@ -1445,7 +1433,8 @@ TEST_F(LayerTreeImplTest, // is also the root layer. page_scale_factor *= 1.5f; host_impl().active_tree()->SetPageScaleOnActiveTree(page_scale_factor); - EXPECT_EQ(page_scale_layer, host_impl().active_tree()->PageScaleLayer()); + EXPECT_EQ(page_scale_layer->transform_tree_index(), + host_impl().active_tree()->PageScaleTransformNode()->id); test_point = gfx::PointF(35.f, 35.f); test_point = @@ -1913,9 +1902,10 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) { gfx::Size scaled_bounds_for_root = gfx::ScaleToCeiledSize( root->bounds(), device_scale_factor * page_scale_factor); - LayerTreeImpl::ViewportLayerIds viewport_ids; - viewport_ids.page_scale = page_scale_layer->id(); - host_impl().active_tree()->SetViewportLayersFromIds(viewport_ids); + LayerTreeImpl::ViewportPropertyIds viewport_property_ids; + viewport_property_ids.page_scale_transform = + page_scale_layer->transform_tree_index(); + host_impl().active_tree()->SetViewportPropertyIds(viewport_property_ids); host_impl().active_tree()->SetDeviceViewportRect( gfx::Rect(scaled_bounds_for_root)); host_impl().active_tree()->SetDeviceScaleFactor(device_scale_factor); @@ -2155,28 +2145,6 @@ TEST_F(LayerTreeImplTest, HitTestingCorrectLayerWheelListener) { EXPECT_EQ(left_child, result_layer); } -// When using layer lists, we may not have layers for the outer viewport. This -// test verifies that scroll size can be calculated using property tree nodes. -TEST_F(LayerTreeImplTest, ScrollSizeWithoutLayers) { - const gfx::Size inner_viewport_size(1000, 1000); - const gfx::Size outer_viewport_size(1000, 1000); - const gfx::Size scroll_layer_size(2000, 2000); - - auto* tree_impl = host_impl().active_tree(); - root_layer()->SetBounds(inner_viewport_size); - SetupViewport(root_layer(), outer_viewport_size, scroll_layer_size); - - // With viewport layers the scrollable size should be correct. - EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize()); - - // The scrollable size should be correct without non-outer viewport layers. - LayerTreeImpl::ViewportLayerIds updated_viewport_ids; - updated_viewport_ids.outer_viewport_scroll = - tree_impl->OuterViewportScrollLayer()->id(); - tree_impl->SetViewportLayersFromIds(updated_viewport_ids); - EXPECT_EQ(gfx::SizeF(scroll_layer_size), tree_impl->ScrollableSize()); -} - namespace { class PersistentSwapPromise @@ -2294,17 +2262,13 @@ TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) { auto* root = EnsureRootLayerInPendingTree(); root->SetBounds(gfx::Size(100, 100)); - SetupRootProperties(root); // Add three layers; two with PaintWorklets and one without. - auto* child1 = - AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + auto* child1 = AddLayerInPendingTree<PictureLayerImpl>(); child1->SetBounds(gfx::Size(100, 100)); - auto* child2 = - AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + auto* child2 = AddLayerInPendingTree<PictureLayerImpl>(); child2->SetBounds(gfx::Size(100, 100)); - auto* child3 = - AddLayerInPendingTree<PictureLayerImpl>(Layer::LayerMaskType::NOT_MASK); + auto* child3 = AddLayerInPendingTree<PictureLayerImpl>(); child3->SetBounds(gfx::Size(100, 100)); CopyProperties(root, child1); @@ -2336,8 +2300,7 @@ TEST_F(LayerTreeImplTest, TrackPictureLayersWithPaintWorklets) { EXPECT_EQ(layers.size(), 1u); EXPECT_FALSE(layers.contains(child1)); - // Deleting a layer should also cause it to be removed from the set. - root->test_properties()->RemoveChild(child3); + pending_tree->DetachLayers(); EXPECT_EQ(layers.size(), 0u); } @@ -2365,7 +2328,7 @@ TEST_F(CommitToPendingTreeLayerTreeImplTest, // active tree (as they are only used on the sync tree). LayerTreeImpl* active_tree = host_impl().active_tree(); UpdateDrawProperties(active_tree); - LayerImpl* active_root = active_tree->root_layer_for_testing(); + LayerImpl* active_root = active_tree->root_layer(); auto& active_opacity_map = active_tree->element_id_to_opacity_animations_for_testing(); @@ -2395,7 +2358,6 @@ TEST_F(CommitToPendingTreeLayerTreeImplTest, LayerImpl* child = AddLayerInPendingTree<LayerImpl>(); pending_tree->SetElementIdsForTesting(); - SetupRootProperties(pending_root); // A scale transform forces a TransformNode. gfx::Transform scale3d; scale3d.Scale3d(1, 1, 0.5); @@ -2458,7 +2420,7 @@ TEST_F(LayerTreeImplTest, ElementIdToAnimationMapsTrackOnlyOnSyncTree) { // they are used on the sync tree). LayerTreeImpl* active_tree = host_impl().active_tree(); UpdateDrawProperties(active_tree); - LayerImpl* root = active_tree->root_layer_for_testing(); + LayerImpl* root = active_tree->root_layer(); auto& opacity_map = active_tree->element_id_to_opacity_animations_for_testing(); diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index ce1e19e2915..182eb5f6873 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -43,6 +43,7 @@ class CC_EXPORT LayerTreeSettings { bool enable_latency_recovery = true; bool can_use_lcd_text = true; bool gpu_rasterization_forced = false; + bool gpu_rasterization_disabled = false; int gpu_rasterization_msaa_sample_count = 0; float gpu_rasterization_skewport_target_time_in_seconds = 0.2f; bool create_low_res_tiling = false; @@ -109,10 +110,6 @@ class CC_EXPORT LayerTreeSettings { LayerTreeDebugState initial_debug_state; - // Indicates that the LayerTreeHost should defer commits unless it has a valid - // viz::LocalSurfaceId set. - bool enable_surface_synchronization = true; - // Indicates the case when a sub-frame gets its own LayerTree because it's // rendered in a different process from its ancestor frames. bool is_layer_tree_for_subframe = false; @@ -128,6 +125,9 @@ class CC_EXPORT LayerTreeSettings { // deadlines. bool wait_for_all_pipeline_stages_before_draw = false; + // Determines whether the zoom needs to be applied to the device scale factor. + bool use_zoom_for_dsf = false; + // Determines whether mouse interactions on composited scrollbars are handled // on the compositor thread. bool compositor_threaded_scrollbar_scrolling = false; @@ -177,6 +177,11 @@ class CC_EXPORT LayerTreeSettings { bool allow_de_jelly_effect = false; }; +class CC_EXPORT LayerListSettings : public LayerTreeSettings { + public: + LayerListSettings() { use_layer_lists = true; } +}; + } // namespace cc #endif // CC_TREES_LAYER_TREE_SETTINGS_H_ diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h index c52ce403301..a77f8413551 100644 --- a/chromium/cc/trees/mutator_host.h +++ b/chromium/cc/trees/mutator_host.h @@ -158,6 +158,7 @@ class MutatorHost { virtual size_t CompositedAnimationsCount() const = 0; virtual size_t MainThreadAnimationsCount() const = 0; + virtual bool HasCustomPropertyAnimations() const = 0; virtual bool CurrentFrameHadRAF() const = 0; virtual bool NextFrameHasPendingRAF() const = 0; }; diff --git a/chromium/cc/trees/occlusion_tracker.cc b/chromium/cc/trees/occlusion_tracker.cc index e4da0f3f7c4..363461feb19 100644 --- a/chromium/cc/trees/occlusion_tracker.cc +++ b/chromium/cc/trees/occlusion_tracker.cc @@ -196,8 +196,7 @@ void OcclusionTracker::FinishedRenderTarget( // If the occlusion within the surface can not be applied to things outside of // the surface's subtree, then clear the occlusion here so it won't be used. - if (finished_target_surface->HasMask() || - finished_target_surface->HasMaskingContributingSurface() || + if (finished_target_surface->HasMaskingContributingSurface() || finished_target_surface->draw_opacity() < 1 || !finished_target_surface->UsesDefaultBlendMode() || target_is_only_for_copy_request_or_force_render_surface || diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index 41c812e1585..6fa6693d1f4 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -14,13 +14,15 @@ #include "cc/paint/filter_operations.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_impl_task_runner_provider.h" +#include "cc/test/fake_layer_tree_frame_sink.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_test_common.h" +#include "cc/test/property_tree_test_utils.h" #include "cc/test/test_occlusion_tracker.h" #include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/draw_property_utils.h" #include "cc/trees/single_thread_proxy.h" #include "components/viz/common/frame_sinks/copy_output_request.h" #include "components/viz/common/frame_sinks/copy_output_result.h" @@ -90,35 +92,34 @@ class OcclusionTrackerTest : public testing::Test { protected: explicit OcclusionTrackerTest(bool opaque_layers) : opaque_layers_(opaque_layers), + layer_tree_frame_sink_(FakeLayerTreeFrameSink::Create3d()), animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)), host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_, - animation_host_.get())), - next_layer_impl_id_(1) {} + animation_host_.get(), + LayerListSettings())), + next_layer_impl_id_(1) { + host_->host_impl()->InitializeFrameSink(layer_tree_frame_sink_.get()); + } virtual void RunMyTest() = 0; void TearDown() override { DestroyLayers(); } - TestContentLayerImpl* CreateRoot(const gfx::Transform& transform, - const gfx::PointF& position, - const gfx::Size& bounds) { + TestContentLayerImpl* CreateRoot(const gfx::Size& bounds) { LayerTreeImpl* tree = host_->host_impl()->active_tree(); int id = next_layer_impl_id_++; std::unique_ptr<TestContentLayerImpl> layer( new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); - SetProperties(layer_ptr, transform, position, bounds); + layer_ptr->SetBounds(bounds); + SetupRootProperties(layer_ptr); host_->host_impl()->active_tree()->SetRootLayerForTesting(std::move(layer)); - - layer_ptr->test_properties()->force_render_surface = true; - SetRootLayerOnMainThread(layer_ptr); - return layer_ptr; } - LayerImpl* CreateLayer(LayerImpl* parent, + LayerImpl* CreateLayer(LayerImpl* property_parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds) { @@ -126,21 +127,30 @@ class OcclusionTrackerTest : public testing::Test { int id = next_layer_impl_id_++; std::unique_ptr<LayerImpl> layer = LayerImpl::Create(tree, id); LayerImpl* layer_ptr = layer.get(); - SetProperties(layer_ptr, transform, position, bounds); - parent->test_properties()->AddChild(std::move(layer)); + SetProperties(layer_ptr, property_parent, transform, position, bounds); + tree->AddLayer(std::move(layer)); return layer_ptr; } + void EnsureTransformNode(LayerImpl* layer) { + if (!layer->has_transform_node()) { + CreateTransformNode(layer).post_translation = + layer->offset_to_transform_parent(); + layer->SetOffsetToTransformParent(gfx::Vector2dF()); + } + } + LayerImpl* CreateSurface(LayerImpl* parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds) { LayerImpl* layer = CreateLayer(parent, transform, position, bounds); - layer->test_properties()->force_render_surface = true; + EnsureTransformNode(layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; return layer; } - TestContentLayerImpl* CreateDrawingLayer(LayerImpl* parent, + TestContentLayerImpl* CreateDrawingLayer(LayerImpl* property_parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds, @@ -150,7 +160,7 @@ class OcclusionTrackerTest : public testing::Test { std::unique_ptr<TestContentLayerImpl> layer( new TestContentLayerImpl(tree, id)); TestContentLayerImpl* layer_ptr = layer.get(); - SetProperties(layer_ptr, transform, position, bounds); + SetProperties(layer_ptr, property_parent, transform, position, bounds); if (opaque_layers_) { layer_ptr->SetContentsOpaque(opaque); @@ -162,64 +172,76 @@ class OcclusionTrackerTest : public testing::Test { layer_ptr->SetOpaqueContentsRect(gfx::Rect()); } - parent->test_properties()->AddChild(std::move(layer)); + tree->AddLayer(std::move(layer)); return layer_ptr; } - TestContentLayerImpl* CreateDrawingSurface(LayerImpl* parent, + TestContentLayerImpl* CreateDrawingSurface(LayerImpl* property_parent, const gfx::Transform& transform, const gfx::PointF& position, const gfx::Size& bounds, bool opaque) { - TestContentLayerImpl* layer = - CreateDrawingLayer(parent, transform, position, bounds, opaque); - layer->test_properties()->force_render_surface = true; + TestContentLayerImpl* layer = CreateDrawingLayer(property_parent, transform, + position, bounds, opaque); + EnsureTransformNode(layer); + CreateEffectNode(layer).render_surface_reason = RenderSurfaceReason::kTest; return layer; } - void DestroyLayers() { - host_->host_impl()->active_tree()->SetRootLayerForTesting(nullptr); - render_surface_list_impl_.clear(); - mask_layers_.clear(); - layer_iterator_.reset(); + void SetMasksToBounds(LayerImpl* layer) { + layer->SetMasksToBounds(true); + CreateClipNode(layer); } - void AddCopyRequest(Layer* layer) { - layer->RequestCopyOfOutput(viz::CopyOutputRequest::CreateStubForTesting()); + void DestroyLayers() { + auto* tree = host_->host_impl()->active_tree(); + tree->DetachLayers(); + tree->property_trees()->clear(); + layer_iterator_.reset(); } - void AddCopyRequest(LayerImpl* layer) { - layer->test_properties()->copy_requests.push_back( - viz::CopyOutputRequest::CreateStubForTesting()); + LayerImpl* CreateCopyLayer(LayerImpl* parent, + const gfx::Transform& transform, + const gfx::PointF& position, + const gfx::Size& bounds) { + LayerImpl* layer = CreateSurface(parent, transform, position, bounds); + auto* effect_node = GetEffectNode(layer); + effect_node->render_surface_reason = RenderSurfaceReason::kCopyRequest; + effect_node->has_copy_request = true; + effect_node->closest_ancestor_with_copy_request_id = effect_node->id; + auto& effect_tree = GetPropertyTrees(layer)->effect_tree; + effect_tree.AddCopyRequest(effect_node->id, + viz::CopyOutputRequest::CreateStubForTesting()); + // TODO(wangxianzhu): Let EffectTree::UpdateEffects() handle this. + do { + effect_node->subtree_has_copy_request = true; + effect_node = effect_tree.Node(effect_node->parent_id); + } while (effect_node && !effect_node->subtree_has_copy_request); + return layer; } - void CalcDrawEtc(TestContentLayerImpl* root) { - root->layer_tree_impl()->BuildLayerListForTesting(); - DCHECK(root == root->layer_tree_impl()->root_layer_for_testing()); - - // These occlusion tests attach and detach layers in multiple - // iterations, so rebuild property trees every time. - root->layer_tree_impl()->property_trees()->needs_rebuild = true; - - LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting inputs( - root, gfx::Rect(root->bounds()), &render_surface_list_impl_); - LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); + void CalcDrawEtc() { + LayerTreeImpl* tree = host_->host_impl()->active_tree(); + tree->SetDeviceViewportRect(gfx::Rect(tree->root_layer()->bounds())); + UpdateDrawProperties(tree); - layer_iterator_ = std::make_unique<EffectTreeLayerListIterator>( - host_->host_impl()->active_tree()); + layer_iterator_ = std::make_unique<EffectTreeLayerListIterator>(tree); } +#define ASSERT_EQ_WITH_IDS(a, b) \ + ASSERT_EQ(a, b) << " ids: " << (a)->id() << " vs " << (b)->id() + void EnterLayer(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->current_layer(), layer); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::LAYER); + ASSERT_EQ(EffectTreeLayerListIterator::State::LAYER, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(layer, layer_iterator_->current_layer()); occlusion->EnterLayer(*layer_iterator_); } void LeaveLayer(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->current_layer(), layer); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::LAYER); + ASSERT_EQ(EffectTreeLayerListIterator::State::LAYER, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(layer, layer_iterator_->current_layer()); occlusion->LeaveLayer(*layer_iterator_); ++(*layer_iterator_); } @@ -230,23 +252,23 @@ class OcclusionTrackerTest : public testing::Test { } void EnterContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->target_render_surface(), - GetRenderSurface(layer)); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::TARGET_SURFACE); + ASSERT_EQ(EffectTreeLayerListIterator::State::TARGET_SURFACE, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(GetRenderSurface(layer), + layer_iterator_->target_render_surface()); occlusion->EnterLayer(*layer_iterator_); occlusion->LeaveLayer(*layer_iterator_); ++(*layer_iterator_); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE); + ASSERT_EQ(EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE, + layer_iterator_->state()); occlusion->EnterLayer(*layer_iterator_); } void LeaveContributingSurface(LayerImpl* layer, OcclusionTracker* occlusion) { - ASSERT_EQ(layer_iterator_->current_render_surface(), - GetRenderSurface(layer)); - ASSERT_TRUE(layer_iterator_->state() == - EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE); + ASSERT_EQ(EffectTreeLayerListIterator::State::CONTRIBUTING_SURFACE, + layer_iterator_->state()); + ASSERT_EQ_WITH_IDS(GetRenderSurface(layer), + layer_iterator_->current_render_surface()); occlusion->LeaveLayer(*layer_iterator_); ++(*layer_iterator_); } @@ -268,30 +290,33 @@ class OcclusionTrackerTest : public testing::Test { host_->SetRootLayer(scoped_refptr<Layer>(root)); } - void SetRootLayerOnMainThread(LayerImpl* root) {} - void SetProperties(LayerImpl* layer, + LayerImpl* property_parent, const gfx::Transform& transform, - const gfx::PointF& position, + const gfx::PointF& offset_to_property_parent, const gfx::Size& bounds) { - layer->test_properties()->transform = transform; - layer->test_properties()->position = position; + layer->SetElementId(LayerIdToElementIdForTesting(layer->id())); layer->SetBounds(bounds); - } - - void SetMask(LayerImpl* owning_layer, std::unique_ptr<LayerImpl> layer) { - owning_layer->test_properties()->SetMaskLayer(std::move(layer)); + CopyProperties(property_parent, layer); + gfx::Vector2dF offset_to_transform_parent = + property_parent->offset_to_transform_parent() + + offset_to_property_parent.OffsetFromOrigin(); + if (transform.IsIdentity()) { + layer->SetOffsetToTransformParent(offset_to_transform_parent); + } else { + auto& transform_node = CreateTransformNode(layer); + transform_node.local = transform; + transform_node.post_translation = offset_to_transform_parent; + } } bool opaque_layers_; FakeLayerTreeHostClient client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink_; std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> host_; - // These hold ownership of the layers for the duration of the test. - RenderSurfaceList render_surface_list_impl_; std::unique_ptr<EffectTreeLayerListIterator> layer_iterator_; - LayerList mask_layers_; int next_layer_impl_id_; }; @@ -318,20 +343,19 @@ class OcclusionTrackerTestIdentityTransforms : public OcclusionTrackerTest { : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); + SetMasksToBounds(parent); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - parent->SetMasksToBounds(true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -352,20 +376,19 @@ class OcclusionTrackerTestRotatedChild : public OcclusionTrackerTest { layer_transform.Rotate(90.0); layer_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); + SetMasksToBounds(parent); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - parent->SetMasksToBounds(true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -384,20 +407,19 @@ class OcclusionTrackerTestTranslatedChild : public OcclusionTrackerTest { gfx::Transform layer_transform; layer_transform.Translate(20.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); + SetMasksToBounds(parent); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - parent->SetMasksToBounds(true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -418,29 +440,28 @@ class OcclusionTrackerTestChildInRotatedChild : public OcclusionTrackerTest { child_transform.Rotate(90.0); child_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); LayerImpl* child = this->CreateSurface( parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); - child->SetMasksToBounds(true); + SetMasksToBounds(child); TestContentLayerImpl* layer = this->CreateDrawingLayer( child, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer, &occlusion); - this->EnterContributingSurface(child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -505,14 +526,12 @@ class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest { : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 200)); gfx::Transform layer1_matrix; layer1_matrix.Scale(2.0, 2.0); - TestContentLayerImpl* layer1 = this->CreateDrawingLayer( + TestContentLayerImpl* layer1 = this->CreateDrawingSurface( parent, layer1_matrix, gfx::PointF(), gfx::Size(100, 100), true); - layer1->test_properties()->force_render_surface = true; gfx::Transform layer2_matrix; layer2_matrix.Translate(25.0, 25.0); @@ -521,12 +540,12 @@ class OcclusionTrackerTestScaledRenderSurface : public OcclusionTrackerTest { TestContentLayerImpl* occluder = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(100.f, 100.f), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(occluder, &occlusion); - this->EnterLayer(layer2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluder, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer2, &occlusion)); EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -542,8 +561,7 @@ class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest { explicit OcclusionTrackerTestVisitTargetTwoTimes(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface( root, this->identity_matrix, gfx::PointF(30.f, 30.f), gfx::Size()); TestContentLayerImpl* surface_child = this->CreateDrawingLayer( @@ -556,25 +574,26 @@ class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest { TestContentLayerImpl* top_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(40.f, 90.f), gfx::Size(50, 20), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(top_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(top_layer, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(40, 90, 50, 20).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface_child, &occlusion)); EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(10, 10, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->EnterContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect(10, 60, 50, 20).ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -583,8 +602,9 @@ class OcclusionTrackerTestVisitTargetTwoTimes : public OcclusionTrackerTest { // Occlusion from |top_layer| already in the root target should get merged // with the occlusion from the |surface| we are leaving now. - this->LeaveContributingSurface(surface, &occlusion); - this->EnterLayer(root, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(root, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(40, 40, 50, 70).ToString(), @@ -607,31 +627,30 @@ class OcclusionTrackerTestSurfaceRotatedOffAxis : public OcclusionTrackerTest { gfx::Transform layer_transform; layer_transform.Translate(10.0, 10.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(1000, 1000)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); LayerImpl* child = this->CreateSurface( parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500)); TestContentLayerImpl* layer = this->CreateDrawingLayer( child, layer_transform, gfx::PointF(), gfx::Size(500, 500), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); gfx::Rect clipped_layer_in_child = MathUtil::MapEnclosingClippedRect( layer_transform, layer->visible_layer_rect()); - this->VisitLayer(layer, &occlusion); - this->EnterContributingSurface(child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(clipped_layer_in_child.ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -653,37 +672,36 @@ class OcclusionTrackerTestSurfaceWithTwoOpaqueChildren child_transform.Rotate(90.0); child_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(1000, 1000)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(1000, 1000)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), true); - parent->SetMasksToBounds(true); + SetMasksToBounds(parent); TestContentLayerImpl* child = this->CreateDrawingSurface( parent, child_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), false); - child->SetMasksToBounds(true); + SetMasksToBounds(child); TestContentLayerImpl* layer1 = this->CreateDrawingLayer( child, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(500, 500), true); TestContentLayerImpl* layer2 = this->CreateDrawingLayer( child, this->identity_matrix, gfx::PointF(10.f, 450.f), gfx::Size(500, 60), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer2, &occlusion); - this->VisitLayer(layer1, &occlusion); - this->VisitLayer(child, &occlusion); - this->EnterContributingSurface(child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(10, 430, 60, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -725,9 +743,8 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings explicit OcclusionTrackerTestOverlappingSurfaceSiblings(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); LayerImpl* child1 = this->CreateSurface( parent, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size()); LayerImpl* child2 = this->CreateSurface( @@ -737,12 +754,12 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings TestContentLayerImpl* layer2 = this->CreateDrawingLayer( child2, this->identity_matrix, gfx::PointF(10.f, 0.f), gfx::Size(40, 50), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer2, &occlusion); - this->EnterContributingSurface(child2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child2, &occlusion)); // layer2's occlusion. EXPECT_EQ(gfx::Rect().ToString(), @@ -750,9 +767,9 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings EXPECT_EQ(gfx::Rect(10, 0, 40, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child2, &occlusion); - this->VisitLayer(layer1, &occlusion); - this->EnterContributingSurface(child1, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child1, &occlusion)); // layer2's occlusion in the target space of layer1. EXPECT_EQ(gfx::Rect(30, 0, 40, 50).ToString(), @@ -761,8 +778,8 @@ class OcclusionTrackerTestOverlappingSurfaceSiblings EXPECT_EQ(gfx::Rect(0, 0, 40, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child1, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); // The occlusion from from layer1 and layer2 is merged. EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); @@ -790,51 +807,50 @@ class OcclusionTrackerTestOverlappingSurfaceSiblingsWithTwoTransforms child2_transform.Rotate(90.0); child2_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); LayerImpl* child1 = this->CreateSurface( parent, child1_transform, gfx::PointF(30.f, 20.f), gfx::Size(10, 10)); - LayerImpl* child2 = this->CreateDrawingSurface(parent, child2_transform, - gfx::PointF(20.f, 40.f), - gfx::Size(10, 10), false); TestContentLayerImpl* layer1 = this->CreateDrawingLayer( child1, this->identity_matrix, gfx::PointF(-10.f, -20.f), gfx::Size(510, 510), true); + LayerImpl* child2 = this->CreateDrawingSurface(parent, child2_transform, + gfx::PointF(20.f, 40.f), + gfx::Size(10, 10), false); TestContentLayerImpl* layer2 = this->CreateDrawingLayer( child2, this->identity_matrix, gfx::PointF(-10.f, -10.f), gfx::Size(510, 510), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(layer2, &occlusion); - this->EnterLayer(child2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(child2, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveLayer(child2, &occlusion); - this->EnterContributingSurface(child2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(child2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child2, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(-10, 420, 70, 80).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child2, &occlusion); - this->VisitLayer(layer1, &occlusion); - this->EnterContributingSurface(child1, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterContributingSurface(child1, &occlusion)); EXPECT_EQ(gfx::Rect(420, -10, 70, 80).ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(420, -20, 80, 90).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveContributingSurface(child1, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveContributingSurface(child1, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -880,16 +896,15 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest { layer_transform.Rotate(90.0); layer_transform.Translate(-250.0, -250.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - parent->SetMasksToBounds(true); - TestContentLayerImpl* blur_layer = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + SetMasksToBounds(parent); + TestContentLayerImpl* blur_layer = this->CreateDrawingSurface( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - TestContentLayerImpl* opaque_layer = this->CreateDrawingLayer( + TestContentLayerImpl* opaque_layer = this->CreateDrawingSurface( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - TestContentLayerImpl* opacity_layer = this->CreateDrawingLayer( + TestContentLayerImpl* opacity_layer = this->CreateDrawingSurface( parent, layer_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); @@ -898,75 +913,82 @@ class OcclusionTrackerTestFilters : public OcclusionTrackerTest { parent, rounded_corner_transform, gfx::PointF(30.f, 30.f), gfx::Size(500, 500), true); - blur_layer->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(10.f)); - blur_layer->test_properties()->filters = filters; + GetEffectNode(blur_layer)->filters = filters; - opaque_layer->test_properties()->force_render_surface = true; filters.Clear(); filters.Append(FilterOperation::CreateGrayscaleFilter(0.5f)); - opaque_layer->test_properties()->filters = filters; + GetEffectNode(opaque_layer)->filters = filters; - opacity_layer->test_properties()->force_render_surface = true; filters.Clear(); filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); - opacity_layer->test_properties()->filters = filters; + GetEffectNode(opacity_layer)->filters = filters; - rounded_corner_layer->test_properties()->rounded_corner_bounds = + CreateEffectNode(rounded_corner_layer).rounded_corner_bounds = gfx::RRectF(1, 2, 3, 4, 5, 6); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); + EXPECT_TRUE(rounded_corner_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(blur_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(opaque_layer->contributes_to_drawn_render_surface()); + EXPECT_TRUE(opacity_layer->contributes_to_drawn_render_surface()); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); // Rounded corners won't contribute to occlusion. - this->EnterLayer(rounded_corner_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(rounded_corner_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); - this->LeaveLayer(rounded_corner_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(rounded_corner_layer, &occlusion)); // Opacity layer won't contribute to occlusion. - this->VisitLayer(opacity_layer, &occlusion); - this->EnterContributingSurface(opacity_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(opacity_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(opacity_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // And has nothing to contribute to its parent surface. - this->LeaveContributingSurface(opacity_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(opacity_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // Opaque layer will contribute to occlusion. - this->VisitLayer(opaque_layer, &occlusion); - this->EnterContributingSurface(opaque_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(opaque_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(opaque_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(0, 430, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); // And it gets translated to the parent surface. - this->LeaveContributingSurface(opaque_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(opaque_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); // The blur layer needs to throw away any occlusion from outside its // subtree. - this->EnterLayer(blur_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(blur_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // And it won't contribute to occlusion. - this->LeaveLayer(blur_layer, &occlusion); - this->EnterContributingSurface(blur_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(blur_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(blur_layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); // But the opaque layer's occlusion is preserved on the parent. - this->LeaveContributingSurface(blur_layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(blur_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_EQ(gfx::Rect(30, 30, 70, 70).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -981,22 +1003,21 @@ class OcclusionTrackerTestOpaqueContentsRegionEmpty explicit OcclusionTrackerTestOpaqueContentsRegionEmpty(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 300)); TestContentLayerImpl* layer = this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->EnterLayer(layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); - this->LeaveLayer(layer, &occlusion); - this->VisitContributingSurface(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitContributingSurface(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); @@ -1011,19 +1032,18 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty explicit OcclusionTrackerTestOpaqueContentsRegionNonEmpty(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 300)); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(100.f, 100.f), gfx::Size(200, 200), false); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); { TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); layer->SetOpaqueContentsRect(gfx::Rect(0, 0, 100, 100)); this->ResetLayerIterator(); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect(100, 100, 100, 100).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1033,8 +1053,8 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty layer->SetOpaqueContentsRect(gfx::Rect(20, 20, 180, 180)); this->ResetLayerIterator(); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect(120, 120, 180, 180).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1044,8 +1064,8 @@ class OcclusionTrackerTestOpaqueContentsRegionNonEmpty layer->SetOpaqueContentsRect(gfx::Rect(150, 150, 100, 100)); this->ResetLayerIterator(); - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_EQ(gfx::Rect(250, 250, 50, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1068,21 +1088,20 @@ class OcclusionTrackerTestLayerBehindCameraDoesNotOcclude transform.Translate3d(0.0, 0.0, 110.0); transform.Translate(-50.0, -50.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); TestContentLayerImpl* layer = this->CreateDrawingLayer( parent, transform, gfx::PointF(), gfx::Size(100, 100), true); - parent->test_properties()->should_flatten_transform = false; - parent->test_properties()->sorting_context_id = 1; - layer->test_properties()->should_flatten_transform = false; - layer->test_properties()->sorting_context_id = 1; - this->CalcDrawEtc(parent); + GetTransformNode(parent)->flattens_inherited_transform = false; + GetTransformNode(parent)->sorting_context_id = 1; + GetTransformNode(layer)->flattens_inherited_transform = false; + GetTransformNode(layer)->sorting_context_id = 1; + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); // The |layer| is entirely behind the camera and should not occlude. - this->VisitLayer(layer, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); EXPECT_TRUE(occlusion.occlusion_from_inside_target().IsEmpty()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); } @@ -1100,8 +1119,7 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent surface_transform.Scale(2.0, 2.0); surface_transform.Translate(-150.0, -150.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(500, 500)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(500, 500)); TestContentLayerImpl* surface = this->CreateDrawingSurface( parent, surface_transform, gfx::PointF(), gfx::Size(300, 300), false); TestContentLayerImpl* surface2 = this->CreateDrawingSurface( @@ -1109,12 +1127,13 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent gfx::Size(300, 300), false); surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); surface2->SetOpaqueContentsRect(gfx::Rect(0, 0, 200, 200)); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(surface2, &occlusion); - this->VisitContributingSurface(surface2, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface2, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface2, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1125,8 +1144,9 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesToParent occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); - this->VisitLayer(surface, &occlusion); - this->VisitContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1145,19 +1165,19 @@ class OcclusionTrackerTestSurfaceOcclusionTranslatesWithClipping bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 300)); - parent->SetMasksToBounds(true); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 300)); + SetMasksToBounds(parent); TestContentLayerImpl* surface = this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(), gfx::Size(500, 300), false); surface->SetOpaqueContentsRect(gfx::Rect(0, 0, 400, 200)); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(surface, &occlusion); - this->VisitContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1177,8 +1197,7 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { // This test verifies that the surface cliprect does not end up empty and // clip away the entire unoccluded rect. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 200)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 200)); LayerImpl* surface = this->CreateDrawingSurface(parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 100), false); @@ -1187,20 +1206,20 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { gfx::Size(100, 50), true); LayerImpl* topmost = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(), gfx::Size(100, 50), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(-100, -100, 1000, 1000)); // |topmost| occludes everything partially so we know occlusion is happening // at all. - this->VisitLayer(topmost, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(topmost, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface_child, &occlusion)); // surface_child increases the occlusion in the screen by a narrow sliver. EXPECT_EQ(gfx::Rect(0, -10, 100, 50).ToString(), @@ -1215,7 +1234,8 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { // |surface_child| exercises different code paths as its parent does not // have a clip rect. - this->EnterContributingSurface(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface_child, &occlusion)); // The |surface_child| can't occlude its own surface, but occlusion from // |topmost| can. EXPECT_EQ(gfx::Rect().ToString(), @@ -1224,18 +1244,20 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusion_on_contributing_surface_from_inside_target() .ToString()); - this->LeaveContributingSurface(surface_child, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(surface_child, &occlusion)); // When the surface_child's occlusion is transformed up to its parent, make // sure it is not clipped away inappropriately. - this->EnterLayer(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(surface, &occlusion)); EXPECT_EQ(gfx::Rect(0, 0, 100, 50).ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(0, 10, 100, 50).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->LeaveLayer(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->LeaveLayer(surface, &occlusion)); - this->EnterContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface, &occlusion)); // The occlusion from inside |surface| can't affect the surface, but // |topmost| can. EXPECT_EQ(gfx::Rect().ToString(), @@ -1245,8 +1267,9 @@ class OcclusionTrackerTestSurfaceChildOfSurface : public OcclusionTrackerTest { occlusion.occlusion_on_contributing_surface_from_inside_target() .ToString()); - this->LeaveContributingSurface(surface, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->LeaveContributingSurface(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); // The occlusion in |surface| and without are merged into the parent. EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1285,12 +1308,11 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter // which are above it in the z-order in various configurations. The // surface is scaled to test that the pixel moving is done in the target // space, where the backdrop filter is applied. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); - LayerImpl* filtered_surface = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 200)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), false); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; gfx::Rect occlusion_rect; switch (i) { case LEFT: @@ -1312,21 +1334,20 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), occlusion_rect.size(), true); - occluding_layer->test_properties()->force_render_surface = false; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); // This layer occludes pixels directly beside the filtered_surface. // Because filtered surface blends pixels in a radius, it will need to see // some of the pixels (up to radius far) underneath the occluding layers. - this->VisitLayer(occluding_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluding_layer, &occlusion)); EXPECT_EQ(occlusion_rect.ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - this->VisitLayer(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); // The occlusion is used fully inside the surface. gfx::Rect occlusion_inside_surface = @@ -1339,8 +1360,9 @@ class OcclusionTrackerTestDontOccludePixelsNeededForBackdropFilter // currently considered occluded in order to be drawn. The pixels it // needs should be removed from the occluded area, so that they are drawn // when we get to the parent. - this->VisitContributingSurface(filtered_surface, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); // The spread due to a 10px blur is 30px. gfx::Rect expected_occlusion = occlusion_rect; @@ -1400,12 +1422,11 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter // which are above it in the z-order in various configurations. The // surface is scaled to test that the pixel moving is done in the target // space, where the backdrop filter is applied. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); - LayerImpl* filtered_surface = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 200)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), false); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; gfx::Rect occlusion_rect; switch (i) { case LEFT: @@ -1427,21 +1448,20 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(occlusion_rect.origin()), occlusion_rect.size(), true); - occluding_layer->test_properties()->force_render_surface = false; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); // This layer occludes pixels directly beside the filtered_surface. // Because filtered surface blends pixels in a radius, it will need to see // some of the pixels (up to radius far) underneath the occluding layers. - this->VisitLayer(occluding_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluding_layer, &occlusion)); EXPECT_EQ(occlusion_rect.ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - this->VisitLayer(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); // The occlusion is used fully inside the surface. gfx::Rect occlusion_inside_surface = @@ -1454,8 +1474,9 @@ class OcclusionTrackerTestPixelsNeededForDropShadowBackdropFilter // currently considered occluded in order to be drawn. The pixels it // needs should be removed from the occluded area, so that they are drawn // when we get to the parent. - this->VisitContributingSurface(filtered_surface, &occlusion); - this->EnterLayer(parent, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(parent, &occlusion)); gfx::Rect expected_occlusion; switch (i) { @@ -1504,41 +1525,41 @@ class OcclusionTrackerTestTwoBackdropFiltersReduceOcclusionTwice // Makes two surfaces that completely cover |parent|. The occlusion both // above and below the filters will be reduced by each of them. - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(75, 75)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(75, 75)); LayerImpl* parent = this->CreateSurface(root, scale_by_half, gfx::PointF(), gfx::Size(150, 150)); - parent->SetMasksToBounds(true); - LayerImpl* filtered_surface1 = this->CreateDrawingLayer( + SetMasksToBounds(parent); + LayerImpl* filtered_surface1 = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); - LayerImpl* filtered_surface2 = this->CreateDrawingLayer( + LayerImpl* filtered_surface2 = this->CreateDrawingSurface( parent, scale_by_half, gfx::PointF(), gfx::Size(300, 300), false); LayerImpl* occluding_layer_above = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(100.f, 100.f), gfx::Size(50, 50), true); // Filters make the layers own surfaces. - filtered_surface1->test_properties()->force_render_surface = true; - filtered_surface2->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(1.f)); - filtered_surface1->test_properties()->backdrop_filters = filters; - filtered_surface2->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface1)->backdrop_filters = filters; + GetEffectNode(filtered_surface2)->backdrop_filters = filters; - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(occluding_layer_above, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitLayer(occluding_layer_above, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(100 / 2, 100 / 2, 50 / 2, 50 / 2).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(filtered_surface2, &occlusion); - this->VisitContributingSurface(filtered_surface2, &occlusion); - this->VisitLayer(filtered_surface1, &occlusion); - this->VisitContributingSurface(filtered_surface1, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface2, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface2, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface1, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface1, &occlusion)); // Test expectations in the target. int blur_outset = 3; @@ -1572,29 +1593,28 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackdropFilter // The surface is scaled to test that the pixel moving is done in the target // space, where the backdrop filter is applied, and the surface appears at // 50, 50. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 150)); LayerImpl* behind_surface_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(60.f, 60.f), gfx::Size(30, 30), true); - LayerImpl* filtered_surface = - this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f), - gfx::Size(100, 100), false); + LayerImpl* filtered_surface = this->CreateDrawingSurface( + parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), + false); // Filters make the layer own a surface. - filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); // The surface has a backdrop blur, so it blurs non-opaque pixels below // it. - this->VisitLayer(filtered_surface, &occlusion); - this->VisitContributingSurface(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); // The layers behind the surface are not blurred, and their occlusion does // not change, until we leave the surface. So it should not be modified by @@ -1605,7 +1625,7 @@ class OcclusionTrackerTestDontReduceOcclusionBelowBackdropFilter // without existing occlusion interfering. occlusion.set_occlusion_from_inside_target(SimpleEnclosedRegion()); - this->VisitLayer(behind_surface_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(behind_surface_layer, &occlusion)); // The layers behind the surface are not blurred, and their occlusion does // not change, until we leave the surface. So it should not be modified by @@ -1634,28 +1654,26 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackdropFilterIsOccluded // layer which is above it in the z-order. The surface is // scaled to test that the pixel moving is done in the target space, where // the backdrop filter is applied, and the surface appears at 50, 50. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 150)); - LayerImpl* filtered_surface = - this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f), - gfx::Size(100, 100), false); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(200, 150)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( + parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), + false); LayerImpl* occluding_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(50.f, 50.f), gfx::Size(50, 50), true); // Filters make the layer own a surface. - filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(occluding_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(occluding_layer, &occlusion)); - this->VisitLayer(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); { // The layers above the filtered surface occlude from outside. gfx::Rect occlusion_above_surface = gfx::Rect(0, 0, 50, 50); @@ -1668,7 +1686,8 @@ class OcclusionTrackerTestDontReduceOcclusionIfBackdropFilterIsOccluded // The surface has a backdrop blur, so it blurs non-opaque pixels below // it. - this->VisitContributingSurface(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); { // The filter is completely occluded, so it should not blur anything and // reduce any occlusion. @@ -1699,11 +1718,10 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded // are above it in the z-order. The surface is scaled to test that the // pixel moving is done in the target space, where the backdrop filter is // applied, but the surface appears at 50, 50. - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(300, 150)); - LayerImpl* filtered_surface = - this->CreateDrawingLayer(parent, scale_by_half, gfx::PointF(50.f, 50.f), - gfx::Size(100, 100), false); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(300, 150)); + LayerImpl* filtered_surface = this->CreateDrawingSurface( + parent, scale_by_half, gfx::PointF(50.f, 50.f), gfx::Size(100, 100), + false); LayerImpl* above_surface_layer = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(70.f, 50.f), gfx::Size(30, 50), true); @@ -1712,22 +1730,22 @@ class OcclusionTrackerTestReduceOcclusionWhenBkgdFilterIsPartiallyOccluded gfx::Size(10, 10), true); // Filters make the layer own a surface. - filtered_surface->test_properties()->force_render_surface = true; FilterOperations filters; filters.Append(FilterOperation::CreateBlurFilter(3.f)); - filtered_surface->test_properties()->backdrop_filters = filters; + GetEffectNode(filtered_surface)->backdrop_filters = filters; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(beside_surface_layer, &occlusion); - this->VisitLayer(above_surface_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(beside_surface_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(above_surface_layer, &occlusion)); // The surface has a backdrop blur, so it blurs non-opaque pixels below // it. - this->VisitLayer(filtered_surface, &occlusion); - this->VisitContributingSurface(filtered_surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(filtered_surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(filtered_surface, &occlusion)); // The filter in the surface is partially unoccluded. Only the unoccluded // parts should reduce occlusion. This means it will push back the @@ -1766,9 +1784,8 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude explicit OcclusionTrackerTestBlendModeDoesNotOcclude(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(100, 100)); - LayerImpl* blend_mode_layer = this->CreateDrawingLayer( + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(100, 100)); + LayerImpl* blend_mode_layer = this->CreateDrawingSurface( parent, this->identity_matrix, gfx::PointF(0.f, 0.f), gfx::Size(100, 100), true); LayerImpl* top_layer = this->CreateDrawingLayer( @@ -1776,20 +1793,19 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude gfx::Size(20, 22), true); // Blend mode makes the layer own a surface. - blend_mode_layer->test_properties()->force_render_surface = true; - blend_mode_layer->test_properties()->blend_mode = SkBlendMode::kMultiply; + GetEffectNode(blend_mode_layer)->blend_mode = SkBlendMode::kMultiply; - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(top_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(top_layer, &occlusion)); // |top_layer| occludes. EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), occlusion.occlusion_from_inside_target().ToString()); EXPECT_TRUE(occlusion.occlusion_from_outside_target().IsEmpty()); - this->VisitLayer(blend_mode_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(blend_mode_layer, &occlusion)); // |top_layer| and |blend_mode_layer| both occlude, since the blend mode // gets applied by blend_mode_layer's render surface, not when drawing the // layer itself. @@ -1798,7 +1814,8 @@ class OcclusionTrackerTestBlendModeDoesNotOcclude EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), occlusion.occlusion_from_outside_target().ToString()); - this->VisitContributingSurface(blend_mode_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(blend_mode_layer, &occlusion)); // |top_layer| occludes but not |blend_mode_layer|. EXPECT_EQ(gfx::Rect(10, 12, 20, 22).ToString(), occlusion.occlusion_from_inside_target().ToString()); @@ -1816,20 +1833,19 @@ class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest { gfx::Size tracking_size(100, 100); gfx::Size below_tracking_size(99, 99); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(400, 400)); LayerImpl* large = this->CreateDrawingLayer( parent, this->identity_matrix, gfx::PointF(), tracking_size, true); LayerImpl* small = this->CreateDrawingLayer(parent, this->identity_matrix, gfx::PointF(), below_tracking_size, true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); occlusion.set_minimum_tracking_size(tracking_size); // The small layer is not tracked because it is too small. - this->VisitLayer(small, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(small, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1837,7 +1853,7 @@ class OcclusionTrackerTestMinimumTrackingSize : public OcclusionTrackerTest { occlusion.occlusion_from_inside_target().ToString()); // The large layer is tracked as it is large enough. - this->VisitLayer(large, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(large, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1856,21 +1872,20 @@ class OcclusionTrackerTestScaledLayerIsClipped : public OcclusionTrackerTest { gfx::Transform scale_transform; scale_transform.Scale(512.0, 512.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(400, 400)); LayerImpl* clip = this->CreateLayer(parent, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(50, 50)); - clip->SetMasksToBounds(true); + SetMasksToBounds(clip); LayerImpl* scale = this->CreateLayer(clip, scale_transform, gfx::PointF(), gfx::Size(1, 1)); LayerImpl* scaled = this->CreateDrawingLayer( scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(scaled, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(scaled, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1890,25 +1905,25 @@ class OcclusionTrackerTestScaledLayerInSurfaceIsClipped gfx::Transform scale_transform; scale_transform.Scale(512.0, 512.0); - TestContentLayerImpl* parent = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* parent = this->CreateRoot(gfx::Size(400, 400)); LayerImpl* clip = this->CreateLayer(parent, this->identity_matrix, gfx::PointF(10.f, 10.f), gfx::Size(50, 50)); - clip->SetMasksToBounds(true); + SetMasksToBounds(clip); LayerImpl* surface = this->CreateDrawingSurface( clip, this->identity_matrix, gfx::PointF(), gfx::Size(400, 30), false); LayerImpl* scale = this->CreateLayer(surface, scale_transform, gfx::PointF(), gfx::Size(1, 1)); LayerImpl* scaled = this->CreateDrawingLayer( scale, this->identity_matrix, gfx::PointF(), gfx::Size(500, 500), true); - this->CalcDrawEtc(parent); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(scaled, &occlusion); - this->VisitLayer(surface, &occlusion); - this->VisitContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(scaled, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(surface, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->VisitContributingSurface(surface, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1924,30 +1939,28 @@ class OcclusionTrackerTestCopyRequestDoesOcclude : public OcclusionTrackerTest { explicit OcclusionTrackerTestCopyRequestDoesOcclude(bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(400, 400)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(400, 400), true); LayerImpl* copy = - this->CreateLayer(parent, this->identity_matrix, gfx::PointF(100, 0), - gfx::Size(200, 400)); - this->AddCopyRequest(copy); + this->CreateCopyLayer(parent, this->identity_matrix, + gfx::PointF(100, 0), gfx::Size(200, 400)); LayerImpl* copy_child = this->CreateDrawingLayer( copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true); LayerImpl* top_layer = this->CreateDrawingLayer(root, this->identity_matrix, gfx::PointF(50, 0), gfx::Size(50, 400), true); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(top_layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(top_layer, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(50, 0, 50, 400).ToString(), occlusion.occlusion_from_inside_target().ToString()); - this->VisitLayer(copy_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(copy_child, &occlusion)); // Layers outside the copy request do not occlude. EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); @@ -1955,7 +1968,7 @@ class OcclusionTrackerTestCopyRequestDoesOcclude : public OcclusionTrackerTest { occlusion.occlusion_from_inside_target().ToString()); // CopyRequests cause the layer to own a surface. - this->VisitContributingSurface(copy, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitContributingSurface(copy, &occlusion)); // The occlusion from the copy should be kept. EXPECT_EQ(gfx::Rect().ToString(), @@ -1974,35 +1987,32 @@ class OcclusionTrackerTestHiddenCopyRequestDoesNotOcclude bool opaque_layers) : OcclusionTrackerTest(opaque_layers) {} void RunMyTest() override { - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(400, 400)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(400, 400)); TestContentLayerImpl* parent = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(400, 400), true); LayerImpl* hide = this->CreateLayer(parent, this->identity_matrix, gfx::PointF(), gfx::Size()); + // The |copy| layer is hidden but since it is being copied, it will be + // drawn. + CreateEffectNode(hide).opacity = 0.f; LayerImpl* copy = - this->CreateLayer(hide, this->identity_matrix, gfx::PointF(100.f, 0.f), - gfx::Size(200, 400)); - this->AddCopyRequest(copy); + this->CreateCopyLayer(hide, this->identity_matrix, + gfx::PointF(100.f, 0.f), gfx::Size(200, 400)); LayerImpl* copy_child = this->CreateDrawingLayer( copy, this->identity_matrix, gfx::PointF(), gfx::Size(200, 400), true); - // The |copy| layer is hidden but since it is being copied, it will be - // drawn. - hide->test_properties()->hide_layer_and_subtree = true; - - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 1000, 1000)); - this->VisitLayer(copy_child, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(copy_child, &occlusion)); EXPECT_EQ(gfx::Rect().ToString(), occlusion.occlusion_from_outside_target().ToString()); EXPECT_EQ(gfx::Rect(200, 400).ToString(), occlusion.occlusion_from_inside_target().ToString()); // CopyRequests cause the layer to own a surface. - this->VisitContributingSurface(copy, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitContributingSurface(copy, &occlusion)); // The occlusion from the copy should be dropped since it is hidden. EXPECT_EQ(gfx::Rect().ToString(), @@ -2021,19 +2031,18 @@ class OcclusionTrackerTestOccludedLayer : public OcclusionTrackerTest { void RunMyTest() override { gfx::Transform translate; translate.Translate(10.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); LayerImpl* layer = this->CreateDrawingLayer( surface, translate, gfx::PointF(), gfx::Size(200, 200), false); TestContentLayerImpl* outside_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); - this->VisitLayer(outside_layer, &occlusion); - this->EnterLayer(layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(outside_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer, &occlusion)); // No occlusion, is not occluded. occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); @@ -2109,19 +2118,18 @@ class OcclusionTrackerTestUnoccludedLayerQuery : public OcclusionTrackerTest { void RunMyTest() override { gfx::Transform translate; translate.Translate(10.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); LayerImpl* layer = this->CreateDrawingLayer( surface, translate, gfx::PointF(), gfx::Size(200, 200), false); TestContentLayerImpl* outside_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); - this->VisitLayer(outside_layer, &occlusion); - this->EnterLayer(layer, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(outside_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->EnterLayer(layer, &occlusion)); // No occlusion, is not occluded. occlusion.set_occlusion_from_outside_target(SimpleEnclosedRegion()); @@ -2272,8 +2280,7 @@ class OcclusionTrackerTestUnoccludedSurfaceQuery : public OcclusionTrackerTest { void RunMyTest() override { gfx::Transform translate; translate.Translate(10.0, 20.0); - TestContentLayerImpl* root = this->CreateRoot( - this->identity_matrix, gfx::PointF(), gfx::Size(200, 200)); + TestContentLayerImpl* root = this->CreateRoot(gfx::Size(200, 200)); LayerImpl* surface = this->CreateSurface(root, translate, gfx::PointF(), gfx::Size(200, 200)); LayerImpl* layer = @@ -2281,12 +2288,13 @@ class OcclusionTrackerTestUnoccludedSurfaceQuery : public OcclusionTrackerTest { gfx::Size(200, 200), false); TestContentLayerImpl* outside_layer = this->CreateDrawingLayer( root, this->identity_matrix, gfx::PointF(), gfx::Size(200, 200), false); - this->CalcDrawEtc(root); + this->CalcDrawEtc(); TestOcclusionTrackerWithClip occlusion(gfx::Rect(0, 0, 200, 200)); - this->VisitLayer(outside_layer, &occlusion); - this->VisitLayer(layer, &occlusion); - this->EnterContributingSurface(surface, &occlusion); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(outside_layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE(this->VisitLayer(layer, &occlusion)); + ASSERT_NO_FATAL_FAILURE( + this->EnterContributingSurface(surface, &occlusion)); // No occlusion, is not occluded. occlusion.set_occlusion_on_contributing_surface_from_outside_target( diff --git a/chromium/cc/trees/presentation_time_callback_buffer.cc b/chromium/cc/trees/presentation_time_callback_buffer.cc index 5274d5bdf1c..636f36ac351 100644 --- a/chromium/cc/trees/presentation_time_callback_buffer.cc +++ b/chromium/cc/trees/presentation_time_callback_buffer.cc @@ -49,6 +49,18 @@ void PresentationTimeCallbackBuffer::RegisterMainThreadPresentationCallbacks( DCHECK_LE(frame_token_infos_.size(), 25u); } +void PresentationTimeCallbackBuffer::RegisterCompositorPresentationCallbacks( + uint32_t frame_token, + std::vector<CallbackType> callbacks) { + // Splice the given |callbacks| onto the vector of existing callbacks. + std::vector<LayerTreeHost::PresentationTimeCallback>& sink = + GetOrMakeRegistration(frame_token).compositor_thread_callbacks; + sink.reserve(sink.size() + callbacks.size()); + std::move(callbacks.begin(), callbacks.end(), std::back_inserter(sink)); + + DCHECK_LE(frame_token_infos_.size(), 25u); +} + void PresentationTimeCallbackBuffer::RegisterFrameTime( uint32_t frame_token, base::TimeTicks frame_time) { @@ -93,6 +105,12 @@ PresentationTimeCallbackBuffer::PopPendingCallbacks(uint32_t frame_token) { info->main_thread_callbacks.end(), std::back_inserter(result.main_thread_callbacks)); + // Collect the compositor-thread callbacks. It's the caller's job to run + // them on the compositor thread. + std::move(info->compositor_thread_callbacks.begin(), + info->compositor_thread_callbacks.end(), + std::back_inserter(result.compositor_thread_callbacks)); + frame_token_infos_.erase(info); } diff --git a/chromium/cc/trees/presentation_time_callback_buffer.h b/chromium/cc/trees/presentation_time_callback_buffer.h index cdebf905c36..d5ccdc5e2fb 100644 --- a/chromium/cc/trees/presentation_time_callback_buffer.h +++ b/chromium/cc/trees/presentation_time_callback_buffer.h @@ -15,16 +15,19 @@ namespace cc { // Maintains a queue of callbacks and compositor frame times that we want to // buffer until a relevant frame is presented. // -// Callbacks are queued through |RegisterMainThreadPresentationCallbacks|. +// Callbacks are queued through |RegisterMainThreadPresentationCallbacks| and +// |RegisterCompositorPresentationCallbacks| if the callback is to be run on +// the main thread or compositor thread respectively. // // Once a frame is presented, users of this class can call // |PopPendingCallbacks| to get their callbacks back. This class never runs -// callbacks itself so it's up to calling code to |PostTask| as needed. +// callbacks itself so it's up to calling code to |PostTask| or call |Run()| as +// needed. // // This class is thread unsafe so concurrent access would require external // synchronization. In practice, however, instances of this class are only used -// on the compositor thread even though the buffered callbacks are intended to -// be run on the renderer main thread. +// on the compositor thread even though some of the buffered callbacks are +// intended to be run on the renderer main thread. // // CC_EXPORT is only needed for testing. class CC_EXPORT PresentationTimeCallbackBuffer { @@ -50,6 +53,13 @@ class CC_EXPORT PresentationTimeCallbackBuffer { uint32_t frame_token, std::vector<CallbackType> callbacks); + // Buffers the given |callbacks| in preparation for a GPU frame swap at or + // after the given |frame_token|. Calling code invokes these callbacks on the + // compositor thread once they're popped. + void RegisterCompositorPresentationCallbacks( + uint32_t frame_token, + std::vector<CallbackType> callbacks); + // The given |frame_time| is associated with the given |frame_token| and will // be exposed through |PopPendingCallbacks| if there is an exact frame token // match. Note that it is an error to register distinct |frame_time|s against @@ -73,6 +83,10 @@ class CC_EXPORT PresentationTimeCallbackBuffer { // |RegisterMainThreadPresentationCallbacks|. std::vector<CallbackType> main_thread_callbacks; + // Holds callbacks registered through + // |RegisterCompositorPresentationCallbacks|. + std::vector<CallbackType> compositor_thread_callbacks; + // Note: calling code needs to test against frame_time.is_null() because // frame_time is not always defined. See |PopPendingCallbacks|. base::TimeTicks frame_time; @@ -111,6 +125,9 @@ class CC_EXPORT PresentationTimeCallbackBuffer { // The callbacks to send back to the main thread. std::vector<CallbackType> main_thread_callbacks; + + // The callbacks to invoke on the compositor thread. + std::vector<CallbackType> compositor_thread_callbacks; }; // Returns a reference to a |FrameTokenInfo| with the given |frame_token|. diff --git a/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc b/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc index 2d6b36f1f54..f080d6d4a11 100644 --- a/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc +++ b/chromium/cc/trees/presentation_time_callback_buffer_unittest.cc @@ -43,6 +43,7 @@ TEST(PresentationTimeCallbackBufferTest, TestNoCallbacks) { auto result = buffer.PopPendingCallbacks(kFrameToken1); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } @@ -57,12 +58,14 @@ TEST(PresentationTimeCallbackBufferTest, TestOneMainThreadCallback) { { auto result = buffer.PopPendingCallbacks(kFrameToken1); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_EQ(result.main_thread_callbacks.size(), 1ull); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } @@ -70,6 +73,38 @@ TEST(PresentationTimeCallbackBufferTest, TestOneMainThreadCallback) { { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } +} + +TEST(PresentationTimeCallbackBufferTest, TestOneCompositorThreadCallback) { + PresentationTimeCallbackBuffer buffer; + + buffer.RegisterCompositorPresentationCallbacks(kFrameToken2, + GenerateCallbacks(1)); + + // Make sure that popping early frame tokens doesn't return irrelevant + // entries. + { + auto result = buffer.PopPendingCallbacks(kFrameToken1); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } + + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_EQ(result.compositor_thread_callbacks.size(), 1ull); + EXPECT_TRUE(result.frame_time.is_null()); + } + + // Make sure that the buffer has removed the registration since the "pop". + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } } @@ -85,12 +120,14 @@ TEST(PresentationTimeCallbackBufferTest, TestFrameTimeRegistration) { { auto result = buffer.PopPendingCallbacks(kFrameToken1); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_FALSE(result.frame_time.is_null()); EXPECT_EQ(result.frame_time, frame_time); } @@ -99,6 +136,43 @@ TEST(PresentationTimeCallbackBufferTest, TestFrameTimeRegistration) { { auto result = buffer.PopPendingCallbacks(kFrameToken2); EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } +} + +TEST(PresentationTimeCallbackBufferTest, TestMixedCallbacks) { + PresentationTimeCallbackBuffer buffer; + + base::TimeTicks frame_time = MakeTicks(123); + buffer.RegisterMainThreadPresentationCallbacks(kFrameToken2, + GenerateCallbacks(1)); + buffer.RegisterCompositorPresentationCallbacks(kFrameToken2, + GenerateCallbacks(1)); + buffer.RegisterFrameTime(kFrameToken2, frame_time); + + // Make sure that popping early frame tokens doesn't return irrelevant + // entries. + { + auto result = buffer.PopPendingCallbacks(kFrameToken1); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); + EXPECT_TRUE(result.frame_time.is_null()); + } + + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_EQ(result.main_thread_callbacks.size(), 1ull); + EXPECT_EQ(result.compositor_thread_callbacks.size(), 1ull); + EXPECT_FALSE(result.frame_time.is_null()); + EXPECT_EQ(result.frame_time, frame_time); + } + + // Make sure that the buffer has removed the registrations since the "pop". + { + auto result = buffer.PopPendingCallbacks(kFrameToken2); + EXPECT_TRUE(result.main_thread_callbacks.empty()); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } } @@ -127,6 +201,7 @@ TEST(PresentationTimeCallbackBufferTest, TestCallbackBatchingNoFrameTime) { { auto result = buffer.PopPendingCallbacks(kFrameToken3); EXPECT_EQ(result.main_thread_callbacks.size(), 3ull); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_TRUE(result.frame_time.is_null()); } } @@ -151,6 +226,7 @@ TEST(PresentationTimeCallbackBufferTest, TestCallbackBatchingWithFrameTime) { { auto result = buffer.PopPendingCallbacks(kFrameToken3); EXPECT_EQ(result.main_thread_callbacks.size(), 3ull); + EXPECT_TRUE(result.compositor_thread_callbacks.empty()); EXPECT_FALSE(result.frame_time.is_null()); EXPECT_EQ(result.frame_time, frame_time3); } diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index f826436980d..6b306c718bd 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -12,12 +12,11 @@ #include "base/memory/ptr_util.h" #include "base/numerics/checked_math.h" #include "base/trace_event/traced_value.h" -#include "cc/layers/layer_impl.h" #include "cc/trees/clip_node.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/property_tree.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" #include "components/viz/common/frame_sinks/copy_output_request.h" @@ -132,47 +131,6 @@ void TransformTree::set_needs_update(bool needs_update) { PropertyTree<TransformNode>::set_needs_update(needs_update); } -bool TransformTree::ComputeTranslation(int source_id, - int dest_id, - gfx::Transform* transform) const { - transform->MakeIdentity(); - if (source_id == dest_id) - return true; - - const TransformNode* dest = Node(dest_id); - if (!dest->ancestors_are_invertible) - return false; - if (source_id != kInvalidNodeId) - transform->ConcatTransform(ToScreen(source_id)); - if (dest_id != kInvalidNodeId) { - if (dest->local.IsFlat() && (dest->node_and_ancestors_are_flat || - dest->flattens_inherited_transform)) { - // In this case, flattenning will not affect the result, so we can use the - // FromScreen transform of the dest node. - transform->ConcatTransform(FromScreen(dest_id)); - } else { - // In this case, some node between source and destination flattens - // inherited transform. Consider the tree R->A->B->C->D, where D is the - // source, A is the destination and C flattens inherited transform. The - // expected result is D * C * flattened(B). D's ToScreen will be D * C * - // flattened(B * A * R), but as the source to destination transform is - // at most translation, C and B cannot be non-flat and so flattened(B * A - // * R) = B * flattened(A * R). So, to get the expected result we have to - // multiply D's ToScreen transform with flattened(A * R)^{-1}, which is - // the inverse of flattened ToScreen of destination. - gfx::Transform to_screen = ToScreen(dest_id); - to_screen.FlattenTo2d(); - gfx::Transform from_screen; - bool success = to_screen.GetInverse(&from_screen); - if (!success) - return false; - transform->ConcatTransform(from_screen); - } - } - - return true; -} - TransformNode* TransformTree::FindNodeFromElementId(ElementId id) { auto iterator = property_trees()->element_id_to_transform_node_index.find(id); if (iterator == property_trees()->element_id_to_transform_node_index.end()) @@ -708,7 +666,6 @@ int EffectTree::Insert(const EffectNode& tree_node, int parent_id) { void EffectTree::clear() { PropertyTree<EffectNode>::clear(); - mask_layer_ids_.clear(); render_surfaces_.clear(); render_surfaces_.push_back(nullptr); @@ -1024,10 +981,6 @@ int EffectTree::LowestCommonAncestorWithRenderSurface(int id_1, return id_1; } -void EffectTree::AddMaskLayerId(int id) { - mask_layer_ids_.push_back(id); -} - bool EffectTree::ContributesToDrawnSurface(int id) { // All drawn nodes contribute to drawn surface. // Exception : Nodes that are hidden and are drawn only for the sake of @@ -1138,7 +1091,7 @@ bool EffectTree::HitTestMayBeAffectedByMask(int effect_id) const { for (; effect_node->id != kContentsRootNodeId; effect_node = Node(effect_node->parent_id)) { if (!effect_node->rounded_corner_bounds.IsEmpty() || - effect_node->has_masking_child || effect_node->is_masked) + effect_node->has_masking_child) return true; } return false; @@ -1176,7 +1129,6 @@ bool ClipTree::operator==(const ClipTree& other) const { EffectTree& EffectTree::operator=(const EffectTree& from) { PropertyTree::operator=(from); render_surfaces_.resize(size()); - mask_layer_ids_ = from.mask_layer_ids_; // copy_requests_ are omitted here, since these need to be moved rather // than copied or assigned. @@ -1184,8 +1136,7 @@ EffectTree& EffectTree::operator=(const EffectTree& from) { } bool EffectTree::operator==(const EffectTree& other) const { - return PropertyTree::operator==(other) && - mask_layer_ids_ == other.mask_layer_ids_; + return PropertyTree::operator==(other); } ScrollTree::ScrollTree() @@ -1478,10 +1429,7 @@ void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info, scroll_info->inner_viewport_scroll.element_id = id; scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta; } else { - LayerTreeHostCommon::ScrollUpdateInfo scroll; - scroll.element_id = id; - scroll.scroll_delta = scroll_delta; - scroll_info->scrolls.push_back(scroll); + scroll_info->scrolls.push_back({id, scroll_delta}); } } } @@ -1735,8 +1683,6 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) { from.inner_viewport_container_bounds_delta(); outer_viewport_container_bounds_delta_ = from.outer_viewport_container_bounds_delta(); - inner_viewport_scroll_bounds_delta_ = - from.inner_viewport_scroll_bounds_delta(); transform_tree.SetPropertyTrees(this); effect_tree.SetPropertyTrees(this); clip_tree.SetPropertyTrees(this); @@ -1910,11 +1856,6 @@ void PropertyTrees::AnimationScalesChanged(ElementId element_id, } } -void PropertyTrees::SetInnerViewportScrollBoundsDelta( - gfx::Vector2dF bounds_delta) { - inner_viewport_scroll_bounds_delta_ = bounds_delta; -} - void PropertyTrees::UpdateChangeTracking() { for (int id = EffectTree::kContentsRootNodeId; id < static_cast<int>(effect_tree.size()); ++id) { diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index 214b9fca971..8370ad169cf 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -137,16 +137,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { TransformNode* FindNodeFromElementId(ElementId id); bool OnTransformAnimated(ElementId element_id, const gfx::Transform& transform); - // Computes the change of basis transform from node |source_id| to |dest_id|. - // This is used by scroll children to compute transform from their scroll - // parent space (source) to their parent space (destination) and it can atmost - // be a translation. This function assumes that the path from source to - // destination has only translations. So, it should not be called when there - // can be intermediate 3d transforms but the end result is a translation. - bool ComputeTranslation(int source_id, - int dest_id, - gfx::Transform* transform) const; - void ResetChangeTracking(); // Updates the parent, target, and screen space transforms and snapping. void UpdateTransforms(int id); @@ -325,9 +315,6 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { // surface. int LowestCommonAncestorWithRenderSurface(int id_1, int id_2) const; - void AddMaskLayerId(int id); - const std::vector<int>& mask_layer_ids() const { return mask_layer_ids_; } - RenderSurfaceImpl* GetRenderSurface(int id) { return render_surfaces_[id].get(); } @@ -371,9 +358,6 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { std::unordered_multimap<int, std::unique_ptr<viz::CopyOutputRequest>> copy_requests_; - // Unsorted list of all mask layer ids that effect nodes refer to. - std::vector<int> mask_layer_ids_; - // Indexed by node id. std::vector<std::unique_ptr<RenderSurfaceImpl>> render_surfaces_; }; @@ -644,7 +628,6 @@ class CC_EXPORT PropertyTrees final { float starting_scale); void SetInnerViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); void SetOuterViewportContainerBoundsDelta(gfx::Vector2dF bounds_delta); - void SetInnerViewportScrollBoundsDelta(gfx::Vector2dF bounds_delta); void UpdateChangeTracking(); void PushChangeTrackingTo(PropertyTrees* tree); void ResetAllChangeTracking(); @@ -652,13 +635,13 @@ class CC_EXPORT PropertyTrees final { gfx::Vector2dF inner_viewport_container_bounds_delta() const { return inner_viewport_container_bounds_delta_; } - - gfx::Vector2dF outer_viewport_container_bounds_delta() const { + gfx::Vector2dF inner_viewport_scroll_bounds_delta() const { + // Inner viewport scroll bounds are always the same as outer viewport + // container bounds. return outer_viewport_container_bounds_delta_; } - - gfx::Vector2dF inner_viewport_scroll_bounds_delta() const { - return inner_viewport_scroll_bounds_delta_; + gfx::Vector2dF outer_viewport_container_bounds_delta() const { + return outer_viewport_container_bounds_delta_; } std::unique_ptr<base::trace_event::TracedValue> AsTracedValue() const; @@ -690,7 +673,6 @@ class CC_EXPORT PropertyTrees final { private: gfx::Vector2dF inner_viewport_container_bounds_delta_; gfx::Vector2dF outer_viewport_container_bounds_delta_; - gfx::Vector2dF inner_viewport_scroll_bounds_delta_; // GetDrawTransforms may change the value of cached_data_. DrawTransforms& GetDrawTransforms(int transform_id, int effect_id) const; diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index e962ff9a63c..0f04b6a6660 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -17,7 +17,7 @@ #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_impl.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/mutator_host.h" #include "cc/trees/scroll_node.h" @@ -37,71 +37,48 @@ struct DataForRecursion { int scroll_tree_parent; int closest_ancestor_with_cached_render_surface; int closest_ancestor_with_copy_request; - uint32_t main_thread_scrolling_reasons; SkColor safe_opaque_background_color; - bool in_subtree_of_page_scale_layer; - bool affected_by_outer_viewport_bounds_delta; - bool should_flatten; - bool scroll_tree_parent_created_by_uninheritable_criteria; bool animation_axis_aligned_since_render_target; bool not_axis_aligned_since_last_clip; gfx::Transform compound_transform_since_render_target; bool* subtree_has_rounded_corner; }; -template <typename LayerType> class PropertyTreeBuilderContext { public: - PropertyTreeBuilderContext(LayerType* root_layer, - const LayerType* page_scale_layer, - const LayerType* inner_viewport_scroll_layer, - const LayerType* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - const gfx::Transform& device_transform, - MutatorHost* mutator_host, - PropertyTrees* property_trees) - : root_layer_(root_layer), - page_scale_layer_(page_scale_layer), - inner_viewport_scroll_layer_(inner_viewport_scroll_layer), - outer_viewport_scroll_layer_(outer_viewport_scroll_layer), - overscroll_elasticity_element_id_(overscroll_elasticity_element_id), - elastic_overscroll_(elastic_overscroll), - page_scale_factor_(page_scale_factor), - device_transform_(device_transform), - mutator_host_(*mutator_host), - property_trees_(*property_trees), - transform_tree_(property_trees->transform_tree), - clip_tree_(property_trees->clip_tree), - effect_tree_(property_trees->effect_tree), - scroll_tree_(property_trees->scroll_tree) {} - - void BuildPropertyTrees(float device_scale_factor, - const gfx::Rect& viewport, - SkColor root_background_color) const; + explicit PropertyTreeBuilderContext(LayerTreeHost* layer_tree_host) + : layer_tree_host_(layer_tree_host), + root_layer_(layer_tree_host->root_layer()), + mutator_host_(*layer_tree_host->mutator_host()), + property_trees_(*layer_tree_host->property_trees()), + transform_tree_(property_trees_.transform_tree), + clip_tree_(property_trees_.clip_tree), + effect_tree_(property_trees_.effect_tree), + scroll_tree_(property_trees_.scroll_tree) {} + + void BuildPropertyTrees(); private: void BuildPropertyTreesInternal( - LayerType* layer, + Layer* layer, const DataForRecursion& data_from_parent) const; bool AddTransformNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_render_surface, DataForRecursion* data_for_children) const; void AddClipNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_transform_node, DataForRecursion* data_for_children) const; bool AddEffectNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const; void AddScrollNodeIfNeeded(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const; bool UpdateRenderSurfaceIfNeeded(int parent_effect_tree_id, @@ -109,14 +86,8 @@ class PropertyTreeBuilderContext { bool subtree_has_rounded_corner, bool created_transform_node) const; - LayerType* root_layer_; - const LayerType* page_scale_layer_; - const LayerType* inner_viewport_scroll_layer_; - const LayerType* outer_viewport_scroll_layer_; - const ElementId overscroll_elasticity_element_id_; - const gfx::Vector2dF elastic_overscroll_; - float page_scale_factor_; - const gfx::Transform& device_transform_; + LayerTreeHost* layer_tree_host_; + Layer* root_layer_; MutatorHost& mutator_host_; PropertyTrees& property_trees_; TransformTree& transform_tree_; @@ -125,121 +96,47 @@ class PropertyTreeBuilderContext { ScrollTree& scroll_tree_; }; -static LayerImplList& LayerChildren(LayerImpl* layer) { - return layer->test_properties()->children; -} - -static const LayerList& LayerChildren(Layer* layer) { - return layer->children(); -} - -static LayerImpl* LayerChildAt(LayerImpl* layer, int index) { - return layer->test_properties()->children[index]; -} - -static Layer* LayerChildAt(Layer* layer, int index) { - return layer->children()[index].get(); -} - -static bool HasClipRect(Layer* layer) { - return !layer->clip_rect().IsEmpty(); -} - -static bool HasClipRect(LayerImpl* layer) { - return false; -} - -static inline const FilterOperations& Filters(Layer* layer) { - return layer->filters(); -} - -static inline const FilterOperations& Filters(LayerImpl* layer) { - return layer->test_properties()->filters; -} - -static bool IsFastRoundedCorner(Layer* layer) { - return layer->is_fast_rounded_corner(); -} - -static bool IsFastRoundedCorner(LayerImpl* layer) { - return false; -} - -static bool HasRoundedCorner(Layer* layer) { - return layer->HasRoundedCorner(); -} - -static bool HasRoundedCorner(LayerImpl* layer) { - return !layer->test_properties()->rounded_corner_bounds.IsEmpty(); -} - -static PictureLayer* MaskLayer(Layer* layer) { - return layer->mask_layer(); -} - -static LayerImpl* MaskLayer(LayerImpl* layer) { - return layer->test_properties()->mask_layer; -} - -static const gfx::Transform& Transform(Layer* layer) { - return layer->transform(); -} - -static const gfx::Transform& Transform(LayerImpl* layer) { - return layer->test_properties()->transform; -} - -static const gfx::PointF& Position(Layer* layer) { - return layer->position(); -} - -static const gfx::PointF& Position(LayerImpl* layer) { - return layer->test_properties()->position; -} - // Methods to query state from the AnimationHost ---------------------- -template <typename LayerType> -bool OpacityIsAnimating(const MutatorHost& host, LayerType* layer) { +bool OpacityIsAnimating(const MutatorHost& host, Layer* layer) { return host.IsAnimatingOpacityProperty(layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> bool HasPotentiallyRunningOpacityAnimation(const MutatorHost& host, - LayerType* layer) { + Layer* layer) { return host.HasPotentiallyRunningOpacityAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> -bool FilterIsAnimating(const MutatorHost& host, LayerType* layer) { +bool HasPotentialOpacityAnimation(const MutatorHost& host, Layer* layer) { + return HasPotentiallyRunningOpacityAnimation(host, layer) || + layer->OpacityCanAnimateOnImplThread(); +} + +bool FilterIsAnimating(const MutatorHost& host, Layer* layer) { return host.IsAnimatingFilterProperty(layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> bool HasPotentiallyRunningFilterAnimation(const MutatorHost& host, - LayerType* layer) { + Layer* layer) { return host.HasPotentiallyRunningFilterAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> -bool TransformIsAnimating(const MutatorHost& host, LayerType* layer) { +bool TransformIsAnimating(const MutatorHost& host, Layer* layer) { return host.IsAnimatingTransformProperty(layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> bool HasPotentiallyRunningTransformAnimation(const MutatorHost& host, - LayerType* layer) { + Layer* layer) { return host.HasPotentiallyRunningTransformAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } -template <typename LayerType> void GetAnimationScales(const MutatorHost& host, - LayerType* layer, + Layer* layer, float* maximum_scale, float* starting_scale) { return host.GetAnimationScales(layer->element_id(), @@ -247,94 +144,46 @@ void GetAnimationScales(const MutatorHost& host, maximum_scale, starting_scale); } -template <typename LayerType> -bool AnimationsPreserveAxisAlignment(const MutatorHost& host, - LayerType* layer) { +bool AnimationsPreserveAxisAlignment(const MutatorHost& host, Layer* layer) { return host.AnimationsPreserveAxisAlignment(layer->element_id()); } -template <typename LayerType> bool HasAnyAnimationTargetingProperty(const MutatorHost& host, - LayerType* layer, + Layer* layer, TargetProperty::Type property) { return host.HasAnyAnimationTargetingProperty(layer->element_id(), property); } // ------------------------------------------------------------------- -template <typename LayerType> -static bool LayerClipsSubtreeToItsBounds(LayerType* layer) { - return layer->masks_to_bounds() || MaskLayer(layer); -} - -template <typename LayerType> -static bool LayerClipsSubtree(LayerType* layer) { - return LayerClipsSubtreeToItsBounds(layer) || HasRoundedCorner(layer) || - HasClipRect(layer); -} - -gfx::RectF EffectiveClipRect(Layer* layer) { - return layer->EffectiveClipRect(); -} - -gfx::RectF EffectiveClipRect(LayerImpl* layer) { - return gfx::RectF(gfx::PointF(), gfx::SizeF(layer->bounds())); -} - -static gfx::RRectF RoundedCornerBounds(Layer* layer) { - return gfx::RRectF(EffectiveClipRect(layer), layer->corner_radii()); -} - -static gfx::RRectF RoundedCornerBounds(LayerImpl* layer) { - return layer->test_properties()->rounded_corner_bounds; -} - -static Layer* LayerParent(Layer* layer) { - return layer->parent(); -} - -static LayerImpl* LayerParent(LayerImpl* layer) { - return layer->test_properties()->parent; -} - -static inline int SortingContextId(Layer* layer) { - return layer->sorting_context_id(); -} - -static inline int SortingContextId(LayerImpl* layer) { - return layer->test_properties()->sorting_context_id; +bool LayerClipsSubtreeToItsBounds(Layer* layer) { + return layer->masks_to_bounds() || layer->IsMaskedByChild(); } -static inline bool Is3dSorted(Layer* layer) { - return layer->sorting_context_id() != 0; +bool LayerClipsSubtree(Layer* layer) { + return LayerClipsSubtreeToItsBounds(layer) || layer->HasRoundedCorner() || + !layer->clip_rect().IsEmpty(); } -static inline bool Is3dSorted(LayerImpl* layer) { - return layer->test_properties()->sorting_context_id != 0; +gfx::RRectF RoundedCornerBounds(Layer* layer) { + return gfx::RRectF(layer->EffectiveClipRect(), layer->corner_radii()); } -static inline void SetHasClipNode(Layer* layer, bool val) { - layer->SetHasClipNode(val); -} - -static inline void SetHasClipNode(LayerImpl* layer, bool val) {} - -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded( +void PropertyTreeBuilderContext::AddClipNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_transform_node, DataForRecursion* data_for_children) const { const int parent_id = data_from_ancestor.clip_tree_parent; bool layer_clips_subtree = LayerClipsSubtree(layer); bool requires_node = - layer_clips_subtree || Filters(layer).HasFilterThatMovesPixels(); + layer_clips_subtree || layer->filters().HasFilterThatMovesPixels(); if (!requires_node) { data_for_children->clip_tree_parent = parent_id; } else { ClipNode node; - node.clip = EffectiveClipRect(layer); + node.clip = layer->EffectiveClipRect(); // Move the clip bounds so that it is relative to the transform parent. node.clip += layer->offset_to_transform_parent(); @@ -345,51 +194,23 @@ void PropertyTreeBuilderContext<LayerType>::AddClipNodeIfNeeded( if (layer_clips_subtree) { node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; } else { - DCHECK(Filters(layer).HasFilterThatMovesPixels()); + DCHECK(layer->filters().HasFilterThatMovesPixels()); node.clip_type = ClipNode::ClipType::EXPANDS_CLIP; node.clip_expander = ClipExpander(layer->effect_tree_index()); } data_for_children->clip_tree_parent = clip_tree_.Insert(node, parent_id); } - SetHasClipNode(layer, requires_node); + layer->SetHasClipNode(requires_node); layer->SetClipTreeIndex(data_for_children->clip_tree_parent); } -template <typename LayerType> -static inline bool IsAtBoundaryOf3dRenderingContext(LayerType* layer) { - return LayerParent(layer) - ? SortingContextId(LayerParent(layer)) != SortingContextId(layer) - : Is3dSorted(layer); -} - -static inline gfx::Point3F TransformOrigin(Layer* layer) { - return layer->transform_origin(); -} - -static inline gfx::Point3F TransformOrigin(LayerImpl* layer) { - return layer->test_properties()->transform_origin; -} - -static inline bool ShouldFlattenTransform(Layer* layer) { - return layer->should_flatten_transform(); -} - -static inline bool ShouldFlattenTransform(LayerImpl* layer) { - return layer->test_properties()->should_flatten_transform; -} - -template <typename LayerType> -bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( +bool PropertyTreeBuilderContext::AddTransformNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, bool created_render_surface, DataForRecursion* data_for_children) const { - const bool is_root = !LayerParent(layer); - const bool is_page_scale_layer = layer == page_scale_layer_; - const bool is_overscroll_elasticity_layer = - overscroll_elasticity_element_id_ && - layer->element_id() == overscroll_elasticity_element_id_; + const bool is_root = !layer->parent(); const bool is_scrollable = layer->scrollable(); // Scrolling a layer should not move it from being pixel-aligned to moving off // the pixel grid and becoming fuzzy. So always snap scrollable things to the @@ -398,7 +219,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( is_scrollable || layer->IsSnappedToPixelGridInTarget(); const bool has_significant_transform = - !Transform(layer).IsIdentityOr2DTranslation(); + !layer->transform().IsIdentityOr2DTranslation(); const bool has_potentially_animated_transform = HasPotentiallyRunningTransformAnimation(mutator_host_, layer); @@ -412,15 +233,10 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( const bool has_surface = created_render_surface; - const bool is_at_boundary_of_3d_rendering_context = - IsAtBoundaryOf3dRenderingContext(layer); - DCHECK(!is_scrollable || is_snapped); bool requires_node = is_root || is_snapped || has_significant_transform || has_any_transform_animation || has_surface || - is_page_scale_layer || is_overscroll_elasticity_layer || - is_at_boundary_of_3d_rendering_context || - HasRoundedCorner(layer); + layer->HasRoundedCorner(); int parent_index = TransformTree::kRootNodeId; gfx::Vector2dF parent_offset; @@ -428,17 +244,14 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( parent_index = data_from_ancestor.transform_tree_parent; // Now layer tree mode (IsUsingLayerLists is false) is for ui compositor // only. The transform tree hierarchy is always the same as layer hierarchy. - DCHECK_EQ(parent_index, LayerParent(layer)->transform_tree_index()); - parent_offset = LayerParent(layer)->offset_to_transform_parent(); + DCHECK_EQ(parent_index, layer->parent()->transform_tree_index()); + parent_offset = layer->parent()->offset_to_transform_parent(); } if (!requires_node) { - data_for_children->should_flatten |= ShouldFlattenTransform(layer); - gfx::Vector2dF local_offset = - Position(layer).OffsetFromOrigin() + Transform(layer).To2dTranslation(); + gfx::Vector2dF local_offset = layer->position().OffsetFromOrigin() + + layer->transform().To2dTranslation(); layer->SetOffsetToTransformParent(parent_offset + local_offset); - layer->SetShouldFlattenScreenSpaceTransformFromPropertyTree( - data_from_ancestor.should_flatten); layer->SetTransformTreeIndex(parent_index); return false; } @@ -458,272 +271,60 @@ bool PropertyTreeBuilderContext<LayerType>::AddTransformNodeIfNeeded( node->scrolls = is_scrollable; node->should_be_snapped = is_snapped; - node->flattens_inherited_transform = data_for_children->should_flatten; - node->sorting_context_id = SortingContextId(layer); - if (is_root || is_page_scale_layer) { + if (is_root) { // Root layer and page scale layer should not have transform or offset. - DCHECK(Position(layer).IsOrigin()); + DCHECK(layer->position().IsOrigin()); DCHECK(parent_offset.IsZero()); - DCHECK(Transform(layer).IsIdentity()); + DCHECK(layer->transform().IsIdentity()); - if (is_root) { - DCHECK(!is_page_scale_layer); - transform_tree_.SetRootScaleAndTransform( - transform_tree_.device_scale_factor(), device_transform_); - } else { - DCHECK(is_page_scale_layer); - transform_tree_.set_page_scale_factor(page_scale_factor_); - node->local.Scale(page_scale_factor_, page_scale_factor_); - data_for_children->in_subtree_of_page_scale_layer = true; - } + transform_tree_.SetRootScaleAndTransform( + transform_tree_.device_scale_factor(), gfx::Transform()); } else { - node->local = Transform(layer); - node->origin = TransformOrigin(layer); - node->post_translation = parent_offset + Position(layer).OffsetFromOrigin(); + node->local = layer->transform(); + node->origin = layer->transform_origin(); + node->post_translation = + parent_offset + layer->position().OffsetFromOrigin(); } - node->in_subtree_of_page_scale_layer = - data_for_children->in_subtree_of_page_scale_layer; - - // Surfaces inherently flatten transforms. - data_for_children->should_flatten = - ShouldFlattenTransform(layer) || has_surface; - node->has_potential_animation = has_potentially_animated_transform; node->is_currently_animating = TransformIsAnimating(mutator_host_, layer); GetAnimationScales(mutator_host_, layer, &node->maximum_animation_scale, &node->starting_animation_scale); - if (is_overscroll_elasticity_layer) { - DCHECK(!is_scrollable); - node->scroll_offset = gfx::ScrollOffset(elastic_overscroll_); - } else { - node->scroll_offset = layer->CurrentScrollOffset(); - } + node->scroll_offset = layer->CurrentScrollOffset(); node->needs_local_transform_update = true; transform_tree_.UpdateTransforms(node->id); layer->SetOffsetToTransformParent(gfx::Vector2dF()); - // Flattening (if needed) will be handled by |node|. - layer->SetShouldFlattenScreenSpaceTransformFromPropertyTree(false); - return true; } -static inline bool HasPotentialOpacityAnimation(const MutatorHost& host, - Layer* layer) { - return HasPotentiallyRunningOpacityAnimation(host, layer) || - layer->OpacityCanAnimateOnImplThread(); -} - -static inline bool HasPotentialOpacityAnimation(const MutatorHost& host, - LayerImpl* layer) { - return HasPotentiallyRunningOpacityAnimation(host, layer) || - layer->test_properties()->opacity_can_animate; -} - -static inline bool DoubleSided(Layer* layer) { - return layer->double_sided(); -} - -static inline bool DoubleSided(LayerImpl* layer) { - return layer->test_properties()->double_sided; -} - -static inline bool TrilinearFiltering(Layer* layer) { - return layer->trilinear_filtering(); -} - -static inline bool TrilinearFiltering(LayerImpl* layer) { - return layer->test_properties()->trilinear_filtering; -} - -static inline bool CacheRenderSurface(Layer* layer) { - return layer->cache_render_surface(); -} - -static inline bool CacheRenderSurface(LayerImpl* layer) { - return layer->test_properties()->cache_render_surface; -} - -static inline bool ForceRenderSurfaceForTesting(Layer* layer) { - return layer->force_render_surface_for_testing(); -} - -static inline bool ForceRenderSurfaceForTesting(LayerImpl* layer) { - return layer->test_properties()->force_render_surface; -} - -template <typename LayerType> -static inline bool LayerIsInExisting3DRenderingContext(LayerType* layer) { - return Is3dSorted(layer) && LayerParent(layer) && - Is3dSorted(LayerParent(layer)) && - (SortingContextId(LayerParent(layer)) == SortingContextId(layer)); -} - -static inline bool IsRootForIsolatedGroup(Layer* layer) { - return layer->is_root_for_isolated_group(); -} - -static inline bool IsRootForIsolatedGroup(LayerImpl* layer) { - return false; -} - -static inline int NumDescendantsThatDrawContent(Layer* layer) { - return layer->NumDescendantsThatDrawContent(); -} - -static inline int NumLayerOrDescendantsThatDrawContentRecursive( - LayerImpl* layer) { - int num = layer->DrawsContent() ? 1 : 0; - for (size_t i = 0; i < layer->test_properties()->children.size(); ++i) { - LayerImpl* child_layer = layer->test_properties()->children[i]; - num += NumLayerOrDescendantsThatDrawContentRecursive(child_layer); - } - return num; -} - -static inline int NumDescendantsThatDrawContent(LayerImpl* layer) { - int num_descendants_that_draw_content = 0; - for (size_t i = 0; i < layer->test_properties()->children.size(); ++i) { - LayerImpl* child_layer = layer->test_properties()->children[i]; - num_descendants_that_draw_content += - NumLayerOrDescendantsThatDrawContentRecursive(child_layer); - } - return num_descendants_that_draw_content; -} - -static inline float EffectiveOpacity(Layer* layer) { - return layer->EffectiveOpacity(); -} - -static inline float EffectiveOpacity(LayerImpl* layer) { - return layer->test_properties()->hide_layer_and_subtree - ? 0.f - : layer->test_properties()->opacity; -} - -static inline float Opacity(Layer* layer) { - return layer->opacity(); -} - -static inline float Opacity(LayerImpl* layer) { - return layer->test_properties()->opacity; -} - -static inline SkBlendMode BlendMode(Layer* layer) { - return layer->blend_mode(); -} - -static inline SkBlendMode BlendMode(LayerImpl* layer) { - return layer->test_properties()->blend_mode; -} - -static inline const gfx::PointF FiltersOrigin(Layer* layer) { - return layer->filters_origin(); -} - -static inline const gfx::PointF FiltersOrigin(LayerImpl* layer) { - return layer->test_properties()->filters_origin; -} - -static inline const FilterOperations& BackdropFilters(Layer* layer) { - return layer->backdrop_filters(); -} - -static inline const FilterOperations& BackdropFilters(LayerImpl* layer) { - return layer->test_properties()->backdrop_filters; -} - -static inline const base::Optional<gfx::RRectF>& BackdropFilterBounds( - Layer* layer) { - return layer->backdrop_filter_bounds(); -} - -static inline const base::Optional<gfx::RRectF>& BackdropFilterBounds( - LayerImpl* layer) { - return layer->test_properties()->backdrop_filter_bounds; -} - -static inline ElementId BackdropMaskElementId(Layer* layer) { - return layer->backdrop_mask_element_id(); -} - -static inline ElementId BackdropMaskElementId(LayerImpl* layer) { - return layer->test_properties()->backdrop_mask_element_id; -} - -static inline float BackdropFilterQuality(Layer* layer) { - return layer->backdrop_filter_quality(); -} - -static inline float BackdropFilterQuality(LayerImpl* layer) { - return layer->test_properties()->backdrop_filter_quality; -} - -static inline bool HideLayerAndSubtree(Layer* layer) { - return layer->hide_layer_and_subtree(); -} - -static inline bool HideLayerAndSubtree(LayerImpl* layer) { - return layer->test_properties()->hide_layer_and_subtree; -} - -static inline bool HasCopyRequest(Layer* layer) { - return layer->HasCopyRequest(); -} - -static inline bool HasCopyRequest(LayerImpl* layer) { - return !layer->test_properties()->copy_requests.empty(); -} - -static inline int MirrorCount(Layer* layer) { - return layer->mirror_count(); -} - -static inline int MirrorCount(LayerImpl* layer) { - return 0; -} - -static inline bool PropertyChanged(Layer* layer) { - return layer->subtree_property_changed(); -} - -static inline bool PropertyChanged(LayerImpl* layer) { - return false; -} - -template <typename LayerType> RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, - LayerType* layer, + Layer* layer, gfx::Transform current_transform, bool animation_axis_aligned) { const bool preserves_2d_axis_alignment = current_transform.Preserves2dAxisAlignment() && animation_axis_aligned; - const bool is_root = !LayerParent(layer); + const bool is_root = !layer->parent(); if (is_root) return RenderSurfaceReason::kRoot; - // If the layer uses a mask. - if (MaskLayer(layer)) { + if (layer->IsMaskedByChild()) { return RenderSurfaceReason::kMask; } - // If the layer uses trilinear filtering. - if (TrilinearFiltering(layer)) { + if (layer->trilinear_filtering()) { return RenderSurfaceReason::kTrilinearFiltering; } - // If the layer uses a CSS filter. - if (!Filters(layer).IsEmpty()) { + if (!layer->filters().IsEmpty()) { return RenderSurfaceReason::kFilter; } - // If the layer uses a CSS backdrop-filter. - if (!BackdropFilters(layer).IsEmpty()) { + if (!layer->backdrop_filters().IsEmpty()) { return RenderSurfaceReason::kBackdropFilter; } @@ -733,16 +334,10 @@ RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, return RenderSurfaceReason::kFilterAnimation; } - int num_descendants_that_draw_content = NumDescendantsThatDrawContent(layer); - - // If the layer flattens its subtree, but it is treated as a 3D object by its - // parent (i.e. parent participates in a 3D rendering context). - if (LayerIsInExisting3DRenderingContext(layer) && - ShouldFlattenTransform(layer) && num_descendants_that_draw_content > 0) { - return RenderSurfaceReason::k3dTransformFlattening; - } + int num_descendants_that_draw_content = + layer->NumDescendantsThatDrawContent(); - if (!IsFastRoundedCorner(layer) && HasRoundedCorner(layer) && + if (!layer->is_fast_rounded_corner() && layer->HasRoundedCorner() && num_descendants_that_draw_content > 1) { return RenderSurfaceReason::kRoundedCorner; } @@ -751,7 +346,7 @@ RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, // TODO(rosca): this is temporary, until blending is implemented for other // types of quads than viz::RenderPassDrawQuad. Layers having descendants that // draw content will still create a separate rendering surface. - if (BlendMode(layer) != SkBlendMode::kSrcOver) { + if (layer->blend_mode() != SkBlendMode::kSrcOver) { return RenderSurfaceReason::kBlendMode; } // If the layer clips its descendants but it is not axis-aligned with respect @@ -772,94 +367,50 @@ RenderSurfaceReason ComputeRenderSurfaceReason(const MutatorHost& mutator_host, (layer->DrawsContent() || num_descendants_that_draw_content > 1); bool may_have_transparency = - EffectiveOpacity(layer) != 1.f || + layer->EffectiveOpacity() != 1.f || HasPotentiallyRunningOpacityAnimation(mutator_host, layer); - if (may_have_transparency && ShouldFlattenTransform(layer) && - at_least_two_layers_in_subtree_draw_content) { + if (may_have_transparency && at_least_two_layers_in_subtree_draw_content) { DCHECK(!is_root); return RenderSurfaceReason::kOpacity; } - // If the layer has isolation. - // TODO(rosca): to be optimized - create separate rendering surface only when - // the blending descendants might have access to the content behind this layer - // (layer has transparent background or descendants overflow). - // https://code.google.com/p/chromium/issues/detail?id=301738 - if (IsRootForIsolatedGroup(layer)) { - return RenderSurfaceReason::kRootOrIsolatedGroup; - } // If we force it. - if (ForceRenderSurfaceForTesting(layer)) + if (layer->force_render_surface_for_testing()) return RenderSurfaceReason::kTest; // If we cache it. - if (CacheRenderSurface(layer)) + if (layer->cache_render_surface()) return RenderSurfaceReason::kCache; // If we'll make a copy of the layer's contents. - if (HasCopyRequest(layer)) + if (layer->HasCopyRequest()) return RenderSurfaceReason::kCopyRequest; // If the layer is mirrored. - if (MirrorCount(layer)) + if (layer->mirror_count()) return RenderSurfaceReason::kMirrored; return RenderSurfaceReason::kNone; } -static void TakeCopyRequests( - Layer* layer, - std::vector<std::unique_ptr<viz::CopyOutputRequest>>* copy_requests) { - layer->TakeCopyRequests(copy_requests); -} - -static void TakeCopyRequests( - LayerImpl* layer, - std::vector<std::unique_ptr<viz::CopyOutputRequest>>* copy_requests) { - for (auto& request : layer->test_properties()->copy_requests) - copy_requests->push_back(std::move(request)); - layer->test_properties()->copy_requests.clear(); -} - -static void SetSubtreeHasCopyRequest(Layer* layer, - bool subtree_has_copy_request) { - layer->SetSubtreeHasCopyRequest(subtree_has_copy_request); -} - -static void SetSubtreeHasCopyRequest(LayerImpl* layer, - bool subtree_has_copy_request) { - layer->test_properties()->subtree_has_copy_request = subtree_has_copy_request; -} - -static bool SubtreeHasCopyRequest(Layer* layer) { - return layer->SubtreeHasCopyRequest(); -} - -static bool SubtreeHasCopyRequest(LayerImpl* layer) { - return layer->test_properties()->subtree_has_copy_request; -} - -template <typename LayerType> -bool UpdateSubtreeHasCopyRequestRecursive(LayerType* layer) { +bool UpdateSubtreeHasCopyRequestRecursive(Layer* layer) { bool subtree_has_copy_request = false; - if (HasCopyRequest(layer)) + if (layer->HasCopyRequest()) subtree_has_copy_request = true; - for (size_t i = 0; i < LayerChildren(layer).size(); ++i) { - LayerType* current_child = LayerChildAt(layer, i); + for (const scoped_refptr<Layer>& child : layer->children()) { subtree_has_copy_request |= - UpdateSubtreeHasCopyRequestRecursive(current_child); + UpdateSubtreeHasCopyRequestRecursive(child.get()); } - SetSubtreeHasCopyRequest(layer, subtree_has_copy_request); + layer->SetSubtreeHasCopyRequest(subtree_has_copy_request); return subtree_has_copy_request; } -template <typename LayerType> -bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( +bool PropertyTreeBuilderContext::AddEffectNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const { - const bool is_root = !LayerParent(layer); - const bool has_transparency = EffectiveOpacity(layer) != 1.f; + const bool is_root = !layer->parent(); + const bool has_transparency = layer->EffectiveOpacity() != 1.f; const bool has_potential_opacity_animation = HasPotentialOpacityAnimation(mutator_host_, layer); const bool has_potential_filter_animation = @@ -867,7 +418,8 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( data_for_children->animation_axis_aligned_since_render_target &= AnimationsPreserveAxisAlignment(mutator_host_, layer); - data_for_children->compound_transform_since_render_target *= Transform(layer); + data_for_children->compound_transform_since_render_target *= + layer->transform(); auto render_surface_reason = ComputeRenderSurfaceReason( mutator_host_, layer, data_for_children->compound_transform_since_render_target, @@ -879,7 +431,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( data_from_ancestor.not_axis_aligned_since_last_clip ? true : !AnimationsPreserveAxisAlignment(mutator_host_, layer) || - !Transform(layer).Preserves2dAxisAlignment(); + !layer->transform().Preserves2dAxisAlignment(); // A non-axis aligned clip may need a render surface. So, we create an effect // node. bool has_non_axis_aligned_clip = @@ -888,7 +440,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( bool requires_node = is_root || has_transparency || has_potential_opacity_animation || has_potential_filter_animation || has_non_axis_aligned_clip || - should_create_render_surface || HasRoundedCorner(layer); + should_create_render_surface || layer->HasRoundedCorner(); int parent_id = data_from_ancestor.effect_tree_parent; @@ -902,55 +454,47 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( EffectNode* node = effect_tree_.back(); node->stable_id = layer->id(); - node->opacity = Opacity(layer); - node->blend_mode = BlendMode(layer); - node->unscaled_mask_target_size = layer->bounds(); - node->cache_render_surface = CacheRenderSurface(layer); - node->has_copy_request = HasCopyRequest(layer); - node->filters = Filters(layer); - node->backdrop_filters = BackdropFilters(layer); - node->backdrop_filter_bounds = BackdropFilterBounds(layer); - node->backdrop_filter_quality = BackdropFilterQuality(layer); - node->backdrop_mask_element_id = BackdropMaskElementId(layer); - node->filters_origin = FiltersOrigin(layer); - node->trilinear_filtering = TrilinearFiltering(layer); + node->opacity = layer->opacity(); + node->blend_mode = layer->blend_mode(); + node->cache_render_surface = layer->cache_render_surface(); + node->has_copy_request = layer->HasCopyRequest(); + node->filters = layer->filters(); + node->backdrop_filters = layer->backdrop_filters(); + node->backdrop_filter_bounds = layer->backdrop_filter_bounds(); + node->backdrop_filter_quality = layer->backdrop_filter_quality(); + node->filters_origin = layer->filters_origin(); + node->trilinear_filtering = layer->trilinear_filtering(); node->has_potential_opacity_animation = has_potential_opacity_animation; node->has_potential_filter_animation = has_potential_filter_animation; - node->double_sided = DoubleSided(layer); - node->subtree_hidden = HideLayerAndSubtree(layer); + node->double_sided = layer->double_sided(); + node->subtree_hidden = layer->hide_layer_and_subtree(); node->is_currently_animating_opacity = OpacityIsAnimating(mutator_host_, layer); node->is_currently_animating_filter = FilterIsAnimating(mutator_host_, layer); - node->effect_changed = PropertyChanged(layer); - node->subtree_has_copy_request = SubtreeHasCopyRequest(layer); + node->effect_changed = layer->subtree_property_changed(); + node->subtree_has_copy_request = layer->SubtreeHasCopyRequest(); node->render_surface_reason = render_surface_reason; node->closest_ancestor_with_cached_render_surface_id = - CacheRenderSurface(layer) + layer->cache_render_surface() ? node_id : data_from_ancestor.closest_ancestor_with_cached_render_surface; node->closest_ancestor_with_copy_request_id = - HasCopyRequest(layer) + layer->HasCopyRequest() ? node_id : data_from_ancestor.closest_ancestor_with_copy_request; - if (MaskLayer(layer)) { - node->mask_layer_id = MaskLayer(layer)->id(); - effect_tree_.AddMaskLayerId(node->mask_layer_id); - node->is_masked = true; - } - - if (HasRoundedCorner(layer)) { + if (layer->HasRoundedCorner()) { // This is currently in the local space of the layer and hence in an invalid // space. Once we have the associated transform node for this effect node, // we will update this to the transform node's coordinate space. node->rounded_corner_bounds = RoundedCornerBounds(layer); - node->is_fast_rounded_corner = IsFastRoundedCorner(layer); + node->is_fast_rounded_corner = layer->is_fast_rounded_corner(); } if (!is_root) { // Having a rounded corner or a render surface, both trigger the creation // of a transform node. - if (should_create_render_surface || HasRoundedCorner(layer)) { + if (should_create_render_surface || layer->HasRoundedCorner()) { // In this case, we will create a transform node, so it's safe to use the // next available id from the transform tree as this effect node's // transform id. @@ -958,12 +502,11 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( } node->clip_id = data_from_ancestor.clip_tree_parent; } else { - // The root render surface acts as the unbounded and untransformed - // surface into which content is drawn. The transform node created - // from the root layer (which includes device scale factor) and - // the clip node created from the root layer (which includes - // viewports) apply to the root render surface's content, but not - // to the root render surface itself. + // The root render surface acts as the unbounded and untransformed surface + // into which content is drawn. The transform node created from the root + // layer (which includes device scale factor) and the clip node created from + // the root layer apply to the root render surface's content, but not to the + // root render surface itself. node->transform_id = TransformTree::kRootNodeId; node->clip_id = ClipTree::kViewportNodeId; } @@ -983,7 +526,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( } std::vector<std::unique_ptr<viz::CopyOutputRequest>> layer_copy_requests; - TakeCopyRequests(layer, &layer_copy_requests); + layer->TakeCopyRequests(&layer_copy_requests); for (auto& it : layer_copy_requests) { effect_tree_.AddCopyRequest(node_id, std::move(it)); } @@ -997,8 +540,7 @@ bool PropertyTreeBuilderContext<LayerType>::AddEffectNodeIfNeeded( return should_create_render_surface; } -template <typename LayerType> -bool PropertyTreeBuilderContext<LayerType>::UpdateRenderSurfaceIfNeeded( +bool PropertyTreeBuilderContext::UpdateRenderSurfaceIfNeeded( int parent_effect_tree_id, DataForRecursion* data_for_children, bool subtree_has_rounded_corner, @@ -1039,70 +581,19 @@ bool PropertyTreeBuilderContext<LayerType>::UpdateRenderSurfaceIfNeeded( return effect_node->HasRenderSurface(); } -static inline bool UserScrollableHorizontal(Layer* layer) { - return layer->GetUserScrollableHorizontal(); -} - -static inline bool UserScrollableHorizontal(LayerImpl* layer) { - return layer->test_properties()->user_scrollable_horizontal; -} - -static inline bool UserScrollableVertical(Layer* layer) { - return layer->GetUserScrollableVertical(); -} - -static inline bool UserScrollableVertical(LayerImpl* layer) { - return layer->test_properties()->user_scrollable_vertical; -} - -static inline const base::Optional<SnapContainerData>& GetSnapContainerData( - Layer* layer) { - return layer->snap_container_data(); -} - -static inline const base::Optional<SnapContainerData>& GetSnapContainerData( - LayerImpl* layer) { - return layer->test_properties()->snap_container_data; -} - -static inline uint32_t MainThreadScrollingReasons(Layer* layer) { - return layer->GetMainThreadScrollingReasons(); -} - -static inline uint32_t MainThreadScrollingReasons(LayerImpl* layer) { - return layer->test_properties()->main_thread_scrolling_reasons; -} - -template <typename LayerType> -void SetHasTransformNode(LayerType* layer, bool val) { - layer->SetHasTransformNode(val); -} - -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( +void PropertyTreeBuilderContext::AddScrollNodeIfNeeded( const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) const { int parent_id = data_from_ancestor.scroll_tree_parent; - bool is_root = !LayerParent(layer); + bool is_root = !layer->parent(); bool scrollable = layer->scrollable(); bool contains_non_fast_scrollable_region = !layer->non_fast_scrollable_region().IsEmpty(); - uint32_t main_thread_scrolling_reasons = MainThreadScrollingReasons(layer); - bool scroll_node_uninheritable_criteria = - is_root || scrollable || contains_non_fast_scrollable_region; - bool has_different_main_thread_scrolling_reasons = - main_thread_scrolling_reasons != - data_from_ancestor.main_thread_scrolling_reasons; bool requires_node = - scroll_node_uninheritable_criteria || - (main_thread_scrolling_reasons != - MainThreadScrollingReason::kNotScrollingOnMain && - (has_different_main_thread_scrolling_reasons || - data_from_ancestor - .scroll_tree_parent_created_by_uninheritable_criteria)); + is_root || scrollable || contains_non_fast_scrollable_region; int node_id; if (!requires_node) { @@ -1111,32 +602,17 @@ void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( } else { ScrollNode node; node.scrollable = scrollable; - node.main_thread_scrolling_reasons = main_thread_scrolling_reasons; - node.scrolls_inner_viewport = layer == inner_viewport_scroll_layer_; - node.scrolls_outer_viewport = layer == outer_viewport_scroll_layer_; - - if (node.scrolls_inner_viewport && - data_from_ancestor.in_subtree_of_page_scale_layer) { - node.max_scroll_offset_affected_by_page_scale = true; - } - node.bounds = layer->bounds(); node.container_bounds = layer->scroll_container_bounds(); node.offset_to_transform_parent = layer->offset_to_transform_parent(); - node.should_flatten = - layer->should_flatten_screen_space_transform_from_property_tree(); - node.user_scrollable_horizontal = UserScrollableHorizontal(layer); - node.user_scrollable_vertical = UserScrollableVertical(layer); + node.user_scrollable_horizontal = layer->GetUserScrollableHorizontal(); + node.user_scrollable_vertical = layer->GetUserScrollableVertical(); node.element_id = layer->element_id(); node.transform_id = data_for_children->transform_tree_parent; - node.snap_container_data = GetSnapContainerData(layer); node_id = scroll_tree_.Insert(node, parent_id); data_for_children->scroll_tree_parent = node_id; - data_for_children->main_thread_scrolling_reasons = - node.main_thread_scrolling_reasons; - data_for_children->scroll_tree_parent_created_by_uninheritable_criteria = - scroll_node_uninheritable_criteria; + // For animation subsystem purposes, if this layer has a compositor element // id, we build a map from that id to this scroll node. if (layer->element_id()) { @@ -1153,28 +629,24 @@ void PropertyTreeBuilderContext<LayerType>::AddScrollNodeIfNeeded( layer->SetScrollTreeIndex(node_id); } -template <typename LayerType> -void SetBackfaceVisibilityTransform(LayerType* layer, - bool created_transform_node) { +void SetBackfaceVisibilityTransform(Layer* layer, bool created_transform_node) { if (layer->use_parent_backface_visibility()) { - DCHECK(LayerParent(layer)); - DCHECK(!LayerParent(layer)->use_parent_backface_visibility()); + DCHECK(layer->parent()); + DCHECK(!layer->parent()->use_parent_backface_visibility()); layer->SetShouldCheckBackfaceVisibility( - LayerParent(layer)->should_check_backface_visibility()); + layer->parent()->should_check_backface_visibility()); } else { // A double-sided layer's backface can been shown when its visible. // In addition, we need to check if (1) there might be a local 3D transform // on the layer that might turn it to the backface, or (2) it is not drawn // into a flattened space. - layer->SetShouldCheckBackfaceVisibility( - !DoubleSided(layer) && (created_transform_node || - !ShouldFlattenTransform(LayerParent(layer)))); + layer->SetShouldCheckBackfaceVisibility(!layer->double_sided() && + created_transform_node); } } -template <typename LayerType> void SetSafeOpaqueBackgroundColor(const DataForRecursion& data_from_ancestor, - LayerType* layer, + Layer* layer, DataForRecursion* data_for_children) { SkColor background_color = layer->background_color(); data_for_children->safe_opaque_background_color = @@ -1185,17 +657,8 @@ void SetSafeOpaqueBackgroundColor(const DataForRecursion& data_from_ancestor, data_for_children->safe_opaque_background_color); } -static void SetLayerPropertyChangedForChild(Layer* parent, Layer* child) { - if (parent->subtree_property_changed()) - child->SetSubtreePropertyChanged(); -} - -static void SetLayerPropertyChangedForChild(LayerImpl* parent, - LayerImpl* child) {} - -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( - LayerType* layer, +void PropertyTreeBuilderContext::BuildPropertyTreesInternal( + Layer* layer, const DataForRecursion& data_from_parent) const { layer->set_property_tree_sequence_number(property_trees_.sequence_number); @@ -1207,7 +670,7 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( bool created_transform_node = AddTransformNodeIfNeeded( data_from_parent, layer, created_render_surface, &data_for_children); - SetHasTransformNode(layer, created_transform_node); + layer->SetHasTransformNode(created_transform_node); AddClipNodeIfNeeded(data_from_parent, layer, created_transform_node, &data_for_children); @@ -1220,78 +683,40 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTreesInternal( data_from_parent.not_axis_aligned_since_last_clip ? true : !AnimationsPreserveAxisAlignment(mutator_host_, layer) || - !Transform(layer).Preserves2dAxisAlignment(); + !layer->transform().Preserves2dAxisAlignment(); bool has_non_axis_aligned_clip = not_axis_aligned_since_last_clip && LayerClipsSubtree(layer); data_for_children.not_axis_aligned_since_last_clip = !has_non_axis_aligned_clip; bool subtree_has_rounded_corner = false; - for (size_t i = 0; i < LayerChildren(layer).size(); ++i) { - LayerType* current_child = LayerChildAt(layer, i); - SetLayerPropertyChangedForChild(layer, current_child); - BuildPropertyTreesInternal(current_child, data_for_children); + for (const scoped_refptr<Layer>& child : layer->children()) { + if (layer->subtree_property_changed()) + child->SetSubtreePropertyChanged(); + BuildPropertyTreesInternal(child.get(), data_for_children); subtree_has_rounded_corner |= *data_for_children.subtree_has_rounded_corner; } created_render_surface = UpdateRenderSurfaceIfNeeded( data_from_parent.effect_tree_parent, &data_for_children, subtree_has_rounded_corner, created_transform_node); - - if (MaskLayer(layer)) { - MaskLayer(layer)->set_property_tree_sequence_number( - property_trees_.sequence_number); - MaskLayer(layer)->SetOffsetToTransformParent( - layer->offset_to_transform_parent()); - MaskLayer(layer)->SetTransformTreeIndex(layer->transform_tree_index()); - MaskLayer(layer)->SetClipTreeIndex(layer->clip_tree_index()); - MaskLayer(layer)->SetEffectTreeIndex(layer->effect_tree_index()); - MaskLayer(layer)->SetScrollTreeIndex(layer->scroll_tree_index()); - } } -} // namespace - -Layer* PropertyTreeBuilder::FindFirstScrollableLayer(Layer* layer) { - if (!layer) - return nullptr; - - if (layer->scrollable()) - return layer; +void PropertyTreeBuilderContext::BuildPropertyTrees() { + property_trees_.is_main_thread = true; + property_trees_.is_active = false; - for (size_t i = 0; i < layer->children().size(); ++i) { - Layer* found = FindFirstScrollableLayer(layer->children()[i].get()); - if (found) - return found; - } - - return nullptr; -} + if (layer_tree_host_->has_copy_request()) + UpdateSubtreeHasCopyRequestRecursive(root_layer_); -template <typename LayerType> -void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( - float device_scale_factor, - const gfx::Rect& viewport, - SkColor root_background_color) const { if (!property_trees_.needs_rebuild) { - DCHECK_NE(page_scale_layer_, root_layer_); - if (page_scale_layer_) { - DCHECK_GE(page_scale_layer_->transform_tree_index(), - TransformTree::kRootNodeId); - TransformNode* node = property_trees_.transform_tree.Node( - page_scale_layer_->transform_tree_index()); - draw_property_utils::UpdatePageScaleFactor(&property_trees_, node, - page_scale_factor_); - } - draw_property_utils::UpdateElasticOverscroll( - &property_trees_, overscroll_elasticity_element_id_, - elastic_overscroll_); - clip_tree_.SetViewportClip(gfx::RectF(viewport)); + clip_tree_.SetViewportClip( + gfx::RectF(layer_tree_host_->device_viewport_rect())); // SetRootScaleAndTransform will be incorrect if the root layer has // non-zero position, so ensure it is zero. - DCHECK(Position(root_layer_).IsOrigin()); - transform_tree_.SetRootScaleAndTransform(device_scale_factor, - device_transform_); + DCHECK(root_layer_->position().IsOrigin()); + transform_tree_.SetRootScaleAndTransform( + layer_tree_host_->device_scale_factor(), gfx::Transform()); return; } @@ -1304,23 +729,21 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( EffectTree::kInvalidNodeId; data_for_recursion.closest_ancestor_with_copy_request = EffectTree::kInvalidNodeId; - data_for_recursion.in_subtree_of_page_scale_layer = false; - data_for_recursion.affected_by_outer_viewport_bounds_delta = false; - data_for_recursion.should_flatten = false; - data_for_recursion.main_thread_scrolling_reasons = - MainThreadScrollingReason::kNotScrollingOnMain; - data_for_recursion.scroll_tree_parent_created_by_uninheritable_criteria = - true; data_for_recursion.compound_transform_since_render_target = gfx::Transform(); data_for_recursion.animation_axis_aligned_since_render_target = true; data_for_recursion.not_axis_aligned_since_last_clip = false; + + SkColor root_background_color = layer_tree_host_->background_color(); + if (SkColorGetA(root_background_color) != 255) + root_background_color = SkColorSetA(root_background_color, 255); data_for_recursion.safe_opaque_background_color = root_background_color; property_trees_.clear(); - transform_tree_.set_device_scale_factor(device_scale_factor); + transform_tree_.set_device_scale_factor( + layer_tree_host_->device_scale_factor()); ClipNode root_clip; root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; - root_clip.clip = gfx::RectF(viewport); + root_clip.clip = gfx::RectF(layer_tree_host_->device_viewport_rect()); root_clip.transform_id = TransformTree::kRootNodeId; data_for_recursion.clip_tree_parent = clip_tree_.Insert(root_clip, ClipTree::kRootNodeId); @@ -1340,70 +763,17 @@ void PropertyTreeBuilderContext<LayerType>::BuildPropertyTrees( scroll_tree_.set_needs_update(false); } -void PropertyTreeBuilder::BuildPropertyTrees( - Layer* root_layer, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees) { - property_trees->is_main_thread = true; - property_trees->is_active = false; - SkColor color = root_layer->layer_tree_host()->background_color(); - if (SkColorGetA(color) != 255) - color = SkColorSetA(color, 255); - if (root_layer->layer_tree_host()->has_copy_request()) - UpdateSubtreeHasCopyRequestRecursive(root_layer); - PropertyTreeBuilderContext<Layer>( - root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, overscroll_elasticity_element_id, - elastic_overscroll, page_scale_factor, device_transform, - root_layer->layer_tree_host()->mutator_host(), property_trees) - .BuildPropertyTrees(device_scale_factor, viewport, color); - property_trees->ResetCachedData(); +} // namespace + +void PropertyTreeBuilder::BuildPropertyTrees(LayerTreeHost* layer_tree_host) { + PropertyTreeBuilderContext(layer_tree_host).BuildPropertyTrees(); + + layer_tree_host->property_trees()->ResetCachedData(); // During building property trees, all copy requests are moved from layers to // effect tree, which are then pushed at commit to compositor thread and // handled there. LayerTreeHost::has_copy_request is only required to // decide if we want to create a effect node. So, it can be reset now. - root_layer->layer_tree_host()->SetHasCopyRequest(false); -} - -void PropertyTreeBuilder::BuildPropertyTrees( - LayerImpl* root_layer, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees) { - // Preserve render surfaces when rebuilding. - std::vector<std::unique_ptr<RenderSurfaceImpl>> render_surfaces; - property_trees->effect_tree.TakeRenderSurfaces(&render_surfaces); - property_trees->is_main_thread = false; - property_trees->is_active = root_layer->IsActive(); - SkColor color = root_layer->layer_tree_impl()->background_color(); - if (SkColorGetA(color) != 255) - color = SkColorSetA(color, 255); - UpdateSubtreeHasCopyRequestRecursive(root_layer); - - PropertyTreeBuilderContext<LayerImpl>( - root_layer, page_scale_layer, inner_viewport_scroll_layer, - outer_viewport_scroll_layer, overscroll_elasticity_element_id, - elastic_overscroll, page_scale_factor, device_transform, - root_layer->layer_tree_impl()->mutator_host(), property_trees) - .BuildPropertyTrees(device_scale_factor, viewport, color); - property_trees->effect_tree.CreateOrReuseRenderSurfaces( - &render_surfaces, root_layer->layer_tree_impl()); - property_trees->ResetCachedData(); + layer_tree_host->SetHasCopyRequest(false); } } // namespace cc diff --git a/chromium/cc/trees/property_tree_builder.h b/chromium/cc/trees/property_tree_builder.h index c22bf43378e..8103a91e88e 100644 --- a/chromium/cc/trees/property_tree_builder.h +++ b/chromium/cc/trees/property_tree_builder.h @@ -7,39 +7,15 @@ #include <vector> -#include "cc/trees/layer_tree_host_common.h" -#include "cc/trees/property_tree.h" +#include "cc/cc_export.h" namespace cc { +class LayerTreeHost; + class PropertyTreeBuilder { public: - static Layer* FindFirstScrollableLayer(Layer* root_layer); - - static void CC_EXPORT - BuildPropertyTrees(Layer* root_layer, - const Layer* page_scale_layer, - const Layer* inner_viewport_scroll_layer, - const Layer* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees); - static void CC_EXPORT - BuildPropertyTrees(LayerImpl* root_layer, - const LayerImpl* page_scale_layer, - const LayerImpl* inner_viewport_scroll_layer, - const LayerImpl* outer_viewport_scroll_layer, - const ElementId overscroll_elasticity_element_id, - const gfx::Vector2dF& elastic_overscroll, - float page_scale_factor, - float device_scale_factor, - const gfx::Rect& viewport, - const gfx::Transform& device_transform, - PropertyTrees* property_trees); + static void CC_EXPORT BuildPropertyTrees(LayerTreeHost*); }; } // namespace cc diff --git a/chromium/cc/trees/property_tree_builder_unittest.cc b/chromium/cc/trees/property_tree_builder_unittest.cc new file mode 100644 index 00000000000..9b4a5f348b0 --- /dev/null +++ b/chromium/cc/trees/property_tree_builder_unittest.cc @@ -0,0 +1,1954 @@ +// Copyright 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/trees/property_tree_builder.h" + +#include "cc/animation/keyframed_animation_curve.h" +#include "cc/layers/layer.h" +#include "cc/layers/layer_impl.h" +#include "cc/layers/picture_layer.h" +#include "cc/layers/render_surface_impl.h" +#include "cc/layers/texture_layer.h" +#include "cc/test/animation_test_common.h" +#include "cc/test/fake_content_layer_client.h" +#include "cc/test/layer_tree_impl_test_base.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "ui/gfx/geometry/size_conversions.h" +#include "ui/gfx/geometry/vector2d_conversions.h" +#include "ui/gfx/transform.h" + +namespace cc { +namespace { + +class PropertyTreeBuilderTest : public LayerTreeImplTestBase, + public testing::Test { + public: + PropertyTreeBuilderTest() : LayerTreeImplTestBase(LayerTreeSettings()) {} + + void UpdateMainDrawProperties(float device_scale_factor = 1.0f) { + SetDeviceScaleAndUpdateViewportRect(host(), device_scale_factor); + UpdateDrawProperties(host()); + } + + LayerImpl* ImplOf(const scoped_refptr<Layer>& layer) { + return layer ? host_impl()->active_tree()->LayerById(layer->id()) : nullptr; + } + RenderSurfaceImpl* GetRenderSurfaceImpl(const scoped_refptr<Layer>& layer) { + return GetRenderSurface(ImplOf(layer)); + } + + // Updates main thread draw properties, commits main thread tree to + // impl-side pending tree, and updates pending tree draw properties. + void Commit(float device_scale_factor = 1.0f) { + UpdateMainDrawProperties(device_scale_factor); + if (!host_impl()->pending_tree()) + host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + // TODO(https://crbug.com/939968) This call should be handled by + // FakeLayerTreeHost instead of manually pushing the properties from the + // layer tree host to the pending tree. + host()->PushLayerTreePropertiesTo(host_impl()->pending_tree()); + + UpdateDrawProperties(host_impl()->pending_tree()); + } + + // Calls Commit(), then activates the pending tree, and updates active tree + // draw properties. + void CommitAndActivate(float device_scale_factor = 1.0f) { + Commit(device_scale_factor); + host_impl()->ActivateSyncTree(); + DCHECK_EQ(device_scale_factor, + host_impl()->active_tree()->device_scale_factor()); + UpdateActiveTreeDrawProperties(device_scale_factor); + } + + const RenderSurfaceList& GetRenderSurfaceList() { + return host_impl()->active_tree()->GetRenderSurfaceList(); + } +}; + +TEST_F(PropertyTreeBuilderTest, EffectTreeTransformIdTest) { + // Tests that effect tree node gets a valid transform id when a layer + // has opacity but doesn't create a render surface. + auto parent = Layer::Create(); + host()->SetRootLayer(parent); + auto child = Layer::Create(); + parent->AddChild(child); + child->SetIsDrawable(true); + + parent->SetBounds(gfx::Size(100, 100)); + child->SetPosition(gfx::PointF(10, 10)); + child->SetBounds(gfx::Size(100, 100)); + child->SetOpacity(0.f); + UpdateMainDrawProperties(); + EffectNode* node = GetEffectNode(child.get()); + const int transform_tree_size = + GetPropertyTrees(parent.get())->transform_tree.next_available_id(); + EXPECT_LT(node->transform_id, transform_tree_size); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceForNonAxisAlignedClipping) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto rotated_and_transparent = Layer::Create(); + root->AddChild(rotated_and_transparent); + auto clips_subtree = Layer::Create(); + rotated_and_transparent->AddChild(clips_subtree); + auto draws_content = Layer::Create(); + clips_subtree->AddChild(draws_content); + + root->SetBounds(gfx::Size(10, 10)); + rotated_and_transparent->SetBounds(gfx::Size(10, 10)); + rotated_and_transparent->SetOpacity(0.5f); + gfx::Transform rotate; + rotate.Rotate(2); + rotated_and_transparent->SetTransform(rotate); + clips_subtree->SetBounds(gfx::Size(10, 10)); + clips_subtree->SetMasksToBounds(true); + draws_content->SetBounds(gfx::Size(10, 10)); + draws_content->SetIsDrawable(true); + + UpdateMainDrawProperties(); + EXPECT_TRUE(GetEffectNode(clips_subtree.get())->HasRenderSurface()); +} + +TEST_F(PropertyTreeBuilderTest, EffectNodesForNonAxisAlignedClips) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto rotate_and_clip = Layer::Create(); + root->AddChild(rotate_and_clip); + auto only_clip = Layer::Create(); + rotate_and_clip->AddChild(only_clip); + auto rotate_and_clip2 = Layer::Create(); + only_clip->AddChild(rotate_and_clip2); + + gfx::Transform rotate; + rotate.Rotate(2); + root->SetBounds(gfx::Size(10, 10)); + rotate_and_clip->SetBounds(gfx::Size(10, 10)); + rotate_and_clip->SetTransform(rotate); + rotate_and_clip->SetMasksToBounds(true); + only_clip->SetBounds(gfx::Size(10, 10)); + only_clip->SetMasksToBounds(true); + rotate_and_clip2->SetBounds(gfx::Size(10, 10)); + rotate_and_clip2->SetTransform(rotate); + rotate_and_clip2->SetMasksToBounds(true); + + UpdateMainDrawProperties(); + // non-axis aligned clip should create an effect node + EXPECT_NE(root->effect_tree_index(), rotate_and_clip->effect_tree_index()); + // Since only_clip's clip is in the same non-axis aligned space as + // rotate_and_clip's clip, no new effect node should be created. + EXPECT_EQ(rotate_and_clip->effect_tree_index(), + only_clip->effect_tree_index()); + // rotate_and_clip2's clip and only_clip's clip are in different non-axis + // aligned spaces. So, new effect node should be created. + EXPECT_NE(rotate_and_clip2->effect_tree_index(), + only_clip->effect_tree_index()); +} + +TEST_F(PropertyTreeBuilderTest, + RenderSurfaceListForRenderSurfaceWithClippedLayer) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + root->SetMasksToBounds(true); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + child->SetIsDrawable(true); + child->SetPosition(gfx::PointF(30.f, 30.f)); + child->SetBounds(gfx::Size(10, 10)); + + CommitAndActivate(); + + // The child layer's content is entirely outside the root's clip rect, so + // the intermediate render surface should not be listed here, even if it was + // forced to be created. Render surfaces without children or visible content + // are unexpected at draw time (e.g. we might try to create a content texture + // of size 0). + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(1U, GetRenderSurfaceList().size()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForTransparentChild) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + render_surface1->SetOpacity(0.f); + child->SetBounds(gfx::Size(10, 10)); + child->SetIsDrawable(true); + + CommitAndActivate(); + + // Since the layer is transparent, render_surface1_impl->GetRenderSurface() + // should not have gotten added anywhere. Also, the drawable content rect + // should not have been extended by the children. + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(0, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_EQ(1U, GetRenderSurfaceList().size()); + EXPECT_EQ(static_cast<viz::RenderPassId>(root->id()), + GetRenderSurfaceList().at(0)->id()); + EXPECT_EQ(gfx::Rect(), ImplOf(root)->drawable_content_rect()); +} + +TEST_F(PropertyTreeBuilderTest, + RenderSurfaceListForTransparentChildWithBackdropFilter) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + render_surface1->SetOpacity(0.f); + render_surface1->SetIsDrawable(true); + FilterOperations filters; + filters.Append(FilterOperation::CreateBlurFilter(1.5f)); + render_surface1->SetBackdropFilters(filters); + child->SetBounds(gfx::Size(10, 10)); + child->SetIsDrawable(true); + host()->SetElementIdsForTesting(); + + CommitAndActivate(); + EXPECT_EQ(2U, GetRenderSurfaceList().size()); + + // The layer is fully transparent, but has a backdrop filter, so it + // shouldn't be skipped and should be drawn. + ASSERT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(1, GetRenderSurfaceImpl(root)->num_contributors()); + EXPECT_EQ(gfx::RectF(0, 0, 10, 10), + GetRenderSurfaceImpl(root)->DrawableContentRect()); + EXPECT_TRUE(GetEffectNode(ImplOf(render_surface1))->is_drawn); + + // When root is transparent, the layer should not be drawn. + host_impl()->active_tree()->SetOpacityMutated(root->element_id(), 0.f); + host_impl()->active_tree()->SetOpacityMutated(render_surface1->element_id(), + 1.f); + ImplOf(render_surface1)->set_visible_layer_rect(gfx::Rect()); + UpdateActiveTreeDrawProperties(); + + EXPECT_FALSE(GetEffectNode(ImplOf(render_surface1))->is_drawn); + EXPECT_EQ(gfx::Rect(), ImplOf(render_surface1)->visible_layer_rect()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForFilter) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child1 = Layer::Create(); + parent->AddChild(child1); + auto child2 = Layer::Create(); + parent->AddChild(child2); + + gfx::Transform scale_matrix; + scale_matrix.Scale(2.0f, 2.0f); + + root->SetBounds(gfx::Size(100, 100)); + parent->SetTransform(scale_matrix); + FilterOperations filters; + filters.Append(FilterOperation::CreateBlurFilter(10.0f)); + parent->SetFilters(filters); + parent->SetForceRenderSurfaceForTesting(true); + child1->SetBounds(gfx::Size(25, 25)); + child1->SetIsDrawable(true); + child1->SetForceRenderSurfaceForTesting(true); + child2->SetPosition(gfx::PointF(25, 25)); + child2->SetBounds(gfx::Size(25, 25)); + child2->SetIsDrawable(true); + child2->SetForceRenderSurfaceForTesting(true); + + CommitAndActivate(); + + ASSERT_TRUE(GetRenderSurfaceImpl(parent)); + EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); + EXPECT_EQ(4U, GetRenderSurfaceList().size()); + + // The rectangle enclosing child1 and child2 (0,0 50x50), expanded for the + // blur (-30,-30 110x110), and then scaled by the scale matrix + // (-60,-60 220x220). + EXPECT_EQ(gfx::RectF(-60, -60, 220, 220), + GetRenderSurfaceImpl(parent)->DrawableContentRect()); +} + +TEST_F(PropertyTreeBuilderTest, ForceRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto render_surface1 = Layer::Create(); + root->AddChild(render_surface1); + auto child = Layer::Create(); + render_surface1->AddChild(child); + + root->SetBounds(gfx::Size(10, 10)); + render_surface1->SetBounds(gfx::Size(10, 10)); + render_surface1->SetForceRenderSurfaceForTesting(true); + child->SetBounds(gfx::Size(10, 10)); + child->SetIsDrawable(true); + + CommitAndActivate(); + + // The root layer always creates a render surface + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); + + render_surface1->SetForceRenderSurfaceForTesting(false); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(render_surface1), GetRenderSurfaceImpl(root)); +} + +TEST_F(PropertyTreeBuilderTest, VisibleRectWithClippingAndFilters) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto clip = Layer::Create(); + root->AddChild(clip); + auto filter = Layer::Create(); + clip->AddChild(filter); + auto filter_child = Layer::Create(); + filter->AddChild(filter_child); + + root->SetBounds(gfx::Size(100, 100)); + clip->SetBounds(gfx::Size(10, 10)); + filter->SetForceRenderSurfaceForTesting(true); + filter_child->SetBounds(gfx::Size(2000, 2000)); + filter_child->SetPosition(gfx::PointF(-50, -50)); + filter_child->SetIsDrawable(true); + + clip->SetMasksToBounds(true); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(50, 50, 10, 10), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(10, 10), GetRenderSurfaceImpl(filter)->content_rect()); + + FilterOperations blur_filter; + blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); + filter->SetFilters(blur_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(38, 38, 34, 34), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-12, -12, 34, 34), + GetRenderSurfaceImpl(filter)->content_rect()); + + gfx::Transform vertical_flip; + vertical_flip.Scale(1, -1); + sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( + vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); + FilterOperations reflection_filter; + reflection_filter.Append( + FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( + SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); + filter->SetFilters(reflection_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(49, 39, 12, 21), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-1, -11, 12, 21), + GetRenderSurfaceImpl(filter)->content_rect()); +} + +TEST_F(PropertyTreeBuilderTest, VisibleRectWithScalingClippingAndFilters) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto scale = Layer::Create(); + root->AddChild(scale); + auto clip = Layer::Create(); + scale->AddChild(clip); + auto filter = Layer::Create(); + clip->AddChild(filter); + auto filter_child = Layer::Create(); + filter->AddChild(filter_child); + + root->SetBounds(gfx::Size(100, 100)); + clip->SetBounds(gfx::Size(10, 10)); + filter->SetForceRenderSurfaceForTesting(true); + filter_child->SetBounds(gfx::Size(2000, 2000)); + filter_child->SetPosition(gfx::PointF(-50, -50)); + filter_child->SetIsDrawable(true); + + clip->SetMasksToBounds(true); + + gfx::Transform scale_transform; + scale_transform.Scale(3, 3); + scale->SetTransform(scale_transform); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(50, 50, 10, 10), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(30, 30), GetRenderSurfaceImpl(filter)->content_rect()); + + FilterOperations blur_filter; + blur_filter.Append(FilterOperation::CreateBlurFilter(4.0f)); + filter->SetFilters(blur_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(38, 38, 34, 34), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-36, -36, 102, 102), + GetRenderSurfaceImpl(filter)->content_rect()); + + gfx::Transform vertical_flip; + vertical_flip.Scale(1, -1); + sk_sp<PaintFilter> flip_filter = sk_make_sp<MatrixPaintFilter>( + vertical_flip.matrix(), kLow_SkFilterQuality, nullptr); + FilterOperations reflection_filter; + reflection_filter.Append( + FilterOperation::CreateReferenceFilter(sk_make_sp<XfermodePaintFilter>( + SkBlendMode::kSrcOver, std::move(flip_filter), nullptr))); + filter->SetFilters(reflection_filter); + + CommitAndActivate(); + + EXPECT_EQ(gfx::Rect(49, 39, 12, 21), + ImplOf(filter_child)->visible_layer_rect()); + EXPECT_EQ(gfx::Rect(-1, -31, 32, 61), + GetRenderSurfaceImpl(filter)->content_rect()); +} + +TEST_F(PropertyTreeBuilderTest, TextureLayerSnapping) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = TextureLayer::CreateForMailbox(nullptr); + root->AddChild(child); + + root->SetBounds(gfx::Size(100, 100)); + child->SetBounds(gfx::Size(100, 100)); + child->SetIsDrawable(true); + gfx::Transform fractional_translate; + fractional_translate.Translate(10.5f, 20.3f); + child->SetTransform(fractional_translate); + + CommitAndActivate(); + + auto child_screen_space_transform = ImplOf(child)->ScreenSpaceTransform(); + EXPECT_NE(child_screen_space_transform, fractional_translate); + fractional_translate.RoundTranslationComponents(); + EXPECT_TRANSFORMATION_MATRIX_EQ(child_screen_space_transform, + fractional_translate); + gfx::RectF layer_bounds_in_screen_space = MathUtil::MapClippedRect( + child_screen_space_transform, gfx::RectF(gfx::SizeF(child->bounds()))); + EXPECT_EQ(layer_bounds_in_screen_space, gfx::RectF(11.f, 20.f, 100.f, 100.f)); +} + +// Verify the behavior of back-face culling when there are no preserve-3d +// layers. Note that 3d transforms still apply in this case, but they are +// "flattened" to each parent layer according to current W3C spec. +TEST_F(PropertyTreeBuilderTest, BackFaceCullingWithoutPreserves3d) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto front_facing_child = Layer::Create(); + root->AddChild(front_facing_child); + auto back_facing_child = Layer::Create(); + root->AddChild(back_facing_child); + auto front_facing_surface = Layer::Create(); + root->AddChild(front_facing_surface); + auto back_facing_surface = Layer::Create(); + root->AddChild(back_facing_surface); + auto front_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(front_facing_child_of_front_facing_surface); + auto back_facing_child_of_front_facing_surface = Layer::Create(); + front_facing_surface->AddChild(back_facing_child_of_front_facing_surface); + auto front_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(front_facing_child_of_back_facing_surface); + auto back_facing_child_of_back_facing_surface = Layer::Create(); + back_facing_surface->AddChild(back_facing_child_of_back_facing_surface); + + // Nothing is double-sided + front_facing_child->SetDoubleSided(false); + back_facing_child->SetDoubleSided(false); + front_facing_surface->SetDoubleSided(false); + back_facing_surface->SetDoubleSided(false); + front_facing_child_of_front_facing_surface->SetDoubleSided(false); + back_facing_child_of_front_facing_surface->SetDoubleSided(false); + front_facing_child_of_back_facing_surface->SetDoubleSided(false); + back_facing_child_of_back_facing_surface->SetDoubleSided(false); + + // Everything draws content. + front_facing_child->SetIsDrawable(true); + back_facing_child->SetIsDrawable(true); + front_facing_surface->SetIsDrawable(true); + back_facing_surface->SetIsDrawable(true); + front_facing_child_of_front_facing_surface->SetIsDrawable(true); + back_facing_child_of_front_facing_surface->SetIsDrawable(true); + front_facing_child_of_back_facing_surface->SetIsDrawable(true); + back_facing_child_of_back_facing_surface->SetIsDrawable(true); + + gfx::Transform backface_matrix; + backface_matrix.Translate(50.0, 50.0); + backface_matrix.RotateAboutYAxis(180.0); + backface_matrix.Translate(-50.0, -50.0); + + root->SetBounds(gfx::Size(100, 100)); + front_facing_child->SetBounds(gfx::Size(100, 100)); + back_facing_child->SetBounds(gfx::Size(100, 100)); + front_facing_surface->SetBounds(gfx::Size(100, 100)); + back_facing_surface->SetBounds(gfx::Size(100, 100)); + front_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); + back_facing_child_of_front_facing_surface->SetBounds(gfx::Size(100, 100)); + front_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); + back_facing_child_of_back_facing_surface->SetBounds(gfx::Size(100, 100)); + + front_facing_surface->SetForceRenderSurfaceForTesting(true); + back_facing_surface->SetForceRenderSurfaceForTesting(true); + + back_facing_child->SetTransform(backface_matrix); + back_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_front_facing_surface->SetTransform(backface_matrix); + back_facing_child_of_back_facing_surface->SetTransform(backface_matrix); + + // Note: No layers preserve 3d. According to current W3C CSS gfx::Transforms + // spec, these layers should blindly use their own local transforms to + // determine back-face culling. + CommitAndActivate(); + + // Verify which render surfaces were created. + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(front_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(back_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_front_facing_surface), + GetRenderSurfaceImpl(front_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(front_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(back_facing_child_of_back_facing_surface), + GetRenderSurfaceImpl(back_facing_surface)); + + EXPECT_EQ(3u, update_layer_impl_list().size()); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_child->id())); + EXPECT_TRUE(UpdateLayerImplListContains(front_facing_surface->id())); + EXPECT_TRUE(UpdateLayerImplListContains( + front_facing_child_of_front_facing_surface->id())); +} + +// Verify that layers are appropriately culled when their back face is showing +// and they are not double sided, while animations are going on. +// Even layers that are animating get culled if their back face is showing and +// they are not double sided. +TEST_F(PropertyTreeBuilderTest, BackFaceCullingWithAnimatingTransforms) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto animating_surface = Layer::Create(); + root->AddChild(animating_surface); + auto child_of_animating_surface = Layer::Create(); + animating_surface->AddChild(child_of_animating_surface); + auto animating_child = Layer::Create(); + root->AddChild(animating_child); + auto child2 = Layer::Create(); + root->AddChild(child2); + + // Nothing is double-sided + child->SetDoubleSided(false); + child2->SetDoubleSided(false); + animating_surface->SetDoubleSided(false); + child_of_animating_surface->SetDoubleSided(false); + animating_child->SetDoubleSided(false); + + // Everything draws content. + child->SetIsDrawable(true); + child2->SetIsDrawable(true); + animating_surface->SetIsDrawable(true); + child_of_animating_surface->SetIsDrawable(true); + animating_child->SetIsDrawable(true); + + gfx::Transform backface_matrix; + backface_matrix.Translate(50.0, 50.0); + backface_matrix.RotateAboutYAxis(180.0); + backface_matrix.Translate(-50.0, -50.0); + + host()->SetElementIdsForTesting(); + + // Animate the transform on the render surface. + AddAnimatedTransformToElementWithAnimation(animating_surface->element_id(), + timeline(), 10.0, 30, 0); + // This is just an animating layer, not a surface. + AddAnimatedTransformToElementWithAnimation(animating_child->element_id(), + timeline(), 10.0, 30, 0); + + root->SetBounds(gfx::Size(100, 100)); + child->SetBounds(gfx::Size(100, 100)); + child->SetTransform(backface_matrix); + animating_surface->SetBounds(gfx::Size(100, 100)); + animating_surface->SetTransform(backface_matrix); + animating_surface->SetForceRenderSurfaceForTesting(true); + child_of_animating_surface->SetBounds(gfx::Size(100, 100)); + child_of_animating_surface->SetTransform(backface_matrix); + animating_child->SetBounds(gfx::Size(100, 100)); + animating_child->SetTransform(backface_matrix); + child2->SetBounds(gfx::Size(100, 100)); + + CommitAndActivate(); + + EXPECT_EQ(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_TRUE(GetRenderSurfaceImpl(animating_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(child_of_animating_surface), + GetRenderSurfaceImpl(animating_surface)); + EXPECT_EQ(GetRenderSurfaceImpl(animating_child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(child2), GetRenderSurfaceImpl(root)); + + EXPECT_EQ(1u, update_layer_impl_list().size()); + + // The back facing layers are culled from the layer list, and have an empty + // visible rect. + EXPECT_TRUE(UpdateLayerImplListContains(child2->id())); + EXPECT_TRUE(ImplOf(child)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(ImplOf(animating_surface)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE( + ImplOf(child_of_animating_surface)->visible_layer_rect().IsEmpty()); + EXPECT_TRUE(ImplOf(animating_child)->visible_layer_rect().IsEmpty()); + + EXPECT_EQ(gfx::Rect(100, 100), ImplOf(child2)->visible_layer_rect()); +} + +// Verify that having animated opacity but current opacity 1 still creates +// a render surface. +TEST_F(PropertyTreeBuilderTest, AnimatedOpacityCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); + + root->SetBounds(gfx::Size(50, 50)); + child->SetBounds(gfx::Size(50, 50)); + child->SetIsDrawable(true); + grandchild->SetBounds(gfx::Size(50, 50)); + grandchild->SetIsDrawable(true); + + host()->SetElementIdsForTesting(); + AddOpacityTransitionToElementWithAnimation(child->element_id(), timeline(), + 10.0, 1.f, 0.2f, false); + CommitAndActivate(); + + EXPECT_EQ(1.f, ImplOf(child)->Opacity()); + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); +} + +static bool FilterIsAnimating(LayerImpl* layer) { + MutatorHost* host = layer->layer_tree_impl()->mutator_host(); + return host->IsAnimatingFilterProperty(layer->element_id(), + layer->GetElementTypeForAnimation()); +} + +// Verify that having an animated filter (but no current filter, as these +// are mutually exclusive) correctly creates a render surface. +TEST_F(PropertyTreeBuilderTest, AnimatedFilterCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); + + root->SetBounds(gfx::Size(50, 50)); + child->SetBounds(gfx::Size(50, 50)); + grandchild->SetBounds(gfx::Size(50, 50)); + + host()->SetElementIdsForTesting(); + AddAnimatedFilterToElementWithAnimation(child->element_id(), timeline(), 10.0, + 0.1f, 0.2f); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); + + EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); + EXPECT_TRUE(FilterIsAnimating(ImplOf(child))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); +} + +bool HasPotentiallyRunningFilterAnimation(const LayerImpl& layer) { + MutatorHost* host = layer.layer_tree_impl()->mutator_host(); + return host->HasPotentiallyRunningFilterAnimation( + layer.element_id(), layer.GetElementTypeForAnimation()); +} + +// Verify that having a filter animation with a delayed start time creates a +// render surface. +TEST_F(PropertyTreeBuilderTest, DelayedFilterAnimationCreatesRenderSurface) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto child = Layer::Create(); + root->AddChild(child); + auto grandchild = Layer::Create(); + child->AddChild(grandchild); + + root->SetBounds(gfx::Size(50, 50)); + child->SetBounds(gfx::Size(50, 50)); + grandchild->SetBounds(gfx::Size(50, 50)); + + host()->SetElementIdsForTesting(); + + std::unique_ptr<KeyframedFilterAnimationCurve> curve( + KeyframedFilterAnimationCurve::Create()); + FilterOperations start_filters; + start_filters.Append(FilterOperation::CreateBrightnessFilter(0.1f)); + FilterOperations end_filters; + end_filters.Append(FilterOperation::CreateBrightnessFilter(0.3f)); + curve->AddKeyframe( + FilterKeyframe::Create(base::TimeDelta(), start_filters, nullptr)); + curve->AddKeyframe(FilterKeyframe::Create( + base::TimeDelta::FromMilliseconds(100), end_filters, nullptr)); + std::unique_ptr<KeyframeModel> keyframe_model = + KeyframeModel::Create(std::move(curve), 0, 1, TargetProperty::FILTER); + keyframe_model->set_fill_mode(KeyframeModel::FillMode::NONE); + keyframe_model->set_time_offset(base::TimeDelta::FromMilliseconds(-1000)); + + AddKeyframeModelToElementWithAnimation(child->element_id(), timeline(), + std::move(keyframe_model)); + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_NE(GetRenderSurfaceImpl(child), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(grandchild), GetRenderSurfaceImpl(child)); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)->Filters().IsEmpty()); + EXPECT_TRUE(GetRenderSurfaceImpl(child)->Filters().IsEmpty()); + + EXPECT_FALSE(FilterIsAnimating(ImplOf(root))); + EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(root))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(child))); + EXPECT_TRUE(HasPotentiallyRunningFilterAnimation(*ImplOf(child))); + EXPECT_FALSE(FilterIsAnimating(ImplOf(grandchild))); + EXPECT_FALSE(HasPotentiallyRunningFilterAnimation(*ImplOf(grandchild))); +} + +TEST_F(PropertyTreeBuilderTest, ChangingAxisAlignmentTriggersRebuild) { + gfx::Transform translate; + gfx::Transform rotate; + + translate.Translate(10, 10); + rotate.Rotate(45); + + scoped_refptr<Layer> root = Layer::Create(); + root->SetBounds(gfx::Size(800, 800)); + + host()->SetRootLayer(root); + + UpdateMainDrawProperties(); + EXPECT_FALSE(host()->property_trees()->needs_rebuild); + + root->SetTransform(translate); + EXPECT_FALSE(host()->property_trees()->needs_rebuild); + + root->SetTransform(rotate); + EXPECT_TRUE(host()->property_trees()->needs_rebuild); +} + +TEST_F(PropertyTreeBuilderTest, ResetPropertyTreeIndices) { + scoped_refptr<Layer> root = Layer::Create(); + root->SetBounds(gfx::Size(800, 800)); + + gfx::Transform translate_z; + translate_z.Translate3d(0, 0, 10); + + scoped_refptr<Layer> child = Layer::Create(); + child->SetTransform(translate_z); + child->SetBounds(gfx::Size(100, 100)); + + root->AddChild(child); + + host()->SetRootLayer(root); + + UpdateMainDrawProperties(); + EXPECT_NE(-1, child->transform_tree_index()); + + child->RemoveFromParent(); + + UpdateMainDrawProperties(); + EXPECT_EQ(-1, child->transform_tree_index()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceClipsSubtree) { + // Ensure that a Clip Node is added when a render surface applies clip. + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto significant_transform = Layer::Create(); + root->AddChild(significant_transform); + auto layer_clips_subtree = Layer::Create(); + significant_transform->AddChild(layer_clips_subtree); + auto render_surface = Layer::Create(); + layer_clips_subtree->AddChild(render_surface); + auto test_layer = Layer::Create(); + render_surface->AddChild(test_layer); + + // This transform should be a significant one so that a transform node is + // formed for it. + gfx::Transform transform1; + transform1.RotateAboutYAxis(45); + transform1.RotateAboutXAxis(30); + // This transform should be a 3d transform as we want the render surface + // to flatten the transform + gfx::Transform transform2; + transform2.Translate3d(10, 10, 10); + + root->SetBounds(gfx::Size(30, 30)); + significant_transform->SetTransform(transform1); + significant_transform->SetBounds(gfx::Size(30, 30)); + layer_clips_subtree->SetBounds(gfx::Size(30, 30)); + layer_clips_subtree->SetMasksToBounds(true); + layer_clips_subtree->SetForceRenderSurfaceForTesting(true); + render_surface->SetTransform(transform2); + render_surface->SetBounds(gfx::Size(30, 30)); + render_surface->SetForceRenderSurfaceForTesting(true); + test_layer->SetBounds(gfx::Size(30, 30)); + test_layer->SetIsDrawable(true); + + CommitAndActivate(); + + EXPECT_TRUE(GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(significant_transform), + GetRenderSurfaceImpl(root)); + EXPECT_TRUE(GetRenderSurfaceImpl(layer_clips_subtree)); + EXPECT_NE(GetRenderSurfaceImpl(render_surface), GetRenderSurfaceImpl(root)); + EXPECT_EQ(GetRenderSurfaceImpl(test_layer), + GetRenderSurfaceImpl(render_surface)); + + EXPECT_EQ(gfx::Rect(30, 20), ImplOf(test_layer)->visible_layer_rect()); +} + +TEST_F(PropertyTreeBuilderTest, PropertyTreesRebuildWithOpacityChanges) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> child = Layer::Create(); + child->SetIsDrawable(true); + root->AddChild(child); + host()->SetRootLayer(root); + + root->SetBounds(gfx::Size(100, 100)); + child->SetBounds(gfx::Size(20, 20)); + UpdateMainDrawProperties(); + + // Changing the opacity from 1 to non-1 value should trigger rebuild of + // property trees as a new effect node will be created. + child->SetOpacity(0.5f); + PropertyTrees* property_trees = host()->property_trees(); + EXPECT_TRUE(property_trees->needs_rebuild); + + UpdateMainDrawProperties(); + EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); + + // child already has an effect node. Changing its opacity shouldn't trigger + // a property trees rebuild. + child->SetOpacity(0.8f); + property_trees = host()->property_trees(); + EXPECT_FALSE(property_trees->needs_rebuild); + + UpdateMainDrawProperties(); + EXPECT_NE(child->effect_tree_index(), root->effect_tree_index()); + + // Changing the opacity from non-1 value to 1 should trigger a rebuild of + // property trees as the effect node may no longer be needed. + child->SetOpacity(1.f); + property_trees = host()->property_trees(); + EXPECT_TRUE(property_trees->needs_rebuild); + + UpdateMainDrawProperties(); + EXPECT_EQ(child->effect_tree_index(), root->effect_tree_index()); +} + +TEST_F(PropertyTreeBuilderTest, RenderSurfaceListForTrilinearFiltering) { + auto root = Layer::Create(); + host()->SetRootLayer(root); + auto parent = Layer::Create(); + root->AddChild(parent); + auto child1 = Layer::Create(); + parent->AddChild(child1); + auto child2 = Layer::Create(); + parent->AddChild(child2); + + gfx::Transform scale_matrix; + scale_matrix.Scale(.25f, .25f); + + root->SetBounds(gfx::Size(200, 200)); + parent->SetTransform(scale_matrix); + parent->SetTrilinearFiltering(true); + child1->SetBounds(gfx::Size(50, 50)); + child1->SetIsDrawable(true); + child1->SetForceRenderSurfaceForTesting(true); + child2->SetPosition(gfx::PointF(50, 50)); + child2->SetBounds(gfx::Size(50, 50)); + child2->SetIsDrawable(true); + child2->SetForceRenderSurfaceForTesting(true); + + CommitAndActivate(); + + ASSERT_TRUE(GetRenderSurfaceImpl(parent)); + EXPECT_EQ(2, GetRenderSurfaceImpl(parent)->num_contributors()); + EXPECT_EQ(4U, GetRenderSurfaceList().size()); + + // The rectangle enclosing child1 and child2 (0,0 100x100), scaled by the + // scale matrix to (0,0 25x25). + EXPECT_EQ(gfx::RectF(0, 0, 25, 25), + GetRenderSurfaceImpl(parent)->DrawableContentRect()); +} + +TEST_F(PropertyTreeBuilderTest, RoundedCornerBounds) { + // Layer Tree: + // +root + // +--render surface + // +----rounded corner layer 1 [should trigger render surface] + // +----layer 1 + // +--rounded corner layer 2 [should trigger render surface] + // +----layer 2 + // +------rounded corner layer 3 [should trigger render surface] + // +--------rounded corner layer 4 [should trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + constexpr int kRoundedCorner3Radius = 1; + constexpr int kRoundedCorner4Radius = 1; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(15.f, 15.f, 20.f, 20.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); + constexpr gfx::RectF kRoundedCornerLayer3Bound(0.f, 15.f, 5.f, 5.f); + constexpr gfx::RectF kRoundedCornerLayer4Bound(1.f, 1.f, 3.f, 3.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> render_surface = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + scoped_refptr<Layer> layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); + + // Set up layer tree + root->AddChild(render_surface); + root->AddChild(rounded_corner_layer_2); + + render_surface->AddChild(rounded_corner_layer_1); + render_surface->AddChild(layer_1); + + rounded_corner_layer_2->AddChild(layer_2); + + layer_2->AddChild(rounded_corner_layer_3); + + rounded_corner_layer_3->AddChild(rounded_corner_layer_4); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + render_surface->SetPosition(gfx::PointF(0, 0)); + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + layer_1->SetPosition(gfx::PointF(10.f, 10.f)); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + layer_2->SetPosition(gfx::PointF(30.f, 30.f)); + rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); + rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + render_surface->SetBounds(gfx::Size(50, 50)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + layer_1->SetBounds(gfx::Size(10, 10)); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + layer_2->SetBounds(gfx::Size(25, 25)); + rounded_corner_layer_3->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); + rounded_corner_layer_4->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); + + // Add Layer transforms. + gfx::Transform layer_2_transform; + constexpr gfx::Vector2dF kLayer2Translation(10.f, 10.f); + layer_2_transform.Translate(kLayer2Translation); + layer_2->SetTransform(layer_2_transform); + + gfx::Transform rounded_corner_layer_3_transform; + constexpr float kRoundedCorner3Scale = 2.f; + rounded_corner_layer_3_transform.Scale(kRoundedCorner3Scale, + kRoundedCorner3Scale); + rounded_corner_layer_3->SetTransform(rounded_corner_layer_3_transform); + + // Set the layer properties + render_surface->SetForceRenderSurfaceForTesting(true); + + root->SetIsDrawable(true); + render_surface->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + layer_2->SetIsDrawable(true); + rounded_corner_layer_3->SetIsDrawable(true); + rounded_corner_layer_4->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + rounded_corner_layer_3->SetRoundedCorner( + {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, + kRoundedCorner3Radius}); + rounded_corner_layer_4->SetRoundedCorner( + {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, + kRoundedCorner4Radius}); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this effect node has no descendants that draw and no descendant that + // has a rounded corner, it does not need a render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this node has descendants with roudned corners, it needs a render + // surface. It also has 2 descendants that draw. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + // Since this node has a descendant that has a rounded corner, it will trigger + // the creation of a render surface. + effect_node = GetEffectNode(rounded_corner_layer_3.get()); + gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), + kRoundedCorner3Radius); + EXPECT_EQ(rounded_corner_bounds_3.rect(), + gfx::RectF(kRoundedCornerLayer3Bound.size())); + + // Since this node has no descendants that draw nor any descendant that has a + // rounded corner, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_4.get()); + gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), + kRoundedCorner4Radius); + EXPECT_EQ(rounded_corner_bounds_4.rect(), + gfx::RectF(kRoundedCornerLayer4Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_1_impl = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_2_impl = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + LayerImpl* rounded_corner_layer_3_impl = + layer_tree_impl->LayerById(rounded_corner_layer_3->id()); + LayerImpl* rounded_corner_layer_4_impl = + layer_tree_impl->LayerById(rounded_corner_layer_4->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1 + // The render target for this layer is |render_surface|, hence its target + // bounds are relative to |render_surface|. + // The offset from the origin of the render target is [15, 15] and the device + // scale factor is 1.6 thus giving the target space origin of [24, 24]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_rrect_1 = + rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 2 + // The render target for this layer is |root|. + // The offset from the origin of the render target is [40, 40] and the device + // scale factor is 1.6 thus giving the target space origin of [64, 64]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_2 = + rounded_corner_layer_2_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Rounded corner layer 3 + // The render target for this layer is |rounded_corner_2|. + // The net offset from the origin of the render target is [40, 55] and the + // device scale factor is 1.6 thus giving the target space origin of [64, 88]. + // The corner radius is also scaled by a factor of 1.6 * transform scale. + const gfx::RRectF actual_self_rrect_3 = + rounded_corner_layer_3_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer3Bound; + bounds_in_target_space += + layer_2->position().OffsetFromOrigin() + kLayer2Translation; + bounds_in_target_space.Scale(kDeviceScale); + gfx::SizeF transformed_size = bounds_in_target_space.size(); + transformed_size.Scale(kRoundedCorner3Scale); + bounds_in_target_space.set_size(transformed_size); + + const gfx::RRectF actual_render_target_rrect_3 = + rounded_corner_layer_3_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), + kRoundedCorner3Radius * kDeviceScale * kRoundedCorner3Scale); + + // Rounded corner layer 4 + // The render target for this layer is |rounded_corner_3|. + // The net offset from the origin of the render target is [1, 1] and the + // net scale is 1.6 * transform scale = 3.2 thus giving the target space o + // rigin of [3.2, 3.2]. + // The corner radius is also scaled by a factor of 3.2. + const gfx::RRectF actual_rrect_4 = + rounded_corner_layer_4_impl->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer4Bound; + bounds_in_target_space.Scale(kDeviceScale * kRoundedCorner3Scale); + EXPECT_EQ(actual_rrect_4.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_4.GetSimpleRadius(), + kRoundedCorner4Radius * kDeviceScale * kRoundedCorner3Scale); +} + +TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsInterveningRenderTarget) { + // Layer Tree: + // +root + // +--rounded corner layer 1 [should not trigger render surface] + // +----render surface [Does not draw] + // +------rounded corner layer 2 [should not trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(60.f, 0.f, 40.f, 30.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 30.f, 20.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> render_surface = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + + // Set up layer tree + root->AddChild(rounded_corner_layer_1); + rounded_corner_layer_1->AddChild(render_surface); + render_surface->AddChild(rounded_corner_layer_2); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + render_surface->SetPosition(gfx::PointF(0, 0)); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + render_surface->SetBounds(gfx::Size(30, 30)); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + + // Set the layer properties + render_surface->SetForceRenderSurfaceForTesting(true); + + root->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this effect node has only 1 descendant that draws and no descendant + // that has a rounded corner before the render surface, it does not need a + // render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this effect node has no descendants that draw and no descendant that + // has a rounded corner, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_1_impl = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_2_impl = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1 + // The render target for this layer is |root|, hence its target + // bounds are relative to |root|. + // The offset from the origin of the render target is [60, 0] and the device + // scale factor is 1.6 thus giving the target space origin of [96, 0]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_rrect_1 = + rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 2 + // The render target for this layer is |render_surface|. + // The offset from the origin of the render target is [0, 0]. + const gfx::RRectF actual_rrect_2 = + rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); +} + +TEST_F(PropertyTreeBuilderTest, RoundedCornerBoundsSiblingRenderTarget) { + // Layer Tree: + // +root + // +--rounded corner layer 1 [should trigger render surface] + // +----render surface [Does not draw] + // +----rounded corner layer 2 [should not trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 60.f, 30.f, 40.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 20.f, 30.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> render_surface = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + + // Set up layer tree + root->AddChild(rounded_corner_layer_1); + rounded_corner_layer_1->AddChild(render_surface); + rounded_corner_layer_1->AddChild(rounded_corner_layer_2); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + render_surface->SetPosition(gfx::PointF(0, 0)); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + render_surface->SetBounds(gfx::Size(30, 30)); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + + // Set the layer properties + render_surface->SetForceRenderSurfaceForTesting(true); + + root->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this effect node has 1 descendant with a rounded corner without a + // render surface along the chain, it need a render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this effect node has no descendants that draw and no descendant that + // has a rounded corner, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_1_impl = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_2_impl = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1 + // The render target for this layer is |root|, hence its target + // bounds are relative to |root|. + // The offset from the origin of the render target is [0, 60] and the device + // scale factor is 1.6 thus giving the target space origin of [0, 96]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_1 = + rounded_corner_layer_1_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); + + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_1 = + rounded_corner_layer_1_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 2 + // The render target for this layer is |render_surface|. + // The offset from the origin of the render target is [0, 0]. + const gfx::RRectF actual_rrect_2 = + rounded_corner_layer_2_impl->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); +} + +TEST_F(PropertyTreeBuilderTest, FastRoundedCornerDoesNotTriggerRenderSurface) { + // Layer Tree: + // +root + // +--fast rounded corner layer [should not trigger render surface] + // +----layer 1 + // +----layer 2 + // +--rounded corner layer [should trigger render surface] + // +----layer 3 + // +----layer 4 + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(0.f, 0.f, 50.f, 50.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(40.f, 40.f, 60.f, 60.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> fast_rounded_corner_layer = Layer::Create(); + scoped_refptr<Layer> layer_1 = Layer::Create(); + scoped_refptr<Layer> layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer = Layer::Create(); + scoped_refptr<Layer> layer_3 = Layer::Create(); + scoped_refptr<Layer> layer_4 = Layer::Create(); + + // Set up layer tree + root->AddChild(fast_rounded_corner_layer); + root->AddChild(rounded_corner_layer); + + fast_rounded_corner_layer->AddChild(layer_1); + fast_rounded_corner_layer->AddChild(layer_2); + + rounded_corner_layer->AddChild(layer_3); + rounded_corner_layer->AddChild(layer_4); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + fast_rounded_corner_layer->SetPosition(kRoundedCornerLayer1Bound.origin()); + layer_1->SetPosition(gfx::PointF(0.f, 0.f)); + layer_2->SetPosition(gfx::PointF(25.f, 0.f)); + rounded_corner_layer->SetPosition(kRoundedCornerLayer2Bound.origin()); + layer_3->SetPosition(gfx::PointF(0.f, 0.f)); + layer_4->SetPosition(gfx::PointF(30.f, 0.f)); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + fast_rounded_corner_layer->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + layer_1->SetBounds(gfx::Size(25, 25)); + layer_2->SetBounds(gfx::Size(25, 25)); + rounded_corner_layer->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + layer_3->SetBounds(gfx::Size(30, 60)); + layer_4->SetBounds(gfx::Size(30, 60)); + + root->SetIsDrawable(true); + fast_rounded_corner_layer->SetIsDrawable(true); + layer_1->SetIsDrawable(true); + layer_2->SetIsDrawable(true); + rounded_corner_layer->SetIsDrawable(true); + layer_3->SetIsDrawable(true); + layer_4->SetIsDrawable(true); + + // Set Rounded corners + fast_rounded_corner_layer->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + + fast_rounded_corner_layer->SetIsFastRoundedCorner(true); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this layer has a fast rounded corner, it should not have a render + // surface even though it has 2 layers in the subtree that draws content. + const EffectNode* effect_node = + GetEffectNode(fast_rounded_corner_layer.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this node has 2 descendants that draw, it will have a rounded corner. + effect_node = GetEffectNode(rounded_corner_layer.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* fast_rounded_corner_layer_impl = + layer_tree_impl->LayerById(fast_rounded_corner_layer->id()); + LayerImpl* layer_1_impl = layer_tree_impl->LayerById(layer_1->id()); + LayerImpl* layer_2_impl = layer_tree_impl->LayerById(layer_2->id()); + LayerImpl* rounded_corner_layer_impl = + layer_tree_impl->LayerById(rounded_corner_layer->id()); + LayerImpl* layer_3_impl = layer_tree_impl->LayerById(layer_3->id()); + LayerImpl* layer_4_impl = layer_tree_impl->LayerById(layer_4->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Fast rounded corner layer. + // The render target for this layer is |root|, hence its target bounds are + // relative to |root|. + // The offset from the origin of the render target is [0, 0] and the device + // scale factor is 1.6. + const gfx::RRectF actual_rrect_1 = + fast_rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Layer 1 and layer 2 rounded corner bounds + // This should have the same rounded corner boudns as fast rounded corner + // layer. + const gfx::RRectF layer_1_rrect = + layer_1_impl->draw_properties().rounded_corner_bounds; + const gfx::RRectF layer_2_rrect = + layer_2_impl->draw_properties().rounded_corner_bounds; + EXPECT_EQ(actual_rrect_1, layer_1_rrect); + EXPECT_EQ(actual_rrect_1, layer_2_rrect); + + // Rounded corner layer + // The render target for this layer is |root|. + // The offset from the origin of the render target is [40, 40] and the device + // scale factor is 1.6 thus giving the target space origin of [64, 64]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + rounded_corner_layer_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_2.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_2 = + rounded_corner_layer_impl->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Layer 3 and layer 4 should have no rounded corner bounds set as their + // parent is a render surface. + const gfx::RRectF layer_3_rrect = + layer_3_impl->draw_properties().rounded_corner_bounds; + const gfx::RRectF layer_4_rrect = + layer_4_impl->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(layer_3_rrect.IsEmpty()); + EXPECT_TRUE(layer_4_rrect.IsEmpty()); +} + +TEST_F(PropertyTreeBuilderTest, + FastRoundedCornerTriggersRenderSurfaceInAncestor) { + // Layer Tree: + // +root + // +--rounded corner layer [1] [should trigger render surface] + // +----fast rounded corner layer [2] [should not trigger render surface] + // +--rounded corner layer [3] [should trigger render surface] + // +----rounded corner layer [4] [should not trigger render surface] + + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + constexpr int kRoundedCorner3Radius = 1; + constexpr int kRoundedCorner4Radius = 3; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(5.f, 5.f, 50.f, 50.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(0.f, 0.f, 25.f, 25.f); + constexpr gfx::RectF kRoundedCornerLayer3Bound(40.f, 40.f, 60.f, 60.f); + constexpr gfx::RectF kRoundedCornerLayer4Bound(30.f, 0.f, 30.f, 60.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> fast_rounded_corner_layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_4 = Layer::Create(); + + // Set up layer tree + root->AddChild(rounded_corner_layer_1); + root->AddChild(rounded_corner_layer_3); + + rounded_corner_layer_1->AddChild(fast_rounded_corner_layer_2); + + rounded_corner_layer_3->AddChild(rounded_corner_layer_4); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + fast_rounded_corner_layer_2->SetPosition(kRoundedCornerLayer2Bound.origin()); + rounded_corner_layer_3->SetPosition(kRoundedCornerLayer3Bound.origin()); + rounded_corner_layer_4->SetPosition(kRoundedCornerLayer4Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + fast_rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + rounded_corner_layer_3->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); + rounded_corner_layer_4->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); + + root->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + fast_rounded_corner_layer_2->SetIsDrawable(true); + rounded_corner_layer_3->SetIsDrawable(true); + rounded_corner_layer_4->SetIsDrawable(true); + + // Set Rounded corners + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + fast_rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + rounded_corner_layer_3->SetRoundedCorner( + {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, + kRoundedCorner3Radius}); + rounded_corner_layer_4->SetRoundedCorner( + {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, + kRoundedCorner4Radius}); + + fast_rounded_corner_layer_2->SetIsFastRoundedCorner(true); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this layer has a descendant that has rounded corner, this node will + // require a render surface. + const EffectNode* effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this layer has no descendant with rounded corner or drawable, it will + // not have a render surface. + effect_node = GetEffectNode(fast_rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + // Since this layer has 1 descendant with a rounded corner, it should have a + // render surface. + effect_node = GetEffectNode(rounded_corner_layer_3.get()); + gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), + kRoundedCorner3Radius); + EXPECT_EQ(rounded_corner_bounds_3.rect(), + gfx::RectF(kRoundedCornerLayer3Bound.size())); + + // Since this layer no descendants, it would no thave a render pass. + effect_node = GetEffectNode(rounded_corner_layer_4.get()); + gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), + kRoundedCorner4Radius); + EXPECT_EQ(rounded_corner_bounds_4.rect(), + gfx::RectF(kRoundedCornerLayer4Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* rounded_corner_layer_impl_1 = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* fast_rounded_corner_layer_impl_2 = + layer_tree_impl->LayerById(fast_rounded_corner_layer_2->id()); + LayerImpl* rounded_corner_layer_impl_3 = + layer_tree_impl->LayerById(rounded_corner_layer_3->id()); + LayerImpl* rounded_corner_layer_impl_4 = + layer_tree_impl->LayerById(rounded_corner_layer_4->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Rounded corner layer 1. + // The render target for this layer is |root|, hence its target bounds are + // relative to |root|. + // The offset from the origin of the render target is [5, 5] and the device + // scale factor is 1.6 giving a total offset of [8, 8]. + const gfx::RRectF actual_self_rrect_1 = + rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); + + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_1 = + rounded_corner_layer_impl_1->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Fast rounded corner layer 2 + // The render target for this layer is |rounded_corner_layer_1|. + // The offset from the origin of the render target is [0, 0] and the device + // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + fast_rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Rounded corner layer 3 + // The render target for this layer is |root|. + // The offset from the origin of the render target is [40, 40] and the device + // scale factor is 1.6 thus giving the target space origin of [64, 64]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_3 = + rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer3Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_3 = + rounded_corner_layer_impl_3->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), + kRoundedCorner3Radius * kDeviceScale); + + // Rounded corner layer 4 + // The render target for this layer is |rounded_corner_layer_3|. + // The offset from the origin of the render target is [30, 0] and the device + // scale factor is 1.6 thus giving the target space origin of [48, 0]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_4 = + rounded_corner_layer_impl_4->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer4Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), + kRoundedCorner4Radius * kDeviceScale); +} + +TEST_F(PropertyTreeBuilderTest, + FastRoundedCornerDoesNotTriggerRenderSurfaceFromSubtree) { + // Layer Tree: + // +root + // +--fast rounded corner layer 1 [should trigger render surface] + // +----rounded corner layer 1 [should not trigger render surface] + // +--rounded corner layer 2 [should trigger render surface] + // +----rounded corner layer 3 [should not trigger render surface] + constexpr int kRoundedCorner1Radius = 2; + constexpr int kRoundedCorner2Radius = 5; + constexpr int kRoundedCorner3Radius = 4; + constexpr int kRoundedCorner4Radius = 5; + + constexpr gfx::RectF kRoundedCornerLayer1Bound(10.f, 5.f, 45.f, 50.f); + constexpr gfx::RectF kRoundedCornerLayer2Bound(5.f, 5.f, 20.f, 20.f); + constexpr gfx::RectF kRoundedCornerLayer3Bound(60.f, 5.f, 40.f, 25.f); + constexpr gfx::RectF kRoundedCornerLayer4Bound(0.f, 10.f, 10.f, 20.f); + + constexpr float kDeviceScale = 1.6f; + + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> fast_rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_1 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_2 = Layer::Create(); + scoped_refptr<Layer> rounded_corner_layer_3 = Layer::Create(); + + // Set up layer tree + root->AddChild(fast_rounded_corner_layer_1); + root->AddChild(rounded_corner_layer_2); + + fast_rounded_corner_layer_1->AddChild(rounded_corner_layer_1); + rounded_corner_layer_2->AddChild(rounded_corner_layer_3); + + // Set the root layer on host. + host()->SetRootLayer(root); + + // Set layer positions. + fast_rounded_corner_layer_1->SetPosition(kRoundedCornerLayer1Bound.origin()); + rounded_corner_layer_1->SetPosition(kRoundedCornerLayer2Bound.origin()); + rounded_corner_layer_2->SetPosition(kRoundedCornerLayer3Bound.origin()); + rounded_corner_layer_3->SetPosition(kRoundedCornerLayer4Bound.origin()); + + // Set up layer bounds. + root->SetBounds(gfx::Size(100, 100)); + fast_rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer1Bound.size())); + rounded_corner_layer_1->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer2Bound.size())); + rounded_corner_layer_2->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer3Bound.size())); + rounded_corner_layer_3->SetBounds( + gfx::ToRoundedSize(kRoundedCornerLayer4Bound.size())); + + root->SetIsDrawable(true); + fast_rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_1->SetIsDrawable(true); + rounded_corner_layer_2->SetIsDrawable(true); + rounded_corner_layer_3->SetIsDrawable(true); + + // Set Rounded corners + fast_rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner1Radius, kRoundedCorner1Radius, kRoundedCorner1Radius, + kRoundedCorner1Radius}); + rounded_corner_layer_1->SetRoundedCorner( + {kRoundedCorner2Radius, kRoundedCorner2Radius, kRoundedCorner2Radius, + kRoundedCorner2Radius}); + rounded_corner_layer_2->SetRoundedCorner( + {kRoundedCorner3Radius, kRoundedCorner3Radius, kRoundedCorner3Radius, + kRoundedCorner3Radius}); + rounded_corner_layer_3->SetRoundedCorner( + {kRoundedCorner4Radius, kRoundedCorner4Radius, kRoundedCorner4Radius, + kRoundedCorner4Radius}); + + fast_rounded_corner_layer_1->SetIsFastRoundedCorner(true); + + UpdateMainDrawProperties(kDeviceScale); + + // Since this layer has a descendant with rounded corner, it needs a render + // surface. + const EffectNode* effect_node = + GetEffectNode(fast_rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_1 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_TRUE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_1.GetSimpleRadius(), + kRoundedCorner1Radius); + EXPECT_EQ(rounded_corner_bounds_1.rect(), + gfx::RectF(kRoundedCornerLayer1Bound.size())); + + // Since this layer has no descendant with rounded corner or drawable, it will + // not have a render surface. + effect_node = GetEffectNode(rounded_corner_layer_1.get()); + gfx::RRectF rounded_corner_bounds_2 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_2.GetSimpleRadius(), + kRoundedCorner2Radius); + EXPECT_EQ(rounded_corner_bounds_2.rect(), + gfx::RectF(kRoundedCornerLayer2Bound.size())); + + // Since this layer has a descendant with rounded corner, it should have a + // render surface. + effect_node = GetEffectNode(rounded_corner_layer_2.get()); + gfx::RRectF rounded_corner_bounds_3 = effect_node->rounded_corner_bounds; + EXPECT_TRUE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_3.GetSimpleRadius(), + kRoundedCorner3Radius); + EXPECT_EQ(rounded_corner_bounds_3.rect(), + gfx::RectF(kRoundedCornerLayer3Bound.size())); + + // Since this layer has no descendant, it does not need a render surface. + effect_node = GetEffectNode(rounded_corner_layer_3.get()); + gfx::RRectF rounded_corner_bounds_4 = effect_node->rounded_corner_bounds; + EXPECT_FALSE(effect_node->HasRenderSurface()); + EXPECT_FALSE(effect_node->is_fast_rounded_corner); + EXPECT_FLOAT_EQ(rounded_corner_bounds_4.GetSimpleRadius(), + kRoundedCorner4Radius); + EXPECT_EQ(rounded_corner_bounds_4.rect(), + gfx::RectF(kRoundedCornerLayer4Bound.size())); + + CommitAndActivate(kDeviceScale); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + // Get the layer impl for each Layer. + LayerImpl* fast_rounded_corner_layer_impl_1 = + layer_tree_impl->LayerById(fast_rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_impl_1 = + layer_tree_impl->LayerById(rounded_corner_layer_1->id()); + LayerImpl* rounded_corner_layer_impl_2 = + layer_tree_impl->LayerById(rounded_corner_layer_2->id()); + LayerImpl* rounded_corner_layer_impl_3 = + layer_tree_impl->LayerById(rounded_corner_layer_3->id()); + + EXPECT_EQ(kDeviceScale, layer_tree_impl->device_scale_factor()); + + // Fast rounded corner layer 1. + // The render target for this layer is |root|, hence its target bounds are + // relative to |root|. + // The offset from the origin of the render target is [5, 5] and the device + // scale factor is 1.6. + const gfx::RRectF actual_self_rrect_1 = + fast_rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_1.IsEmpty()); + + gfx::RectF bounds_in_target_space = kRoundedCornerLayer1Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_1 = + fast_rounded_corner_layer_impl_1->render_target() + ->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_1.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_1.GetSimpleRadius(), + kRoundedCorner1Radius * kDeviceScale); + + // Rounded corner layer 1 + // The render target for this layer is |fast_rounded_corner_layer_1|. + // The offset from the origin of the render target is [0, 0] and the device + // scale factor is 1.6. The corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_2 = + rounded_corner_layer_impl_1->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer2Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_2.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_2.GetSimpleRadius(), + kRoundedCorner2Radius * kDeviceScale); + + // Rounded corner layer 3 + // The render target for this layer is |root|. + // The offset from the origin of the render target is [5, 5] and the device + // scale factor is 1.6 thus giving the target space origin of [8, 8]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_3 = + rounded_corner_layer_impl_2->draw_properties().rounded_corner_bounds; + EXPECT_TRUE(actual_self_rrect_3.IsEmpty()); + + bounds_in_target_space = kRoundedCornerLayer3Bound; + bounds_in_target_space.Scale(kDeviceScale); + const gfx::RRectF actual_render_target_rrect_3 = + rounded_corner_layer_impl_2->render_target()->rounded_corner_bounds(); + EXPECT_EQ(actual_render_target_rrect_3.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_render_target_rrect_3.GetSimpleRadius(), + kRoundedCorner3Radius * kDeviceScale); + + // Rounded corner layer 4 + // The render target for this layer is |rounded_corner_layer_2|. + // The offset from the origin of the render target is [0, 5] and the device + // scale factor is 1.6 thus giving the target space origin of [0, 8]. The + // corner radius is also scaled by a factor of 1.6. + const gfx::RRectF actual_self_rrect_4 = + rounded_corner_layer_impl_3->draw_properties().rounded_corner_bounds; + bounds_in_target_space = kRoundedCornerLayer4Bound; + bounds_in_target_space.Scale(kDeviceScale); + EXPECT_EQ(actual_self_rrect_4.rect(), bounds_in_target_space); + EXPECT_FLOAT_EQ(actual_self_rrect_4.GetSimpleRadius(), + kRoundedCorner4Radius * kDeviceScale); +} + +} // namespace +} // namespace cc diff --git a/chromium/cc/trees/proxy_common.cc b/chromium/cc/trees/proxy_common.cc index f80fd3553fb..a04796a3aa0 100644 --- a/chromium/cc/trees/proxy_common.cc +++ b/chromium/cc/trees/proxy_common.cc @@ -5,6 +5,7 @@ #include "cc/trees/proxy_common.h" #include "cc/trees/layer_tree_host.h" +#include "cc/trees/scroll_and_scale_set.h" namespace cc { diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h index e4de8308fa4..3d363b26a8a 100644 --- a/chromium/cc/trees/proxy_common.h +++ b/chromium/cc/trees/proxy_common.h @@ -9,11 +9,12 @@ #include "base/callback_forward.h" #include "cc/cc_export.h" -#include "cc/trees/layer_tree_host_common.h" #include "components/viz/common/frame_sinks/begin_frame_args.h" namespace cc { +struct ScrollAndScaleSet; + struct CC_EXPORT BeginMainFrameAndCommitState { BeginMainFrameAndCommitState(); ~BeginMainFrameAndCommitState(); diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index ed8eb19667d..a43c4b40b7d 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -24,12 +24,13 @@ #include "cc/trees/mutator_host.h" #include "cc/trees/proxy_main.h" #include "cc/trees/render_frame_metadata_observer.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/task_runner_provider.h" #include "components/viz/common/frame_sinks/delay_based_time_source.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/gpu/context_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" #include "services/metrics/public/cpp/ukm_recorder.h" -#include "ui/gfx/presentation_feedback.h" namespace cc { @@ -378,6 +379,10 @@ size_t ProxyImpl::MainThreadAnimationsCount() const { return host_impl_->mutator_host()->MainThreadAnimationsCount(); } +bool ProxyImpl::HasCustomPropertyAnimations() const { + return host_impl_->mutator_host()->HasCustomPropertyAnimations(); +} + bool ProxyImpl::CurrentFrameHadRAF() const { return host_impl_->mutator_host()->CurrentFrameHadRAF(); } @@ -500,13 +505,14 @@ void ProxyImpl::NotifyImageDecodeRequestFinished() { void ProxyImpl::DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) { + const viz::FrameTimingDetails& details) { MainThreadTaskRunner()->PostTask( - FROM_HERE, base::BindOnce(&ProxyMain::DidPresentCompositorFrame, - proxy_main_weak_ptr_, frame_token, - std::move(callbacks), feedback)); + FROM_HERE, + base::BindOnce(&ProxyMain::DidPresentCompositorFrame, + proxy_main_weak_ptr_, frame_token, std::move(callbacks), + details.presentation_feedback)); if (scheduler_) - scheduler_->DidPresentCompositorFrame(frame_token, feedback.timestamp); + scheduler_->DidPresentCompositorFrame(frame_token, details); } void ProxyImpl::NotifyAnimationWorkletStateChange( diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h index d8222df2013..b245b60c0f5 100644 --- a/chromium/cc/trees/proxy_impl.h +++ b/chromium/cc/trees/proxy_impl.h @@ -14,6 +14,10 @@ #include "cc/scheduler/scheduler.h" #include "cc/trees/layer_tree_host_impl.h" +namespace viz { +struct FrameTimingDetails; +} + namespace cc { class LayerTreeHost; class ProxyMain; @@ -109,7 +113,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) override; + const viz::FrameTimingDetails& details) override; void NotifyAnimationWorkletStateChange( AnimationWorkletMutationState state, ElementListType element_list_type) override; @@ -137,6 +141,7 @@ class CC_EXPORT ProxyImpl : public LayerTreeHostImplClient, void FrameIntervalUpdated(base::TimeDelta interval) override {} size_t CompositedAnimationsCount() const override; size_t MainThreadAnimationsCount() const override; + bool HasCustomPropertyAnimations() const override; bool CurrentFrameHadRAF() const override; bool NextFrameHasPendingRAF() const override; diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index 7e9e5b66b2f..f5b1875c8b0 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -132,6 +132,10 @@ void ProxyMain::BeginMainFrame( benchmark_instrumentation::kDoBeginFrame, begin_main_frame_state->begin_frame_id); + // This needs to run unconditionally, so do it before any early-returns. + if (layer_tree_host_->scheduling_client()) + layer_tree_host_->scheduling_client()->DidRunBeginMainFrame(); + // If the commit finishes, LayerTreeHost will transfer its swap promises to // LayerTreeImpl. The destructor of ScopedSwapPromiseChecker aborts the // remaining swap promises. @@ -217,6 +221,13 @@ void ProxyMain::BeginMainFrame( } layer_tree_host_->WillBeginMainFrame(); + + // This call winds through to the LocalFrameView to mark the beginning + // of a main frame for metrics purposes. Some metrics are only gathered + // between calls to RecordStartOfFrameMetrics and RecordEndOfFrameMetrics. + // This is not wrapped into layer_tree_host_->WillBeginMainFrame because + // it should only be called from the multi-threaded proxy (we do not want + // metrics gathering in tests). layer_tree_host_->RecordStartOfFrameMetrics(); // See LayerTreeHostClient::BeginMainFrame for more documentation on @@ -236,7 +247,7 @@ void ProxyMain::BeginMainFrame( // See LayerTreeHostClient::MainFrameUpdate for more documentation on // what this does. - layer_tree_host_->RequestMainFrameUpdate(); + layer_tree_host_->RequestMainFrameUpdate(true /* report_cc_metrics */); // At this point the main frame may have deferred main frame updates to // avoid committing right now, or we may be deferring commits but not @@ -313,16 +324,6 @@ void ProxyMain::BeginMainFrame( return; } - // Queue the LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT swap promise only - // once we know we will commit since QueueSwapPromise itself requests a - // commit. - ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME); - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_RENDERER_MAIN_COMPONENT, - begin_main_frame_state->begin_frame_args.frame_time); - layer_tree_host_->QueueSwapPromise( - std::make_unique<LatencyInfoSwapPromise>(new_latency_info)); - current_pipeline_stage_ = NO_PIPELINE_STAGE; // Notify the impl thread that the main thread is ready to commit. This will diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h index 515f1e10de9..cfef4ce6031 100644 --- a/chromium/cc/trees/proxy_main.h +++ b/chromium/cc/trees/proxy_main.h @@ -7,6 +7,7 @@ #include "cc/cc_export.h" #include "cc/input/browser_controls_state.h" +#include "cc/trees/layer_tree_host.h" #include "cc/trees/proxy.h" #include "cc/trees/proxy_common.h" diff --git a/chromium/cc/trees/scroll_and_scale_set.cc b/chromium/cc/trees/scroll_and_scale_set.cc new file mode 100644 index 00000000000..e2d08c839c1 --- /dev/null +++ b/chromium/cc/trees/scroll_and_scale_set.cc @@ -0,0 +1,22 @@ +// Copyright 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "cc/trees/scroll_and_scale_set.h" + +#include "cc/trees/swap_promise.h" + +namespace cc { + +ScrollAndScaleSet::ScrollAndScaleSet() + : page_scale_delta(1.f), + is_pinch_gesture_active(false), + top_controls_delta(0.f), + browser_controls_constraint(BrowserControlsState::kBoth), + browser_controls_constraint_changed(false), + scroll_gesture_did_end(false), + manipulation_info(kManipulationInfoNone) {} + +ScrollAndScaleSet::~ScrollAndScaleSet() = default; + +} // namespace cc diff --git a/chromium/cc/trees/scroll_and_scale_set.h b/chromium/cc/trees/scroll_and_scale_set.h new file mode 100644 index 00000000000..41687918fb2 --- /dev/null +++ b/chromium/cc/trees/scroll_and_scale_set.h @@ -0,0 +1,93 @@ +// Copyright 2011 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CC_TREES_SCROLL_AND_SCALE_SET_H_ +#define CC_TREES_SCROLL_AND_SCALE_SET_H_ + +#include <vector> + +#include "cc/cc_export.h" +#include "cc/input/browser_controls_state.h" +#include "cc/paint/element_id.h" +#include "cc/trees/layer_tree_host_client.h" +#include "ui/gfx/geometry/scroll_offset.h" +#include "ui/gfx/geometry/vector2d.h" +#include "ui/gfx/transform.h" + +namespace cc { + +class SwapPromise; + +struct CC_EXPORT ScrollAndScaleSet { + ScrollAndScaleSet(); + ScrollAndScaleSet(const ScrollAndScaleSet&) = delete; + ~ScrollAndScaleSet(); + + ScrollAndScaleSet& operator=(const ScrollAndScaleSet&) = delete; + + struct CC_EXPORT ScrollUpdateInfo { + ElementId element_id; + gfx::ScrollOffset scroll_delta; + + bool operator==(const ScrollUpdateInfo& other) const { + return element_id == other.element_id && + scroll_delta == other.scroll_delta; + } + }; + + // The inner viewport scroll delta is kept separate since it's special. + // Because the inner (visual) viewport's maximum offset depends on the + // current page scale, the two must be committed at the same time to prevent + // clamping. + ScrollUpdateInfo inner_viewport_scroll; + + std::vector<ScrollUpdateInfo> scrolls; + float page_scale_delta; + bool is_pinch_gesture_active; + + // Elastic overscroll effect offset delta. This is used only on Mac and shows + // the pixels that the page is rubber-banned/stretched by. + gfx::Vector2dF elastic_overscroll_delta; + + // Unconsumed scroll delta used to send overscroll events to the latched + // element on the main thread; + gfx::Vector2dF overscroll_delta; + + // The element id of the node to which scrolling is latched. This is used to + // send overscroll/scrollend DOM events to proper targets whenever needed. + ElementId scroll_latched_element_id; + + float top_controls_delta; + + // Used to communicate scrollbar visibility from Impl thread to Blink. + // Scrollbar input is handled by Blink but the compositor thread animates + // opacity on scrollbars to fade them out when they're overlay. Blink needs + // to be told when they're faded out so it can stop handling input for + // invisible scrollbars. + struct CC_EXPORT ScrollbarsUpdateInfo { + ElementId element_id; + bool hidden = true; + + bool operator==(const ScrollbarsUpdateInfo& other) const { + return element_id == other.element_id && hidden == other.hidden; + } + }; + std::vector<ScrollbarsUpdateInfo> scrollbars; + + std::vector<std::unique_ptr<SwapPromise>> swap_promises; + BrowserControlsState browser_controls_constraint; + bool browser_controls_constraint_changed; + + // Set to true when a scroll gesture being handled on the compositor has + // ended. + bool scroll_gesture_did_end; + + // Tracks different methods of scrolling (e.g. wheel, touch, precision + // touchpad, etc.). + ManipulationInfo manipulation_info; +}; + +} // namespace cc + +#endif // CC_TREES_SCROLL_AND_SCALE_SET_H_ diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index 962b023a9a2..64cf02bdbf2 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -19,15 +19,15 @@ #include "cc/trees/latency_info_swap_promise.h" #include "cc/trees/layer_tree_frame_sink.h" #include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_single_thread_client.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/mutator_host.h" #include "cc/trees/render_frame_metadata_observer.h" #include "cc/trees/scoped_abort_remaining_swap_promises.h" +#include "cc/trees/scroll_and_scale_set.h" #include "components/viz/common/frame_sinks/delay_based_time_source.h" +#include "components/viz/common/frame_timing_details.h" #include "components/viz/common/gpu/context_provider.h" -#include "ui/gfx/presentation_feedback.h" namespace cc { @@ -427,6 +427,10 @@ size_t SingleThreadProxy::MainThreadAnimationsCount() const { return 0; } +bool SingleThreadProxy::HasCustomPropertyAnimations() const { + return false; +} + bool SingleThreadProxy::CurrentFrameHadRAF() const { return false; } @@ -529,13 +533,12 @@ void SingleThreadProxy::NotifyImageDecodeRequestFinished() { void SingleThreadProxy::DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) { + const viz::FrameTimingDetails& details) { layer_tree_host_->DidPresentCompositorFrame(frame_token, std::move(callbacks), - feedback); + details.presentation_feedback); if (scheduler_on_impl_thread_) { - scheduler_on_impl_thread_->DidPresentCompositorFrame(frame_token, - feedback.timestamp); + scheduler_on_impl_thread_->DidPresentCompositorFrame(frame_token, details); } } @@ -576,8 +579,8 @@ void SingleThreadProxy::CompositeImmediately(base::TimeTicks frame_begin_time, } viz::BeginFrameArgs begin_frame_args(viz::BeginFrameArgs::Create( - BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1, - frame_begin_time, base::TimeTicks(), + BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, + begin_frame_sequence_number_++, frame_begin_time, base::TimeTicks(), viz::BeginFrameArgs::DefaultInterval(), viz::BeginFrameArgs::NORMAL)); // Start the impl frame. @@ -841,14 +844,6 @@ void SingleThreadProxy::BeginMainFrame( return; } - // Queue the LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT swap promise only once we - // know we will commit since QueueSwapPromise itself requests a commit. - ui::LatencyInfo new_latency_info(ui::SourceEventType::FRAME); - new_latency_info.AddLatencyNumberWithTimestamp( - ui::LATENCY_BEGIN_FRAME_UI_MAIN_COMPONENT, begin_frame_args.frame_time); - layer_tree_host_->QueueSwapPromise( - std::make_unique<LatencyInfoSwapPromise>(new_latency_info)); - DoPainting(); } @@ -868,7 +863,7 @@ void SingleThreadProxy::DoBeginMainFrame( layer_tree_host_->WillBeginMainFrame(); layer_tree_host_->BeginMainFrame(begin_frame_args); layer_tree_host_->AnimateLayers(begin_frame_args.frame_time); - layer_tree_host_->RequestMainFrameUpdate(); + layer_tree_host_->RequestMainFrameUpdate(false /* record_cc_metrics */); } void SingleThreadProxy::DoPainting() { diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index 320688ea79b..3cde647963d 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -17,6 +17,7 @@ namespace viz { class BeginFrameSource; +struct FrameTimingDetails; } namespace cc { @@ -96,6 +97,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void FrameIntervalUpdated(base::TimeDelta interval) override; size_t CompositedAnimationsCount() const override; size_t MainThreadAnimationsCount() const override; + bool HasCustomPropertyAnimations() const override; bool CurrentFrameHadRAF() const override; bool NextFrameHasPendingRAF() const override; @@ -130,7 +132,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void DidPresentCompositorFrameOnImplThread( uint32_t frame_token, std::vector<LayerTreeHost::PresentationTimeCallback> callbacks, - const gfx::PresentationFeedback& feedback) override; + const viz::FrameTimingDetails& details) override; void NotifyAnimationWorkletStateChange( AnimationWorkletMutationState state, ElementListType element_list_type) override; @@ -201,6 +203,10 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // initialized. bool layer_tree_frame_sink_lost_; + // A number that kept incrementing in CompositeImmediately, which indicates a + // new impl frame. + uint64_t begin_frame_sequence_number_ = 1u; + // This is the callback for the scheduled RequestNewLayerTreeFrameSink. base::CancelableOnceClosure layer_tree_frame_sink_creation_callback_; diff --git a/chromium/cc/trees/swap_promise_manager_unittest.cc b/chromium/cc/trees/swap_promise_manager_unittest.cc index 154feb117f0..5bf0c072971 100644 --- a/chromium/cc/trees/swap_promise_manager_unittest.cc +++ b/chromium/cc/trees/swap_promise_manager_unittest.cc @@ -21,7 +21,6 @@ class MockSwapPromiseMonitor : public SwapPromiseMonitor { MOCK_METHOD0(OnSetNeedsCommitOnMain, void()); void OnSetNeedsRedrawOnImpl() override {} - void OnForwardScrollUpdateToMainThreadOnImpl() override {} }; class MockSwapPromise : public SwapPromise { diff --git a/chromium/cc/trees/swap_promise_monitor.h b/chromium/cc/trees/swap_promise_monitor.h index 7efe2e281a5..3350ca1ffd9 100644 --- a/chromium/cc/trees/swap_promise_monitor.h +++ b/chromium/cc/trees/swap_promise_monitor.h @@ -33,7 +33,6 @@ class CC_EXPORT SwapPromiseMonitor { virtual void OnSetNeedsCommitOnMain() = 0; virtual void OnSetNeedsRedrawOnImpl() = 0; - virtual void OnForwardScrollUpdateToMainThreadOnImpl() = 0; protected: SwapPromiseManager* swap_promise_manager_; diff --git a/chromium/cc/trees/tree_synchronizer.cc b/chromium/cc/trees/tree_synchronizer.cc index 33c32cbb52c..0419820ba5d 100644 --- a/chromium/cc/trees/tree_synchronizer.cc +++ b/chromium/cc/trees/tree_synchronizer.cc @@ -68,7 +68,7 @@ template <typename LayerTreeType> void PushLayerList(OwnedLayerImplMap* old_layers, LayerTreeType* host, LayerTreeImpl* tree_impl) { - tree_impl->ClearLayerList(); + DCHECK(tree_impl->LayerListIsEmpty()); for (auto* layer : *host) { std::unique_ptr<LayerImpl> layer_impl( ReuseOrCreateLayerImpl(old_layers, layer, tree_impl)); @@ -82,7 +82,6 @@ void PushLayerList(OwnedLayerImplMap* old_layers, LayerWillPushProperties(host, layer)); #endif - tree_impl->AddToLayerList(layer_impl.get()); tree_impl->AddLayer(std::move(layer_impl)); } tree_impl->OnCanDrawStateChangedForTree(); @@ -95,21 +94,15 @@ void SynchronizeTreesInternal(LayerTreeType* source_tree, DCHECK(tree_impl); TRACE_EVENT0("cc", "TreeSynchronizer::SynchronizeTrees"); - std::unique_ptr<OwnedLayerImplList> old_layers(tree_impl->DetachLayers()); + OwnedLayerImplList old_layers = tree_impl->DetachLayers(); OwnedLayerImplMap old_layer_map; - for (auto& it : *old_layers) { + for (auto& it : old_layers) { DCHECK(it); old_layer_map[it->id()] = std::move(it); } PushLayerList(&old_layer_map, source_tree, tree_impl); - - for (int id : property_trees->effect_tree.mask_layer_ids()) { - std::unique_ptr<LayerImpl> layer_impl(ReuseOrCreateLayerImpl( - &old_layer_map, source_tree->LayerById(id), tree_impl)); - tree_impl->AddLayer(std::move(layer_impl)); - } } } // namespace diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index 08690725e5f..5f1a8f09d31 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -27,7 +27,7 @@ #include "cc/test/stub_layer_tree_host_single_thread_client.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/effect_node.h" -#include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/scroll_and_scale_set.h" #include "cc/trees/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/task_runner_provider.h" @@ -109,16 +109,6 @@ void ExpectTreesAreIdentical(Layer* root_layer, EXPECT_EQ(layer->non_fast_scrollable_region(), layer_impl->non_fast_scrollable_region()); - - const EffectTree& effect_tree = tree_impl->property_trees()->effect_tree; - if (layer->mask_layer()) { - SCOPED_TRACE("mask_layer"); - int mask_layer_id = layer->mask_layer()->id(); - EXPECT_TRUE(tree_impl->LayerById(mask_layer_id)); - EXPECT_EQ( - mask_layer_id, - effect_tree.Node(layer_impl->effect_tree_index())->mask_layer_id); - } } } @@ -150,7 +140,7 @@ class TreeSynchronizerTest : public testing::Test { host_impl->ActivateSyncTree(); ExpectTreesAreIdentical(layer_tree_root.get(), - host_impl->active_tree()->root_layer_for_testing(), + host_impl->active_tree()->root_layer(), host_impl->active_tree()); return scroll_layer; @@ -175,7 +165,7 @@ class TreeSynchronizerTest : public testing::Test { TEST_F(TreeSynchronizerTest, SyncNullTree) { TreeSynchronizer::SynchronizeTrees(static_cast<Layer*>(nullptr), host_->pending_tree()); - EXPECT_TRUE(!host_->pending_tree()->root_layer_for_testing()); + EXPECT_TRUE(!host_->pending_tree()->root_layer()); } // Constructs a very simple tree and synchronizes it without trying to reuse any @@ -191,12 +181,12 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeFromEmpty) { TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->pending_tree()); - LayerImpl* root = host_->pending_tree()->root_layer_for_testing(); + LayerImpl* root = host_->pending_tree()->root_layer(); EXPECT_TRUE(base::Contains( host_->pending_tree()->LayersThatShouldPushProperties(), root)); ExpectTreesAreIdentical(layer_tree_root.get(), - host_->pending_tree()->root_layer_for_testing(), + host_->pending_tree()->root_layer(), host_->pending_tree()); } @@ -217,12 +207,12 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndPushPropertiesFromEmpty) { // First time the main thread layers are synced to pending tree, and all the // layers are created on pending tree and they all need to push properties to // active tree. - LayerImpl* root = host_->pending_tree()->root_layer_for_testing(); + LayerImpl* root = host_->pending_tree()->root_layer(); EXPECT_TRUE(base::Contains( host_->pending_tree()->LayersThatShouldPushProperties(), root)); ExpectTreesAreIdentical(layer_tree_root.get(), - host_->pending_tree()->root_layer_for_testing(), + host_->pending_tree()->root_layer(), host_->pending_tree()); // Push properties to make pending tree have valid property tree index. @@ -267,8 +257,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->pending_tree()); - LayerImpl* layer_impl_tree_root = - host_->pending_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->pending_tree()->root_layer(); EXPECT_TRUE( base::Contains(host_->pending_tree()->LayersThatShouldPushProperties(), layer_impl_tree_root)); @@ -291,7 +280,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeReusingLayers) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->pending_tree()); - layer_impl_tree_root = host_->pending_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->pending_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->pending_tree()); @@ -322,8 +311,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -339,7 +327,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndTrackStackingOrderChange) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -382,8 +370,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeAndProperties) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -430,8 +417,7 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -458,7 +444,7 @@ TEST_F(TreeSynchronizerTest, ReuseLayerImplsAfterStructuralChange) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(layer_tree_root.get(), host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -488,8 +474,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(old_layer_tree_root.get(), host_->active_tree()); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(old_layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -508,7 +493,7 @@ TEST_F(TreeSynchronizerTest, SyncSimpleTreeThenDestroy) { host_->BuildPropertyTreesForTesting(); TreeSynchronizer::SynchronizeTrees(new_layer_tree_root.get(), host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(new_layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -538,8 +523,7 @@ TEST_F(TreeSynchronizerTest, SyncMaskLayer) { host_->BuildPropertyTreesForTesting(); host_->CommitAndCreateLayerImplTree(); - LayerImpl* layer_impl_tree_root = - host_->active_tree()->root_layer_for_testing(); + LayerImpl* layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -548,15 +532,15 @@ TEST_F(TreeSynchronizerTest, SyncMaskLayer) { host_->BuildPropertyTreesForTesting(); host_->CommitAndCreateLayerImplTree(); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); - layer_impl_tree_root = host_->active_tree()->root_layer_for_testing(); + layer_impl_tree_root = host_->active_tree()->root_layer(); ExpectTreesAreIdentical(layer_tree_root.get(), layer_impl_tree_root, host_->active_tree()); @@ -589,7 +573,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) { host_impl->ActivateSyncTree(); ExpectTreesAreIdentical(layer_tree_root.get(), - host_impl->active_tree()->root_layer_for_testing(), + host_impl->active_tree()->root_layer(), host_impl->active_tree()); ScrollNode* scroll_node = @@ -641,7 +625,7 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { host_impl->ActivateSyncTree(); ExpectTreesAreIdentical(layer_tree_root.get(), - host_impl->active_tree()->root_layer_for_testing(), + host_impl->active_tree()->root_layer(), host_impl->active_tree()); // After the initial commit, scroll_offset_map in scroll_tree is expected to |