diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-03-08 10:28:10 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2017-03-20 13:40:30 +0000 |
commit | e733310db58160074f574c429d48f8308c0afe17 (patch) | |
tree | f8aef4b7e62a69928dbcf880620eece20f98c6df /chromium/cc | |
parent | 2f583e4aec1ae3a86fa047829c96b310dc12ecdf (diff) | |
download | qtwebengine-chromium-e733310db58160074f574c429d48f8308c0afe17.tar.gz |
BASELINE: Update Chromium to 56.0.2924.122
Change-Id: I4e04de8f47e47e501c46ed934c76a431c6337ced
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/cc')
410 files changed, 10569 insertions, 14707 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn index 963347a95f1..e461a898db3 100644 --- a/chromium/cc/BUILD.gn +++ b/chromium/cc/BUILD.gn @@ -24,20 +24,14 @@ component("cc") { "animation/animation_timeline.h", "animation/element_animations.cc", "animation/element_animations.h", - "animation/element_id.cc", - "animation/element_id.h", "animation/keyframed_animation_curve.cc", "animation/keyframed_animation_curve.h", - "animation/property_animation_state.cc", - "animation/property_animation_state.h", "animation/scroll_offset_animation_curve.cc", "animation/scroll_offset_animation_curve.h", "animation/scroll_offset_animations.cc", "animation/scroll_offset_animations.h", "animation/scroll_offset_animations_impl.cc", "animation/scroll_offset_animations_impl.h", - "animation/target_property.cc", - "animation/target_property.h", "animation/timing_function.cc", "animation/timing_function.h", "animation/transform_operation.cc", @@ -49,7 +43,8 @@ component("cc") { "blimp/compositor_proto_state.h", "blimp/compositor_state_deserializer.cc", "blimp/compositor_state_deserializer.h", - "blimp/compositor_state_deserializer_client.h", + "blimp/deserialized_content_layer_client.cc", + "blimp/deserialized_content_layer_client.h", "blimp/engine_picture_cache.h", "blimp/image_serialization_processor.h", "blimp/layer_factory.h", @@ -62,6 +57,7 @@ component("cc") { "blimp/remote_compositor_bridge.cc", "blimp/remote_compositor_bridge.h", "blimp/remote_compositor_bridge_client.h", + "blimp/synced_property_remote.h", "debug/benchmark_instrumentation.cc", "debug/benchmark_instrumentation.h", "debug/debug_colors.cc", @@ -106,10 +102,14 @@ component("cc") { "debug/unittest_only_benchmark.h", "debug/unittest_only_benchmark_impl.cc", "debug/unittest_only_benchmark_impl.h", + "input/browser_controls_offset_manager.cc", + "input/browser_controls_offset_manager.h", + "input/browser_controls_offset_manager_client.h", "input/input_handler.cc", "input/input_handler.h", "input/layer_selection_bound.cc", "input/layer_selection_bound.h", + "input/main_thread_scrolling_reason.h", "input/page_scale_animation.cc", "input/page_scale_animation.h", "input/scroll_elasticity_helper.cc", @@ -125,9 +125,6 @@ component("cc") { "input/scrollbar_animation_controller_thinning.cc", "input/scrollbar_animation_controller_thinning.h", "input/selection.h", - "input/top_controls_manager.cc", - "input/top_controls_manager.h", - "input/top_controls_manager_client.h", "layers/append_quads_data.h", "layers/content_layer_client.h", "layers/draw_properties.cc", @@ -151,8 +148,6 @@ component("cc") { "layers/layer_list_iterator.h", "layers/layer_position_constraint.cc", "layers/layer_position_constraint.h", - "layers/layer_proto_converter.cc", - "layers/layer_proto_converter.h", "layers/layer_sticky_position_constraint.cc", "layers/layer_sticky_position_constraint.h", "layers/layer_utils.cc", @@ -337,12 +332,8 @@ component("cc") { "proto/cc_conversions.h", "proto/gfx_conversions.cc", "proto/gfx_conversions.h", - "proto/gpu_conversions.cc", - "proto/gpu_conversions.h", "proto/skia_conversions.cc", "proto/skia_conversions.h", - "proto/synced_property_conversions.cc", - "proto/synced_property_conversions.h", "quads/content_draw_quad_base.cc", "quads/content_draw_quad_base.h", "quads/debug_border_draw_quad.cc", @@ -450,7 +441,6 @@ component("cc") { "scheduler/begin_frame_source.h", "scheduler/begin_frame_tracker.cc", "scheduler/begin_frame_tracker.h", - "scheduler/commit_earlyout_reason.cc", "scheduler/commit_earlyout_reason.h", "scheduler/compositor_timing_history.cc", "scheduler/compositor_timing_history.h", @@ -516,6 +506,8 @@ component("cc") { "trees/draw_property_utils.h", "trees/effect_node.cc", "trees/effect_node.h", + "trees/element_id.cc", + "trees/element_id.h", "trees/latency_info_swap_promise_monitor.cc", "trees/latency_info_swap_promise_monitor.h", "trees/layer_tree.cc", @@ -531,13 +523,18 @@ component("cc") { "trees/layer_tree_host_single_thread_client.h", "trees/layer_tree_impl.cc", "trees/layer_tree_impl.h", + "trees/layer_tree_mutator.h", "trees/layer_tree_settings.cc", "trees/layer_tree_settings.h", + "trees/mutable_properties.h", + "trees/mutator_host.h", "trees/mutator_host_client.h", "trees/occlusion.cc", "trees/occlusion.h", "trees/occlusion_tracker.cc", "trees/occlusion_tracker.h", + "trees/property_animation_state.cc", + "trees/property_animation_state.h", "trees/property_tree.cc", "trees/property_tree.h", "trees/property_tree_builder.cc", @@ -549,11 +546,6 @@ component("cc") { "trees/proxy_impl.h", "trees/proxy_main.cc", "trees/proxy_main.h", - "trees/remote_channel_impl.cc", - "trees/remote_channel_impl.h", - "trees/remote_channel_main.cc", - "trees/remote_channel_main.h", - "trees/remote_proto_channel.h", "trees/scoped_abort_remaining_swap_promises.h", "trees/scroll_node.cc", "trees/scroll_node.h", @@ -563,6 +555,8 @@ component("cc") { "trees/swap_promise_manager.h", "trees/swap_promise_monitor.cc", "trees/swap_promise_monitor.h", + "trees/target_property.cc", + "trees/target_property.h", "trees/task_runner_provider.cc", "trees/task_runner_provider.h", "trees/threaded_channel.cc", @@ -700,6 +694,8 @@ static_library("test_support") { "test/layer_internals_for_test.h", "test/layer_test_common.cc", "test/layer_test_common.h", + "test/layer_tree_host_remote_for_testing.cc", + "test/layer_tree_host_remote_for_testing.h", "test/layer_tree_json_parser.cc", "test/layer_tree_json_parser.h", "test/layer_tree_pixel_resource_test.cc", @@ -728,14 +724,20 @@ static_library("test_support") { "test/pixel_test_output_surface.h", "test/pixel_test_utils.cc", "test/pixel_test_utils.h", + "test/push_properties_counting_layer.cc", + "test/push_properties_counting_layer.h", + "test/push_properties_counting_layer_impl.cc", + "test/push_properties_counting_layer_impl.h", "test/remote_client_layer_factory.cc", "test/remote_client_layer_factory.h", - "test/remote_proto_channel_bridge.cc", - "test/remote_proto_channel_bridge.h", + "test/remote_compositor_test.cc", + "test/remote_compositor_test.h", "test/render_pass_test_utils.cc", "test/render_pass_test_utils.h", "test/scheduler_test_common.cc", "test/scheduler_test_common.h", + "test/serialization_test_utils.cc", + "test/serialization_test_utils.h", "test/skia_common.cc", "test/skia_common.h", "test/solid_color_content_layer_client.cc", @@ -796,10 +798,10 @@ static_library("test_support") { "//cc/proto", "//cc/surfaces", "//cc/surfaces:surface_id", - "//gpu/command_buffer/client:gl_in_process_context", "//gpu/command_buffer/client:gles2_c_lib", "//gpu/command_buffer/client:gles2_implementation", "//gpu/command_buffer/common:gles2_utils", + "//gpu/ipc:gl_in_process_context", "//gpu/skia_bindings", "//media", "//skia", @@ -845,15 +847,16 @@ test("cc_unittests") { "base/unique_notifier_unittest.cc", "blimp/compositor_state_deserializer_unittest.cc", "blimp/layer_tree_host_remote_unittest.cc", + "blimp/layer_tree_host_unittest_serialization.cc", "blimp/picture_data_conversions_unittest.cc", - "debug/layer_tree_debug_state_unittest.cc", + "blimp/synced_property_remote_unittest.cc", "debug/micro_benchmark_controller_unittest.cc", "debug/rendering_stats_unittest.cc", + "input/browser_controls_offset_manager_unittest.cc", "input/layer_selection_bound_unittest.cc", "input/scroll_state_unittest.cc", "input/scrollbar_animation_controller_linear_fade_unittest.cc", "input/scrollbar_animation_controller_thinning_unittest.cc", - "input/top_controls_manager_unittest.cc", "ipc/cc_param_traits_unittest.cc", "ipc/struct_traits_unittest.cc", "layers/heads_up_display_layer_impl_unittest.cc", @@ -862,7 +865,6 @@ test("cc_unittests") { "layers/layer_iterator_unittest.cc", "layers/layer_list_iterator_unittest.cc", "layers/layer_position_constraint_unittest.cc", - "layers/layer_proto_converter_unittest.cc", "layers/layer_unittest.cc", "layers/layer_utils_unittest.cc", "layers/nine_patch_layer_impl_unittest.cc", @@ -894,11 +896,8 @@ test("cc_unittests") { "output/filter_operations_unittest.cc", "output/gl_renderer_unittest.cc", "output/layer_quad_unittest.cc", - "output/managed_memory_policy_unittest.cc", - "output/output_surface_unittest.cc", "output/overlay_unittest.cc", "output/renderer_pixeltest.cc", - "output/renderer_settings_unittest.cc", "output/shader_unittest.cc", "output/software_renderer_unittest.cc", "output/texture_mailbox_deleter_unittest.cc", @@ -909,9 +908,7 @@ test("cc_unittests") { "proto/base_conversions_unittest.cc", "proto/cc_conversions_unittest.cc", "proto/gfx_conversions_unittest.cc", - "proto/gpu_conversions_unittest.cc", "proto/skia_conversions_unittest.cc", - "proto/synced_property_conversions_unittest.cc", "quads/draw_polygon_unittest.cc", "quads/draw_quad_unittest.cc", "quads/render_pass_unittest.cc", @@ -927,7 +924,6 @@ test("cc_unittests") { "resources/scoped_resource_unittest.cc", "resources/video_resource_updater_unittest.cc", "scheduler/begin_frame_source_unittest.cc", - "scheduler/commit_earlyout_reason_unittest.cc", "scheduler/compositor_timing_history_unittest.cc", "scheduler/delay_based_time_source_unittest.cc", "scheduler/scheduler_state_machine_unittest.cc", @@ -965,15 +961,12 @@ test("cc_unittests") { "trees/layer_tree_host_unittest_picture.cc", "trees/layer_tree_host_unittest_proxy.cc", "trees/layer_tree_host_unittest_record_gpu_histogram.cc", - "trees/layer_tree_host_unittest_remote_server.cc", "trees/layer_tree_host_unittest_scroll.cc", - "trees/layer_tree_host_unittest_serialization.cc", "trees/layer_tree_host_unittest_video.cc", "trees/layer_tree_impl_unittest.cc", "trees/occlusion_tracker_unittest.cc", "trees/occlusion_unittest.cc", "trees/property_tree_unittest.cc", - "trees/proxy_common_unittest.cc", "trees/swap_promise_manager_unittest.cc", "trees/tree_synchronizer_unittest.cc", @@ -984,6 +977,7 @@ test("cc_unittests") { "surfaces/surface_aggregator_unittest.cc", "surfaces/surface_factory_unittest.cc", "surfaces/surface_hittest_unittest.cc", + "surfaces/surface_manager_ref_unittest.cc", "surfaces/surface_manager_unittest.cc", "surfaces/surface_sequence_generator_unittest.cc", "surfaces/surface_unittest.cc", @@ -1081,5 +1075,11 @@ test("cc_perftests") { data = [ "test/data/", + + # Needed for isolate script to execute. + "//testing/scripts/common.py", + "//testing/xvfb.py", + "//testing/scripts/run_gtest_perf_test.py", + "//tools/perf/generate_legacy_perf_dashboard_json.py", ] } diff --git a/chromium/cc/PRESUBMIT.py b/chromium/cc/PRESUBMIT.py index c26129430db..94e6692244a 100644 --- a/chromium/cc/PRESUBMIT.py +++ b/chromium/cc/PRESUBMIT.py @@ -339,7 +339,7 @@ def PostUploadHook(cl, change, output_api): return [] bots = [ - 'master.tryserver.blink:linux_precise_blink_rel', + 'master.tryserver.blink:linux_trusty_blink_rel', ] results = [] diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h index 38d4883d9d8..6d1524df642 100644 --- a/chromium/cc/animation/animation.h +++ b/chromium/cc/animation/animation.h @@ -9,8 +9,8 @@ #include "base/macros.h" #include "base/time/time.h" -#include "cc/animation/target_property.h" #include "cc/base/cc_export.h" +#include "cc/trees/target_property.h" namespace cc { diff --git a/chromium/cc/animation/animation_curve.h b/chromium/cc/animation/animation_curve.h index c52ff180039..a42fcaffe3e 100644 --- a/chromium/cc/animation/animation_curve.h +++ b/chromium/cc/animation/animation_curve.h @@ -23,7 +23,6 @@ class FilterAnimationCurve; class FloatAnimationCurve; class ScrollOffsetAnimationCurve; class TransformAnimationCurve; -class TransformOperations; // An animation curve is a function that returns a value given a time. class CC_EXPORT AnimationCurve { diff --git a/chromium/cc/animation/animation_events.cc b/chromium/cc/animation/animation_events.cc index 8c39e26a776..7c1e3ae5556 100644 --- a/chromium/cc/animation/animation_events.cc +++ b/chromium/cc/animation/animation_events.cc @@ -56,4 +56,8 @@ AnimationEvents::AnimationEvents() {} AnimationEvents::~AnimationEvents() {} +bool AnimationEvents::IsEmpty() const { + return events_.empty(); +} + } // namespace cc diff --git a/chromium/cc/animation/animation_events.h b/chromium/cc/animation/animation_events.h index fc0c41e9d1c..c6cb0e9dd70 100644 --- a/chromium/cc/animation/animation_events.h +++ b/chromium/cc/animation/animation_events.h @@ -12,7 +12,8 @@ #include "cc/animation/animation_curve.h" #include "cc/base/cc_export.h" #include "cc/output/filter_operations.h" -#include "cc/trees/mutator_host_client.h" +#include "cc/trees/element_id.h" +#include "cc/trees/mutator_host.h" #include "ui/gfx/transform.h" namespace cc { @@ -46,10 +47,13 @@ struct CC_EXPORT AnimationEvent { std::unique_ptr<AnimationCurve> curve; }; -class CC_EXPORT AnimationEvents { +class CC_EXPORT AnimationEvents : public NON_EXPORTED_BASE(MutatorEvents) { public: AnimationEvents(); - ~AnimationEvents(); + + // MutatorEvents implementation. + ~AnimationEvents() override; + bool IsEmpty() const override; std::vector<AnimationEvent> events_; }; diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc index b350bfd4eab..3ca17859125 100644 --- a/chromium/cc/animation/animation_host.cc +++ b/chromium/cc/animation/animation_host.cc @@ -55,18 +55,19 @@ AnimationHost::AnimationHost(ThreadInstance thread_instance) AnimationHost::~AnimationHost() { scroll_offset_animations_impl_ = nullptr; - ClearTimelines(); + ClearMutators(); DCHECK(!mutator_host_client()); DCHECK(element_to_animations_map_.empty()); } -std::unique_ptr<AnimationHost> AnimationHost::CreateImplInstance( +std::unique_ptr<MutatorHost> AnimationHost::CreateImplInstance( bool supports_impl_scrolling) const { DCHECK_EQ(thread_instance_, ThreadInstance::MAIN); - auto animation_host_impl = - base::WrapUnique(new AnimationHost(ThreadInstance::IMPL)); - animation_host_impl->SetSupportsScrollAnimations(supports_impl_scrolling); - return animation_host_impl; + + auto mutator_host_impl = + base::WrapUnique<MutatorHost>(new AnimationHost(ThreadInstance::IMPL)); + mutator_host_impl->SetSupportsScrollAnimations(supports_impl_scrolling); + return mutator_host_impl; } AnimationTimeline* AnimationHost::GetTimelineById(int timeline_id) const { @@ -74,7 +75,7 @@ AnimationTimeline* AnimationHost::GetTimelineById(int timeline_id) const { return f == id_to_timeline_map_.end() ? nullptr : f->second.get(); } -void AnimationHost::ClearTimelines() { +void AnimationHost::ClearMutators() { for (auto& kv : id_to_timeline_map_) EraseTimeline(kv.second); id_to_timeline_map_.clear(); @@ -179,7 +180,9 @@ void AnimationHost::SetNeedsPushProperties() { needs_push_properties_ = true; } -void AnimationHost::PushPropertiesTo(AnimationHost* host_impl) { +void AnimationHost::PushPropertiesTo(MutatorHost* mutator_host_impl) { + auto host_impl = static_cast<AnimationHost*>(mutator_host_impl); + if (needs_push_properties_) { needs_push_properties_ = false; PushTimelinesToImplThread(host_impl); @@ -297,25 +300,30 @@ bool AnimationHost::AnimateLayers(base::TimeTicks monotonic_time) { } bool AnimationHost::UpdateAnimationState(bool start_ready_animations, - AnimationEvents* events) { + MutatorEvents* mutator_events) { if (!NeedsAnimateLayers()) return false; + auto animation_events = static_cast<AnimationEvents*>(mutator_events); + TRACE_EVENT0("cc", "AnimationHost::UpdateAnimationState"); ElementToAnimationsMap active_element_animations_map_copy = active_element_to_animations_map_; for (auto& it : active_element_animations_map_copy) - it.second->UpdateState(start_ready_animations, events); + it.second->UpdateState(start_ready_animations, animation_events); return true; } -std::unique_ptr<AnimationEvents> AnimationHost::CreateEvents() { +std::unique_ptr<MutatorEvents> AnimationHost::CreateEvents() { return base::MakeUnique<AnimationEvents>(); } void AnimationHost::SetAnimationEvents( - std::unique_ptr<AnimationEvents> events) { + std::unique_ptr<MutatorEvents> mutator_events) { + auto events = + base::WrapUnique(static_cast<AnimationEvents*>(mutator_events.release())); + for (size_t event_index = 0; event_index < events->events_.size(); ++event_index) { ElementId element_id = events->events_[event_index].element_id; diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h index a81df79f094..f9298cade22 100644 --- a/chromium/cc/animation/animation_host.h +++ b/chromium/cc/animation/animation_host.h @@ -14,6 +14,7 @@ #include "base/time/time.h" #include "cc/animation/animation.h" #include "cc/base/cc_export.h" +#include "cc/trees/mutator_host.h" #include "cc/trees/mutator_host_client.h" #include "ui/gfx/geometry/box_f.h" #include "ui/gfx/geometry/vector2d_f.h" @@ -24,7 +25,6 @@ class ScrollOffset; namespace cc { -class AnimationEvents; class AnimationPlayer; class AnimationTimeline; class ElementAnimations; @@ -41,8 +41,8 @@ enum class ThreadInstance { MAIN, IMPL }; // We synchronize them during the commit process in a one-way data flow process // (PushPropertiesTo). // An AnimationHost talks to its correspondent LayerTreeHost via -// LayerTreeMutatorsClient interface. -class CC_EXPORT AnimationHost { +// MutatorHostClient interface. +class CC_EXPORT AnimationHost : public NON_EXPORTED_BASE(MutatorHost) { public: using ElementToAnimationsMap = std::unordered_map<ElementId, @@ -52,19 +52,12 @@ class CC_EXPORT AnimationHost { static std::unique_ptr<AnimationHost> CreateMainInstance(); static std::unique_ptr<AnimationHost> CreateForTesting( ThreadInstance thread_instance); - std::unique_ptr<AnimationHost> CreateImplInstance( - bool supports_impl_scrolling) const; - ~AnimationHost(); + ~AnimationHost() override; void AddAnimationTimeline(scoped_refptr<AnimationTimeline> timeline); void RemoveAnimationTimeline(scoped_refptr<AnimationTimeline> timeline); AnimationTimeline* GetTimelineById(int timeline_id) const; - void ClearTimelines(); - - void RegisterElement(ElementId element_id, ElementListType list_type); - void UnregisterElement(ElementId element_id, ElementListType list_type); - void RegisterPlayerForElement(ElementId element_id, AnimationPlayer* player); void UnregisterPlayerForElement(ElementId element_id, AnimationPlayer* player); @@ -77,82 +70,100 @@ class CC_EXPORT AnimationHost { const MutatorHostClient* mutator_host_client() const { return mutator_host_client_; } - void SetMutatorHostClient(MutatorHostClient* client); void SetNeedsCommit(); void SetNeedsPushProperties(); bool needs_push_properties() const { return needs_push_properties_; } - void PushPropertiesTo(AnimationHost* host_impl); - - void SetSupportsScrollAnimations(bool supports_scroll_animations); bool SupportsScrollAnimations() const; - bool NeedsAnimateLayers() const; - bool ActivateAnimations(); - bool AnimateLayers(base::TimeTicks monotonic_time); + // MutatorHost implementation. + std::unique_ptr<MutatorHost> CreateImplInstance( + bool supports_impl_scrolling) const override; + void ClearMutators() override; + + void RegisterElement(ElementId element_id, + ElementListType list_type) override; + void UnregisterElement(ElementId element_id, + ElementListType list_type) override; + + void SetMutatorHostClient(MutatorHostClient* client) override; + + void PushPropertiesTo(MutatorHost* host_impl) override; + + void SetSupportsScrollAnimations(bool supports_scroll_animations) override; + bool NeedsAnimateLayers() const override; + + bool ActivateAnimations() override; + bool AnimateLayers(base::TimeTicks monotonic_time) override; bool UpdateAnimationState(bool start_ready_animations, - AnimationEvents* events); + MutatorEvents* events) override; - std::unique_ptr<AnimationEvents> CreateEvents(); - void SetAnimationEvents(std::unique_ptr<AnimationEvents> events); + std::unique_ptr<MutatorEvents> CreateEvents() override; + void SetAnimationEvents(std::unique_ptr<MutatorEvents> events) override; - bool ScrollOffsetAnimationWasInterrupted(ElementId element_id) const; + bool ScrollOffsetAnimationWasInterrupted(ElementId element_id) const override; bool IsAnimatingFilterProperty(ElementId element_id, - ElementListType list_type) const; + ElementListType list_type) const override; bool IsAnimatingOpacityProperty(ElementId element_id, - ElementListType list_type) const; + ElementListType list_type) const override; bool IsAnimatingTransformProperty(ElementId element_id, - ElementListType list_type) const; + ElementListType list_type) const override; - bool HasPotentiallyRunningFilterAnimation(ElementId element_id, - ElementListType list_type) const; - bool HasPotentiallyRunningOpacityAnimation(ElementId element_id, - ElementListType list_type) const; - bool HasPotentiallyRunningTransformAnimation(ElementId element_id, - ElementListType list_type) const; + bool HasPotentiallyRunningFilterAnimation( + ElementId element_id, + ElementListType list_type) const override; + bool HasPotentiallyRunningOpacityAnimation( + ElementId element_id, + ElementListType list_type) const override; + bool HasPotentiallyRunningTransformAnimation( + ElementId element_id, + ElementListType list_type) const override; - bool HasAnyAnimationTargetingProperty(ElementId element_id, - TargetProperty::Type property) const; + bool HasAnyAnimationTargetingProperty( + ElementId element_id, + TargetProperty::Type property) const override; - bool HasFilterAnimationThatInflatesBounds(ElementId element_id) const; - bool HasTransformAnimationThatInflatesBounds(ElementId element_id) const; - bool HasAnimationThatInflatesBounds(ElementId element_id) const; + bool HasFilterAnimationThatInflatesBounds( + ElementId element_id) const override; + bool HasTransformAnimationThatInflatesBounds( + ElementId element_id) const override; + bool HasAnimationThatInflatesBounds(ElementId element_id) const override; bool FilterAnimationBoundsForBox(ElementId element_id, const gfx::BoxF& box, - gfx::BoxF* bounds) const; + gfx::BoxF* bounds) const override; bool TransformAnimationBoundsForBox(ElementId element_id, const gfx::BoxF& box, - gfx::BoxF* bounds) const; + gfx::BoxF* bounds) const override; bool HasOnlyTranslationTransforms(ElementId element_id, - ElementListType list_type) const; - bool AnimationsPreserveAxisAlignment(ElementId element_id) const; + ElementListType list_type) const override; + bool AnimationsPreserveAxisAlignment(ElementId element_id) const override; bool MaximumTargetScale(ElementId element_id, ElementListType list_type, - float* max_scale) const; + float* max_scale) const override; bool AnimationStartScale(ElementId element_id, ElementListType list_type, - float* start_scale) const; + float* start_scale) const override; - bool HasAnyAnimation(ElementId element_id) const; - bool HasActiveAnimationForTesting(ElementId element_id) const; + bool HasAnyAnimation(ElementId element_id) const override; + bool HasActiveAnimationForTesting(ElementId element_id) const override; void ImplOnlyScrollAnimationCreate(ElementId element_id, const gfx::ScrollOffset& target_offset, const gfx::ScrollOffset& current_offset, - base::TimeDelta delayed_by); + base::TimeDelta delayed_by) override; bool ImplOnlyScrollAnimationUpdateTarget( ElementId element_id, const gfx::Vector2dF& scroll_delta, const gfx::ScrollOffset& max_scroll_offset, base::TimeTicks frame_monotonic_time, - base::TimeDelta delayed_by); + base::TimeDelta delayed_by) override; - void ScrollAnimationAbort(bool needs_completion); + void ScrollAnimationAbort(bool needs_completion) override; // This should only be called from the main thread. ScrollOffsetAnimations& scroll_offset_animations() const; diff --git a/chromium/cc/animation/animation_host_perftest.cc b/chromium/cc/animation/animation_host_perftest.cc index c20fcd97f9b..4e8bb38a461 100644 --- a/chromium/cc/animation/animation_host_perftest.cc +++ b/chromium/cc/animation/animation_host_perftest.cc @@ -32,8 +32,9 @@ class AnimationHostPerfTest : public testing::Test { void SetUp() override { LayerTreeSettings settings; - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_, settings); + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + layer_tree_host_ = FakeLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host_.get(), settings); layer_tree_host_->InitializeSingleThreaded( &single_thread_client_, base::ThreadTaskRunnerHandle::Get()); @@ -51,9 +52,7 @@ class AnimationHostPerfTest : public testing::Test { layer_tree_host_ = nullptr; } - AnimationHost* host() const { - return layer_tree_host_->GetLayerTree()->animation_host(); - } + AnimationHost* host() const { return animation_host_.get(); } AnimationHost* host_impl() const { return layer_tree_host_->host_impl()->animation_host(); } @@ -137,6 +136,7 @@ class AnimationHostPerfTest : public testing::Test { private: StubLayerTreeHostSingleThreadClient single_thread_client_; FakeLayerTreeHostClient fake_client_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; scoped_refptr<Layer> root_layer_; LayerImpl* root_layer_impl_; diff --git a/chromium/cc/animation/animation_host_unittest.cc b/chromium/cc/animation/animation_host_unittest.cc index eb51bc5861b..4ae691a64e2 100644 --- a/chromium/cc/animation/animation_host_unittest.cc +++ b/chromium/cc/animation/animation_host_unittest.cc @@ -99,7 +99,7 @@ TEST_F(AnimationHostTest, ImplOnlyScrollAnimationUpdateTargetIfDetached) { element_id_, scroll_delta, max_scroll_offset, time, base::TimeDelta())); // Detach all players from layers and timelines. - host_impl_->ClearTimelines(); + host_impl_->ClearMutators(); time += base::TimeDelta::FromSecondsD(0.1); EXPECT_FALSE(host_impl_->ImplOnlyScrollAnimationUpdateTarget( diff --git a/chromium/cc/animation/animation_player.cc b/chromium/cc/animation/animation_player.cc index 4749eecee07..dcc92e22ff8 100644 --- a/chromium/cc/animation/animation_player.cc +++ b/chromium/cc/animation/animation_player.cc @@ -10,8 +10,8 @@ #include "cc/animation/animation_events.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_timeline.h" -#include "cc/animation/property_animation_state.h" #include "cc/animation/scroll_offset_animation_curve.h" +#include "cc/trees/property_animation_state.h" namespace cc { @@ -1035,8 +1035,8 @@ void AnimationPlayer::PurgeAnimationsMarkedForDeletion() { void AnimationPlayer::PushNewAnimationsToImplThread( AnimationPlayer* animation_player_impl) const { - // Any new animations owned by the main thread's ElementAnimations are cloned - // and added to the impl thread's ElementAnimations. + // Any new animations owned by the main thread's AnimationPlayer are cloned + // and added to the impl thread's AnimationPlayer. for (size_t i = 0; i < animations_.size(); ++i) { // If the animation is already running on the impl thread, there is no // need to copy it over. diff --git a/chromium/cc/animation/animation_player.h b/chromium/cc/animation/animation_player.h index 56050546d39..06b4433bb67 100644 --- a/chromium/cc/animation/animation_player.h +++ b/chromium/cc/animation/animation_player.h @@ -13,8 +13,8 @@ #include "cc/animation/animation.h" #include "cc/animation/animation_curve.h" #include "cc/animation/element_animations.h" -#include "cc/animation/element_id.h" #include "cc/base/cc_export.h" +#include "cc/trees/element_id.h" namespace cc { diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc index 6b29c31808a..ae6fd01e4ca 100644 --- a/chromium/cc/animation/element_animations.cc +++ b/chromium/cc/animation/element_animations.cc @@ -26,8 +26,7 @@ scoped_refptr<ElementAnimations> ElementAnimations::Create() { } ElementAnimations::ElementAnimations() - : players_list_(new PlayersList()), - animation_host_(), + : animation_host_(), element_id_(), is_active_(false), has_element_in_active_list_(false), @@ -123,15 +122,15 @@ void ElementAnimations::ElementUnregistered(ElementId element_id, } void ElementAnimations::AddPlayer(AnimationPlayer* player) { - players_list_->AddObserver(player); + players_list_.AddObserver(player); } void ElementAnimations::RemovePlayer(AnimationPlayer* player) { - players_list_->RemoveObserver(player); + players_list_.RemoveObserver(player); } bool ElementAnimations::IsEmpty() const { - return !players_list_->might_have_observers(); + return !players_list_.might_have_observers(); } void ElementAnimations::SetNeedsPushProperties() { @@ -164,22 +163,14 @@ void ElementAnimations::Animate(base::TimeTicks monotonic_time) { if (!has_element_in_active_list() && !has_element_in_pending_list()) return; - { - // TODO(crbug.com/634916): Shouldn't manually iterate through the list if - // base::ObserverList has a callback mechanism. - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->needs_to_start_animations()) - player->StartAnimations(monotonic_time); - } - } - { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) - player->TickAnimations(monotonic_time); + for (auto& player : players_list_) { + if (player.needs_to_start_animations()) + player.StartAnimations(monotonic_time); } + + for (auto& player : players_list_) + player.TickAnimations(monotonic_time); + last_tick_time_ = monotonic_time; UpdateClientAnimationState(); } @@ -195,32 +186,21 @@ void ElementAnimations::UpdateState(bool start_ready_animations, return; if (start_ready_animations) { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) - player->PromoteStartedAnimations(last_tick_time_, events); + for (auto& player : players_list_) + player.PromoteStartedAnimations(last_tick_time_, events); } - { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) - player->MarkFinishedAnimations(last_tick_time_); - } - { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) - player->MarkAnimationsForDeletion(last_tick_time_, events); - } + for (auto& player : players_list_) + player.MarkFinishedAnimations(last_tick_time_); + + for (auto& player : players_list_) + player.MarkAnimationsForDeletion(last_tick_time_, events); if (start_ready_animations) { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->needs_to_start_animations()) { - player->StartAnimations(last_tick_time_); - player->PromoteStartedAnimations(last_tick_time_, events); + for (auto& player : players_list_) { + if (player.needs_to_start_animations()) { + player.StartAnimations(last_tick_time_); + player.PromoteStartedAnimations(last_tick_time_, events); } } } @@ -229,10 +209,8 @@ void ElementAnimations::UpdateState(bool start_ready_animations, } void ElementAnimations::ActivateAnimations() { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) - player->ActivateAnimations(); + for (auto& player : players_list_) + player.ActivateAnimations(); scroll_offset_animation_was_interrupted_ = false; UpdateActivation(ActivationType::NORMAL); @@ -240,20 +218,16 @@ void ElementAnimations::ActivateAnimations() { void ElementAnimations::NotifyAnimationStarted(const AnimationEvent& event) { DCHECK(!event.is_impl_only); - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->NotifyAnimationStarted(event)) + for (auto& player : players_list_) { + if (player.NotifyAnimationStarted(event)) break; } } void ElementAnimations::NotifyAnimationFinished(const AnimationEvent& event) { DCHECK(!event.is_impl_only); - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->NotifyAnimationFinished(event)) + for (auto& player : players_list_) { + if (player.NotifyAnimationFinished(event)) break; } } @@ -262,19 +236,15 @@ void ElementAnimations::NotifyAnimationTakeover(const AnimationEvent& event) { DCHECK(!event.is_impl_only); DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET); - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) - player->NotifyAnimationTakeover(event); + for (auto& player : players_list_) + player.NotifyAnimationTakeover(event); } void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) { DCHECK(!event.is_impl_only); - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->NotifyAnimationAborted(event)) + for (auto& player : players_list_) { + if (player.NotifyAnimationAborted(event)) break; } @@ -301,20 +271,16 @@ void ElementAnimations::NotifyAnimationPropertyUpdate( } bool ElementAnimations::HasFilterAnimationThatInflatesBounds() const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->HasFilterAnimationThatInflatesBounds()) + for (auto& player : players_list_) { + if (player.HasFilterAnimationThatInflatesBounds()) return true; } return false; } bool ElementAnimations::HasTransformAnimationThatInflatesBounds() const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->HasTransformAnimationThatInflatesBounds()) + for (auto& player : players_list_) { + if (player.HasTransformAnimationThatInflatesBounds()) return true; } return false; @@ -331,11 +297,9 @@ bool ElementAnimations::TransformAnimationBoundsForBox( gfx::BoxF* bounds) const { *bounds = gfx::BoxF(); - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { + for (auto& player : players_list_) { gfx::BoxF player_bounds; - bool success = player->TransformAnimationBoundsForBox(box, &player_bounds); + bool success = player.TransformAnimationBoundsForBox(box, &player_bounds); if (!success) return false; bounds->Union(player_bounds); @@ -345,20 +309,16 @@ bool ElementAnimations::TransformAnimationBoundsForBox( bool ElementAnimations::HasOnlyTranslationTransforms( ElementListType list_type) const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (!player->HasOnlyTranslationTransforms(list_type)) + for (auto& player : players_list_) { + if (!player.HasOnlyTranslationTransforms(list_type)) return false; } return true; } bool ElementAnimations::AnimationsPreserveAxisAlignment() const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (!player->AnimationsPreserveAxisAlignment()) + for (auto& player : players_list_) { + if (!player.AnimationsPreserveAxisAlignment()) return false; } return true; @@ -368,11 +328,9 @@ bool ElementAnimations::AnimationStartScale(ElementListType list_type, float* start_scale) const { *start_scale = 0.f; - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { + for (auto& player : players_list_) { float player_start_scale = 0.f; - bool success = player->AnimationStartScale(list_type, &player_start_scale); + bool success = player.AnimationStartScale(list_type, &player_start_scale); if (!success) return false; // Union: a maximum. @@ -386,11 +344,9 @@ bool ElementAnimations::MaximumTargetScale(ElementListType list_type, float* max_scale) const { *max_scale = 0.f; - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { + for (auto& player : players_list_) { float player_max_scale = 0.f; - bool success = player->MaximumTargetScale(list_type, &player_max_scale); + bool success = player.MaximumTargetScale(list_type, &player_max_scale); if (!success) return false; // Union: a maximum. @@ -411,10 +367,8 @@ void ElementAnimations::UpdateActivation(ActivationType type) { bool was_active = is_active_; is_active_ = false; - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->HasNonDeletedAnimation()) { + for (auto& player : players_list_) { + if (player.HasNonDeletedAnimation()) { is_active_ = true; break; } @@ -488,12 +442,10 @@ void ElementAnimations::UpdateClientAnimationState() { pending_state_.Clear(); active_state_.Clear(); - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { + for (auto& player : players_list_) { PropertyAnimationState player_pending_state, player_active_state; - player->GetPropertyAnimationState(&player_pending_state, - &player_active_state); + player.GetPropertyAnimationState(&player_pending_state, + &player_active_state); pending_state_ |= player_pending_state; active_state_ |= player_active_state; } @@ -522,10 +474,8 @@ void ElementAnimations::UpdateClientAnimationState() { } bool ElementAnimations::HasActiveAnimation() const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->HasActiveAnimation()) + for (auto& player : players_list_) { + if (player.HasActiveAnimation()) return true; } @@ -533,10 +483,8 @@ bool ElementAnimations::HasActiveAnimation() const { } bool ElementAnimations::HasAnyAnimation() const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->has_any_animation()) + for (auto& player : players_list_) { + if (player.has_any_animation()) return true; } @@ -545,10 +493,8 @@ bool ElementAnimations::HasAnyAnimation() const { bool ElementAnimations::HasAnyAnimationTargetingProperty( TargetProperty::Type property) const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->GetAnimation(property)) + for (auto& player : players_list_) { + if (player.GetAnimation(property)) return true; } return false; @@ -557,10 +503,8 @@ bool ElementAnimations::HasAnyAnimationTargetingProperty( bool ElementAnimations::IsPotentiallyAnimatingProperty( TargetProperty::Type target_property, ElementListType list_type) const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->IsPotentiallyAnimatingProperty(target_property, list_type)) + for (auto& player : players_list_) { + if (player.IsPotentiallyAnimatingProperty(target_property, list_type)) return true; } @@ -570,10 +514,8 @@ bool ElementAnimations::IsPotentiallyAnimatingProperty( bool ElementAnimations::IsCurrentlyAnimatingProperty( TargetProperty::Type target_property, ElementListType list_type) const { - ElementAnimations::PlayersList::Iterator it(players_list_.get()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - if (player->IsCurrentlyAnimatingProperty(target_property, list_type)) + for (auto& player : players_list_) { + if (player.IsCurrentlyAnimatingProperty(target_property, list_type)) return true; } diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h index 5ee709d2716..a07b63e544b 100644 --- a/chromium/cc/animation/element_animations.h +++ b/chromium/cc/animation/element_animations.h @@ -12,10 +12,10 @@ #include "base/memory/ref_counted.h" #include "base/observer_list.h" #include "base/time/time.h" -#include "cc/animation/element_id.h" -#include "cc/animation/property_animation_state.h" -#include "cc/animation/target_property.h" #include "cc/base/cc_export.h" +#include "cc/trees/element_id.h" +#include "cc/trees/property_animation_state.h" +#include "cc/trees/target_property.h" #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/transform.h" @@ -25,7 +25,6 @@ class BoxF; namespace cc { -class AnimationDelegate; class AnimationEvents; class AnimationHost; class AnimationPlayer; @@ -60,7 +59,7 @@ class CC_EXPORT ElementAnimations : public base::RefCounted<ElementAnimations> { bool IsEmpty() const; typedef base::ObserverList<AnimationPlayer> PlayersList; - PlayersList& players_list() const { return *players_list_.get(); } + const PlayersList& players_list() const { return players_list_; } // Ensures that the list of active animations on the main thread and the impl // thread are kept in sync. This function does not take ownership of the impl @@ -199,7 +198,7 @@ class CC_EXPORT ElementAnimations : public base::RefCounted<ElementAnimations> { static TargetProperties GetPropertiesMaskForAnimationState(); - std::unique_ptr<PlayersList> players_list_; + PlayersList players_list_; AnimationHost* animation_host_; ElementId element_id_; diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc index 012743a4beb..d494e72655c 100644 --- a/chromium/cc/animation/element_animations_unittest.cc +++ b/chromium/cc/animation/element_animations_unittest.cc @@ -37,6 +37,12 @@ class ElementAnimationsTest : public AnimationTimelinesTest { public: ElementAnimationsTest() {} ~ElementAnimationsTest() override {} + + std::unique_ptr<AnimationEvents> CreateEventsForTesting() { + auto mutator_events = host_impl_->CreateEvents(); + return base::WrapUnique( + static_cast<AnimationEvents*>(mutator_events.release())); + } }; // See animation_player_unittest.cc for integration with AnimationPlayer. @@ -175,11 +181,8 @@ TEST_F(ElementAnimationsTest, AddRemovePlayers) { EXPECT_TRUE(element_animations_impl); int list_size_before = 0; - ElementAnimations::PlayersList::Iterator it( - &element_animations_impl_->players_list()); - AnimationPlayer* player; - while ((player = it.GetNext()) != nullptr) { - EXPECT_TRUE(timeline_->GetPlayerById(player->id())); + for (auto& player : element_animations_impl_->players_list()) { + EXPECT_TRUE(timeline_->GetPlayerById(player.id())); ++list_size_before; } EXPECT_EQ(3, list_size_before); @@ -193,10 +196,8 @@ TEST_F(ElementAnimationsTest, AddRemovePlayers) { EXPECT_EQ(element_animations_impl, player_impl_->element_animations()); int list_size_after = 0; - it = ElementAnimations::PlayersList::Iterator( - &element_animations_impl_->players_list()); - while ((player = it.GetNext()) != nullptr) { - EXPECT_TRUE(timeline_->GetPlayerById(player->id())); + for (auto& player : element_animations_impl_->players_list()) { + EXPECT_TRUE(timeline_->GetPlayerById(player.id())); ++list_size_after; } EXPECT_EQ(2, list_size_after); @@ -336,7 +337,7 @@ TEST_F(ElementAnimationsTest, AddedPlayerIsDestroyed) { element_animations_impl_->Animate(kInitialTickTime); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); element_animations_impl_->UpdateState(true, events.get()); EXPECT_EQ(1u, events->events_.size()); EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); @@ -365,7 +366,7 @@ TEST_F(ElementAnimationsTest, DoNotClobberStartTimes) { EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, player_impl_->GetAnimationById(animation_id)->run_state()); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime); element_animations_impl_->UpdateState(true, events.get()); @@ -401,7 +402,7 @@ TEST_F(ElementAnimationsTest, UseSpecifiedStartTimes) { EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, player_impl_->GetAnimationById(animation_id)->run_state()); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime); element_animations_impl_->UpdateState(true, events.get()); @@ -431,7 +432,7 @@ TEST_F(ElementAnimationsTest, Activation) { AnimationHost* host = client_.host(); AnimationHost* host_impl = client_impl_.host(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); EXPECT_EQ(1u, host->all_element_animations_for_testing().size()); EXPECT_EQ(1u, host_impl->all_element_animations_for_testing().size()); @@ -470,7 +471,7 @@ TEST_F(ElementAnimationsTest, Activation) { player_->GetAnimation(TargetProperty::OPACITY)->run_state()); EXPECT_EQ(1u, host->active_element_animations_for_testing().size()); - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1500)); @@ -526,7 +527,7 @@ TEST_F(ElementAnimationsTest, SyncPause) { TimeTicks time = kInitialTickTime; // Start the animations on each animations. - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); element_animations_impl_->Animate(time); element_animations_impl_->UpdateState(true, events.get()); EXPECT_EQ(1u, events->events_.size()); @@ -578,7 +579,7 @@ TEST_F(ElementAnimationsTest, DoNotSyncFinishedAnimation) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); EXPECT_FALSE(player_impl_->GetAnimation(TargetProperty::OPACITY)); @@ -592,7 +593,7 @@ TEST_F(ElementAnimationsTest, DoNotSyncFinishedAnimation) { EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, player_impl_->GetAnimationById(animation_id)->run_state()); - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime); element_animations_impl_->UpdateState(true, events.get()); EXPECT_EQ(1u, events->events_.size()); @@ -602,7 +603,7 @@ TEST_F(ElementAnimationsTest, DoNotSyncFinishedAnimation) { player_->NotifyAnimationStarted(events->events_[0]); // Complete animation on impl thread. - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime + TimeDelta::FromSeconds(1)); element_animations_impl_->UpdateState(true, events.get()); @@ -627,7 +628,7 @@ TEST_F(ElementAnimationsTest, AnimationsAreDeleted) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); AddOpacityTransitionToPlayer(player_.get(), 1.0, 0.0f, 1.0f, false); element_animations_->Animate(kInitialTickTime); @@ -658,7 +659,7 @@ TEST_F(ElementAnimationsTest, AnimationsAreDeleted) { EXPECT_FALSE(host_->needs_push_properties()); EXPECT_FALSE(host_impl_->needs_push_properties()); - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); element_animations_impl_->UpdateState(true, events.get()); @@ -713,7 +714,7 @@ TEST_F(ElementAnimationsTest, TrivialTransition) { CreateTestLayer(true, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); std::unique_ptr<Animation> to_add(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), @@ -743,7 +744,7 @@ TEST_F(ElementAnimationsTest, FilterTransition) { CreateTestLayer(true, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); std::unique_ptr<KeyframedFilterAnimationCurve> curve( KeyframedFilterAnimationCurve::Create()); @@ -795,7 +796,7 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransition) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); gfx::ScrollOffset initial_value(100.f, 300.f); gfx::ScrollOffset target_value(300.f, 200.f); @@ -871,7 +872,7 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransitionOnImplOnly) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); gfx::ScrollOffset initial_value(100.f, 300.f); gfx::ScrollOffset target_value(300.f, 200.f); @@ -925,7 +926,7 @@ TEST_F(ElementAnimationsTest, UpdateStateWithoutAnimate) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); // Add first scroll offset animation. AddScrollOffsetAnimationToPlayer(player_impl_.get(), @@ -983,7 +984,7 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransitionNoImplProvider) { EXPECT_TRUE(element_animations_impl_->has_element_in_pending_list()); EXPECT_FALSE(element_animations_impl_->has_element_in_active_list()); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); gfx::ScrollOffset initial_value(500.f, 100.f); gfx::ScrollOffset target_value(300.f, 200.f); @@ -1068,7 +1069,7 @@ TEST_F(ElementAnimationsTest, ScrollOffsetRemovalClearsScrollDelta) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); // First test the 1-argument version of RemoveAnimation. gfx::ScrollOffset target_value(300.f, 200.f); @@ -1175,7 +1176,7 @@ TEST_F(ElementAnimationsTest, AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); TestAnimationDelegate delegate; player_impl_->set_animation_delegate(&delegate); @@ -1202,7 +1203,7 @@ TEST_F(ElementAnimationsTest, EXPECT_TRUE(delegate.started()); EXPECT_FALSE(delegate.finished()); - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime + duration); EXPECT_EQ(duration, player_impl_->GetAnimation(TargetProperty::SCROLL_OFFSET) ->curve() @@ -1235,7 +1236,7 @@ TEST_F(ElementAnimationsTest, SpecifiedStartTimesAreSentToMainThreadDelegate) { EXPECT_EQ(Animation::WAITING_FOR_TARGET_AVAILABILITY, player_impl_->GetAnimationById(animation_id)->run_state()); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime); element_animations_impl_->UpdateState(true, events.get()); @@ -1254,7 +1255,7 @@ TEST_F(ElementAnimationsTest, CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); std::unique_ptr<Animation> to_add(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), @@ -1295,7 +1296,7 @@ TEST_F(ElementAnimationsTest, TrivialQueuing) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); EXPECT_FALSE(player_->needs_to_start_animations()); @@ -1337,7 +1338,7 @@ TEST_F(ElementAnimationsTest, Interrupt) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); player_->AddAnimation(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), @@ -1373,7 +1374,7 @@ TEST_F(ElementAnimationsTest, ScheduleTogetherWhenAPropertyIsBlocked) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); player_->AddAnimation(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, @@ -1410,7 +1411,7 @@ TEST_F(ElementAnimationsTest, ScheduleTogetherWithAnAnimWaiting) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); player_->AddAnimation(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeTransformTransition(2)), 1, @@ -1451,7 +1452,7 @@ TEST_F(ElementAnimationsTest, TrivialLooping) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); std::unique_ptr<Animation> to_add(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), @@ -1501,7 +1502,7 @@ TEST_F(ElementAnimationsTest, InfiniteLooping) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); std::unique_ptr<Animation> to_add(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), @@ -1548,7 +1549,7 @@ TEST_F(ElementAnimationsTest, PauseResume) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); player_->AddAnimation(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)), @@ -1596,7 +1597,7 @@ TEST_F(ElementAnimationsTest, AbortAGroupedAnimation) { CreateTestLayer(false, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); const int animation_id = 2; player_->AddAnimation(Animation::Create( @@ -1640,7 +1641,7 @@ TEST_F(ElementAnimationsTest, PushUpdatesWhenSynchronizedStartTimeNeeded) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); std::unique_ptr<Animation> to_add(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeFloatTransition(2.0, 0.f, 1.f)), @@ -1670,7 +1671,7 @@ TEST_F(ElementAnimationsTest, SkipUpdateState) { CreateTestLayer(true, false); AttachTimelinePlayerLayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); std::unique_ptr<Animation> first_animation(CreateAnimation( std::unique_ptr<AnimationCurve>(new FakeTransformTransition(1)), 1, @@ -1693,7 +1694,7 @@ TEST_F(ElementAnimationsTest, SkipUpdateState) { element_animations_->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(2000)); - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_->UpdateState(true, events.get()); // Should have one STARTED event and one FINISHED event. @@ -1719,7 +1720,7 @@ TEST_F(ElementAnimationsTest, InactiveObserverGetsTicked) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); const int id = 1; player_impl_->AddAnimation(CreateAnimation( @@ -1963,7 +1964,7 @@ TEST_F(ElementAnimationsTest, ImplThreadAbortedAnimationGetsDeleted) { EXPECT_TRUE(host_impl_->needs_push_properties()); EXPECT_TRUE(player_impl_->needs_push_properties()); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime); element_animations_impl_->UpdateState(true, events.get()); EXPECT_TRUE(host_impl_->needs_push_properties()); @@ -2030,7 +2031,7 @@ TEST_F(ElementAnimationsTest, ImplThreadTakeoverAnimationGetsDeleted) { Animation::ABORTED_BUT_NEEDS_COMPLETION, player_impl_->GetAnimation(TargetProperty::SCROLL_OFFSET)->run_state()); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime); element_animations_impl_->UpdateState(true, events.get()); EXPECT_TRUE(delegate_impl.finished()); @@ -2069,7 +2070,7 @@ TEST_F(ElementAnimationsTest, FinishedEventsForGroup) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); const int group_id = 1; @@ -2094,7 +2095,7 @@ TEST_F(ElementAnimationsTest, FinishedEventsForGroup) { EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type); EXPECT_EQ(AnimationEvent::STARTED, events->events_[1].type); - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); element_animations_impl_->UpdateState(true, events.get()); @@ -2124,7 +2125,7 @@ TEST_F(ElementAnimationsTest, FinishedAndAbortedEventsForGroup) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); // Add two animations with the same group id. std::unique_ptr<Animation> first_animation(CreateAnimation( @@ -2149,7 +2150,7 @@ TEST_F(ElementAnimationsTest, FinishedAndAbortedEventsForGroup) { player_impl_->AbortAnimations(TargetProperty::OPACITY, false); - events = host_impl_->CreateEvents(); + events = CreateEventsForTesting(); element_animations_impl_->Animate(kInitialTickTime + TimeDelta::FromMilliseconds(1000)); element_animations_impl_->UpdateState(true, events.get()); @@ -2566,7 +2567,7 @@ TEST_F(ElementAnimationsTest, NewlyPushedAnimationWaitsForActivation) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); EXPECT_FALSE(player_->needs_to_start_animations()); int animation_id = @@ -2625,7 +2626,7 @@ TEST_F(ElementAnimationsTest, ActivationBetweenAnimateAndUpdateState) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); const int animation_id = AddOpacityTransitionToPlayer(player_.get(), 1, 0.5f, 1.f, true); @@ -2676,7 +2677,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenTransformAnimationChanges) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); EXPECT_FALSE(client_.GetHasPotentialTransformAnimation( element_id_, ElementListType::ACTIVE)); @@ -2897,7 +2898,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenOpacityAnimationChanges) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); EXPECT_FALSE(client_.GetHasPotentialOpacityAnimation( element_id_, ElementListType::ACTIVE)); @@ -3113,7 +3114,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenFilterAnimationChanges) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); EXPECT_FALSE(client_.GetHasPotentialFilterAnimation(element_id_, ElementListType::ACTIVE)); @@ -3355,7 +3356,7 @@ TEST_F(ElementAnimationsTest, PushedDeletedAnimationWaitsForActivation) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); const int animation_id = AddOpacityTransitionToPlayer(player_.get(), 1, 0.5f, 1.f, true); @@ -3410,7 +3411,7 @@ TEST_F(ElementAnimationsTest, StartAnimationsAffectingDifferentObservers) { AttachTimelinePlayerLayer(); CreateImplTimelineAndPlayer(); - auto events = host_impl_->CreateEvents(); + auto events = CreateEventsForTesting(); const int first_animation_id = AddOpacityTransitionToPlayer(player_.get(), 1, 0.f, 1.f, true); diff --git a/chromium/cc/animation/scroll_offset_animations_impl.cc b/chromium/cc/animation/scroll_offset_animations_impl.cc index ab3dfe32dbf..71a96b429f5 100644 --- a/chromium/cc/animation/scroll_offset_animations_impl.cc +++ b/chromium/cc/animation/scroll_offset_animations_impl.cc @@ -4,7 +4,6 @@ #include "cc/animation/scroll_offset_animations_impl.h" -#include "cc/animation/animation_events.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" #include "cc/animation/animation_player.h" diff --git a/chromium/cc/animation/scroll_offset_animations_impl.h b/chromium/cc/animation/scroll_offset_animations_impl.h index 4db60057457..9d29cdd72f4 100644 --- a/chromium/cc/animation/scroll_offset_animations_impl.h +++ b/chromium/cc/animation/scroll_offset_animations_impl.h @@ -18,7 +18,6 @@ namespace cc { class AnimationPlayer; class AnimationHost; class AnimationTimeline; -class ElementAnimations; // Contains an AnimationTimeline and its AnimationPlayer that owns the impl // only scroll offset animations running on a particular CC Layer. diff --git a/chromium/cc/base/switches.cc b/chromium/cc/base/switches.cc index 483c2e392a5..3d2fa44a324 100644 --- a/chromium/cc/base/switches.cc +++ b/chromium/cc/base/switches.cc @@ -30,11 +30,13 @@ const char kDisableMainFrameBeforeActivation[] = const char kEnableMainFrameBeforeActivation[] = "enable-main-frame-before-activation"; -// Percentage of the top controls need to be hidden before they will auto hide. -const char kTopControlsHideThreshold[] = "top-controls-hide-threshold"; +// Percentage of the browser controls need to be hidden before they will auto +// hide. +const char kBrowserControlsHideThreshold[] = "top-controls-hide-threshold"; -// Percentage of the top controls need to be shown before they will auto show. -const char kTopControlsShowThreshold[] = "top-controls-show-threshold"; +// Percentage of the browser controls need to be shown before they will auto +// show. +const char kBrowserControlsShowThreshold[] = "top-controls-show-threshold"; // Re-rasters everything multiple times to simulate a much slower machine. // Give a scale factor to cause raster to take that many times longer to diff --git a/chromium/cc/base/switches.h b/chromium/cc/base/switches.h index 954c30f1582..66e406b6e8c 100644 --- a/chromium/cc/base/switches.h +++ b/chromium/cc/base/switches.h @@ -21,8 +21,8 @@ CC_EXPORT extern const char kDisableCachedPictureRaster[]; CC_EXPORT extern const char kDisableCompositedAntialiasing[]; CC_EXPORT extern const char kDisableMainFrameBeforeActivation[]; CC_EXPORT extern const char kEnableMainFrameBeforeActivation[]; -CC_EXPORT extern const char kTopControlsHideThreshold[]; -CC_EXPORT extern const char kTopControlsShowThreshold[]; +CC_EXPORT extern const char kBrowserControlsHideThreshold[]; +CC_EXPORT extern const char kBrowserControlsShowThreshold[]; CC_EXPORT extern const char kSlowDownRasterScaleFactor[]; CC_EXPORT extern const char kStrictLayerPropertyChangeChecking[]; CC_EXPORT extern const char kEnableTileCompression[]; diff --git a/chromium/cc/blimp/compositor_state_deserializer.cc b/chromium/cc/blimp/compositor_state_deserializer.cc index bd2469f01bd..1ea4dd05e5f 100644 --- a/chromium/cc/blimp/compositor_state_deserializer.cc +++ b/chromium/cc/blimp/compositor_state_deserializer.cc @@ -6,15 +6,21 @@ #include "base/bind.h" #include "base/memory/ptr_util.h" -#include "cc/blimp/compositor_state_deserializer_client.h" +#include "cc/blimp/client_picture_cache.h" +#include "cc/blimp/deserialized_content_layer_client.h" #include "cc/blimp/layer_factory.h" +#include "cc/blimp/picture_data_conversions.h" #include "cc/input/layer_selection_bound.h" #include "cc/layers/layer.h" +#include "cc/layers/picture_layer.h" +#include "cc/layers/solid_color_scrollbar_layer.h" #include "cc/proto/cc_conversions.h" +#include "cc/proto/client_state_update.pb.h" #include "cc/proto/gfx_conversions.h" #include "cc/proto/layer_tree_host.pb.h" #include "cc/proto/skia_conversions.h" -#include "cc/trees/layer_tree_host.h" +#include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/layer_tree_host_in_process.h" namespace cc { namespace { @@ -28,18 +34,57 @@ class DefaultLayerFactory : public LayerFactory { scoped_refptr<Layer> CreateLayer(int engine_layer_id) override { return Layer::Create(); } + scoped_refptr<PictureLayer> CreatePictureLayer( + int engine_layer_id, + ContentLayerClient* content_layer_client) override { + return PictureLayer::Create(content_layer_client); + } + scoped_refptr<SolidColorScrollbarLayer> CreateSolidColorScrollbarLayer( + int engine_layer_id, + ScrollbarOrientation orientation, + int thumb_thickness, + int track_start, + bool is_left_side_vertical_scrollbar, + int scroll_layer_id) override { + return SolidColorScrollbarLayer::Create( + orientation, thumb_thickness, track_start, + is_left_side_vertical_scrollbar, scroll_layer_id); + } + scoped_refptr<PictureLayer> CreateFakePictureLayer( + int engine_layer_id, + ContentLayerClient* content_layer_client) override { + // We should never create fake layers in production code. + NOTREACHED(); + return PictureLayer::Create(content_layer_client); + } + scoped_refptr<Layer> CreatePushPropertiesCountingLayer( + int engine_layer_id) override { + // We should never create fake layers in production code. + NOTREACHED(); + return Layer::Create(); + } }; } // namespace +CompositorStateDeserializer::LayerData::LayerData() = default; + +CompositorStateDeserializer::LayerData::~LayerData() = default; + +CompositorStateDeserializer::LayerData::LayerData(LayerData&& other) = default; + +CompositorStateDeserializer::LayerData& CompositorStateDeserializer::LayerData:: +operator=(LayerData&& other) = default; + CompositorStateDeserializer::CompositorStateDeserializer( - LayerTreeHost* layer_tree_host, - ScrollCallback scroll_callback, + LayerTreeHostInProcess* layer_tree_host, + std::unique_ptr<ClientPictureCache> client_picture_cache, CompositorStateDeserializerClient* client) : layer_factory_(base::MakeUnique<DefaultLayerFactory>()), layer_tree_host_(layer_tree_host), - scroll_callback_(scroll_callback), - client_(client) { + client_picture_cache_(std::move(client_picture_cache)), + client_(client), + weak_factory_(this) { DCHECK(layer_tree_host_); DCHECK(client_); } @@ -50,7 +95,7 @@ Layer* CompositorStateDeserializer::GetLayerForEngineId( int engine_layer_id) const { EngineIdToLayerMap::const_iterator layer_it = engine_id_to_layer_.find(engine_layer_id); - return layer_it != engine_id_to_layer_.end() ? layer_it->second.get() + return layer_it != engine_id_to_layer_.end() ? layer_it->second.layer.get() : nullptr; } @@ -58,11 +103,21 @@ void CompositorStateDeserializer::DeserializeCompositorUpdate( const proto::LayerTreeHost& layer_tree_host_proto) { SychronizeLayerTreeState(layer_tree_host_proto.layer_tree()); + // Ensure ClientPictureCache contains all the necessary SkPictures before + // deserializing the properties. + proto::SkPictures proto_pictures = layer_tree_host_proto.pictures(); + std::vector<PictureData> pictures = + SkPicturesProtoToPictureDataVector(proto_pictures); + client_picture_cache_->ApplyCacheUpdate(pictures); + const proto::LayerUpdate& layer_updates = layer_tree_host_proto.layer_updates(); for (int i = 0; i < layer_updates.layers_size(); ++i) { SynchronizeLayerState(layer_updates.layers(i)); } + + // The deserialization is finished, so now clear the cache. + client_picture_cache_->Flush(); } void CompositorStateDeserializer::SetLayerFactoryForTesting( @@ -70,6 +125,99 @@ void CompositorStateDeserializer::SetLayerFactoryForTesting( layer_factory_ = std::move(layer_factory); } +void CompositorStateDeserializer::ApplyViewportDeltas( + const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, + const gfx::Vector2dF& elastic_overscroll_delta, + float page_scale, + float top_controls_delta) { + DCHECK_EQ(top_controls_delta, 0.0f); + DCHECK(elastic_overscroll_delta == gfx::Vector2dF()); + DCHECK(outer_delta == gfx::Vector2dF()); + + // The inner_delta can be ignored here, since we receive that in the scroll + // callback on the layer itself. + if (page_scale != 1.0f) { + LayerTree* layer_tree = layer_tree_host_->GetLayerTree(); + synced_page_scale_.UpdateDeltaFromImplThread( + layer_tree->page_scale_factor()); + layer_tree->SetPageScaleFactorAndLimits( + synced_page_scale_.EngineMain(), layer_tree->min_page_scale_factor(), + layer_tree->max_page_scale_factor()); + client_->DidUpdateLocalState(); + } +} + +void CompositorStateDeserializer::PullClientStateUpdate( + proto::ClientStateUpdate* client_state_update) { + for (auto& layer_it : engine_id_to_layer_) { + int engine_layer_id = layer_it.first; + auto& synced_scroll_offset = layer_it.second.synced_scroll_offset; + gfx::ScrollOffset scroll_offset_delta = + synced_scroll_offset.PullDeltaForEngineUpdate(); + gfx::Vector2dF scroll_delta_vector = + gfx::ScrollOffsetToVector2dF(scroll_offset_delta); + + if (scroll_delta_vector.IsZero()) { + continue; + } + + proto::ScrollUpdate* scroll_update = + client_state_update->add_scroll_updates(); + scroll_update->set_layer_id(engine_layer_id); + Vector2dFToProto(scroll_delta_vector, + scroll_update->mutable_scroll_delta()); + } + + float page_scale_delta = synced_page_scale_.PullDeltaForEngineUpdate(); + if (page_scale_delta != 1.0f) { + client_state_update->set_page_scale_delta(page_scale_delta); + } +} + +void CompositorStateDeserializer::DidApplyStateUpdatesOnEngine() { + for (auto& layer_it : engine_id_to_layer_) { + Layer* layer = layer_it.second.layer.get(); + auto& synced_scroll_offset = layer_it.second.synced_scroll_offset; + + synced_scroll_offset.DidApplySentDeltaOnEngine(); + layer->SetScrollOffset(synced_scroll_offset.EngineMain()); + } + + synced_page_scale_.DidApplySentDeltaOnEngine(); + LayerTree* layer_tree = layer_tree_host_->GetLayerTree(); + layer_tree->SetPageScaleFactorAndLimits(synced_page_scale_.EngineMain(), + layer_tree->min_page_scale_factor(), + layer_tree->max_page_scale_factor()); +} + +void CompositorStateDeserializer::SendUnappliedDeltasToLayerTreeHost() { + std::unique_ptr<ReflectedMainFrameState> reflected_main_frame_state = + base::MakeUnique<ReflectedMainFrameState>(); + + for (auto& layer_it : engine_id_to_layer_) { + Layer* layer = layer_it.second.layer.get(); + auto& synced_scroll_offset = layer_it.second.synced_scroll_offset; + + gfx::ScrollOffset scroll_offset_delta = + synced_scroll_offset.DeltaNotAppliedOnEngine(); + gfx::Vector2dF scroll_delta_vector = + gfx::ScrollOffsetToVector2dF(scroll_offset_delta); + if (scroll_delta_vector.IsZero()) + continue; + + ReflectedMainFrameState::ScrollUpdate scroll_update; + scroll_update.layer_id = layer->id(); + scroll_update.scroll_delta = scroll_delta_vector; + reflected_main_frame_state->scrolls.push_back(scroll_update); + } + + reflected_main_frame_state->page_scale_delta = + synced_page_scale_.DeltaNotAppliedOnEngine(); + layer_tree_host_->SetReflectedMainFrameState( + std::move(reflected_main_frame_state)); +} + void CompositorStateDeserializer::SychronizeLayerTreeState( const proto::LayerTree& layer_tree_proto) { LayerTree* layer_tree = layer_tree_host_->GetLayerTree(); @@ -78,17 +226,36 @@ void CompositorStateDeserializer::SychronizeLayerTreeState( // TODO(khushalsagar): Don't do this if the hierarchy didn't change. See // crbug.com/605170. EngineIdToLayerMap new_engine_id_to_layer; + ScrollbarLayerToScrollLayerId scrollbar_layer_to_scroll_layer; if (layer_tree_proto.has_root_layer()) { const proto::LayerNode& root_layer_node = layer_tree_proto.root_layer(); layer_tree->SetRootLayer( - GetLayerAndAddToNewMap(root_layer_node, &new_engine_id_to_layer)); - SynchronizeLayerHierarchyRecursive( - layer_tree->root_layer(), root_layer_node, &new_engine_id_to_layer); + GetLayerAndAddToNewMap(root_layer_node, &new_engine_id_to_layer, + &scrollbar_layer_to_scroll_layer)); + SynchronizeLayerHierarchyRecursive(layer_tree->root_layer(), + root_layer_node, &new_engine_id_to_layer, + &scrollbar_layer_to_scroll_layer); } else { layer_tree->SetRootLayer(nullptr); } engine_id_to_layer_.swap(new_engine_id_to_layer); + // Now that the tree has been synced, we can set up the scroll layers, since + // the corresponding engine layers have been created. + for (const auto& scrollbar : scrollbar_layer_to_scroll_layer) { + // This corresponds to the id of the Scrollbar Layer. + int scrollbar_layer_id = scrollbar.first; + + // This corresponds to the id of the scroll layer for this scrollbar. + int scroll_layer_id = scrollbar.second; + + SolidColorScrollbarLayer* scrollbar_layer = + static_cast<SolidColorScrollbarLayer*>( + GetLayerForEngineId(scrollbar_layer_id)); + + scrollbar_layer->SetScrollLayer(GetClientIdFromEngineId(scroll_layer_id)); + } + // Synchronize rest of the tree state. layer_tree->RegisterViewportLayers( GetLayer(layer_tree_proto.overscroll_elasticity_layer_id()), @@ -103,10 +270,10 @@ void CompositorStateDeserializer::SychronizeLayerTreeState( float min_page_scale_factor = layer_tree_proto.min_page_scale_factor(); float max_page_scale_factor = layer_tree_proto.max_page_scale_factor(); float page_scale_factor = layer_tree_proto.page_scale_factor(); - if (client_->ShouldRetainClientPageScale(page_scale_factor)) - page_scale_factor = layer_tree->page_scale_factor(); - layer_tree->SetPageScaleFactorAndLimits( - page_scale_factor, min_page_scale_factor, max_page_scale_factor); + synced_page_scale_.PushFromEngineMainThread(page_scale_factor); + layer_tree->SetPageScaleFactorAndLimits(synced_page_scale_.EngineMain(), + min_page_scale_factor, + max_page_scale_factor); layer_tree->set_background_color(layer_tree_proto.background_color()); layer_tree->set_has_transparent_background( @@ -139,8 +306,8 @@ void CompositorStateDeserializer::SynchronizeLayerState( int engine_layer_id = layer_properties_proto.id(); Layer* layer = GetLayerForEngineId(engine_layer_id); + // Layer Inputs ----------------------------------------------------- const proto::BaseLayerProperties& base = layer_properties_proto.base(); - layer->SetNeedsDisplayRect(ProtoToRect(base.update_rect())); layer->SetBounds(ProtoToSize(base.bounds())); layer->SetMasksToBounds(base.masks_to_bounds()); @@ -158,10 +325,12 @@ void CompositorStateDeserializer::SynchronizeLayerState( layer->SetUseParentBackfaceVisibility(base.use_parent_backface_visibility()); layer->SetBackgroundColor(base.background_color()); - gfx::ScrollOffset scroll_offset = ProtoToScrollOffset(base.scroll_offset()); - if (client_->ShouldRetainClientScroll(engine_layer_id, scroll_offset)) - scroll_offset = layer->scroll_offset(); - layer->SetScrollOffset(scroll_offset); + gfx::ScrollOffset engine_scroll_offset = + ProtoToScrollOffset(base.scroll_offset()); + SyncedRemoteScrollOffset& synced_scroll_offset = + GetLayerData(engine_layer_id)->synced_scroll_offset; + synced_scroll_offset.PushFromEngineMainThread(engine_scroll_offset); + layer->SetScrollOffset(synced_scroll_offset.EngineMain()); layer->SetScrollClipLayerId( GetClientIdFromEngineId(base.scroll_clip_layer_id())); @@ -196,82 +365,192 @@ void CompositorStateDeserializer::SynchronizeLayerState( layer->SetHasWillChangeTransformHint(base.has_will_change_transform_hint()); layer->SetHideLayerAndSubtree(base.hide_layer_and_subtree()); + + // ------------------------------------------------------------------ + + // PictureLayer Properties deserialization. + if (layer_properties_proto.has_picture()) { + const proto::PictureLayerProperties& picture_properties = + layer_properties_proto.picture(); + + // Only PictureLayers set picture. + PictureLayer* picture_layer = + static_cast<PictureLayer*>(GetLayerForEngineId(engine_layer_id)); + picture_layer->SetNearestNeighbor(picture_properties.nearest_neighbor()); + + gfx::Rect recorded_viewport = + ProtoToRect(picture_properties.recorded_viewport()); + scoped_refptr<DisplayItemList> display_list; + std::vector<uint32_t> used_engine_picture_ids; + if (picture_properties.has_display_list()) { + display_list = DisplayItemList::CreateFromProto( + picture_properties.display_list(), client_picture_cache_.get(), + &used_engine_picture_ids); + } else { + display_list = nullptr; + } + + // TODO(khushalsagar): The caching here is sub-optimal. If a layer does not + // PushProperties, its pictures won't get counted here even if the layer + // is drawn in the current frame. + for (uint32_t engine_picture_id : used_engine_picture_ids) + client_picture_cache_->MarkUsed(engine_picture_id); + + GetContentLayerClient(engine_layer_id) + ->UpdateDisplayListAndRecordedViewport(display_list, recorded_viewport); + } } void CompositorStateDeserializer::SynchronizeLayerHierarchyRecursive( Layer* layer, const proto::LayerNode& layer_node, - EngineIdToLayerMap* new_layer_map) { + EngineIdToLayerMap* new_layer_map, + ScrollbarLayerToScrollLayerId* scrollbar_layer_to_scroll_layer) { layer->RemoveAllChildren(); // Children. for (int i = 0; i < layer_node.children_size(); i++) { const proto::LayerNode& child_layer_node = layer_node.children(i); - scoped_refptr<Layer> child_layer = - GetLayerAndAddToNewMap(child_layer_node, new_layer_map); + scoped_refptr<Layer> child_layer = GetLayerAndAddToNewMap( + child_layer_node, new_layer_map, scrollbar_layer_to_scroll_layer); layer->AddChild(child_layer); SynchronizeLayerHierarchyRecursive(child_layer.get(), child_layer_node, - new_layer_map); + new_layer_map, + scrollbar_layer_to_scroll_layer); } // Mask Layer. if (layer_node.has_mask_layer()) { const proto::LayerNode& mask_layer_node = layer_node.mask_layer(); - scoped_refptr<Layer> mask_layer = - GetLayerAndAddToNewMap(mask_layer_node, new_layer_map); + scoped_refptr<Layer> mask_layer = GetLayerAndAddToNewMap( + mask_layer_node, new_layer_map, scrollbar_layer_to_scroll_layer); layer->SetMaskLayer(mask_layer.get()); SynchronizeLayerHierarchyRecursive(mask_layer.get(), mask_layer_node, - new_layer_map); + new_layer_map, + scrollbar_layer_to_scroll_layer); } else { layer->SetMaskLayer(nullptr); } // Scroll callback. - layer->set_did_scroll_callback(base::Bind(scroll_callback_, layer_node.id())); + layer->set_did_scroll_callback( + base::Bind(&CompositorStateDeserializer::LayerScrolled, + weak_factory_.GetWeakPtr(), layer_node.id())); } scoped_refptr<Layer> CompositorStateDeserializer::GetLayerAndAddToNewMap( const proto::LayerNode& layer_node, - EngineIdToLayerMap* new_layer_map) { + EngineIdToLayerMap* new_layer_map, + ScrollbarLayerToScrollLayerId* scrollbar_layer_to_scroll_layer) { DCHECK(new_layer_map->find(layer_node.id()) == new_layer_map->end()) << "A LayerNode should have been de-serialized only once"; + scoped_refptr<Layer> layer; EngineIdToLayerMap::iterator layer_map_it = engine_id_to_layer_.find(layer_node.id()); if (layer_map_it != engine_id_to_layer_.end()) { // We can re-use the old layer. - (*new_layer_map)[layer_node.id()] = layer_map_it->second; - return layer_map_it->second; + layer = layer_map_it->second.layer; + (*new_layer_map)[layer_node.id()] = std::move(layer_map_it->second); + engine_id_to_layer_.erase(layer_map_it); + return layer; } // We need to create a new layer. - scoped_refptr<Layer> layer; + auto& layer_data = (*new_layer_map)[layer_node.id()]; switch (layer_node.type()) { case proto::LayerNode::UNKNOWN: NOTREACHED() << "Unknown Layer type"; case proto::LayerNode::LAYER: - layer = layer_factory_->CreateLayer(layer_node.id()); + layer_data.layer = layer_factory_->CreateLayer(layer_node.id()); + break; + case proto::LayerNode::PICTURE_LAYER: + layer_data.content_layer_client = + base::MakeUnique<DeserializedContentLayerClient>(); + layer_data.layer = layer_factory_->CreatePictureLayer( + layer_node.id(), layer_data.content_layer_client.get()); + break; + case proto::LayerNode::FAKE_PICTURE_LAYER: + // FAKE_PICTURE_LAYER is for testing only. + layer_data.content_layer_client = + base::MakeUnique<DeserializedContentLayerClient>(); + layer_data.layer = layer_factory_->CreateFakePictureLayer( + layer_node.id(), layer_data.content_layer_client.get()); + break; + case proto::LayerNode::SOLID_COLOR_SCROLLBAR_LAYER: { + // SolidColorScrollbarLayers attach their properties in the LayerNode + // itself. + const proto::SolidColorScrollbarLayerProperties& scrollbar = + layer_node.solid_scrollbar(); + + DCHECK(scrollbar_layer_to_scroll_layer->find(layer_node.id()) == + scrollbar_layer_to_scroll_layer->end()); + int scroll_layer_id = scrollbar.scroll_layer_id(); + (*scrollbar_layer_to_scroll_layer)[layer_node.id()] = scroll_layer_id; + + int thumb_thickness = scrollbar.thumb_thickness(); + int track_start = scrollbar.track_start(); + bool is_left_side_vertical_scrollbar = + scrollbar.is_left_side_vertical_scrollbar(); + ScrollbarOrientation orientation = + ScrollbarOrientationFromProto(scrollbar.orientation()); + + // We use the invalid id for the |scroll_layer_id| because the + // corresponding layer on the client may not have been created yet. + layer_data.layer = layer_factory_->CreateSolidColorScrollbarLayer( + layer_node.id(), orientation, thumb_thickness, track_start, + is_left_side_vertical_scrollbar, Layer::LayerIdLabels::INVALID_ID); + } break; + case proto::LayerNode::PUSH_PROPERTIES_COUNTING_LAYER: + // PUSH_PROPERTIES_COUNTING_LAYER is for testing only. + layer_data.layer = + layer_factory_->CreatePushPropertiesCountingLayer(layer_node.id()); break; - default: - // TODO(khushalsagar): Add other Layer types. - NOTREACHED(); } - (*new_layer_map)[layer_node.id()] = layer; + layer = layer_data.layer; return layer; } -int CompositorStateDeserializer::GetClientIdFromEngineId(int engine_layer_id) { +void CompositorStateDeserializer::LayerScrolled(int engine_layer_id) { + LayerData* layer_data = GetLayerData(engine_layer_id); + Layer* layer = layer_data->layer.get(); + SyncedRemoteScrollOffset& synced_scroll_offset = + layer_data->synced_scroll_offset; + synced_scroll_offset.UpdateDeltaFromImplThread(layer->scroll_offset()); + layer->SetScrollOffset(synced_scroll_offset.EngineMain()); + client_->DidUpdateLocalState(); +} + +int CompositorStateDeserializer::GetClientIdFromEngineId( + int engine_layer_id) const { Layer* layer = GetLayerForEngineId(engine_layer_id); return layer ? layer->id() : Layer::LayerIdLabels::INVALID_ID; } scoped_refptr<Layer> CompositorStateDeserializer::GetLayer( - int engine_layer_id) { + int engine_layer_id) const { EngineIdToLayerMap::const_iterator layer_it = engine_id_to_layer_.find(engine_layer_id); - return layer_it != engine_id_to_layer_.end() ? layer_it->second : nullptr; + return layer_it != engine_id_to_layer_.end() ? layer_it->second.layer + : nullptr; +} + +DeserializedContentLayerClient* +CompositorStateDeserializer::GetContentLayerClient(int engine_layer_id) const { + EngineIdToLayerMap::const_iterator layer_it = + engine_id_to_layer_.find(engine_layer_id); + return layer_it != engine_id_to_layer_.end() + ? layer_it->second.content_layer_client.get() + : nullptr; +} + +CompositorStateDeserializer::LayerData* +CompositorStateDeserializer::GetLayerData(int engine_layer_id) { + EngineIdToLayerMap::iterator layer_it = + engine_id_to_layer_.find(engine_layer_id); + return layer_it != engine_id_to_layer_.end() ? &layer_it->second : nullptr; } } // namespace cc diff --git a/chromium/cc/blimp/compositor_state_deserializer.h b/chromium/cc/blimp/compositor_state_deserializer.h index 5357bcf5c5d..60e06d0a61a 100644 --- a/chromium/cc/blimp/compositor_state_deserializer.h +++ b/chromium/cc/blimp/compositor_state_deserializer.h @@ -9,31 +9,43 @@ #include "base/callback.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" +#include "cc/blimp/synced_property_remote.h" +#include "ui/gfx/geometry/scroll_offset.h" namespace cc { namespace proto { +class ClientStateUpdate; class LayerNode; class LayerProperties; class LayerTree; class LayerTreeHost; } // namespace proto -class CompositorStateDeserializerClient; +class ClientPictureCache; +class DeserializedContentLayerClient; class Layer; class LayerFactory; -class LayerTreeHost; +class LayerTreeHostInProcess; + +class CC_EXPORT CompositorStateDeserializerClient { + public: + virtual ~CompositorStateDeserializerClient() {} + + // Used to inform the client that the local state received from the engine was + // modified on the impl thread and a ClientStateUpdate needs to be scheduled + // to synchronize it with the main thread on the engine. + virtual void DidUpdateLocalState() = 0; +}; // Deserializes the compositor updates into the LayerTreeHost. class CC_EXPORT CompositorStateDeserializer { public: - // ScrollCallback used to notify the client when the scroll offset for a layer - // is updated. - using ScrollCallback = base::Callback<void(int engine_layer_id)>; - - CompositorStateDeserializer(LayerTreeHost* layer_tree_host, - ScrollCallback scroll_callback, - CompositorStateDeserializerClient* client); + CompositorStateDeserializer( + LayerTreeHostInProcess* layer_tree_host, + std::unique_ptr<ClientPictureCache> client_picture_cache, + CompositorStateDeserializerClient* client); ~CompositorStateDeserializer(); // Returns the local layer on the client for the given |engine_layer_id|. @@ -46,28 +58,91 @@ class CC_EXPORT CompositorStateDeserializer { // Allows tests to inject the LayerFactory. void SetLayerFactoryForTesting(std::unique_ptr<LayerFactory> layer_factory); + // Updates any viewport related deltas that have been reported to the main + // thread from the impl thread. + void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, + const gfx::Vector2dF& outer_delta, + const gfx::Vector2dF& elastic_overscroll_delta, + float page_scale, + float top_controls_delta); + + // Pulls a state update for changes reported to the main thread, that need to + // be synchronized with the associated state on the engine main thread. + void PullClientStateUpdate(proto::ClientStateUpdate* client_state_update); + + // Informs that the client state update pulled was applied to the main thread + // on the engine. + // Note that this assumes that the state update provided to the engine was + // reflected back by the engine. If the application of this update resulted in + // any changes to the main thread state on the engine, these must be + // de-serialized and applied to the LayerTreeHost before a frame is committed + // to the impl thread. + void DidApplyStateUpdatesOnEngine(); + + // Sends any deltas that have been received on the main thread, but have not + // yet been applied to the main thread state back to the impl thread. This + // must be called for every main frame sent to the impl thread. + void SendUnappliedDeltasToLayerTreeHost(); + private: - using EngineIdToLayerMap = std::unordered_map<int, scoped_refptr<Layer>>; + using SyncedRemoteScrollOffset = + SyncedPropertyRemote<AdditionGroup<gfx::ScrollOffset>>; + + // A holder for the Layer and any data tied to it. + struct LayerData { + LayerData(); + LayerData(LayerData&& other); + ~LayerData(); + + LayerData& operator=(LayerData&& other); + + scoped_refptr<Layer> layer; + + // Set only for PictureLayers. + std::unique_ptr<DeserializedContentLayerClient> content_layer_client; + + SyncedRemoteScrollOffset synced_scroll_offset; + + private: + DISALLOW_COPY_AND_ASSIGN(LayerData); + }; + + using EngineIdToLayerMap = std::unordered_map<int, LayerData>; + // Map of the scrollbar layer id to the corresponding scroll layer id. Both + // ids refer to the engine layer id. + using ScrollbarLayerToScrollLayerId = std::unordered_map<int, int>; void SychronizeLayerTreeState(const proto::LayerTree& layer_tree_proto); void SynchronizeLayerState( const proto::LayerProperties& layer_properties_proto); - void SynchronizeLayerHierarchyRecursive(Layer* layer, - const proto::LayerNode& layer_node, - EngineIdToLayerMap* new_layer_map); + void SynchronizeLayerHierarchyRecursive( + Layer* layer, + const proto::LayerNode& layer_node, + EngineIdToLayerMap* new_layer_map, + ScrollbarLayerToScrollLayerId* scrollbar_layer_to_scroll_layer); scoped_refptr<Layer> GetLayerAndAddToNewMap( const proto::LayerNode& layer_node, - EngineIdToLayerMap* new_layer_map); + EngineIdToLayerMap* new_layer_map, + ScrollbarLayerToScrollLayerId* scrollbar_layer_to_scroll_layer); + + void LayerScrolled(int engine_layer_id); - int GetClientIdFromEngineId(int engine_layer_id); - scoped_refptr<Layer> GetLayer(int engine_layer_id); + scoped_refptr<Layer> GetLayer(int engine_layer_id) const; + DeserializedContentLayerClient* GetContentLayerClient( + int engine_layer_id) const; + int GetClientIdFromEngineId(int engine_layer_id) const; + LayerData* GetLayerData(int engine_layer_id); std::unique_ptr<LayerFactory> layer_factory_; - LayerTreeHost* layer_tree_host_; - ScrollCallback scroll_callback_; + + LayerTreeHostInProcess* layer_tree_host_; + std::unique_ptr<ClientPictureCache> client_picture_cache_; CompositorStateDeserializerClient* client_; EngineIdToLayerMap engine_id_to_layer_; + SyncedPropertyRemote<ScaleGroup> synced_page_scale_; + + base::WeakPtrFactory<CompositorStateDeserializer> weak_factory_; DISALLOW_COPY_AND_ASSIGN(CompositorStateDeserializer); }; diff --git a/chromium/cc/blimp/compositor_state_deserializer_client.h b/chromium/cc/blimp/compositor_state_deserializer_client.h deleted file mode 100644 index 57143626b49..00000000000 --- a/chromium/cc/blimp/compositor_state_deserializer_client.h +++ /dev/null @@ -1,34 +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_BLIMP_COMPOSITOR_STATE_DESERIALIZER_CLIENT_H_ -#define CC_BLIMP_COMPOSITOR_STATE_DESERIALIZER_CLIENT_H_ - -#include "base/macros.h" -#include "cc/base/cc_export.h" - -namespace gfx { -class ScrollOffset; -} // namespace gfx - -namespace cc { - -class CC_EXPORT CompositorStateDeserializerClient { - public: - virtual ~CompositorStateDeserializerClient() {} - - // Returns true if the given scroll offset update received from the engine - // should be ignored. - virtual bool ShouldRetainClientScroll( - int engine_layer_id, - const gfx::ScrollOffset& new_offset) = 0; - - // Returns true if the given page scale update from the engine should be - // ignored. - virtual bool ShouldRetainClientPageScale(float new_page_scale) = 0; -}; - -} // namespace cc - -#endif // CC_BLIMP_COMPOSITOR_STATE_DESERIALIZER_CLIENT_H_ diff --git a/chromium/cc/blimp/compositor_state_deserializer_unittest.cc b/chromium/cc/blimp/compositor_state_deserializer_unittest.cc index 3d86f3193b0..46472928b42 100644 --- a/chromium/cc/blimp/compositor_state_deserializer_unittest.cc +++ b/chromium/cc/blimp/compositor_state_deserializer_unittest.cc @@ -6,236 +6,63 @@ #include "base/run_loop.h" #include "cc/animation/animation_host.h" +#include "cc/blimp/client_picture_cache.h" #include "cc/blimp/compositor_proto_state.h" -#include "cc/blimp/compositor_state_deserializer_client.h" #include "cc/blimp/layer_tree_host_remote.h" +#include "cc/layers/content_layer_client.h" +#include "cc/layers/picture_layer.h" +#include "cc/layers/solid_color_scrollbar_layer.h" +#include "cc/playback/display_item_list.h" +#include "cc/playback/drawing_display_item.h" #include "cc/proto/compositor_message.pb.h" +#include "cc/test/fake_image_serialization_processor.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_client.h" +#include "cc/test/fake_proxy.h" #include "cc/test/fake_remote_compositor_bridge.h" #include "cc/test/remote_client_layer_factory.h" +#include "cc/test/remote_compositor_test.h" +#include "cc/test/serialization_test_utils.h" +#include "cc/test/skia_common.h" #include "cc/test/stub_layer_tree_host_client.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host_common.h" #include "testing/gtest/include/gtest/gtest.h" +#include "third_party/skia/include/core/SkPictureRecorder.h" namespace cc { namespace { -#define EXPECT_LAYERS_EQ(engine_layer_id, client_layer) \ - EXPECT_EQ( \ - compositor_state_deserializer_->GetLayerForEngineId(engine_layer_id), \ - client_layer); - -class RemoteCompositorBridgeForTest : public FakeRemoteCompositorBridge { +class FakeContentLayerClient : public ContentLayerClient { public: - using ProtoFrameCallback = base::Callback<void( - std::unique_ptr<CompositorProtoState> compositor_proto_state)>; - - RemoteCompositorBridgeForTest( - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - ProtoFrameCallback proto_frame_callback) - : FakeRemoteCompositorBridge(main_task_runner), - proto_frame_callback_(proto_frame_callback) {} - - ~RemoteCompositorBridgeForTest() override = default; - - void ProcessCompositorStateUpdate( - std::unique_ptr<CompositorProtoState> compositor_proto_state) override { - proto_frame_callback_.Run(std::move(compositor_proto_state)); + FakeContentLayerClient(scoped_refptr<DisplayItemList> display_list, + gfx::Rect recorded_viewport) + : display_list_(std::move(display_list)), + recorded_viewport_(recorded_viewport) {} + ~FakeContentLayerClient() override {} + + // ContentLayerClient implementation. + gfx::Rect PaintableRegion() override { return recorded_viewport_; } + scoped_refptr<DisplayItemList> PaintContentsToDisplayList( + PaintingControlSetting painting_status) override { + return display_list_; } + bool FillsBoundsCompletely() const override { return false; } + size_t GetApproximateUnsharedMemoryUsage() const override { return 0; } private: - ProtoFrameCallback proto_frame_callback_; + scoped_refptr<DisplayItemList> display_list_; + gfx::Rect recorded_viewport_; }; -class CompositorStateDeserializerTest - : public testing::Test, - public CompositorStateDeserializerClient { +class CompositorStateDeserializerTest : public RemoteCompositorTest { public: - void SetUp() override { - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner = - base::ThreadTaskRunnerHandle::Get(); - - // Engine side setup. - LayerTreeHostRemote::InitParams params; - params.client = &layer_tree_host_client_remote_; - params.main_task_runner = main_task_runner; - params.animation_host = AnimationHost::CreateMainInstance(); - params.remote_compositor_bridge = - base::MakeUnique<RemoteCompositorBridgeForTest>( - main_task_runner, - base::Bind( - &CompositorStateDeserializerTest::ProcessCompositorStateUpdate, - base::Unretained(this))); - LayerTreeSettings settings; - params.settings = &settings; - - layer_tree_host_remote_ = base::MakeUnique<LayerTreeHostRemote>(¶ms); - - // Client side setup. - layer_tree_host_in_process_ = FakeLayerTreeHost::Create( - &layer_tree_host_client_client_, &task_graph_runner_); - compositor_state_deserializer_ = - base::MakeUnique<CompositorStateDeserializer>( - layer_tree_host_in_process_.get(), - base::Bind(&CompositorStateDeserializerTest::LayerScrolled, - base::Unretained(this)), - this); - } - - void TearDown() override { - layer_tree_host_remote_ = nullptr; - compositor_state_deserializer_ = nullptr; - layer_tree_host_in_process_ = nullptr; - } - - void ProcessCompositorStateUpdate( - std::unique_ptr<CompositorProtoState> compositor_proto_state) { - // Immediately deserialize the state update. - compositor_state_deserializer_->DeserializeCompositorUpdate( - compositor_proto_state->compositor_message->layer_tree_host()); - } - - // CompositorStateDeserializer implementation. - bool ShouldRetainClientScroll(int engine_layer_id, - const gfx::ScrollOffset& new_offset) override { - return should_retain_client_scroll_; - } - bool ShouldRetainClientPageScale(float new_page_scale) override { - return should_retain_client_scale_; - } - - void LayerScrolled(int engine_layer_id) {} - void VerifyTreesAreIdentical() { - LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); - LayerTree* client_layer_tree = layer_tree_host_in_process_->GetLayerTree(); - - if (engine_layer_tree->root_layer()) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - engine_layer_tree, [this](Layer* engine_layer) { - VerifyLayersAreIdentical( - engine_layer, - compositor_state_deserializer_->GetLayerForEngineId( - engine_layer->id())); - }); - } else { - EXPECT_EQ(layer_tree_host_in_process_->GetLayerTree()->root_layer(), - nullptr); - } - - // Viewport layers. - // Overscroll Elasticty Layer. - Layer* client_overscroll_elasticity_layer = - client_layer_tree->overscroll_elasticity_layer(); - if (engine_layer_tree->overscroll_elasticity_layer()) { - int engine_overscroll_elasticity_layer_id = - engine_layer_tree->overscroll_elasticity_layer()->id(); - - EXPECT_LAYERS_EQ(engine_overscroll_elasticity_layer_id, - client_overscroll_elasticity_layer); - } else { - EXPECT_EQ(client_overscroll_elasticity_layer, nullptr); - } - - // PageScale Layer. - Layer* client_page_scale_layer = client_layer_tree->page_scale_layer(); - if (engine_layer_tree->page_scale_layer()) { - int engine_page_scale_layer_id = - engine_layer_tree->page_scale_layer()->id(); - - EXPECT_LAYERS_EQ(engine_page_scale_layer_id, client_page_scale_layer); - } else { - EXPECT_EQ(client_page_scale_layer, nullptr); - } - - // InnerViewportScroll Layer. - Layer* client_inner_viewport_layer = - client_layer_tree->inner_viewport_scroll_layer(); - if (engine_layer_tree->inner_viewport_scroll_layer()) { - int engine_inner_viewport_layer_id = - engine_layer_tree->inner_viewport_scroll_layer()->id(); - - EXPECT_LAYERS_EQ(engine_inner_viewport_layer_id, - client_inner_viewport_layer); - } else { - EXPECT_EQ(client_inner_viewport_layer, nullptr); - } - - // OuterViewportScroll Layer. - Layer* client_outer_viewport_layer = - client_layer_tree->outer_viewport_scroll_layer(); - if (engine_layer_tree->outer_viewport_scroll_layer()) { - int engine_outer_viewport_layer_id = - engine_layer_tree->outer_viewport_scroll_layer()->id(); - - EXPECT_LAYERS_EQ(engine_outer_viewport_layer_id, - client_outer_viewport_layer); - } else { - EXPECT_EQ(client_outer_viewport_layer, nullptr); - } + VerifySerializedTreesAreIdentical( + layer_tree_host_remote_->GetLayerTree(), + layer_tree_host_in_process_->GetLayerTree(), + compositor_state_deserializer_.get()); } - - void VerifyLayersAreIdentical(Layer* engine_layer, Layer* client_layer) { - ASSERT_NE(client_layer, nullptr); - - LayerTree* client_layer_tree = layer_tree_host_in_process_->GetLayerTree(); - EXPECT_EQ(client_layer_tree, client_layer->GetLayerTree()); - - // Parent. - if (engine_layer->parent()) { - int engine_parent_id = engine_layer->parent()->id(); - EXPECT_LAYERS_EQ(engine_parent_id, client_layer->parent()); - } else { - EXPECT_EQ(client_layer->parent(), nullptr); - } - - // Mask Layers. - if (engine_layer->mask_layer()) { - int engine_mask_layer_id = engine_layer->mask_layer()->id(); - EXPECT_LAYERS_EQ(engine_mask_layer_id, client_layer->mask_layer()); - } else { - EXPECT_EQ(client_layer->mask_layer(), nullptr); - } - - // Scroll parent. - if (engine_layer->scroll_parent()) { - int engine_scroll_parent_id = engine_layer->scroll_parent()->id(); - EXPECT_LAYERS_EQ(engine_scroll_parent_id, client_layer->scroll_parent()); - } else { - EXPECT_EQ(client_layer->scroll_parent(), nullptr); - } - - // Clip parent. - if (engine_layer->clip_parent()) { - int engine_clip_parent_id = engine_layer->clip_parent()->id(); - EXPECT_LAYERS_EQ(engine_clip_parent_id, client_layer->clip_parent()); - } else { - EXPECT_EQ(client_layer->clip_parent(), nullptr); - } - - // Scroll-clip layer. - if (engine_layer->scroll_clip_layer()) { - int scroll_clip_id = engine_layer->scroll_clip_layer()->id(); - EXPECT_LAYERS_EQ(scroll_clip_id, client_layer->scroll_clip_layer()); - } else { - EXPECT_EQ(client_layer->scroll_clip_layer(), nullptr); - } - } - - // Engine setup. - std::unique_ptr<LayerTreeHostRemote> layer_tree_host_remote_; - StubLayerTreeHostClient layer_tree_host_client_remote_; - - // Client setup. - std::unique_ptr<FakeLayerTreeHost> layer_tree_host_in_process_; - std::unique_ptr<CompositorStateDeserializer> compositor_state_deserializer_; - FakeLayerTreeHostClient layer_tree_host_client_client_; - TestTaskGraphRunner task_graph_runner_; - - bool should_retain_client_scroll_ = false; - bool should_retain_client_scale_ = false; }; TEST_F(CompositorStateDeserializerTest, BasicSync) { @@ -338,32 +165,71 @@ TEST_F(CompositorStateDeserializerTest, ReconcileScrollAndScale) { // Synchronize State and verify that the engine values are used. base::RunLoop().RunUntilIdle(); VerifyTreesAreIdentical(); + Layer* client_scroll_layer = + compositor_state_deserializer_->GetLayerForEngineId(scroll_layer->id()); + EXPECT_EQ(engine_page_scale, + layer_tree_host_in_process_->GetLayerTree()->page_scale_factor()); + EXPECT_EQ(engine_offset, client_scroll_layer->scroll_offset()); + // Now send some updates from the impl thread. + ScrollAndScaleSet scroll_and_scale_set; + + gfx::ScrollOffset offset_from_impl_thread(10, 3); + gfx::ScrollOffset scroll_delta = + offset_from_impl_thread - client_scroll_layer->scroll_offset(); + LayerTreeHostCommon::ScrollUpdateInfo scroll_update; + scroll_update.layer_id = client_scroll_layer->id(); + scroll_update.scroll_delta = gfx::ScrollOffsetToFlooredVector2d(scroll_delta); + scroll_and_scale_set.scrolls.push_back(scroll_update); + + float page_scale_from_impl_side = 3.2f; + float page_scale_delta = + page_scale_from_impl_side / + layer_tree_host_in_process_->GetLayerTree()->page_scale_factor(); + scroll_and_scale_set.page_scale_delta = page_scale_delta; + + layer_tree_host_in_process_->ApplyScrollAndScale(&scroll_and_scale_set); + + // The values on the client should have been forced to retain the original + // engine value. EXPECT_EQ(engine_page_scale, layer_tree_host_in_process_->GetLayerTree()->page_scale_factor()); - EXPECT_EQ(engine_offset, compositor_state_deserializer_ - ->GetLayerForEngineId(scroll_layer->id()) - ->scroll_offset()); + EXPECT_EQ(engine_offset, client_scroll_layer->scroll_offset()); + + // Now pull the deltas from the client onto the engine, this should result + // in an aborted commit. + proto::ClientStateUpdate client_state_update; + compositor_state_deserializer_->PullClientStateUpdate(&client_state_update); + + // Send the reflected main frame state to the client layer tree host. + compositor_state_deserializer_->SendUnappliedDeltasToLayerTreeHost(); + const ReflectedMainFrameState* reflected_state = + layer_tree_host_in_process_->reflected_main_frame_state_for_testing(); + EXPECT_EQ(reflected_state->scrolls.size(), 1u); + EXPECT_EQ(reflected_state->scrolls[0].layer_id, client_scroll_layer->id()); + EXPECT_EQ(reflected_state->scrolls[0].scroll_delta, + gfx::ScrollOffsetToVector2dF(scroll_delta)); + EXPECT_EQ(reflected_state->page_scale_delta, page_scale_delta); + + layer_tree_host_remote_->ApplyStateUpdateFromClient(client_state_update); + + // Inform the deserializer that the updates were applied on the engine. + // This should pre-emptively apply the deltas on the client. + compositor_state_deserializer_->DidApplyStateUpdatesOnEngine(); + EXPECT_EQ(page_scale_from_impl_side, + layer_tree_host_in_process_->GetLayerTree()->page_scale_factor()); + EXPECT_EQ(offset_from_impl_thread, client_scroll_layer->scroll_offset()); - // Now reset the scroll offset and page scale and force-retain the client - // values. - gfx::ScrollOffset new_engine_offset(2, 2); + // Now update the scroll offset on the engine, and ensure that the value is + // used on the client. + gfx::ScrollOffset new_engine_offset(10, 20); scroll_layer->SetScrollOffset(new_engine_offset); - float new_engine_page_scale = 0.8f; - layer_tree_host_remote_->GetLayerTree()->SetPageScaleFactorAndLimits( - new_engine_page_scale, 1.0, 1.0); - should_retain_client_scroll_ = true; - should_retain_client_scale_ = true; - // Synchronize State and verify that the client values are retained. base::RunLoop().RunUntilIdle(); VerifyTreesAreIdentical(); - - EXPECT_EQ(engine_page_scale, + EXPECT_EQ(page_scale_from_impl_side, layer_tree_host_in_process_->GetLayerTree()->page_scale_factor()); - EXPECT_EQ(engine_offset, compositor_state_deserializer_ - ->GetLayerForEngineId(scroll_layer->id()) - ->scroll_offset()); + EXPECT_EQ(new_engine_offset, client_scroll_layer->scroll_offset()); } TEST_F(CompositorStateDeserializerTest, PropertyTreesAreIdentical) { @@ -417,5 +283,121 @@ TEST_F(CompositorStateDeserializerTest, PropertyTreesAreIdentical) { EXPECT_EQ(*engine_property_trees, *client_property_trees); } +TEST_F(CompositorStateDeserializerTest, SolidColorScrollbarLayer) { + scoped_refptr<Layer> root_layer = Layer::Create(); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer); + + scoped_refptr<Layer> child_layer1 = Layer::Create(); + root_layer->AddChild(child_layer1); + scoped_refptr<SolidColorScrollbarLayer> scroll_layer1 = + SolidColorScrollbarLayer::Create(ScrollbarOrientation::HORIZONTAL, 20, 5, + true, 3); + scroll_layer1->SetScrollLayer(child_layer1->id()); + child_layer1->AddChild(scroll_layer1); + + scoped_refptr<SolidColorScrollbarLayer> scroll_layer2 = + SolidColorScrollbarLayer::Create(ScrollbarOrientation::VERTICAL, 2, 9, + false, 3); + root_layer->AddChild(scroll_layer2); + scoped_refptr<Layer> child_layer2 = Layer::Create(); + scroll_layer2->AddChild(child_layer2); + scroll_layer2->SetScrollLayer(child_layer2->id()); + + // Synchronize State and verify. + base::RunLoop().RunUntilIdle(); + VerifyTreesAreIdentical(); + + // Verify Scrollbar layers. + SolidColorScrollbarLayer* client_scroll_layer1 = + static_cast<SolidColorScrollbarLayer*>( + compositor_state_deserializer_->GetLayerForEngineId( + scroll_layer1->id())); + EXPECT_EQ(client_scroll_layer1->ScrollLayerId(), + compositor_state_deserializer_ + ->GetLayerForEngineId(scroll_layer1->ScrollLayerId()) + ->id()); + EXPECT_EQ(client_scroll_layer1->orientation(), scroll_layer1->orientation()); + + SolidColorScrollbarLayer* client_scroll_layer2 = + static_cast<SolidColorScrollbarLayer*>( + compositor_state_deserializer_->GetLayerForEngineId( + scroll_layer2->id())); + EXPECT_EQ(client_scroll_layer2->ScrollLayerId(), + compositor_state_deserializer_ + ->GetLayerForEngineId(scroll_layer2->ScrollLayerId()) + ->id()); + EXPECT_EQ(client_scroll_layer2->orientation(), scroll_layer2->orientation()); +} + +TEST_F(CompositorStateDeserializerTest, PictureLayer) { + scoped_refptr<Layer> root_layer = Layer::Create(); + root_layer->SetBounds(gfx::Size(10, 10)); + root_layer->SetIsDrawable(true); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer); + + gfx::Size layer_size = gfx::Size(5, 5); + + gfx::PointF offset(2.f, 3.f); + SkPictureRecorder recorder; + sk_sp<SkCanvas> canvas; + SkPaint red_paint; + red_paint.setColor(SK_ColorRED); + canvas = sk_ref_sp(recorder.beginRecording(SkRect::MakeXYWH( + offset.x(), offset.y(), layer_size.width(), layer_size.height()))); + canvas->translate(offset.x(), offset.y()); + canvas->drawRectCoords(0.f, 0.f, 4.f, 4.f, red_paint); + sk_sp<SkPicture> test_picture = recorder.finishRecordingAsPicture(); + + DisplayItemListSettings settings; + settings.use_cached_picture = false; + scoped_refptr<DisplayItemList> display_list = + DisplayItemList::Create(settings); + const gfx::Rect visual_rect(0, 0, 42, 42); + display_list->CreateAndAppendDrawingItem<DrawingDisplayItem>(visual_rect, + test_picture); + display_list->Finalize(); + FakeContentLayerClient content_client(display_list, gfx::Rect(layer_size)); + + scoped_refptr<PictureLayer> picture_layer = + PictureLayer::Create(&content_client); + picture_layer->SetBounds(layer_size); + picture_layer->SetIsDrawable(true); + root_layer->AddChild(picture_layer); + + // Synchronize State and verify. + base::RunLoop().RunUntilIdle(); + VerifyTreesAreIdentical(); + + // Verify PictureLayer. + PictureLayer* client_picture_layer = static_cast<PictureLayer*>( + compositor_state_deserializer_->GetLayerForEngineId(picture_layer->id())); + scoped_refptr<DisplayItemList> client_display_list = + client_picture_layer->client()->PaintContentsToDisplayList( + ContentLayerClient::PaintingControlSetting::PAINTING_BEHAVIOR_NORMAL); + EXPECT_TRUE(AreDisplayListDrawingResultsSame( + gfx::Rect(layer_size), display_list.get(), client_display_list.get())); + + // Now attach new layer with the same DisplayList. + scoped_refptr<PictureLayer> picture_layer2 = + PictureLayer::Create(&content_client); + picture_layer2->SetBounds(layer_size); + picture_layer2->SetIsDrawable(true); + root_layer->AddChild(picture_layer2); + + // Synchronize State and verify. + base::RunLoop().RunUntilIdle(); + VerifyTreesAreIdentical(); + + // Verify PictureLayer2. + PictureLayer* client_picture_layer2 = static_cast<PictureLayer*>( + compositor_state_deserializer_->GetLayerForEngineId( + picture_layer2->id())); + scoped_refptr<DisplayItemList> client_display_list2 = + client_picture_layer2->client()->PaintContentsToDisplayList( + ContentLayerClient::PaintingControlSetting::PAINTING_BEHAVIOR_NORMAL); + EXPECT_TRUE(AreDisplayListDrawingResultsSame( + gfx::Rect(layer_size), display_list.get(), client_display_list2.get())); +} + } // namespace } // namespace cc diff --git a/chromium/cc/blimp/deserialized_content_layer_client.cc b/chromium/cc/blimp/deserialized_content_layer_client.cc new file mode 100644 index 00000000000..6d52e4ad6b8 --- /dev/null +++ b/chromium/cc/blimp/deserialized_content_layer_client.cc @@ -0,0 +1,39 @@ +// 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/blimp/deserialized_content_layer_client.h" + +namespace cc { + +DeserializedContentLayerClient::DeserializedContentLayerClient() = default; + +DeserializedContentLayerClient::~DeserializedContentLayerClient() = default; + +void DeserializedContentLayerClient::UpdateDisplayListAndRecordedViewport( + scoped_refptr<DisplayItemList> display_list, + gfx::Rect recorded_viewport) { + display_list_ = std::move(display_list); + recorded_viewport_ = recorded_viewport; +} + +gfx::Rect DeserializedContentLayerClient::PaintableRegion() { + return recorded_viewport_; +} + +scoped_refptr<DisplayItemList> +DeserializedContentLayerClient::PaintContentsToDisplayList( + PaintingControlSetting painting_status) { + return display_list_; +} + +bool DeserializedContentLayerClient::FillsBoundsCompletely() const { + return false; +} + +size_t DeserializedContentLayerClient::GetApproximateUnsharedMemoryUsage() + const { + return 0; +} + +} // namespace cc diff --git a/chromium/cc/blimp/deserialized_content_layer_client.h b/chromium/cc/blimp/deserialized_content_layer_client.h new file mode 100644 index 00000000000..af99ba9dc7b --- /dev/null +++ b/chromium/cc/blimp/deserialized_content_layer_client.h @@ -0,0 +1,42 @@ +// 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_BLIMP_DESERIALIZED_CONTENT_LAYER_CLIENT_H_ +#define CC_BLIMP_DESERIALIZED_CONTENT_LAYER_CLIENT_H_ + +#include "base/macros.h" +#include "cc/layers/content_layer_client.h" + +namespace cc { + +// The ContentLayerClient used by the PictureLayers created for the remote +// client. This holds the deserialized DisplayItemList received from the +// corresponding PictureLayer's client on the engine. +class DeserializedContentLayerClient : public ContentLayerClient { + public: + DeserializedContentLayerClient(); + ~DeserializedContentLayerClient() override; + + // Updates from the display list update received from the engine. + void UpdateDisplayListAndRecordedViewport( + scoped_refptr<DisplayItemList> display_list, + gfx::Rect recorded_viewport); + + // ContentLayerClient implementation. + gfx::Rect PaintableRegion() override; + scoped_refptr<DisplayItemList> PaintContentsToDisplayList( + PaintingControlSetting painting_status) override; + bool FillsBoundsCompletely() const override; + size_t GetApproximateUnsharedMemoryUsage() const override; + + private: + scoped_refptr<DisplayItemList> display_list_; + gfx::Rect recorded_viewport_; + + DISALLOW_COPY_AND_ASSIGN(DeserializedContentLayerClient); +}; + +} // namespace cc + +#endif // CC_BLIMP_DESERIALIZED_CONTENT_LAYER_CLIENT_H_ diff --git a/chromium/cc/blimp/layer_factory.h b/chromium/cc/blimp/layer_factory.h index c8ff5dd727c..0c0c88cdeb6 100644 --- a/chromium/cc/blimp/layer_factory.h +++ b/chromium/cc/blimp/layer_factory.h @@ -7,9 +7,13 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "cc/input/scrollbar.h" namespace cc { +class ContentLayerClient; class Layer; +class PictureLayer; +class SolidColorScrollbarLayer; // Used to allow tests to inject the Layer created by the // CompositorStateDeserializer on the client. @@ -18,6 +22,26 @@ class LayerFactory { virtual ~LayerFactory() {} virtual scoped_refptr<Layer> CreateLayer(int engine_layer_id) = 0; + + virtual scoped_refptr<PictureLayer> CreatePictureLayer( + int engine_layer_id, + ContentLayerClient* content_layer_client) = 0; + + virtual scoped_refptr<SolidColorScrollbarLayer> + CreateSolidColorScrollbarLayer(int engine_layer_id, + ScrollbarOrientation orientation, + int thumb_thickness, + int track_start, + bool is_left_side_vertical_scrollbar, + int scroll_layer_id) = 0; + + // Create layers for testing. + virtual scoped_refptr<PictureLayer> CreateFakePictureLayer( + int engine_layer_id, + ContentLayerClient* content_layer_client) = 0; + + virtual scoped_refptr<Layer> CreatePushPropertiesCountingLayer( + int engine_layer_id) = 0; }; } // namespace cc diff --git a/chromium/cc/blimp/layer_tree_host_remote.cc b/chromium/cc/blimp/layer_tree_host_remote.cc index 66b7cbae858..466a4209370 100644 --- a/chromium/cc/blimp/layer_tree_host_remote.cc +++ b/chromium/cc/blimp/layer_tree_host_remote.cc @@ -5,18 +5,23 @@ #include "cc/blimp/layer_tree_host_remote.h" #include "base/atomic_sequence_num.h" +#include "base/auto_reset.h" #include "base/memory/ptr_util.h" -#include "cc/animation/animation_host.h" #include "cc/blimp/compositor_proto_state.h" +#include "cc/blimp/engine_picture_cache.h" +#include "cc/blimp/picture_data_conversions.h" #include "cc/blimp/remote_compositor_bridge.h" #include "cc/output/begin_frame_args.h" #include "cc/output/compositor_frame_sink.h" #include "cc/proto/compositor_message.pb.h" +#include "cc/proto/gfx_conversions.h" #include "cc/proto/layer_tree_host.pb.h" #include "cc/trees/layer_tree.h" #include "cc/trees/layer_tree_host_client.h" #include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/mutator_host.h" #include "cc/trees/task_runner_provider.h" +#include "ui/gfx/geometry/scroll_offset.h" namespace cc { namespace { @@ -25,6 +30,31 @@ namespace { base::TimeDelta kDefaultFrameInterval = base::TimeDelta::FromMilliseconds(16); static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number; + +bool ShouldUpdateLayer(Layer* layer) { + // If the embedder has marked the layer as non-drawable. + if (!layer->DrawsContent()) + return false; + + // If the layer bounds are empty. + if (layer->bounds().IsEmpty()) + return false; + + // If the layer is transparent and has no background filters applied. + // See EffectTree::UpdateIsDrawn for the logic details. + // A few things have been ignored: + // 1) We don't support threaded animations at the moment, so the opacity can + // not change on the client. + // 2) This does not account for layer hiding its subtree, but that is never + // used by the renderer. + // 3) Also updates a transparent layer's subtree when it will be skipped while + // drawing on the client. + if (layer->opacity() == 0.f && layer->background_filters().IsEmpty()) + return false; + + return true; +} + } // namespace LayerTreeHostRemote::InitParams::InitParams() = default; @@ -34,8 +64,7 @@ LayerTreeHostRemote::InitParams::~InitParams() = default; LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params) : LayerTreeHostRemote( params, - base::MakeUnique<LayerTree>(std::move(params->animation_host), - this)) {} + base::MakeUnique<LayerTree>(params->mutator_host, this)) {} LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params, std::unique_ptr<LayerTree> layer_tree) @@ -46,6 +75,7 @@ LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params, TaskRunnerProvider::Create(std::move(params->main_task_runner), nullptr)), remote_compositor_bridge_(std::move(params->remote_compositor_bridge)), + engine_picture_cache_(std::move(params->engine_picture_cache)), settings_(*params->settings), layer_tree_(std::move(layer_tree)), weak_factory_(this) { @@ -53,6 +83,7 @@ LayerTreeHostRemote::LayerTreeHostRemote(InitParams* params, DCHECK(remote_compositor_bridge_); DCHECK(client_); remote_compositor_bridge_->BindToClient(this); + layer_tree_->set_engine_picture_cache(engine_picture_cache_.get()); } LayerTreeHostRemote::~LayerTreeHostRemote() = default; @@ -157,7 +188,11 @@ bool LayerTreeHostRemote::BeginMainFrameRequested() const { } bool LayerTreeHostRemote::CommitRequested() const { - return requested_pipeline_stage_for_next_frame_ == FramePipelineStage::COMMIT; + // We report that a commit is in progress when synchronizing scroll and scale + // updates because in threaded mode, scroll/scale synchronization from the + // impl thread happens only during the main frame. + return synchronizing_client_updates_ || + requested_pipeline_stage_for_next_frame_ == FramePipelineStage::COMMIT; } void LayerTreeHostRemote::SetDeferCommits(bool defer_commits) { @@ -175,12 +210,6 @@ void LayerTreeHostRemote::Composite(base::TimeTicks frame_begin_time) { << " does not support single-thread since it is out of process"; } -void LayerTreeHostRemote::SetNeedsRedraw() { - // The engine shouldn't need to care about draws. CompositorFrames are never - // used here. - NOTREACHED(); -} - void LayerTreeHostRemote::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { // The engine shouldn't need to care about draws. CompositorFrames are never // used here. @@ -193,7 +222,7 @@ void LayerTreeHostRemote::SetNextCommitForcesRedraw() { // Ideally the engine shouldn't need to care about draw requests at all. The // compositor that produces CompositorFrames is on the client and draw // requests should be made directly to it on the client itself. - NOTREACHED(); + NOTIMPLEMENTED(); } void LayerTreeHostRemote::NotifyInputThrottledUntilCommit() { @@ -211,10 +240,11 @@ void LayerTreeHostRemote::NotifyInputThrottledUntilCommit() { NOTIMPLEMENTED(); } -void LayerTreeHostRemote::UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) { - NOTREACHED() << "Using TopControls animations is not supported"; +void LayerTreeHostRemote::UpdateBrowserControlsState( + BrowserControlsState constraints, + BrowserControlsState current, + bool animate) { + NOTREACHED() << "Using BrowserControls animations is not supported"; } const base::WeakPtr<InputHandler>& LayerTreeHostRemote::GetInputHandler() @@ -231,8 +261,9 @@ void LayerTreeHostRemote::DidStopFlinging() { void LayerTreeHostRemote::SetDebugState( const LayerTreeDebugState& debug_state) { - // TODO(khushalsagar): Figure out if we need to send these to the client. - NOTREACHED(); + // If any debugging needs to be enabled, ideally it should be using the + // compositor on the client directly. But the setup code will always set this + // on initialization, even if the settings end up being a no-op. } const LayerTreeDebugState& LayerTreeHostRemote::GetDebugState() const { @@ -345,7 +376,6 @@ void LayerTreeHostRemote::BeginMainFrame() { // We don't run any animations on the layer because threaded animations are // disabled. // TODO(khushalsagar): Revisit this when adding support for animations. - DCHECK(!layer_tree_->animation_host()->needs_push_properties()); client_->UpdateLayerTreeHost(); current_pipeline_stage_ = FramePipelineStage::UPDATE_LAYERS; @@ -357,6 +387,8 @@ void LayerTreeHostRemote::BeginMainFrame() { // layers. See crbug.com/650885. LayerTreeHostCommon::CallFunctionForEveryLayer( layer_tree_.get(), [&layer_list](Layer* layer) { + if (!ShouldUpdateLayer(layer)) + return; layer->SavePaintProperties(); layer_list.push_back(layer); }); @@ -404,8 +436,57 @@ void LayerTreeHostRemote::BeginMainFrame() { // being used for. Consider migrating clients to understand/cope with the fact // that there is no actual compositing happening here. task_runner_provider_->MainThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&LayerTreeHostRemote::DispatchDrawAndSwapCallbacks, - weak_factory_.GetWeakPtr())); + FROM_HERE, + base::Bind(&LayerTreeHostRemote::DispatchDrawAndSubmitCallbacks, + weak_factory_.GetWeakPtr())); +} + +void LayerTreeHostRemote::ApplyStateUpdateFromClient( + const proto::ClientStateUpdate& client_state_update) { + DCHECK(!synchronizing_client_updates_); + base::AutoReset<bool> synchronizing_updates(&synchronizing_client_updates_, + true); + + gfx::Vector2dF inner_viewport_delta; + for (int i = 0; i < client_state_update.scroll_updates_size(); ++i) { + const proto::ScrollUpdate& scroll_update = + client_state_update.scroll_updates(i); + int layer_id = scroll_update.layer_id(); + Layer* layer = layer_tree_->LayerById(layer_id); + gfx::Vector2dF scroll_delta = + ProtoToVector2dF(scroll_update.scroll_delta()); + + if (!layer) + continue; + + if (layer == layer_tree_->inner_viewport_scroll_layer()) { + inner_viewport_delta = scroll_delta; + } else { + layer->SetScrollOffsetFromImplSide( + gfx::ScrollOffsetWithDelta(layer->scroll_offset(), scroll_delta)); + SetNeedsUpdateLayers(); + } + } + + if (!inner_viewport_delta.IsZero()) { + layer_tree_->inner_viewport_scroll_layer()->SetScrollOffsetFromImplSide( + gfx::ScrollOffsetWithDelta( + layer_tree_->inner_viewport_scroll_layer()->scroll_offset(), + inner_viewport_delta)); + } + + float page_scale_delta = 1.0f; + if (client_state_update.has_page_scale_delta()) { + page_scale_delta = client_state_update.page_scale_delta(); + layer_tree_->SetPageScaleFromImplSide(layer_tree_->page_scale_factor() * + page_scale_delta); + } + + if (!inner_viewport_delta.IsZero() || page_scale_delta != 1.0f) { + client_->ApplyViewportDeltas(inner_viewport_delta, gfx::Vector2dF(), + gfx::Vector2dF(), page_scale_delta, 0.0f); + SetNeedsUpdateLayers(); + } } void LayerTreeHostRemote::MainFrameComplete() { @@ -419,27 +500,36 @@ void LayerTreeHostRemote::MainFrameComplete() { client_->DidBeginMainFrame(); } -void LayerTreeHostRemote::DispatchDrawAndSwapCallbacks() { +void LayerTreeHostRemote::DispatchDrawAndSubmitCallbacks() { client_->DidCommitAndDrawFrame(); - client_->DidCompleteSwapBuffers(); + client_->DidReceiveCompositorFrameAck(); +} + +void LayerTreeHostRemote::SetTaskRunnerProviderForTesting( + std::unique_ptr<TaskRunnerProvider> task_runner_provider) { + task_runner_provider_ = std::move(task_runner_provider); } void LayerTreeHostRemote::SerializeCurrentState( proto::LayerTreeHost* layer_tree_host_proto) { - // We need to serialize only the inputs received from the embedder. - const bool inputs_only = true; - // Serialize the LayerTree. - layer_tree_->ToProtobuf(layer_tree_host_proto->mutable_layer_tree(), - inputs_only); + layer_tree_->ToProtobuf(layer_tree_host_proto->mutable_layer_tree()); // Serialize the dirty layers. - for (auto* layer : layer_tree_->LayersThatShouldPushProperties()) - layer->ToLayerPropertiesProto( - layer_tree_host_proto->mutable_layer_updates(), inputs_only); - layer_tree_->LayersThatShouldPushProperties().clear(); + std::unordered_set<Layer*> layers_need_push_properties; + layers_need_push_properties.swap( + layer_tree_->LayersThatShouldPushProperties()); + + for (auto* layer : layers_need_push_properties) { + proto::LayerProperties* layer_properties = + layer_tree_host_proto->mutable_layer_updates()->add_layers(); + layer->ToLayerPropertiesProto(layer_properties); + } - // TODO(khushalsagar): Deal with picture caching. + std::vector<PictureData> pictures = + engine_picture_cache_->CalculateCacheUpdateAndFlush(); + proto::PictureDataVectorToSkPicturesProto( + pictures, layer_tree_host_proto->mutable_pictures()); } } // namespace cc diff --git a/chromium/cc/blimp/layer_tree_host_remote.h b/chromium/cc/blimp/layer_tree_host_remote.h index b27f566e454..e7c3c8b780e 100644 --- a/chromium/cc/blimp/layer_tree_host_remote.h +++ b/chromium/cc/blimp/layer_tree_host_remote.h @@ -24,7 +24,8 @@ namespace proto { class LayerTreeHost; } // namespace proto -class AnimationHost; +class MutatorHost; +class EnginePictureCache; class RemoteCompositorBridge; class LayerTreeHostClient; @@ -34,8 +35,9 @@ class CC_EXPORT LayerTreeHostRemote : public LayerTreeHost, struct CC_EXPORT InitParams { LayerTreeHostClient* client = nullptr; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner; - std::unique_ptr<AnimationHost> animation_host; + MutatorHost* mutator_host; std::unique_ptr<RemoteCompositorBridge> remote_compositor_bridge; + std::unique_ptr<EnginePictureCache> engine_picture_cache; LayerTreeSettings const* settings = nullptr; InitParams(); @@ -72,13 +74,12 @@ class CC_EXPORT LayerTreeHostRemote : public LayerTreeHost, void SetDeferCommits(bool defer_commits) override; void LayoutAndUpdateLayers() override; void Composite(base::TimeTicks frame_begin_time) override; - void SetNeedsRedraw() override; void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override; void SetNextCommitForcesRedraw() override; void NotifyInputThrottledUntilCommit() override; - void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) override; + void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) override; const base::WeakPtr<InputHandler>& GetInputHandler() const override; void DidStopFlinging() override; void SetDebugState(const LayerTreeDebugState& debug_state) override; @@ -93,21 +94,31 @@ class CC_EXPORT LayerTreeHostRemote : public LayerTreeHost, void SetNextCommitWaitsForActivation() override; void ResetGpuRasterizationTracking() override; + // RemoteCompositorBridgeClient implementation. + void BeginMainFrame() override; + void ApplyStateUpdateFromClient( + const proto::ClientStateUpdate& client_state_update) override; + protected: // Protected for testing. Allows tests to inject the LayerTree. LayerTreeHostRemote(InitParams* params, std::unique_ptr<LayerTree> layer_tree); + LayerTreeHostClient* client() const { return client_; } + RemoteCompositorBridge* remote_compositor_bridge() const { + return remote_compositor_bridge_.get(); + } + + virtual void DispatchDrawAndSubmitCallbacks(); + void SetTaskRunnerProviderForTesting( + std::unique_ptr<TaskRunnerProvider> task_runner_provider); + private: enum class FramePipelineStage { NONE, ANIMATE, UPDATE_LAYERS, COMMIT }; - // RemoteCompositorBridgeClient implementation. - void BeginMainFrame() override; - void MainFrameRequested(FramePipelineStage requested_pipeline_stage); void ScheduleMainFrameIfNecessary(); void MainFrameComplete(); - void DispatchDrawAndSwapCallbacks(); void SerializeCurrentState(proto::LayerTreeHost* layer_tree_host_proto); const int id_; @@ -115,6 +126,12 @@ class CC_EXPORT LayerTreeHostRemote : public LayerTreeHost, bool visible_ = false; bool defer_commits_ = false; + // In threaded/single-threaded mode, the LayerTree and Layers expect scroll/ + // scale updates to come from the impl thread only during the main frame. + // Since we synchronize state outside of that, this is set so we can + // temporarily report that a commit is in progress. + bool synchronizing_client_updates_ = false; + // Set to true if a main frame request is pending on the // RemoteCompositorBridge. bool main_frame_requested_from_bridge_ = false; @@ -138,6 +155,11 @@ class CC_EXPORT LayerTreeHostRemote : public LayerTreeHost, // The RemoteCompositorBridge used to submit frame updates to the client. std::unique_ptr<RemoteCompositorBridge> remote_compositor_bridge_; + // Used to cache SkPictures sent with DisplayLists to the client. + // TODO(khushalsagar): Restructure to give this with the CompositorProtoState + // and eliminate this abstraction. See crbug.com/648442. + std::unique_ptr<EnginePictureCache> engine_picture_cache_; + LayerTreeSettings settings_; LayerTreeDebugState debug_state_; diff --git a/chromium/cc/blimp/layer_tree_host_remote_unittest.cc b/chromium/cc/blimp/layer_tree_host_remote_unittest.cc index 845bd11e67c..e5575e7301c 100644 --- a/chromium/cc/blimp/layer_tree_host_remote_unittest.cc +++ b/chromium/cc/blimp/layer_tree_host_remote_unittest.cc @@ -4,12 +4,19 @@ #include "cc/blimp/layer_tree_host_remote.h" +#include <memory> +#include <unordered_set> + #include "base/bind.h" #include "base/run_loop.h" #include "base/threading/thread_task_runner_handle.h" #include "cc/animation/animation_host.h" #include "cc/layers/layer.h" #include "cc/output/begin_frame_args.h" +#include "cc/proto/client_state_update.pb.h" +#include "cc/proto/compositor_message.pb.h" +#include "cc/proto/gfx_conversions.h" +#include "cc/test/fake_image_serialization_processor.h" #include "cc/test/fake_remote_compositor_bridge.h" #include "cc/test/stub_layer_tree_host_client.h" #include "cc/trees/layer_tree_settings.h" @@ -31,11 +38,25 @@ using testing::StrictMock; #define EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(client, num) \ EXPECT_BEGIN_MAIN_FRAME(client, num) \ EXPECT_CALL(client, DidCommitAndDrawFrame()).Times(num); \ - EXPECT_CALL(client, DidCompleteSwapBuffers()).Times(num); + EXPECT_CALL(client, DidReceiveCompositorFrameAck()).Times(num); namespace cc { namespace { +gfx::Vector2dF SerializeScrollUpdate( + proto::ClientStateUpdate* client_state_update, + Layer* layer, + const gfx::ScrollOffset& offset_after_update) { + proto::ScrollUpdate* scroll_update = + client_state_update->add_scroll_updates(); + scroll_update->set_layer_id(layer->id()); + gfx::ScrollOffset scroll_delta = offset_after_update - layer->scroll_offset(); + gfx::Vector2dF scroll_delta_vector = + gfx::ScrollOffsetToVector2dF(scroll_delta); + Vector2dFToProto(scroll_delta_vector, scroll_update->mutable_scroll_delta()); + return scroll_delta_vector; +} + class UpdateTrackingRemoteCompositorBridge : public FakeRemoteCompositorBridge { public: UpdateTrackingRemoteCompositorBridge( @@ -47,12 +68,22 @@ class UpdateTrackingRemoteCompositorBridge : public FakeRemoteCompositorBridge { void ProcessCompositorStateUpdate( std::unique_ptr<CompositorProtoState> compositor_proto_state) override { num_updates_received_++; + compositor_proto_state_ = std::move(compositor_proto_state); }; + void SendUpdates(const proto::ClientStateUpdate& client_state_update) { + client_->ApplyStateUpdateFromClient(client_state_update); + } + int num_updates_received() const { return num_updates_received_; } + CompositorProtoState* compositor_proto_state() { + return compositor_proto_state_.get(); + } + private: int num_updates_received_ = 0; + std::unique_ptr<CompositorProtoState> compositor_proto_state_; }; class MockLayerTreeHostClient : public StubLayerTreeHostClient { @@ -78,10 +109,16 @@ class MockLayerTreeHostClient : public StubLayerTreeHostClient { MOCK_METHOD0(DidBeginMainFrame, void()); MOCK_METHOD0(DidReceiveBeginMainFrame, void()); MOCK_METHOD0(DidUpdateLayerTreeHost, void()); + MOCK_METHOD5(ApplyViewportDeltas, + void(const gfx::Vector2dF&, + const gfx::Vector2dF&, + const gfx::Vector2dF&, + float, + float)); MOCK_METHOD0(WillCommit, void()); MOCK_METHOD0(DidCommit, void()); MOCK_METHOD0(DidCommitAndDrawFrame, void()); - MOCK_METHOD0(DidCompleteSwapBuffers, void()); + MOCK_METHOD0(DidReceiveCompositorFrameAck, void()); private: base::Closure update_host_callback_; @@ -107,9 +144,8 @@ class MockLayer : public Layer { class MockLayerTree : public LayerTree { public: - MockLayerTree(std::unique_ptr<AnimationHost> animation_host, - LayerTreeHost* layer_tree_host) - : LayerTree(std::move(animation_host), layer_tree_host) {} + MockLayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host) + : LayerTree(mutator_host, layer_tree_host) {} ~MockLayerTree() override {} // We don't want tree sync requests to trigger commits. @@ -121,8 +157,7 @@ class LayerTreeHostRemoteForTesting : public LayerTreeHostRemote { explicit LayerTreeHostRemoteForTesting(InitParams* params) : LayerTreeHostRemote( params, - base::MakeUnique<MockLayerTree>(AnimationHost::CreateMainInstance(), - this)) {} + base::MakeUnique<MockLayerTree>(params->mutator_host, this)) {} ~LayerTreeHostRemoteForTesting() override {} }; @@ -135,6 +170,8 @@ class LayerTreeHostRemoteTest : public testing::Test { ~LayerTreeHostRemoteTest() override {} void SetUp() override { + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + LayerTreeHostRemote::InitParams params; params.client = &mock_layer_tree_host_client_; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner = @@ -146,11 +183,17 @@ class LayerTreeHostRemoteTest : public testing::Test { main_task_runner); remote_compositor_bridge_ = remote_compositor_bridge.get(); params.remote_compositor_bridge = std::move(remote_compositor_bridge); + params.engine_picture_cache = + image_serialization_processor_.CreateEnginePictureCache(); LayerTreeSettings settings; params.settings = &settings; - + params.mutator_host = animation_host_.get(); layer_tree_host_ = base::MakeUnique<LayerTreeHostRemoteForTesting>(¶ms); + + // Make sure the root layer always updates. root_layer_ = make_scoped_refptr(new MockLayer(false)); + root_layer_->SetIsDrawable(true); + root_layer_->SetBounds(gfx::Size(5, 10)); layer_tree_host_->GetLayerTree()->SetRootLayer(root_layer_); } @@ -182,10 +225,12 @@ class LayerTreeHostRemoteTest : public testing::Test { } protected: + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<LayerTreeHostRemote> layer_tree_host_; StrictMock<MockLayerTreeHostClient> mock_layer_tree_host_client_; UpdateTrackingRemoteCompositorBridge* remote_compositor_bridge_ = nullptr; scoped_refptr<MockLayer> root_layer_; + FakeImageSerializationProcessor image_serialization_processor_; bool needs_animate_during_main_frame_ = false; bool needs_commit_during_main_frame_ = false; @@ -333,6 +378,8 @@ TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringMainFrame) { TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringLayerUpdates) { // A layer update during a main frame should result in a commit. scoped_refptr<Layer> child_layer = make_scoped_refptr(new MockLayer(true)); + child_layer->SetIsDrawable(true); + child_layer->SetBounds(gfx::Size(5, 10)); root_layer_->AddChild(child_layer); EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); @@ -343,5 +390,148 @@ TEST_F(LayerTreeHostRemoteTest, RequestCommitDuringLayerUpdates) { EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); } +TEST_F(LayerTreeHostRemoteTest, ScrollAndScaleSync) { + scoped_refptr<Layer> child_layer1 = make_scoped_refptr(new MockLayer(false)); + root_layer_->AddChild(child_layer1); + + scoped_refptr<Layer> child_layer2 = make_scoped_refptr(new MockLayer(false)); + child_layer1->AddChild(child_layer2); + child_layer2->SetScrollOffset(gfx::ScrollOffset(3, 9)); + + scoped_refptr<Layer> inner_viewport_layer = + make_scoped_refptr(new MockLayer(false)); + inner_viewport_layer->SetScrollOffset(gfx::ScrollOffset(5, 10)); + root_layer_->AddChild(inner_viewport_layer); + layer_tree_host_->GetLayerTree()->RegisterViewportLayers( + nullptr, nullptr, inner_viewport_layer, nullptr); + + // First test case. + gfx::ScrollOffset expected_child1_offset(4, 5); + gfx::ScrollOffset expected_child2_offset(3, 10); + gfx::ScrollOffset expected_inner_viewport_offset(-2, 5); + float expected_page_scale = 2.0f; + + proto::ClientStateUpdate client_state_update; + SerializeScrollUpdate(&client_state_update, child_layer1.get(), + expected_child1_offset); + SerializeScrollUpdate(&client_state_update, child_layer2.get(), + expected_child2_offset); + gfx::Vector2dF inner_viewport_delta = + SerializeScrollUpdate(&client_state_update, inner_viewport_layer.get(), + expected_inner_viewport_offset); + float page_scale_delta = + expected_page_scale / + layer_tree_host_->GetLayerTree()->page_scale_factor(); + client_state_update.set_page_scale_delta(page_scale_delta); + + EXPECT_CALL(mock_layer_tree_host_client_, + ApplyViewportDeltas(inner_viewport_delta, gfx::Vector2dF(), + gfx::Vector2dF(), page_scale_delta, 0.0f)) + .Times(1); + + remote_compositor_bridge_->SendUpdates(client_state_update); + + // The host should have pre-emtively applied the changes. + EXPECT_EQ(expected_page_scale, + layer_tree_host_->GetLayerTree()->page_scale_factor()); + EXPECT_EQ(expected_child1_offset, child_layer1->scroll_offset()); + EXPECT_EQ(expected_child2_offset, child_layer2->scroll_offset()); + EXPECT_EQ(expected_inner_viewport_offset, + inner_viewport_layer->scroll_offset()); + + // Remove a layer from the tree and send a scroll update for it. + child_layer1->RemoveAllChildren(); + proto::ClientStateUpdate client_state_update2; + SerializeScrollUpdate(&client_state_update2, child_layer2.get(), + gfx::ScrollOffset(9, 10)); + remote_compositor_bridge_->SendUpdates(client_state_update2); +} + +TEST_F(LayerTreeHostRemoteTest, IdentifiedLayersToSkipUpdates) { + EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 1); + + scoped_refptr<MockLayer> non_drawable_layer = new MockLayer(true); + non_drawable_layer->SetIsDrawable(false); + non_drawable_layer->SetBounds(gfx::Size(5, 5)); + + scoped_refptr<MockLayer> empty_bound_layer = new MockLayer(true); + empty_bound_layer->SetIsDrawable(true); + empty_bound_layer->SetBounds(gfx::Size()); + + scoped_refptr<MockLayer> transparent_layer = new MockLayer(true); + transparent_layer->SetIsDrawable(true); + transparent_layer->SetBounds(gfx::Size(5, 5)); + transparent_layer->SetOpacity(0.f); + + scoped_refptr<MockLayer> updated_layer = new MockLayer(true); + updated_layer->SetIsDrawable(true); + updated_layer->SetBounds(gfx::Size(5, 5)); + + root_layer_->AddChild(non_drawable_layer); + root_layer_->AddChild(empty_bound_layer); + empty_bound_layer->SetMaskLayer(transparent_layer.get()); + empty_bound_layer->AddChild(updated_layer); + DCHECK(updated_layer->GetLayerTreeHostForTesting()); + + // Commit and serialize. + layer_tree_host_->SetNeedsCommit(); + base::RunLoop().RunUntilIdle(); + + // Only the updated_layer should have been updated. + EXPECT_FALSE(non_drawable_layer->did_update()); + EXPECT_FALSE(empty_bound_layer->did_update()); + EXPECT_FALSE(transparent_layer->did_update()); + EXPECT_TRUE(updated_layer->did_update()); +} + +TEST_F(LayerTreeHostRemoteTest, OnlyPushPropertiesOnChangingLayers) { + EXPECT_BEGIN_MAIN_FRAME_AND_COMMIT(mock_layer_tree_host_client_, 2); + + // Setup a tree with 3 nodes. + scoped_refptr<Layer> child_layer = Layer::Create(); + scoped_refptr<Layer> grandchild_layer = Layer::Create(); + root_layer_->AddChild(child_layer); + child_layer->AddChild(grandchild_layer); + layer_tree_host_->SetNeedsCommit(); + + base::RunLoop().RunUntilIdle(); + + // Ensure the first proto contains all layer updates. + EXPECT_EQ(1, remote_compositor_bridge_->num_updates_received()); + CompositorProtoState* compositor_proto_state = + remote_compositor_bridge_->compositor_proto_state(); + const proto::LayerUpdate& layer_updates_first_commit = + compositor_proto_state->compositor_message->layer_tree_host() + .layer_updates(); + + std::unordered_set<int> layer_updates_id_set; + for (int i = 0; i < layer_updates_first_commit.layers_size(); ++i) { + layer_updates_id_set.insert(layer_updates_first_commit.layers(i).id()); + } + + EXPECT_TRUE(layer_updates_id_set.find(root_layer_->id()) != + layer_updates_id_set.end()); + EXPECT_TRUE(layer_updates_id_set.find(child_layer->id()) != + layer_updates_id_set.end()); + EXPECT_TRUE(layer_updates_id_set.find(grandchild_layer->id()) != + layer_updates_id_set.end()); + EXPECT_EQ(3, layer_updates_first_commit.layers_size()); + + // Modify the |child_layer|, and run the second frame. + child_layer->SetNeedsPushProperties(); + layer_tree_host_->SetNeedsCommit(); + base::RunLoop().RunUntilIdle(); + + // Ensure the second proto only contains |child_layer|. + EXPECT_EQ(2, remote_compositor_bridge_->num_updates_received()); + compositor_proto_state = remote_compositor_bridge_->compositor_proto_state(); + DCHECK(compositor_proto_state); + const proto::LayerUpdate& layer_updates_second_commit = + compositor_proto_state->compositor_message->layer_tree_host() + .layer_updates(); + EXPECT_EQ(1, layer_updates_second_commit.layers_size()); + EXPECT_EQ(child_layer->id(), layer_updates_second_commit.layers(0).id()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/blimp/layer_tree_host_unittest_serialization.cc b/chromium/cc/blimp/layer_tree_host_unittest_serialization.cc new file mode 100644 index 00000000000..aa0e1c65fc5 --- /dev/null +++ b/chromium/cc/blimp/layer_tree_host_unittest_serialization.cc @@ -0,0 +1,412 @@ +// Copyright 2015 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 <memory> + +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "cc/animation/animation_host.h" +#include "cc/blimp/layer_tree_host_remote.h" +#include "cc/layers/empty_content_layer_client.h" +#include "cc/layers/layer.h" +#include "cc/layers/solid_color_scrollbar_layer.h" +#include "cc/proto/layer.pb.h" +#include "cc/proto/layer_tree_host.pb.h" +#include "cc/test/fake_image_serialization_processor.h" +#include "cc/test/fake_layer_tree_host.h" +#include "cc/test/fake_layer_tree_host_client.h" +#include "cc/test/fake_picture_layer.h" +#include "cc/test/fake_recording_source.h" +#include "cc/test/remote_client_layer_factory.h" +#include "cc/test/remote_compositor_test.h" +#include "cc/test/serialization_test_utils.h" +#include "cc/trees/layer_tree.h" +#include "cc/trees/layer_tree_host_common.h" +#include "cc/trees/layer_tree_settings.h" +#include "third_party/skia/include/core/SkColor.h" +#include "ui/gfx/geometry/point.h" +#include "ui/gfx/geometry/size.h" +#include "ui/gfx/geometry/vector2d_f.h" + +namespace cc { + +#define EXPECT_CLIENT_LAYER_DIRTY(engine_layer) \ + do { \ + Layer* client_layer = compositor_state_deserializer_->GetLayerForEngineId( \ + engine_layer->id()); \ + LayerTree* client_tree = client_layer->GetLayerTree(); \ + EXPECT_TRUE( \ + client_tree->LayerNeedsPushPropertiesForTesting(client_layer)); \ + } while (false) + +class LayerTreeHostSerializationTest : public RemoteCompositorTest { + protected: + void VerifySerializationAndDeserialization() { + // Synchronize state. + CHECK(HasPendingUpdate()); + base::RunLoop().RunUntilIdle(); + VerifySerializedTreesAreIdentical( + layer_tree_host_remote_->GetLayerTree(), + layer_tree_host_in_process_->GetLayerTree(), + compositor_state_deserializer_.get()); + } + + void SetUpViewportLayers(LayerTree* engine_layer_tree) { + scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); + scoped_refptr<Layer> page_scale_layer = Layer::Create(); + scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); + scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create(); + + engine_layer_tree->root_layer()->AddChild(overscroll_elasticity_layer); + engine_layer_tree->root_layer()->AddChild(page_scale_layer); + engine_layer_tree->root_layer()->AddChild(inner_viewport_scroll_layer); + engine_layer_tree->root_layer()->AddChild(outer_viewport_scroll_layer); + + engine_layer_tree->RegisterViewportLayers( + overscroll_elasticity_layer, page_scale_layer, + inner_viewport_scroll_layer, outer_viewport_scroll_layer); + } +}; + +TEST_F(LayerTreeHostSerializationTest, AllMembersChanged) { + LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); + + engine_layer_tree->SetRootLayer(Layer::Create()); + scoped_refptr<Layer> mask_layer = Layer::Create(); + engine_layer_tree->root_layer()->SetMaskLayer(mask_layer.get()); + SetUpViewportLayers(engine_layer_tree); + + engine_layer_tree->SetViewportSize(gfx::Size(3, 14)); + engine_layer_tree->SetDeviceScaleFactor(4.f); + engine_layer_tree->SetPaintedDeviceScaleFactor(2.f); + engine_layer_tree->SetPageScaleFactorAndLimits(2.f, 0.5f, 3.f); + engine_layer_tree->set_background_color(SK_ColorMAGENTA); + engine_layer_tree->set_has_transparent_background(true); + LayerSelectionBound sel_bound; + sel_bound.edge_top = gfx::Point(14, 3); + LayerSelection selection; + selection.start = sel_bound; + engine_layer_tree->RegisterSelection(selection); + VerifySerializationAndDeserialization(); +} + +TEST_F(LayerTreeHostSerializationTest, LayersChangedMultipleSerializations) { + LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); + engine_layer_tree->SetRootLayer(Layer::Create()); + SetUpViewportLayers(engine_layer_tree); + + VerifySerializationAndDeserialization(); + + scoped_refptr<Layer> new_child = Layer::Create(); + engine_layer_tree->root_layer()->AddChild(new_child); + engine_layer_tree->RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr); + VerifySerializationAndDeserialization(); + + engine_layer_tree->SetRootLayer(nullptr); + VerifySerializationAndDeserialization(); +} + +TEST_F(LayerTreeHostSerializationTest, AddAndRemoveNodeFromLayerTree) { + /* Testing serialization when the tree hierarchy changes like this: + root root + / \ / \ + a b => a c + \ \ + c d + */ + LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); + scoped_refptr<Layer> layer_src_root = Layer::Create(); + engine_layer_tree->SetRootLayer(layer_src_root); + + scoped_refptr<Layer> layer_src_a = Layer::Create(); + scoped_refptr<Layer> layer_src_b = Layer::Create(); + scoped_refptr<Layer> layer_src_c = Layer::Create(); + scoped_refptr<Layer> layer_src_d = Layer::Create(); + + layer_src_root->AddChild(layer_src_a); + layer_src_root->AddChild(layer_src_b); + layer_src_b->AddChild(layer_src_c); + VerifySerializationAndDeserialization(); + + // Now change the Layer Hierarchy + layer_src_c->RemoveFromParent(); + layer_src_b->RemoveFromParent(); + layer_src_root->AddChild(layer_src_c); + layer_src_c->AddChild(layer_src_d); + VerifySerializationAndDeserialization(); +} + +TEST_F(LayerTreeHostSerializationTest, TestNoExistingRoot) { + /* Test deserialization of a tree that looks like: + root + / \ + a b + \ + c + There is no existing root node before serialization. + */ + scoped_refptr<Layer> old_root_layer = Layer::Create(); + scoped_refptr<Layer> layer_a = Layer::Create(); + scoped_refptr<Layer> layer_b = Layer::Create(); + scoped_refptr<Layer> layer_c = Layer::Create(); + old_root_layer->AddChild(layer_a); + old_root_layer->AddChild(layer_b); + layer_b->AddChild(layer_c); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(old_root_layer); + VerifySerializationAndDeserialization(); + + // Swap the root node. + scoped_refptr<Layer> new_root_layer = Layer::Create(); + new_root_layer->AddChild(layer_a); + new_root_layer->AddChild(layer_b); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(old_root_layer); + VerifySerializationAndDeserialization(); +} + +TEST_F(LayerTreeHostSerializationTest, RecursivePropertiesSerialization) { + /* Testing serialization of properties for a tree that looks like this: + root+ + / \ + a* b+[mask:*] + / \ + c d + Layers marked with * have changed properties. + Layers marked with + have descendants with changed properties. + Layer b also has a mask layer. + */ + scoped_refptr<Layer> layer_src_root = Layer::Create(); + scoped_refptr<Layer> layer_src_a = Layer::Create(); + scoped_refptr<Layer> layer_src_b = Layer::Create(); + scoped_refptr<Layer> layer_src_b_mask = Layer::Create(); + scoped_refptr<Layer> layer_src_c = Layer::Create(); + scoped_refptr<Layer> layer_src_d = Layer::Create(); + + layer_src_root->AddChild(layer_src_a); + layer_src_root->AddChild(layer_src_b); + layer_src_a->AddChild(layer_src_c); + layer_src_b->AddChild(layer_src_d); + layer_src_b->SetMaskLayer(layer_src_b_mask.get()); + + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root); + VerifySerializationAndDeserialization(); + EXPECT_EQ(layer_tree_host_remote_->GetLayerTree() + ->LayersThatShouldPushProperties() + .size(), + 0u); + EXPECT_EQ(layer_tree_host_in_process_->GetLayerTree() + ->LayersThatShouldPushProperties() + .size(), + 6u); +} + +TEST_F(LayerTreeHostSerializationTest, ChildrenOrderChange) { + /* Testing serialization and deserialization of a tree that initially looks + like this: + root + / \ + a b + The children are then re-ordered and changed to: + root + / \ + b a + \ + c + */ + scoped_refptr<Layer> layer_src_root = Layer::Create(); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root); + scoped_refptr<Layer> layer_src_a = Layer::Create(); + scoped_refptr<Layer> layer_src_b = Layer::Create(); + + layer_src_root->AddChild(layer_src_b); + layer_src_root->AddChild(layer_src_a); + VerifySerializationAndDeserialization(); + + Layer* client_root = + compositor_state_deserializer_->GetLayerForEngineId(layer_src_root->id()); + Layer* client_a = + compositor_state_deserializer_->GetLayerForEngineId(layer_src_a->id()); + Layer* client_b = + compositor_state_deserializer_->GetLayerForEngineId(layer_src_b->id()); + + // Swap the children. + layer_src_root->RemoveAllChildren(); + layer_src_root->AddChild(layer_src_a); + layer_src_root->AddChild(layer_src_b); + layer_src_a->AddChild(Layer::Create()); + VerifySerializationAndDeserialization(); + + // Verify all old layers are re-used. + Layer* new_client_root = + compositor_state_deserializer_->GetLayerForEngineId(layer_src_root->id()); + Layer* new_client_a = + compositor_state_deserializer_->GetLayerForEngineId(layer_src_a->id()); + Layer* new_client_b = + compositor_state_deserializer_->GetLayerForEngineId(layer_src_b->id()); + EXPECT_EQ(client_root, new_client_root); + EXPECT_EQ(client_a, new_client_a); + EXPECT_EQ(client_b, new_client_b); +} + +TEST_F(LayerTreeHostSerializationTest, DeletingLayers) { + /* Testing serialization and deserialization of a tree that initially + looks like this: + root + / \ + a b + \ + c+[mask:*] + First the mask layer is deleted. + Then the subtree from node |b| is deleted in the next update. + */ + scoped_refptr<Layer> layer_src_root = Layer::Create(); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer_src_root); + + scoped_refptr<Layer> layer_src_a = Layer::Create(); + scoped_refptr<Layer> layer_src_b = Layer::Create(); + scoped_refptr<Layer> layer_src_c = Layer::Create(); + scoped_refptr<Layer> layer_src_c_mask = Layer::Create(); + layer_src_root->AddChild(layer_src_a); + layer_src_root->AddChild(layer_src_b); + layer_src_b->AddChild(layer_src_c); + layer_src_c->SetMaskLayer(layer_src_c_mask.get()); + VerifySerializationAndDeserialization(); + + // Delete the mask layer. + layer_src_c->SetMaskLayer(nullptr); + VerifySerializationAndDeserialization(); + + // Remove child b. + layer_src_b->RemoveFromParent(); + VerifySerializationAndDeserialization(); +} + +TEST_F(LayerTreeHostSerializationTest, LayerDataSerialization) { + scoped_refptr<Layer> layer = Layer::Create(); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(layer); + VerifySerializationAndDeserialization(); + + // Change all the fields. + layer->SetTransformOrigin(gfx::Point3F(3.0f, 1.0f, 4.0f)); + layer->SetBackgroundColor(SK_ColorRED); + layer->SetBounds(gfx::Size(3, 14)); + layer->SetDoubleSided(!layer->double_sided()); + layer->SetHideLayerAndSubtree(!layer->hide_layer_and_subtree()); + layer->SetMasksToBounds(!layer->masks_to_bounds()); + layer->AddMainThreadScrollingReasons( + MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects); + layer->SetNonFastScrollableRegion(Region(gfx::Rect(5, 1, 14, 3))); + layer->SetNonFastScrollableRegion(Region(gfx::Rect(3, 14, 1, 5))); + layer->SetContentsOpaque(!layer->contents_opaque()); + layer->SetOpacity(0.4f); + layer->SetBlendMode(SkXfermode::kOverlay_Mode); + layer->SetIsRootForIsolatedGroup(!layer->is_root_for_isolated_group()); + layer->SetPosition(gfx::PointF(3.14f, 6.28f)); + layer->SetIsContainerForFixedPositionLayers( + !layer->IsContainerForFixedPositionLayers()); + LayerPositionConstraint pos_con; + pos_con.set_is_fixed_to_bottom_edge(true); + layer->SetPositionConstraint(pos_con); + layer->SetShouldFlattenTransform(!layer->should_flatten_transform()); + layer->SetUseParentBackfaceVisibility( + !layer->use_parent_backface_visibility()); + gfx::Transform transform; + transform.Rotate(90); + layer->SetTransform(transform); + layer->Set3dSortingContextId(42); + layer->SetUserScrollable(layer->user_scrollable_horizontal(), + layer->user_scrollable_vertical()); + layer->SetScrollOffset(gfx::ScrollOffset(3, 14)); + gfx::Rect update_rect(14, 15); + layer->SetNeedsDisplayRect(update_rect); + + VerifySerializationAndDeserialization(); + Layer* client_layer = + compositor_state_deserializer_->GetLayerForEngineId(layer->id()); + EXPECT_EQ(update_rect, client_layer->update_rect()); +} + +TEST_F(LayerTreeHostSerializationTest, SolidColorScrollbarLayer) { + scoped_refptr<Layer> root_layer = Layer::Create(); + layer_tree_host_remote_->GetLayerTree()->SetRootLayer(root_layer); + scoped_refptr<Layer> child_layer = Layer::Create(); + root_layer->AddChild(child_layer); + + std::vector<scoped_refptr<SolidColorScrollbarLayer>> scrollbar_layers; + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::HORIZONTAL, 20, 5, true, root_layer->id())); + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::VERTICAL, 20, 5, false, child_layer->id())); + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::HORIZONTAL, 0, 0, true, root_layer->id())); + scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( + ScrollbarOrientation::VERTICAL, 10, 35, true, child_layer->id())); + for (const auto& layer : scrollbar_layers) { + root_layer->AddChild(layer); + } + + VerifySerializationAndDeserialization(); + for (const auto& engine_layer : scrollbar_layers) { + VerifySerializedScrollbarLayersAreIdentical( + engine_layer.get(), compositor_state_deserializer_.get()); + } +} + +TEST_F(LayerTreeHostSerializationTest, PictureLayerSerialization) { + // Override the layer factor to create FakePictureLayers in the deserializer. + compositor_state_deserializer_->SetLayerFactoryForTesting( + base::MakeUnique<RemoteClientLayerFactory>()); + + LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); + scoped_refptr<Layer> root_layer_src = Layer::Create(); + engine_layer_tree->SetRootLayer(root_layer_src); + + // Ensure that a PictureLayer work correctly for multiple rounds of + // serialization and deserialization. + FakeContentLayerClient content_client; + gfx::Size bounds(256, 256); + content_client.set_bounds(bounds); + SkPaint simple_paint; + simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34)); + content_client.add_draw_rect(gfx::Rect(bounds), simple_paint); + scoped_refptr<FakePictureLayer> picture_layer_src = + FakePictureLayer::Create(&content_client); + + root_layer_src->AddChild(picture_layer_src); + picture_layer_src->SetNearestNeighbor(!picture_layer_src->nearest_neighbor()); + picture_layer_src->SetNeedsDisplay(); + VerifySerializationAndDeserialization(); + layer_tree_host_in_process_->UpdateLayers(); + VerifySerializedPictureLayersAreIdentical( + picture_layer_src.get(), compositor_state_deserializer_.get()); + + // Another round. + picture_layer_src->SetNeedsDisplay(); + SkPaint new_paint; + new_paint.setColor(SkColorSetARGB(255, 12, 32, 44)); + content_client.add_draw_rect(gfx::Rect(bounds), new_paint); + VerifySerializationAndDeserialization(); + layer_tree_host_in_process_->UpdateLayers(); + VerifySerializedPictureLayersAreIdentical( + picture_layer_src.get(), compositor_state_deserializer_.get()); +} + +TEST_F(LayerTreeHostSerializationTest, EmptyPictureLayerSerialization) { + // Override the layer factor to create FakePictureLayers in the deserializer. + compositor_state_deserializer_->SetLayerFactoryForTesting( + base::MakeUnique<RemoteClientLayerFactory>()); + + LayerTree* engine_layer_tree = layer_tree_host_remote_->GetLayerTree(); + scoped_refptr<Layer> root_layer_src = Layer::Create(); + engine_layer_tree->SetRootLayer(root_layer_src); + scoped_refptr<FakePictureLayer> picture_layer_src = + FakePictureLayer::Create(EmptyContentLayerClient::GetInstance()); + root_layer_src->AddChild(picture_layer_src); + picture_layer_src->SetNeedsDisplay(); + VerifySerializationAndDeserialization(); + layer_tree_host_in_process_->UpdateLayers(); + VerifySerializedPictureLayersAreIdentical( + picture_layer_src.get(), compositor_state_deserializer_.get()); +} + +} // namespace cc diff --git a/chromium/cc/blimp/remote_compositor_bridge.cc b/chromium/cc/blimp/remote_compositor_bridge.cc index 0ff2a21f1fd..6fca07530ec 100644 --- a/chromium/cc/blimp/remote_compositor_bridge.cc +++ b/chromium/cc/blimp/remote_compositor_bridge.cc @@ -4,7 +4,7 @@ #include "cc/blimp/remote_compositor_bridge.h" -#include "base/single_thread_task_runner.h" +#include <utility> namespace cc { diff --git a/chromium/cc/blimp/remote_compositor_bridge.h b/chromium/cc/blimp/remote_compositor_bridge.h index d4a0eded8e9..bc916dafc41 100644 --- a/chromium/cc/blimp/remote_compositor_bridge.h +++ b/chromium/cc/blimp/remote_compositor_bridge.h @@ -7,13 +7,11 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/single_thread_task_runner.h" #include "cc/base/cc_export.h" -namespace base { -class SingleThreadTaskRunner; -} // namespace base - namespace cc { + class CompositorProtoState; class RemoteCompositorBridgeClient; @@ -52,4 +50,5 @@ class CC_EXPORT RemoteCompositorBridge { }; } // namespace cc + #endif // CC_BLIMP_REMOTE_COMPOSITOR_BRIDGE_H_ diff --git a/chromium/cc/blimp/remote_compositor_bridge_client.h b/chromium/cc/blimp/remote_compositor_bridge_client.h index 434dd0abfae..00a651ebacb 100644 --- a/chromium/cc/blimp/remote_compositor_bridge_client.h +++ b/chromium/cc/blimp/remote_compositor_bridge_client.h @@ -5,18 +5,24 @@ #ifndef CC_BLIMP_REMOTE_COMPOSITOR_BRIDGE_CLIENT_H_ #define CC_BLIMP_REMOTE_COMPOSITOR_BRIDGE_CLIENT_H_ +#include <unordered_map> + #include "base/macros.h" #include "cc/base/cc_export.h" -namespace base { -class SingleThreadTaskRunner; -} // namespace base +namespace gfx { +class ScrollOffset; +} // namespace gfx namespace cc { -class CompositorProtoState; +namespace proto { +class ClientStateUpdate; +} // namespace proto class CC_EXPORT RemoteCompositorBridgeClient { public: + using ScrollOffsetMap = std::unordered_map<int, gfx::ScrollOffset>; + virtual ~RemoteCompositorBridgeClient() {} // Called in response to a ScheduleMainFrame request made on the @@ -24,6 +30,11 @@ class CC_EXPORT RemoteCompositorBridgeClient { // Note: The method should always be invoked asynchronously after the request // is made. virtual void BeginMainFrame() = 0; + + // Applied state updates reported from the client onto the main thread state + // on the engine. + virtual void ApplyStateUpdateFromClient( + const proto::ClientStateUpdate& client_state_update) = 0; }; } // namespace cc diff --git a/chromium/cc/blimp/synced_property_remote.h b/chromium/cc/blimp/synced_property_remote.h new file mode 100644 index 00000000000..457d1578add --- /dev/null +++ b/chromium/cc/blimp/synced_property_remote.h @@ -0,0 +1,122 @@ +// 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_BLIMP_SYNCED_PROPERTY_REMOTE_H_ +#define CC_BLIMP_SYNCED_PROPERTY_REMOTE_H_ + +#include "cc/base/synced_property.h" + +namespace cc { + +// This class is heavily inspired from SyncedProperty and is the equivalent of +// SyncedProperty for synchronizing state between the engine and client in +// remote mode. There are effectively 2 trees on the main thread, the LayerTree +// on the main thread on the engine, and the tree on the main thread on the +// client. +// +// The client main thread tree receives deltas from the impl thread, but must +// synchronize them with the engine main thread before applying them onto the +// the main thread associated state. At the same time there are different sets +// of deltas, the value that was received from the impl thread but has not yet +// been reported to the engine main thread, and the value that has been sent +// to the engine main thread, but a state update with the application of these +// deltas has not been received from the engine. The purpose of this class is to +// track these deltas for deciding what needs to be reported to the main thread +// on the engine, and providing the impl thread with the delta that it should +// apply to its associated state since it could not be reflected in the local +// BeginMainFrame on the client main thread. +// +// Instances of this class are held on the client main thread and have a 1:1 +// mapping with their corresponding SyncedProperty instances. + +// Note: This class currently supports only one set of deltas to be in flight to +// the engine. +template <typename T> +class SyncedPropertyRemote { + public: + SyncedPropertyRemote() = default; + + SyncedPropertyRemote(SyncedPropertyRemote&& other) = default; + + SyncedPropertyRemote& operator=(SyncedPropertyRemote&& other) = default; + + // Push the main thread state from the engine onto the client main thread + // associated state. + void PushFromEngineMainThread( + typename T::ValueType engine_main_thread_value) { + engine_main_base_ = T(engine_main_thread_value); + } + + // Called when an update for changes made on the impl thread was received on + // the client main thread. + // |main_thread_value| holds the updated value on the client main thread. + void UpdateDeltaFromImplThread(typename T::ValueType main_thread_value) { + T delta_from_impl_thread = + T(main_thread_value).InverseCombine(engine_main_base_); + unsent_delta_from_impl_thread_ = + unsent_delta_from_impl_thread_.Combine(delta_from_impl_thread); + } + + // Pull deltas for changes tracked on the client main thread to be sent to the + // engine main thread. + // Each call to this must be followed with a call to DidApplySentDeltaOnEngine + // before another set of deltas can be pulled. + typename T::ValueType PullDeltaForEngineUpdate() { + DCHECK(sent_but_unapplied_delta_from_impl_thread_.get() == + T::Identity().get()); + + T delta_to_send = unsent_delta_from_impl_thread_; + sent_but_unapplied_delta_from_impl_thread_ = delta_to_send; + unsent_delta_from_impl_thread_ = T::Identity(); + return delta_to_send.get(); + } + + // Called when deltas sent to the engine were applied to the main thread state + // on the engine. + void DidApplySentDeltaOnEngine() { + // Pre-emptively apply the deltas that were sent. This is necessary since + // the engine may not send a frame update if the deltas were simply + // reflected back by the engine main thread (equivalent to + // BeginMainFrameAborted between the main and impl thread). + // If the engine did send a frame, we expect the frame to come with the ack + // for the deltas, so the value will be over-written with the engine update + // before being pushed to the impl thread. + engine_main_base_ = + engine_main_base_.Combine(sent_but_unapplied_delta_from_impl_thread_); + sent_but_unapplied_delta_from_impl_thread_ = T::Identity(); + } + + // Returns the delta that was reported to the main thread on the client but + // has not yet been applied to the main thread on the engine. + typename T::ValueType DeltaNotAppliedOnEngine() { + T total_delta_on_client = unsent_delta_from_impl_thread_.Combine( + sent_but_unapplied_delta_from_impl_thread_); + return total_delta_on_client.get(); + } + + typename T::ValueType EngineMain() { return engine_main_base_.get(); } + + private: + // The delta that was applied to the state on the impl thread and received on + // the main thread on the client during BeginMainFrame, but has not yet been + // reported to the main thread on the engine. + T unsent_delta_from_impl_thread_; + + // The delta that was applied to the state on the impl thread and has been + // sent to the main thread on the engine, but has not yet been applied to the + // main thread on the engine. + T sent_but_unapplied_delta_from_impl_thread_; + + // The value as last received from the main thread on the engine. The value on + // the main thread state on the client should always be set to this value, + // outside of the interval when deltas from the impl thread are reported to + // the main thread on the client. + T engine_main_base_; + + DISALLOW_COPY_AND_ASSIGN(SyncedPropertyRemote); +}; + +} // namespace cc + +#endif // CC_BLIMP_SYNCED_PROPERTY_REMOTE_H_ diff --git a/chromium/cc/blimp/synced_property_remote_unittest.cc b/chromium/cc/blimp/synced_property_remote_unittest.cc new file mode 100644 index 00000000000..0f94ee4ecbf --- /dev/null +++ b/chromium/cc/blimp/synced_property_remote_unittest.cc @@ -0,0 +1,57 @@ +// 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/blimp/synced_property_remote.h" + +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +TEST(SyncedPropertyRemoteTest, BasicDeltaTracking) { + SyncedPropertyRemote<ScaleGroup> synced_float; + + // Set up the initial value. + float initial_state = 0.5f; + synced_float.PushFromEngineMainThread(initial_state); + EXPECT_EQ(synced_float.EngineMain(), initial_state); + + // Apply a delta from the impl thread. + float delta_from_impl = 0.2f; + synced_float.UpdateDeltaFromImplThread(initial_state * delta_from_impl); + EXPECT_EQ(synced_float.DeltaNotAppliedOnEngine(), delta_from_impl); + EXPECT_EQ(synced_float.EngineMain(), initial_state); + + // Pull a state update for the engine. + float delta_to_send = synced_float.PullDeltaForEngineUpdate(); + EXPECT_EQ(delta_to_send, delta_from_impl); + + // The initial delta should still be reported as unapplied. + EXPECT_EQ(synced_float.DeltaNotAppliedOnEngine(), delta_from_impl); + + // Now send some more delta from impl. It should be included in the unapplied + // delta. + float second_delta_from_impl = 0.3f; + synced_float.UpdateDeltaFromImplThread(synced_float.EngineMain() * + second_delta_from_impl); + float third_delta_from_impl = 0.4f; + synced_float.UpdateDeltaFromImplThread(synced_float.EngineMain() * + third_delta_from_impl); + + float expected_total_delta = + delta_from_impl * second_delta_from_impl * third_delta_from_impl; + EXPECT_EQ(synced_float.DeltaNotAppliedOnEngine(), expected_total_delta); + + // Inform that the delta was applied on the engine and make sure it is + // pre-emptively applied on the client. + synced_float.DidApplySentDeltaOnEngine(); + EXPECT_EQ(synced_float.EngineMain(), initial_state * delta_from_impl); + + // Now pull another delta, it should be now the accumulated delta. + EXPECT_EQ(synced_float.PullDeltaForEngineUpdate(), + second_delta_from_impl * third_delta_from_impl); +} + +} // namespace +} // namespace cc diff --git a/chromium/cc/blink/web_compositor_support_impl.cc b/chromium/cc/blink/web_compositor_support_impl.cc index be6d95e9b24..ac2b81589d6 100644 --- a/chromium/cc/blink/web_compositor_support_impl.cc +++ b/chromium/cc/blink/web_compositor_support_impl.cc @@ -4,8 +4,9 @@ #include "cc/blink/web_compositor_support_impl.h" -#include <memory> +#include <utility> +#include "base/memory/ptr_util.h" #include "cc/blink/web_content_layer_impl.h" #include "cc/blink/web_display_item_list_impl.h" #include "cc/blink/web_external_texture_layer_impl.h" @@ -35,44 +36,49 @@ WebCompositorSupportImpl::WebCompositorSupportImpl() { WebCompositorSupportImpl::~WebCompositorSupportImpl() { } -WebLayer* WebCompositorSupportImpl::createLayer() { - return new WebLayerImpl(); +std::unique_ptr<WebLayer> WebCompositorSupportImpl::createLayer() { + return base::MakeUnique<WebLayerImpl>(); } -WebLayer* WebCompositorSupportImpl::createLayerFromCCLayer(cc::Layer* layer) { - return new WebLayerImpl(layer); +std::unique_ptr<WebLayer> WebCompositorSupportImpl::createLayerFromCCLayer( + cc::Layer* layer) { + return base::MakeUnique<WebLayerImpl>(layer); } -WebContentLayer* WebCompositorSupportImpl::createContentLayer( +std::unique_ptr<WebContentLayer> WebCompositorSupportImpl::createContentLayer( WebContentLayerClient* client) { - return new WebContentLayerImpl(client); + return base::MakeUnique<WebContentLayerImpl>(client); } -WebExternalTextureLayer* WebCompositorSupportImpl::createExternalTextureLayer( +std::unique_ptr<WebExternalTextureLayer> +WebCompositorSupportImpl::createExternalTextureLayer( cc::TextureLayerClient* client) { - return new WebExternalTextureLayerImpl(client); + return base::MakeUnique<WebExternalTextureLayerImpl>(client); } -blink::WebImageLayer* WebCompositorSupportImpl::createImageLayer() { - return new WebImageLayerImpl(); +std::unique_ptr<blink::WebImageLayer> +WebCompositorSupportImpl::createImageLayer() { + return base::MakeUnique<WebImageLayerImpl>(); } -WebScrollbarLayer* WebCompositorSupportImpl::createScrollbarLayer( - WebScrollbar* scrollbar, +std::unique_ptr<WebScrollbarLayer> +WebCompositorSupportImpl::createScrollbarLayer( + std::unique_ptr<WebScrollbar> scrollbar, WebScrollbarThemePainter painter, - WebScrollbarThemeGeometry* geometry) { - return new WebScrollbarLayerImpl(scrollbar, painter, geometry); + std::unique_ptr<WebScrollbarThemeGeometry> geometry) { + return base::MakeUnique<WebScrollbarLayerImpl>(std::move(scrollbar), painter, + std::move(geometry)); } -WebScrollbarLayer* WebCompositorSupportImpl::createSolidColorScrollbarLayer( +std::unique_ptr<WebScrollbarLayer> +WebCompositorSupportImpl::createSolidColorScrollbarLayer( WebScrollbar::Orientation orientation, int thumb_thickness, int track_start, bool is_left_side_vertical_scrollbar) { - return new WebScrollbarLayerImpl(orientation, - thumb_thickness, - track_start, - is_left_side_vertical_scrollbar); + return base::MakeUnique<WebScrollbarLayerImpl>( + orientation, thumb_thickness, track_start, + is_left_side_vertical_scrollbar); } } // namespace cc_blink diff --git a/chromium/cc/blink/web_compositor_support_impl.h b/chromium/cc/blink/web_compositor_support_impl.h index d402d85905c..91a205a12a3 100644 --- a/chromium/cc/blink/web_compositor_support_impl.h +++ b/chromium/cc/blink/web_compositor_support_impl.h @@ -20,18 +20,18 @@ class CC_BLINK_EXPORT WebCompositorSupportImpl WebCompositorSupportImpl(); ~WebCompositorSupportImpl() override; - blink::WebLayer* createLayer() override; - blink::WebLayer* createLayerFromCCLayer(cc::Layer*) override; - blink::WebContentLayer* createContentLayer( + std::unique_ptr<blink::WebLayer> createLayer() override; + std::unique_ptr<blink::WebLayer> createLayerFromCCLayer(cc::Layer*) override; + std::unique_ptr<blink::WebContentLayer> createContentLayer( blink::WebContentLayerClient* client) override; - blink::WebExternalTextureLayer* createExternalTextureLayer( + std::unique_ptr<blink::WebExternalTextureLayer> createExternalTextureLayer( cc::TextureLayerClient* client) override; - blink::WebImageLayer* createImageLayer() override; - blink::WebScrollbarLayer* createScrollbarLayer( - blink::WebScrollbar* scrollbar, + std::unique_ptr<blink::WebImageLayer> createImageLayer() override; + std::unique_ptr<blink::WebScrollbarLayer> createScrollbarLayer( + std::unique_ptr<blink::WebScrollbar> scrollbar, blink::WebScrollbarThemePainter painter, - blink::WebScrollbarThemeGeometry*) override; - blink::WebScrollbarLayer* createSolidColorScrollbarLayer( + std::unique_ptr<blink::WebScrollbarThemeGeometry>) override; + std::unique_ptr<blink::WebScrollbarLayer> createSolidColorScrollbarLayer( blink::WebScrollbar::Orientation orientation, int thumb_thickness, int track_start, diff --git a/chromium/cc/blink/web_content_layer_impl.h b/chromium/cc/blink/web_content_layer_impl.h index 227225df997..5fb47b3da87 100644 --- a/chromium/cc/blink/web_content_layer_impl.h +++ b/chromium/cc/blink/web_content_layer_impl.h @@ -15,11 +15,6 @@ #include "cc/layers/content_layer_client.h" #include "third_party/WebKit/public/platform/WebContentLayer.h" -namespace cc { -class IntRect; -class FloatRect; -} - namespace blink { class WebContentLayerClient; } @@ -31,12 +26,12 @@ class WebContentLayerImpl : public blink::WebContentLayer, public: CC_BLINK_EXPORT explicit WebContentLayerImpl(blink::WebContentLayerClient*); + ~WebContentLayerImpl() override; + // WebContentLayer implementation. blink::WebLayer* layer() override; protected: - ~WebContentLayerImpl() override; - // ContentLayerClient implementation. gfx::Rect PaintableRegion() override; scoped_refptr<cc::DisplayItemList> PaintContentsToDisplayList( diff --git a/chromium/cc/blink/web_display_item_list_impl.h b/chromium/cc/blink/web_display_item_list_impl.h index 7a8e9ef7b88..09b7c58b773 100644 --- a/chromium/cc/blink/web_display_item_list_impl.h +++ b/chromium/cc/blink/web_display_item_list_impl.h @@ -16,7 +16,6 @@ #include "ui/gfx/geometry/point_f.h" class SkColorFilter; -class SkImageFilter; class SkMatrix44; class SkPath; class SkPicture; @@ -29,7 +28,6 @@ struct WebRect; } namespace cc { -class DisplayItemListSettings; class FilterOperations; } diff --git a/chromium/cc/blink/web_layer_impl.cc b/chromium/cc/blink/web_layer_impl.cc index a88fd3068c0..d4e6c9f37da 100644 --- a/chromium/cc/blink/web_layer_impl.cc +++ b/chromium/cc/blink/web_layer_impl.cc @@ -14,12 +14,12 @@ #include "base/strings/string_util.h" #include "base/threading/thread_checker.h" #include "base/trace_event/trace_event_impl.h" -#include "cc/animation/element_id.h" #include "cc/base/region.h" #include "cc/base/switches.h" #include "cc/blink/web_blend_mode.h" #include "cc/layers/layer.h" #include "cc/layers/layer_position_constraint.h" +#include "cc/trees/element_id.h" #include "cc/trees/layer_tree_host.h" #include "third_party/WebKit/public/platform/WebFloatPoint.h" #include "third_party/WebKit/public/platform/WebFloatRect.h" @@ -372,6 +372,8 @@ ToWebLayerStickyPositionConstraint( web_constraint.rightOffset = constraint.right_offset; web_constraint.topOffset = constraint.top_offset; web_constraint.bottomOffset = constraint.bottom_offset; + web_constraint.parentRelativeStickyBoxOffset = + constraint.parent_relative_sticky_box_offset; web_constraint.scrollContainerRelativeStickyBoxRect = constraint.scroll_container_relative_sticky_box_rect; web_constraint.scrollContainerRelativeContainingBlockRect = @@ -390,6 +392,8 @@ static cc::LayerStickyPositionConstraint ToStickyPositionConstraint( constraint.right_offset = web_constraint.rightOffset; constraint.top_offset = web_constraint.topOffset; constraint.bottom_offset = web_constraint.bottomOffset; + constraint.parent_relative_sticky_box_offset = + web_constraint.parentRelativeStickyBoxOffset; constraint.scroll_container_relative_sticky_box_rect = web_constraint.scrollContainerRelativeStickyBoxRect; constraint.scroll_container_relative_containing_block_rect = @@ -470,4 +474,12 @@ void WebLayerImpl::setHasWillChangeTransformHint(bool has_will_change) { layer_->SetHasWillChangeTransformHint(has_will_change); } +void WebLayerImpl::setPreferredRasterBounds(const WebSize& bounds) { + layer_->SetPreferredRasterBounds(bounds); +} + +void WebLayerImpl::clearPreferredRasterBounds() { + layer_->ClearPreferredRasterBounds(); +} + } // namespace cc_blink diff --git a/chromium/cc/blink/web_layer_impl.h b/chromium/cc/blink/web_layer_impl.h index eaa2f05ae98..42eb99c20cc 100644 --- a/chromium/cc/blink/web_layer_impl.h +++ b/chromium/cc/blink/web_layer_impl.h @@ -28,16 +28,6 @@ #include "third_party/WebKit/public/platform/WebVector.h" #include "third_party/skia/include/core/SkMatrix44.h" -namespace blink { -struct WebFloatRect; -} - -namespace base { -namespace trace_event { -class ConvertableToTraceFormat; -} -} - namespace cc { class FilterOperations; class Layer; @@ -136,6 +126,8 @@ class CC_BLINK_EXPORT WebLayerImpl : public NON_EXPORTED_BASE(blink::WebLayer) { void setCompositorMutableProperties(uint32_t properties) override; uint32_t compositorMutableProperties() const override; void setHasWillChangeTransformHint(bool has_will_change) override; + void setPreferredRasterBounds(const blink::WebSize&) override; + void clearPreferredRasterBounds() override; void setScrollParent(blink::WebLayer* parent) override; void setClipParent(blink::WebLayer* parent) override; diff --git a/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc b/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc index 9dc0cbad6d8..cb4e20ac4e4 100644 --- a/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc +++ b/chromium/cc/blink/web_layer_impl_fixed_bounds_unittest.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include <vector> +#include "cc/animation/animation_host.h" #include "cc/blink/web_layer_impl_fixed_bounds.h" #include "cc/layers/picture_image_layer.h" #include "cc/test/fake_layer_tree_host.h" @@ -103,10 +104,13 @@ void CompareFixedBoundsLayerAndNormalLayer(const WebFloatPoint& anchor_point, normal_layer.setPosition(position); root_layer.addChild(&normal_layer); + auto animation_host = + cc::AnimationHost::CreateForTesting(cc::ThreadInstance::MAIN); + cc::FakeLayerTreeHostClient client; cc::TestTaskGraphRunner task_graph_runner; - std::unique_ptr<cc::FakeLayerTreeHost> host = - cc::FakeLayerTreeHost::Create(&client, &task_graph_runner); + std::unique_ptr<cc::FakeLayerTreeHost> host = cc::FakeLayerTreeHost::Create( + &client, &task_graph_runner, animation_host.get()); host->SetRootLayer(root_layer.layer()); { diff --git a/chromium/cc/blink/web_scrollbar_layer_impl.cc b/chromium/cc/blink/web_scrollbar_layer_impl.cc index 7011d5fc91e..b9c6df38b6c 100644 --- a/chromium/cc/blink/web_scrollbar_layer_impl.cc +++ b/chromium/cc/blink/web_scrollbar_layer_impl.cc @@ -4,6 +4,8 @@ #include "cc/blink/web_scrollbar_layer_impl.h" +#include <utility> + #include "base/memory/ptr_util.h" #include "cc/blink/scrollbar_impl.h" #include "cc/blink/web_layer_impl.h" @@ -28,15 +30,13 @@ cc::ScrollbarOrientation ConvertOrientation( namespace cc_blink { WebScrollbarLayerImpl::WebScrollbarLayerImpl( - blink::WebScrollbar* scrollbar, + std::unique_ptr<blink::WebScrollbar> scrollbar, blink::WebScrollbarThemePainter painter, - blink::WebScrollbarThemeGeometry* geometry) + std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry) : layer_(new WebLayerImpl(PaintedScrollbarLayer::Create( - - std::unique_ptr<cc::Scrollbar>( - new ScrollbarImpl(base::WrapUnique(scrollbar), - painter, - base::WrapUnique(geometry))), + base::MakeUnique<ScrollbarImpl>(std::move(scrollbar), + painter, + std::move(geometry)), 0))) {} WebScrollbarLayerImpl::WebScrollbarLayerImpl( diff --git a/chromium/cc/blink/web_scrollbar_layer_impl.h b/chromium/cc/blink/web_scrollbar_layer_impl.h index 0239b413d6f..3fd192efe84 100644 --- a/chromium/cc/blink/web_scrollbar_layer_impl.h +++ b/chromium/cc/blink/web_scrollbar_layer_impl.h @@ -24,9 +24,9 @@ class WebLayerImpl; class WebScrollbarLayerImpl : public blink::WebScrollbarLayer { public: CC_BLINK_EXPORT WebScrollbarLayerImpl( - blink::WebScrollbar* scrollbar, + std::unique_ptr<blink::WebScrollbar> scrollbar, blink::WebScrollbarThemePainter painter, - blink::WebScrollbarThemeGeometry* geometry); + std::unique_ptr<blink::WebScrollbarThemeGeometry> geometry); CC_BLINK_EXPORT WebScrollbarLayerImpl( blink::WebScrollbar::Orientation orientation, int thumb_thickness, diff --git a/chromium/cc/debug/devtools_instrumentation.h b/chromium/cc/debug/devtools_instrumentation.h index 127c9a93c26..9195a31f15c 100644 --- a/chromium/cc/debug/devtools_instrumentation.h +++ b/chromium/cc/debug/devtools_instrumentation.h @@ -10,6 +10,7 @@ #include <memory> #include "base/macros.h" +#include "base/metrics/histogram_macros.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" @@ -57,15 +58,32 @@ class ScopedLayerTask { class ScopedImageDecodeTask { public: - explicit ScopedImageDecodeTask(const void* imagePtr) { + enum Type { SOFTWARE, GPU }; + + ScopedImageDecodeTask(const void* imagePtr, Type type) + : type_(type), start_time_(base::TimeTicks::Now()) { TRACE_EVENT_BEGIN1(internal::kCategory, internal::kImageDecodeTask, internal::kPixelRefId, reinterpret_cast<uint64_t>(imagePtr)); } ~ScopedImageDecodeTask() { TRACE_EVENT_END0(internal::kCategory, internal::kImageDecodeTask); + base::TimeDelta duration = base::TimeTicks::Now() - start_time_; + switch (type_) { + case SOFTWARE: + UMA_HISTOGRAM_COUNTS_1M("Renderer4.ImageDecodeTaskDurationUs.Software", + duration.InMicroseconds()); + break; + case GPU: + UMA_HISTOGRAM_COUNTS_1M("Renderer4.ImageDecodeTaskDurationUs.Gpu", + duration.InMicroseconds()); + break; + } } + private: + const Type type_; + const base::TimeTicks start_time_; DISALLOW_COPY_AND_ASSIGN(ScopedImageDecodeTask); }; diff --git a/chromium/cc/debug/invalidation_benchmark.h b/chromium/cc/debug/invalidation_benchmark.h index d30ac3f1e18..ca69957413e 100644 --- a/chromium/cc/debug/invalidation_benchmark.h +++ b/chromium/cc/debug/invalidation_benchmark.h @@ -14,7 +14,7 @@ namespace cc { class LayerTree; -class Layer; + // NOTE: this benchmark will not measure or return any results, it will simply // invalidate a certain area of each layer every frame. It is intended to be // used in combination with a telemetry benchmark that does the actual diff --git a/chromium/cc/debug/layer_tree_debug_state.cc b/chromium/cc/debug/layer_tree_debug_state.cc index 527bd023204..ea20e3f5a24 100644 --- a/chromium/cc/debug/layer_tree_debug_state.cc +++ b/chromium/cc/debug/layer_tree_debug_state.cc @@ -5,7 +5,6 @@ #include "cc/debug/layer_tree_debug_state.h" #include "base/logging.h" -#include "cc/proto/layer_tree_debug_state.pb.h" namespace cc { @@ -56,44 +55,6 @@ bool LayerTreeDebugState::ShowMemoryStats() const { return show_fps_counter; } -void LayerTreeDebugState::ToProtobuf(proto::LayerTreeDebugState* proto) const { - proto->set_show_fps_counter(show_fps_counter); - proto->set_show_debug_borders(show_debug_borders); - proto->set_show_paint_rects(show_paint_rects); - proto->set_show_property_changed_rects(show_property_changed_rects); - proto->set_show_surface_damage_rects(show_surface_damage_rects); - proto->set_show_screen_space_rects(show_screen_space_rects); - proto->set_show_touch_event_handler_rects(show_touch_event_handler_rects); - proto->set_show_wheel_event_handler_rects(show_wheel_event_handler_rects); - proto->set_show_scroll_event_handler_rects(show_scroll_event_handler_rects); - proto->set_show_non_fast_scrollable_rects(show_non_fast_scrollable_rects); - proto->set_show_layer_animation_bounds_rects( - show_layer_animation_bounds_rects); - proto->set_slow_down_raster_scale_factor(slow_down_raster_scale_factor); - proto->set_rasterize_only_visible_content(rasterize_only_visible_content); - proto->set_show_picture_borders(show_picture_borders); - proto->set_record_rendering_stats(record_rendering_stats_); -} - -void LayerTreeDebugState::FromProtobuf( - const proto::LayerTreeDebugState& proto) { - show_fps_counter = proto.show_fps_counter(); - show_debug_borders = proto.show_debug_borders(); - show_paint_rects = proto.show_paint_rects(); - show_property_changed_rects = proto.show_property_changed_rects(); - show_surface_damage_rects = proto.show_surface_damage_rects(); - show_screen_space_rects = proto.show_screen_space_rects(); - show_touch_event_handler_rects = proto.show_touch_event_handler_rects(); - show_wheel_event_handler_rects = proto.show_wheel_event_handler_rects(); - show_scroll_event_handler_rects = proto.show_scroll_event_handler_rects(); - show_non_fast_scrollable_rects = proto.show_non_fast_scrollable_rects(); - show_layer_animation_bounds_rects = proto.show_layer_animation_bounds_rects(); - slow_down_raster_scale_factor = proto.slow_down_raster_scale_factor(); - rasterize_only_visible_content = proto.rasterize_only_visible_content(); - show_picture_borders = proto.show_picture_borders(); - record_rendering_stats_ = proto.record_rendering_stats(); -} - bool LayerTreeDebugState::Equal(const LayerTreeDebugState& a, const LayerTreeDebugState& b) { return ( diff --git a/chromium/cc/debug/layer_tree_debug_state.h b/chromium/cc/debug/layer_tree_debug_state.h index 176c562313e..09ac66de5c8 100644 --- a/chromium/cc/debug/layer_tree_debug_state.h +++ b/chromium/cc/debug/layer_tree_debug_state.h @@ -43,9 +43,6 @@ class CC_EXPORT LayerTreeDebugState { bool ShowHudRects() const; bool ShowMemoryStats() const; - void ToProtobuf(proto::LayerTreeDebugState* proto) const; - void FromProtobuf(const proto::LayerTreeDebugState& proto); - static bool Equal(const LayerTreeDebugState& a, const LayerTreeDebugState& b); static LayerTreeDebugState Unite(const LayerTreeDebugState& a, const LayerTreeDebugState& b); diff --git a/chromium/cc/debug/layer_tree_debug_state_unittest.cc b/chromium/cc/debug/layer_tree_debug_state_unittest.cc deleted file mode 100644 index b66e44ec206..00000000000 --- a/chromium/cc/debug/layer_tree_debug_state_unittest.cc +++ /dev/null @@ -1,62 +0,0 @@ -// Copyright 2015 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/debug/layer_tree_debug_state.h" - -#include "cc/proto/layer_tree_debug_state.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -void VerifySerializeAndDeserializeProto(const LayerTreeDebugState& state1) { - proto::LayerTreeDebugState proto; - state1.ToProtobuf(&proto); - LayerTreeDebugState state2; - state2.FromProtobuf(proto); - EXPECT_TRUE(LayerTreeDebugState::Equal(state1, state2)); -} - -TEST(LayerTreeDebugStateTest, AllFieldsTrue) { - LayerTreeDebugState state; - state.show_fps_counter = true; - state.show_debug_borders = true; - state.show_paint_rects = true; - state.show_property_changed_rects = true; - state.show_surface_damage_rects = true; - state.show_screen_space_rects = true; - state.show_touch_event_handler_rects = true; - state.show_wheel_event_handler_rects = true; - state.show_scroll_event_handler_rects = true; - state.show_non_fast_scrollable_rects = true; - state.show_layer_animation_bounds_rects = true; - state.slow_down_raster_scale_factor = 1; - state.rasterize_only_visible_content = true; - state.show_picture_borders = true; - state.SetRecordRenderingStats(true); - VerifySerializeAndDeserializeProto(state); -} - -TEST(LayerTreeDebugStateTest, ArbitraryFieldValues) { - LayerTreeDebugState state; - state.show_fps_counter = true; - state.show_debug_borders = true; - state.show_paint_rects = false; - state.show_property_changed_rects = true; - state.show_surface_damage_rects = false; - state.show_screen_space_rects = false; - state.show_touch_event_handler_rects = true; - state.show_wheel_event_handler_rects = true; - state.show_scroll_event_handler_rects = false; - state.show_non_fast_scrollable_rects = true; - state.show_layer_animation_bounds_rects = true; - state.slow_down_raster_scale_factor = 42; - state.rasterize_only_visible_content = false; - state.show_picture_borders = false; - state.SetRecordRenderingStats(true); - VerifySerializeAndDeserializeProto(state); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/debug/micro_benchmark_controller_unittest.cc b/chromium/cc/debug/micro_benchmark_controller_unittest.cc index 99867775805..4a6ce7e50ee 100644 --- a/chromium/cc/debug/micro_benchmark_controller_unittest.cc +++ b/chromium/cc/debug/micro_benchmark_controller_unittest.cc @@ -9,6 +9,7 @@ #include "base/callback.h" #include "base/memory/ptr_util.h" #include "base/run_loop.h" +#include "cc/animation/animation_host.h" #include "cc/debug/micro_benchmark.h" #include "cc/layers/layer.h" #include "cc/test/fake_impl_task_runner_provider.h" @@ -27,11 +28,11 @@ class MicroBenchmarkControllerTest : public testing::Test { impl_task_runner_provider_ = base::WrapUnique(new FakeImplTaskRunnerProvider); layer_tree_host_impl_ = base::MakeUnique<FakeLayerTreeHostImpl>( - impl_task_runner_provider_.get(), &shared_bitmap_manager_, - &task_graph_runner_); + impl_task_runner_provider_.get(), &task_graph_runner_); - layer_tree_host_ = FakeLayerTreeHost::Create(&layer_tree_host_client_, - &task_graph_runner_); + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + layer_tree_host_ = FakeLayerTreeHost::Create( + &layer_tree_host_client_, &task_graph_runner_, animation_host_.get()); layer_tree_host_->SetRootLayer(Layer::Create()); layer_tree_host_->InitializeForTesting( TaskRunnerProvider::Create(nullptr, nullptr), @@ -42,11 +43,12 @@ class MicroBenchmarkControllerTest : public testing::Test { layer_tree_host_impl_ = nullptr; layer_tree_host_ = nullptr; impl_task_runner_provider_ = nullptr; + animation_host_ = nullptr; } FakeLayerTreeHostClient layer_tree_host_client_; TestTaskGraphRunner task_graph_runner_; - TestSharedBitmapManager shared_bitmap_manager_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; std::unique_ptr<FakeLayerTreeHostImpl> layer_tree_host_impl_; std::unique_ptr<FakeImplTaskRunnerProvider> impl_task_runner_provider_; diff --git a/chromium/cc/debug/rasterize_and_record_benchmark.h b/chromium/cc/debug/rasterize_and_record_benchmark.h index f5f8e4599ed..63d7a34f3f0 100644 --- a/chromium/cc/debug/rasterize_and_record_benchmark.h +++ b/chromium/cc/debug/rasterize_and_record_benchmark.h @@ -24,7 +24,6 @@ class DictionaryValue; namespace cc { class LayerTree; -class Layer; class RasterizeAndRecordBenchmark : public MicroBenchmark { public: diff --git a/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc b/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc index d0269876daa..5d443c7cbb2 100644 --- a/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc +++ b/chromium/cc/debug/rasterize_and_record_benchmark_impl.cc @@ -27,7 +27,7 @@ const int kDefaultRasterizeRepeatCount = 100; void RunBenchmark(RasterSource* raster_source, const gfx::Rect& content_rect, - float contents_scale, + const gfx::SizeF& raster_scales, size_t repeat_count, base::TimeDelta* min_time, bool* is_solid_color) { @@ -45,7 +45,7 @@ void RunBenchmark(RasterSource* raster_source, kTimeCheckInterval); SkColor color = SK_ColorTRANSPARENT; *is_solid_color = raster_source->PerformSolidColorAnalysis( - content_rect, contents_scale, &color); + content_rect, raster_scales, &color); do { SkBitmap bitmap; @@ -54,7 +54,7 @@ void RunBenchmark(RasterSource* raster_source, SkCanvas canvas(bitmap); raster_source->PlaybackToCanvas(&canvas, content_rect, content_rect, - contents_scale, + raster_scales, RasterSource::PlaybackSettings()); timer.NextLap(); @@ -188,11 +188,11 @@ void RasterizeAndRecordBenchmarkImpl::RunOnLayer(PictureLayerImpl* layer) { DCHECK(*it); gfx::Rect content_rect = (*it)->content_rect(); - float contents_scale = (*it)->contents_scale(); + const gfx::SizeF& raster_scales = (*it)->raster_scales(); base::TimeDelta min_time; bool is_solid_color = false; - RunBenchmark(raster_source, content_rect, contents_scale, + RunBenchmark(raster_source, content_rect, raster_scales, rasterize_repeat_count_, &min_time, &is_solid_color); int tile_size = content_rect.width() * content_rect.height(); diff --git a/chromium/cc/debug/rasterize_and_record_benchmark_impl.h b/chromium/cc/debug/rasterize_and_record_benchmark_impl.h index bb4d9a09fb8..6d25c8affc1 100644 --- a/chromium/cc/debug/rasterize_and_record_benchmark_impl.h +++ b/chromium/cc/debug/rasterize_and_record_benchmark_impl.h @@ -20,7 +20,7 @@ namespace cc { class LayerTreeHostImpl; class PictureLayerImpl; -class LayerImpl; + class RasterizeAndRecordBenchmarkImpl : public MicroBenchmarkImpl { public: explicit RasterizeAndRecordBenchmarkImpl( diff --git a/chromium/cc/input/top_controls_manager.cc b/chromium/cc/input/browser_controls_offset_manager.cc index 90ebdc661cd..ad61f21902d 100644 --- a/chromium/cc/input/top_controls_manager.cc +++ b/chromium/cc/input/browser_controls_offset_manager.cc @@ -1,8 +1,8 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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/input/top_controls_manager.h" +#include "cc/input/browser_controls_offset_manager.h" #include <stdint.h> @@ -10,7 +10,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "cc/input/top_controls_manager_client.h" +#include "cc/input/browser_controls_offset_manager_client.h" #include "cc/output/begin_frame_args.h" #include "cc/trees/layer_tree_impl.h" #include "ui/gfx/animation/tween.h" @@ -25,64 +25,68 @@ const int64_t kShowHideMaxDurationMs = 200; } // static -std::unique_ptr<TopControlsManager> TopControlsManager::Create( - TopControlsManagerClient* client, - float top_controls_show_threshold, - float top_controls_hide_threshold) { - return base::WrapUnique(new TopControlsManager( - client, top_controls_show_threshold, top_controls_hide_threshold)); +std::unique_ptr<BrowserControlsOffsetManager> +BrowserControlsOffsetManager::Create(BrowserControlsOffsetManagerClient* client, + float controls_show_threshold, + float controls_hide_threshold) { + return base::WrapUnique(new BrowserControlsOffsetManager( + client, controls_show_threshold, controls_hide_threshold)); } -TopControlsManager::TopControlsManager(TopControlsManagerClient* client, - float top_controls_show_threshold, - float top_controls_hide_threshold) +BrowserControlsOffsetManager::BrowserControlsOffsetManager( + BrowserControlsOffsetManagerClient* client, + float controls_show_threshold, + float controls_hide_threshold) : client_(client), animation_start_value_(0.f), animation_stop_value_(0.f), animation_direction_(NO_ANIMATION), permitted_state_(BOTH), accumulated_scroll_delta_(0.f), - baseline_content_offset_(0.f), - top_controls_show_threshold_(top_controls_hide_threshold), - top_controls_hide_threshold_(top_controls_show_threshold), + baseline_top_content_offset_(0.f), + baseline_bottom_content_offset_(0.f), + controls_show_threshold_(controls_hide_threshold), + controls_hide_threshold_(controls_show_threshold), pinch_gesture_active_(false) { CHECK(client_); } -TopControlsManager::~TopControlsManager() { -} +BrowserControlsOffsetManager::~BrowserControlsOffsetManager() {} -float TopControlsManager::ControlsTopOffset() const { +float BrowserControlsOffsetManager::ControlsTopOffset() const { return ContentTopOffset() - TopControlsHeight(); } -float TopControlsManager::ContentTopOffset() const { - return TopControlsShownRatio() * TopControlsHeight(); +float BrowserControlsOffsetManager::ContentTopOffset() const { + return TopControlsHeight() > 0 + ? TopControlsShownRatio() * TopControlsHeight() : 0.0f; } -float TopControlsManager::TopControlsShownRatio() const { - return client_->CurrentTopControlsShownRatio(); +float BrowserControlsOffsetManager::TopControlsShownRatio() const { + return client_->CurrentBrowserControlsShownRatio(); } -float TopControlsManager::TopControlsHeight() const { +float BrowserControlsOffsetManager::TopControlsHeight() const { return client_->TopControlsHeight(); } -float TopControlsManager::BottomControlsHeight() const { +float BrowserControlsOffsetManager::BottomControlsHeight() const { return client_->BottomControlsHeight(); } -float TopControlsManager::ContentBottomOffset() const { - return TopControlsShownRatio() * BottomControlsHeight(); +float BrowserControlsOffsetManager::ContentBottomOffset() const { + return BottomControlsHeight() > 0 + ? BottomControlsShownRatio() * BottomControlsHeight() : 0.0f; } -float TopControlsManager::BottomControlsShownRatio() const { +float BrowserControlsOffsetManager::BottomControlsShownRatio() const { return TopControlsShownRatio(); } -void TopControlsManager::UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) { +void BrowserControlsOffsetManager::UpdateBrowserControlsState( + BrowserControlsState constraints, + BrowserControlsState current, + bool animate) { DCHECK(!(constraints == SHOWN && current == HIDDEN)); DCHECK(!(constraints == HIDDEN && current == SHOWN)); @@ -105,11 +109,11 @@ void TopControlsManager::UpdateTopControlsState(TopControlsState constraints, SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS); } else { ResetAnimations(); - client_->SetCurrentTopControlsShownRatio(final_shown_ratio); + client_->SetCurrentBrowserControlsShownRatio(final_shown_ratio); } } -void TopControlsManager::ScrollBegin() { +void BrowserControlsOffsetManager::ScrollBegin() { if (pinch_gesture_active_) return; @@ -117,9 +121,14 @@ void TopControlsManager::ScrollBegin() { ResetBaseline(); } -gfx::Vector2dF TopControlsManager::ScrollBy( +gfx::Vector2dF BrowserControlsOffsetManager::ScrollBy( const gfx::Vector2dF& pending_delta) { - if (!TopControlsHeight()) + // If one or both of the top/bottom controls are showing, the shown ratio + // needs to be computed. + float controls_height = + TopControlsHeight() ? TopControlsHeight() : BottomControlsHeight(); + + if (!controls_height) return pending_delta; if (pinch_gesture_active_) @@ -132,10 +141,11 @@ gfx::Vector2dF TopControlsManager::ScrollBy( accumulated_scroll_delta_ += pending_delta.y(); - float old_offset = ContentTopOffset(); - client_->SetCurrentTopControlsShownRatio( - (baseline_content_offset_ - accumulated_scroll_delta_) / - TopControlsHeight()); + float old_top_offset = ContentTopOffset(); + float baseline_content_offset = TopControlsHeight() + ? baseline_top_content_offset_ : baseline_bottom_content_offset_; + client_->SetCurrentBrowserControlsShownRatio( + (baseline_content_offset - accumulated_scroll_delta_) / controls_height); // If the controls are fully visible, treat the current position as the // new baseline even if the gesture didn't end. @@ -144,24 +154,28 @@ gfx::Vector2dF TopControlsManager::ScrollBy( ResetAnimations(); - gfx::Vector2dF applied_delta(0.f, old_offset - ContentTopOffset()); + // applied_delta will negate any scroll on the content if the top browser + // controls are showing in favor of hiding the controls and resizing the + // content. If the top controls have no height, the content should scroll + // immediately. + gfx::Vector2dF applied_delta(0.f, old_top_offset - ContentTopOffset()); return pending_delta - applied_delta; } -void TopControlsManager::ScrollEnd() { +void BrowserControlsOffsetManager::ScrollEnd() { if (pinch_gesture_active_) return; StartAnimationIfNecessary(); } -void TopControlsManager::PinchBegin() { +void BrowserControlsOffsetManager::PinchBegin() { DCHECK(!pinch_gesture_active_); pinch_gesture_active_ = true; StartAnimationIfNecessary(); } -void TopControlsManager::PinchEnd() { +void BrowserControlsOffsetManager::PinchEnd() { DCHECK(pinch_gesture_active_); // Pinch{Begin,End} will always occur within the scope of Scroll{Begin,End}, // so return to a state expected by the remaining scroll sequence. @@ -169,11 +183,12 @@ void TopControlsManager::PinchEnd() { ScrollBegin(); } -void TopControlsManager::MainThreadHasStoppedFlinging() { +void BrowserControlsOffsetManager::MainThreadHasStoppedFlinging() { StartAnimationIfNecessary(); } -gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) { +gfx::Vector2dF BrowserControlsOffsetManager::Animate( + base::TimeTicks monotonic_time) { if (!has_animation() || !client_->HaveRootScrollLayer()) return gfx::Vector2dF(); @@ -181,7 +196,7 @@ gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) { float new_ratio = gfx::Tween::ClampedFloatValueBetween( monotonic_time, animation_start_time_, animation_start_value_, animation_stop_time_, animation_stop_value_); - client_->SetCurrentTopControlsShownRatio(new_ratio); + client_->SetCurrentBrowserControlsShownRatio(new_ratio); if (IsAnimationComplete(new_ratio)) ResetAnimations(); @@ -190,7 +205,7 @@ gfx::Vector2dF TopControlsManager::Animate(base::TimeTicks monotonic_time) { return scroll_delta; } -void TopControlsManager::ResetAnimations() { +void BrowserControlsOffsetManager::ResetAnimations() { animation_start_time_ = base::TimeTicks(); animation_start_value_ = 0.f; animation_stop_time_ = base::TimeTicks(); @@ -199,7 +214,8 @@ void TopControlsManager::ResetAnimations() { animation_direction_ = NO_ANIMATION; } -void TopControlsManager::SetupAnimation(AnimationDirection direction) { +void BrowserControlsOffsetManager::SetupAnimation( + AnimationDirection direction) { DCHECK_NE(NO_ANIMATION, direction); DCHECK(direction != HIDING_CONTROLS || TopControlsShownRatio() > 0.f); DCHECK(direction != SHOWING_CONTROLS || TopControlsShownRatio() < 1.f); @@ -208,7 +224,7 @@ void TopControlsManager::SetupAnimation(AnimationDirection direction) { return; if (!TopControlsHeight()) { - client_->SetCurrentTopControlsShownRatio( + client_->SetCurrentBrowserControlsShownRatio( direction == HIDING_CONTROLS ? 0.f : 1.f); return; } @@ -223,17 +239,17 @@ void TopControlsManager::SetupAnimation(AnimationDirection direction) { animation_stop_value_ = animation_start_value_ + max_ending_ratio; animation_direction_ = direction; - client_->DidChangeTopControlsPosition(); + client_->DidChangeBrowserControlsPosition(); } -void TopControlsManager::StartAnimationIfNecessary() { +void BrowserControlsOffsetManager::StartAnimationIfNecessary() { if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f) return; - if (TopControlsShownRatio() >= 1.f - top_controls_hide_threshold_) { + if (TopControlsShownRatio() >= 1.f - controls_hide_threshold_) { // If we're showing so much that the hide threshold won't trigger, show. SetupAnimation(SHOWING_CONTROLS); - } else if (TopControlsShownRatio() <= top_controls_show_threshold_) { + } else if (TopControlsShownRatio() <= controls_show_threshold_) { // If we're showing so little that the show threshold won't trigger, hide. SetupAnimation(HIDING_CONTROLS); } else { @@ -245,14 +261,15 @@ void TopControlsManager::StartAnimationIfNecessary() { } } -bool TopControlsManager::IsAnimationComplete(float new_ratio) { +bool BrowserControlsOffsetManager::IsAnimationComplete(float new_ratio) { return (animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) || (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f); } -void TopControlsManager::ResetBaseline() { +void BrowserControlsOffsetManager::ResetBaseline() { accumulated_scroll_delta_ = 0.f; - baseline_content_offset_ = ContentTopOffset(); + baseline_top_content_offset_ = ContentTopOffset(); + baseline_bottom_content_offset_ = ContentBottomOffset(); } } // namespace cc diff --git a/chromium/cc/input/top_controls_manager.h b/chromium/cc/input/browser_controls_offset_manager.h index 1d8e1d037d6..88e76fa113d 100644 --- a/chromium/cc/input/top_controls_manager.h +++ b/chromium/cc/input/browser_controls_offset_manager.h @@ -1,46 +1,41 @@ -// Copyright 2013 The Chromium Authors. All rights reserved. +// 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_INPUT_TOP_CONTROLS_MANAGER_H_ -#define CC_INPUT_TOP_CONTROLS_MANAGER_H_ +#ifndef CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_H_ +#define CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_H_ #include <memory> #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" -#include "cc/input/top_controls_state.h" +#include "cc/input/browser_controls_state.h" #include "cc/layers/layer_impl.h" #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/vector2d_f.h" namespace cc { -class LayerTreeImpl; -class TopControlsManagerClient; +class BrowserControlsOffsetManagerClient; -// Manages the position of the top controls. -class CC_EXPORT TopControlsManager - : public base::SupportsWeakPtr<TopControlsManager> { +// Manages the position of the browser controls. +class CC_EXPORT BrowserControlsOffsetManager + : public base::SupportsWeakPtr<BrowserControlsOffsetManager> { public: - enum AnimationDirection { - NO_ANIMATION, - SHOWING_CONTROLS, - HIDING_CONTROLS - }; - - static std::unique_ptr<TopControlsManager> Create( - TopControlsManagerClient* client, - float top_controls_show_threshold, - float top_controls_hide_threshold); - virtual ~TopControlsManager(); + enum AnimationDirection { NO_ANIMATION, SHOWING_CONTROLS, HIDING_CONTROLS }; + + static std::unique_ptr<BrowserControlsOffsetManager> Create( + BrowserControlsOffsetManagerClient* client, + float controls_show_threshold, + float controls_hide_threshold); + virtual ~BrowserControlsOffsetManager(); // The offset from the window top to the top edge of the controls. Runs from 0 // (controls fully shown) to negative values (down is positive). float ControlsTopOffset() const; // The amount of offset of the web content area. Same as the current shown - // height of the top controls. + // height of the browser controls. float ContentTopOffset() const; float TopControlsShownRatio() const; float TopControlsHeight() const; @@ -56,9 +51,9 @@ class CC_EXPORT TopControlsManager bool has_animation() const { return animation_direction_ != NO_ANIMATION; } AnimationDirection animation_direction() { return animation_direction_; } - void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate); + void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate); void ScrollBegin(); gfx::Vector2dF ScrollBy(const gfx::Vector2dF& pending_delta); @@ -74,9 +69,9 @@ class CC_EXPORT TopControlsManager gfx::Vector2dF Animate(base::TimeTicks monotonic_time); protected: - TopControlsManager(TopControlsManagerClient* client, - float top_controls_show_threshold, - float top_controls_hide_threshold); + BrowserControlsOffsetManager(BrowserControlsOffsetManagerClient* client, + float controls_show_threshold, + float controls_hide_threshold); private: void ResetAnimations(); @@ -85,8 +80,8 @@ class CC_EXPORT TopControlsManager bool IsAnimationComplete(float new_ratio); void ResetBaseline(); - TopControlsManagerClient* client_; // The client manages the lifecycle of - // this. + // The client manages the lifecycle of this. + BrowserControlsOffsetManagerClient* client_; base::TimeTicks animation_start_time_; float animation_start_value_; @@ -94,27 +89,28 @@ class CC_EXPORT TopControlsManager float animation_stop_value_; AnimationDirection animation_direction_; - TopControlsState permitted_state_; + BrowserControlsState permitted_state_; // Accumulated scroll delta since last baseline reset float accumulated_scroll_delta_; - // Content offset when last baseline reset occurred - float baseline_content_offset_; + // Content offset when last baseline reset occurred. + float baseline_top_content_offset_; + float baseline_bottom_content_offset_; - // The percent height of the visible top control such that it must be shown + // The percent height of the visible control such that it must be shown // when the user stops the scroll. - float top_controls_show_threshold_; + float controls_show_threshold_; - // The percent height of the visible top control such that it must be hidden + // The percent height of the visible control such that it must be hidden // when the user stops the scroll. - float top_controls_hide_threshold_; + float controls_hide_threshold_; bool pinch_gesture_active_; - DISALLOW_COPY_AND_ASSIGN(TopControlsManager); + DISALLOW_COPY_AND_ASSIGN(BrowserControlsOffsetManager); }; } // namespace cc -#endif // CC_INPUT_TOP_CONTROLS_MANAGER_H_ +#endif // CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_H_ diff --git a/chromium/cc/input/browser_controls_offset_manager_client.h b/chromium/cc/input/browser_controls_offset_manager_client.h new file mode 100644 index 00000000000..12e68aa3ae8 --- /dev/null +++ b/chromium/cc/input/browser_controls_offset_manager_client.h @@ -0,0 +1,25 @@ +// 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_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_CLIENT_H_ +#define CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_CLIENT_H_ + +namespace cc { + +class CC_EXPORT BrowserControlsOffsetManagerClient { + public: + virtual float TopControlsHeight() const = 0; + virtual float BottomControlsHeight() const = 0; + virtual void SetCurrentBrowserControlsShownRatio(float ratio) = 0; + virtual float CurrentBrowserControlsShownRatio() const = 0; + virtual void DidChangeBrowserControlsPosition() = 0; + virtual bool HaveRootScrollLayer() const = 0; + + protected: + virtual ~BrowserControlsOffsetManagerClient() {} +}; + +} // namespace cc + +#endif // CC_INPUT_BROWSER_CONTROLS_OFFSET_MANAGER_CLIENT_H_ diff --git a/chromium/cc/input/top_controls_manager_unittest.cc b/chromium/cc/input/browser_controls_offset_manager_unittest.cc index 5ac2cafb9c4..a320e6573e6 100644 --- a/chromium/cc/input/top_controls_manager_unittest.cc +++ b/chromium/cc/input/browser_controls_offset_manager_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/input/top_controls_manager.h" +#include "cc/input/browser_controls_offset_manager.h" #include <algorithm> #include <cmath> @@ -10,11 +10,10 @@ #include "base/logging.h" #include "base/time/time.h" -#include "cc/input/top_controls_manager_client.h" +#include "cc/input/browser_controls_offset_manager_client.h" #include "cc/layers/layer_impl.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host_impl.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -23,30 +22,30 @@ namespace cc { namespace { -class MockTopControlsManagerClient : public TopControlsManagerClient { +class MockBrowserControlsOffsetManagerClient + : public BrowserControlsOffsetManagerClient { public: - MockTopControlsManagerClient(float top_controls_height, - float top_controls_show_threshold, - float top_controls_hide_threshold) + MockBrowserControlsOffsetManagerClient(float top_controls_height, + float browser_controls_show_threshold, + float browser_controls_hide_threshold) : host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_), redraw_needed_(false), update_draw_properties_needed_(false), bottom_controls_height_(0.f), top_controls_shown_ratio_(1.f), top_controls_height_(top_controls_height), - top_controls_show_threshold_(top_controls_show_threshold), - top_controls_hide_threshold_(top_controls_hide_threshold) { + browser_controls_show_threshold_(browser_controls_show_threshold), + browser_controls_hide_threshold_(browser_controls_hide_threshold) { active_tree_ = base::MakeUnique<LayerTreeImpl>( - &host_impl_, new SyncedProperty<ScaleGroup>, new SyncedTopControls, + &host_impl_, new SyncedProperty<ScaleGroup>, new SyncedBrowserControls, new SyncedElasticOverscroll); root_scroll_layer_ = LayerImpl::Create(active_tree_.get(), 1); } - ~MockTopControlsManagerClient() override {} + ~MockBrowserControlsOffsetManagerClient() override {} - void DidChangeTopControlsPosition() override { + void DidChangeBrowserControlsPosition() override { redraw_needed_ = true; update_draw_properties_needed_ = true; } @@ -59,7 +58,7 @@ class MockTopControlsManagerClient : public TopControlsManagerClient { float TopControlsHeight() const override { return top_controls_height_; } - void SetCurrentTopControlsShownRatio(float ratio) override { + void SetCurrentBrowserControlsShownRatio(float ratio) override { ASSERT_FALSE(std::isnan(ratio)); ASSERT_FALSE(ratio == std::numeric_limits<float>::infinity()); ASSERT_FALSE(ratio == -std::numeric_limits<float>::infinity()); @@ -68,24 +67,22 @@ class MockTopControlsManagerClient : public TopControlsManagerClient { top_controls_shown_ratio_ = ratio; } - float CurrentTopControlsShownRatio() const override { + float CurrentBrowserControlsShownRatio() const override { return top_controls_shown_ratio_; } - LayerImpl* rootScrollLayer() { - return root_scroll_layer_.get(); - } + LayerImpl* rootScrollLayer() { return root_scroll_layer_.get(); } - TopControlsManager* manager() { + BrowserControlsOffsetManager* manager() { if (!manager_) { - manager_ = TopControlsManager::Create(this, - top_controls_show_threshold_, - top_controls_hide_threshold_); + manager_ = BrowserControlsOffsetManager::Create( + this, browser_controls_show_threshold_, + browser_controls_hide_threshold_); } return manager_.get(); } - void SetTopControlsHeight(float height) { top_controls_height_ = height; } + void SetBrowserControlsHeight(float height) { top_controls_height_ = height; } void SetBottomControlsHeight(float height) { bottom_controls_height_ = height; @@ -93,25 +90,24 @@ class MockTopControlsManagerClient : public TopControlsManagerClient { private: FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; std::unique_ptr<LayerTreeImpl> active_tree_; std::unique_ptr<LayerImpl> root_scroll_layer_; - std::unique_ptr<TopControlsManager> manager_; + std::unique_ptr<BrowserControlsOffsetManager> manager_; bool redraw_needed_; bool update_draw_properties_needed_; float bottom_controls_height_; float top_controls_shown_ratio_; float top_controls_height_; - float top_controls_show_threshold_; - float top_controls_hide_threshold_; + float browser_controls_show_threshold_; + float browser_controls_hide_threshold_; }; -TEST(TopControlsManagerTest, EnsureScrollThresholdApplied) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, EnsureScrollThresholdApplied) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); @@ -153,9 +149,9 @@ TEST(TopControlsManagerTest, EnsureScrollThresholdApplied) { manager->ScrollEnd(); } -TEST(TopControlsManagerTest, PartialShownHideAnimation) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, PartialShownHideAnimation) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); @@ -183,9 +179,9 @@ TEST(TopControlsManagerTest, PartialShownHideAnimation) { EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, PartialShownShowAnimation) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, PartialShownShowAnimation) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); @@ -213,9 +209,10 @@ TEST(TopControlsManagerTest, PartialShownShowAnimation) { EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) { - MockTopControlsManagerClient client(100.f, 0.25f, 0.25f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, + PartialHiddenWithAmbiguousThresholdShows) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.25f, 0.25f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); @@ -239,9 +236,10 @@ TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdShows) { EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) { - MockTopControlsManagerClient client(100.f, 0.25f, 0.25f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, + PartialHiddenWithAmbiguousThresholdHides) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.25f, 0.25f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); @@ -265,9 +263,10 @@ TEST(TopControlsManagerTest, PartialHiddenWithAmbiguousThresholdHides) { EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) { - MockTopControlsManagerClient client(100.f, 0.25f, 0.25f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, + PartialShownWithAmbiguousThresholdHides) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.25f, 0.25f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBy(gfx::Vector2dF(0.f, 200.f)); EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); @@ -295,9 +294,10 @@ TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdHides) { EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) { - MockTopControlsManagerClient client(100.f, 0.25f, 0.25f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, + PartialShownWithAmbiguousThresholdShows) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.25f, 0.25f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBy(gfx::Vector2dF(0.f, 200.f)); EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset()); @@ -325,9 +325,9 @@ TEST(TopControlsManagerTest, PartialShownWithAmbiguousThresholdShows) { EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, PinchIgnoresScroll) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, PinchIgnoresScroll) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); // Hide the controls. manager->ScrollBegin(); @@ -354,9 +354,9 @@ TEST(TopControlsManagerTest, PinchIgnoresScroll) { EXPECT_TRUE(manager->has_animation()); } -TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, PinchBeginStartsAnimationIfNecessary) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); @@ -407,45 +407,48 @@ TEST(TopControlsManagerTest, PinchBeginStartsAnimationIfNecessary) { EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); } -TEST(TopControlsManagerTest, HeightChangeMaintainsFullyVisibleControls) { - MockTopControlsManagerClient client(0.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, + HeightChangeMaintainsFullyVisibleControls) { + MockBrowserControlsOffsetManagerClient client(0.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); - client.SetTopControlsHeight(100.f); + client.SetBrowserControlsHeight(100.f); EXPECT_FALSE(manager->has_animation()); EXPECT_FLOAT_EQ(100.f, manager->TopControlsHeight()); EXPECT_FLOAT_EQ(0, manager->ControlsTopOffset()); - client.SetTopControlsHeight(50.f); + client.SetBrowserControlsHeight(50.f); EXPECT_FALSE(manager->has_animation()); EXPECT_FLOAT_EQ(50.f, manager->TopControlsHeight()); EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); } -TEST(TopControlsManagerTest, GrowingHeightKeepsTopControlsHidden) { - MockTopControlsManagerClient client(0.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); - client.SetTopControlsHeight(1.f); - manager->UpdateTopControlsState(HIDDEN, HIDDEN, false); +TEST(BrowserControlsOffsetManagerTest, + GrowingHeightKeepsBrowserControlsHidden) { + MockBrowserControlsOffsetManagerClient client(0.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); + client.SetBrowserControlsHeight(1.f); + manager->UpdateBrowserControlsState(HIDDEN, HIDDEN, false); EXPECT_EQ(-1.f, manager->ControlsTopOffset()); EXPECT_EQ(0.f, manager->ContentTopOffset()); - client.SetTopControlsHeight(50.f); + client.SetBrowserControlsHeight(50.f); EXPECT_FALSE(manager->has_animation()); EXPECT_EQ(-50.f, manager->ControlsTopOffset()); EXPECT_EQ(0.f, manager->ContentTopOffset()); - client.SetTopControlsHeight(100.f); + client.SetBrowserControlsHeight(100.f); EXPECT_FALSE(manager->has_animation()); EXPECT_EQ(-100.f, manager->ControlsTopOffset()); EXPECT_EQ(0.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, ShrinkingHeightKeepsTopControlsHidden) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); +TEST(BrowserControlsOffsetManagerTest, + ShrinkingHeightKeepsBrowserControlsHidden) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); @@ -453,35 +456,53 @@ TEST(TopControlsManagerTest, ShrinkingHeightKeepsTopControlsHidden) { EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); manager->ScrollEnd(); - client.SetTopControlsHeight(50.f); + client.SetBrowserControlsHeight(50.f); EXPECT_FALSE(manager->has_animation()); EXPECT_FLOAT_EQ(-50.f, manager->ControlsTopOffset()); EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); - client.SetTopControlsHeight(0.f); + client.SetBrowserControlsHeight(0.f); EXPECT_FALSE(manager->has_animation()); EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); } -TEST(TopControlsManagerTest, ScrollByWithZeroHeightControlsIsNoop) { - MockTopControlsManagerClient client(0.f, 0.5f, 0.5f); - TopControlsManager* manager = client.manager(); - manager->UpdateTopControlsState(BOTH, BOTH, false); +TEST(BrowserControlsOffsetManagerTest, ScrollByWithZeroHeightControlsIsNoop) { + MockBrowserControlsOffsetManagerClient client(0.f, 0.5f, 0.5f); + BrowserControlsOffsetManager* manager = client.manager(); + manager->UpdateBrowserControlsState(BOTH, BOTH, false); manager->ScrollBegin(); gfx::Vector2dF pending = manager->ScrollBy(gfx::Vector2dF(0.f, 20.f)); EXPECT_FLOAT_EQ(20.f, pending.y()); EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset()); EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset()); - EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio()); + EXPECT_FLOAT_EQ(1.f, client.CurrentBrowserControlsShownRatio()); + manager->ScrollEnd(); +} + +TEST(BrowserControlsOffsetManagerTest, ScrollThenRestoreBottomControls) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); + client.SetBottomControlsHeight(100.f); + BrowserControlsOffsetManager* manager = client.manager(); + manager->ScrollBegin(); + manager->ScrollBy(gfx::Vector2dF(0.f, 20.f)); + EXPECT_FLOAT_EQ(80.f, manager->ContentBottomOffset()); + EXPECT_FLOAT_EQ(0.8f, manager->BottomControlsShownRatio()); + manager->ScrollEnd(); + + manager->ScrollBegin(); + manager->ScrollBy(gfx::Vector2dF(0.f, -200.f)); + EXPECT_FLOAT_EQ(100.f, manager->ContentBottomOffset()); + EXPECT_FLOAT_EQ(1.f, manager->BottomControlsShownRatio()); manager->ScrollEnd(); } -TEST(TopControlsManagerTest, ScrollThenRestoreBottomControls) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); +TEST(BrowserControlsOffsetManagerTest, + ScrollThenRestoreBottomControlsNoTopControls) { + MockBrowserControlsOffsetManagerClient client(0.f, 0.5f, 0.5f); client.SetBottomControlsHeight(100.f); - TopControlsManager* manager = client.manager(); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 20.f)); EXPECT_FLOAT_EQ(80.f, manager->ContentBottomOffset()); @@ -495,10 +516,10 @@ TEST(TopControlsManagerTest, ScrollThenRestoreBottomControls) { manager->ScrollEnd(); } -TEST(TopControlsManagerTest, HideAndPeekBottomControls) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); +TEST(BrowserControlsOffsetManagerTest, HideAndPeekBottomControls) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); client.SetBottomControlsHeight(100.f); - TopControlsManager* manager = client.manager(); + BrowserControlsOffsetManager* manager = client.manager(); manager->ScrollBegin(); manager->ScrollBy(gfx::Vector2dF(0.f, 300.f)); EXPECT_FLOAT_EQ(0.f, manager->ContentBottomOffset()); @@ -512,19 +533,20 @@ TEST(TopControlsManagerTest, HideAndPeekBottomControls) { manager->ScrollEnd(); } -TEST(TopControlsManagerTest, HideAndImmediateShowKeepsControlsVisible) { - MockTopControlsManagerClient client(100.f, 0.5f, 0.5f); +TEST(BrowserControlsOffsetManagerTest, + HideAndImmediateShowKeepsControlsVisible) { + MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f); client.SetBottomControlsHeight(100.f); - TopControlsManager* manager = client.manager(); - EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio()); + BrowserControlsOffsetManager* manager = client.manager(); + EXPECT_FLOAT_EQ(1.f, client.CurrentBrowserControlsShownRatio()); - manager->UpdateTopControlsState(BOTH, HIDDEN, true); + manager->UpdateBrowserControlsState(BOTH, HIDDEN, true); EXPECT_TRUE(manager->has_animation()); - EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio()); + EXPECT_FLOAT_EQ(1.f, client.CurrentBrowserControlsShownRatio()); - manager->UpdateTopControlsState(BOTH, SHOWN, true); + manager->UpdateBrowserControlsState(BOTH, SHOWN, true); EXPECT_FALSE(manager->has_animation()); - EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio()); + EXPECT_FLOAT_EQ(1.f, client.CurrentBrowserControlsShownRatio()); } } // namespace diff --git a/chromium/cc/input/browser_controls_state.h b/chromium/cc/input/browser_controls_state.h new file mode 100644 index 00000000000..2d9208d883f --- /dev/null +++ b/chromium/cc/input/browser_controls_state.h @@ -0,0 +1,16 @@ +// Copyright (c) 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_INPUT_BROWSER_CONTROLS_STATE_H_ +#define CC_INPUT_BROWSER_CONTROLS_STATE_H_ + +namespace cc { +enum BrowserControlsState { + SHOWN = 1, + HIDDEN = 2, + BOTH = 3 +}; +} + +#endif // CC_INPUT_BROWSER_CONTROLS_STATE_H_ diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h index 4bf52d52809..6abb510b00c 100644 --- a/chromium/cc/input/input_handler.h +++ b/chromium/cc/input/input_handler.h @@ -18,10 +18,8 @@ namespace gfx { class Point; -class PointF; class ScrollOffset; class SizeF; -class Vector2d; class Vector2dF; } @@ -155,6 +153,7 @@ class CC_EXPORT InputHandler { virtual void MouseMoveAt(const gfx::Point& mouse_position) = 0; virtual void MouseDown() = 0; virtual void MouseUp() = 0; + virtual void MouseLeave() = 0; // Stop scrolling the selected layer. Should only be called if ScrollBegin() // returned SCROLL_STARTED. diff --git a/chromium/cc/input/main_thread_scrolling_reason.h b/chromium/cc/input/main_thread_scrolling_reason.h index 06036796d95..8cc83d3eb01 100644 --- a/chromium/cc/input/main_thread_scrolling_reason.h +++ b/chromium/cc/input/main_thread_scrolling_reason.h @@ -15,32 +15,35 @@ namespace cc { // When adding a new MainThreadScrollingReason, make sure the corresponding // [MainThread/Compositor]CanSetScrollReasons function is also updated. struct MainThreadScrollingReason { - // Non-transient scrolling reasons. - enum : uint32_t { kNotScrollingOnMain = 0 }; - enum : uint32_t { kHasBackgroundAttachmentFixedObjects = 1 << 0 }; - enum : uint32_t { kHasNonLayerViewportConstrainedObjects = 1 << 1 }; - enum : uint32_t { kThreadedScrollingDisabled = 1 << 2 }; - enum : uint32_t { kScrollbarScrolling = 1 << 3 }; - enum : uint32_t { kPageOverlay = 1 << 4 }; - // This bit is set when any of the other main thread scrolling reasons cause - // an input event to be handled on the main thread, and the main thread - // blink::ScrollAnimator is in the middle of running a scroll offset - // animation. Note that a scroll handled by the main thread can result in an - // animation running on the main thread or on the compositor thread. - enum : uint32_t { kHandlingScrollFromMainThread = 1 << 13 }; - enum : uint32_t { kCustomScrollbarScrolling = 1 << 15 }; + enum : uint32_t { + // Non-transient scrolling reasons. + kNotScrollingOnMain = 0, + kHasBackgroundAttachmentFixedObjects = 1 << 0, + kHasNonLayerViewportConstrainedObjects = 1 << 1, + kThreadedScrollingDisabled = 1 << 2, + kScrollbarScrolling = 1 << 3, + kPageOverlay = 1 << 4, - // Transient scrolling reasons. These are computed for each scroll begin. - enum : uint32_t { kNonFastScrollableRegion = 1 << 5 }; - enum : uint32_t { kFailedHitTest = 1 << 7 }; - enum : uint32_t { kNoScrollingLayer = 1 << 8 }; - enum : uint32_t { kNotScrollable = 1 << 9 }; - enum : uint32_t { kContinuingMainThreadScroll = 1 << 10 }; - enum : uint32_t { kNonInvertibleTransform = 1 << 11 }; - enum : uint32_t { kPageBasedScrolling = 1 << 12 }; + // This bit is set when any of the other main thread scrolling reasons cause + // an input event to be handled on the main thread, and the main thread + // blink::ScrollAnimator is in the middle of running a scroll offset + // animation. Note that a scroll handled by the main thread can result in an + // animation running on the main thread or on the compositor thread. + kHandlingScrollFromMainThread = 1 << 13, + kCustomScrollbarScrolling = 1 << 15, - // The number of flags in this struct (excluding itself). - enum : uint32_t { kMainThreadScrollingReasonCount = 17 }; + // Transient scrolling reasons. These are computed for each scroll begin. + kNonFastScrollableRegion = 1 << 5, + kFailedHitTest = 1 << 7, + kNoScrollingLayer = 1 << 8, + kNotScrollable = 1 << 9, + kContinuingMainThreadScroll = 1 << 10, + kNonInvertibleTransform = 1 << 11, + kPageBasedScrolling = 1 << 12, + + // The number of flags in this struct (excluding itself). + kMainThreadScrollingReasonCount = 17, + }; // Returns true if the given MainThreadScrollingReason can be set by the main // thread. diff --git a/chromium/cc/input/scroll_state_unittest.cc b/chromium/cc/input/scroll_state_unittest.cc index 1a3a8965ad9..0da54d17ffa 100644 --- a/chromium/cc/input/scroll_state_unittest.cc +++ b/chromium/cc/input/scroll_state_unittest.cc @@ -63,10 +63,8 @@ TEST_F(ScrollStateTest, CurrentNativeScrollingScrollable) { ScrollState scroll_state(scroll_state_data); FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> layer_impl = LayerImpl::Create(host_impl.active_tree(), 1); diff --git a/chromium/cc/input/scrollbar_animation_controller.cc b/chromium/cc/input/scrollbar_animation_controller.cc index 45feb3ae2bf..a8fb1d04d02 100644 --- a/chromium/cc/input/scrollbar_animation_controller.cc +++ b/chromium/cc/input/scrollbar_animation_controller.cc @@ -15,12 +15,10 @@ ScrollbarAnimationController::ScrollbarAnimationController( int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, - base::TimeDelta resize_delay_before_starting, - base::TimeDelta duration) + base::TimeDelta resize_delay_before_starting) : client_(client), delay_before_starting_(delay_before_starting), resize_delay_before_starting_(resize_delay_before_starting), - duration_(duration), is_animating_(false), scroll_layer_id_(scroll_layer_id), currently_scrolling_(false), @@ -44,10 +42,14 @@ bool ScrollbarAnimationController::Animate(base::TimeTicks now) { return true; } +bool ScrollbarAnimationController::ScrollbarsHidden() const { + return false; +} + float ScrollbarAnimationController::AnimationProgressAtTime( base::TimeTicks now) { base::TimeDelta delta = now - last_awaken_time_; - float progress = delta.InSecondsF() / duration_.InSecondsF(); + float progress = delta.InSecondsF() / Duration().InSecondsF(); return std::max(std::min(progress, 1.f), 0.f); } @@ -57,7 +59,6 @@ void ScrollbarAnimationController::DidScrollBegin() { void ScrollbarAnimationController::DidScrollUpdate(bool on_resize) { StopAnimation(); - delayed_scrollbar_fade_.Cancel(); // As an optimization, we avoid spamming fade delay tasks during active fast // scrolls. But if we're not within one, we need to post every scroll update. @@ -94,6 +95,7 @@ void ScrollbarAnimationController::StartAnimation() { } void ScrollbarAnimationController::StopAnimation() { + delayed_scrollbar_fade_.Cancel(); is_animating_ = false; } diff --git a/chromium/cc/input/scrollbar_animation_controller.h b/chromium/cc/input/scrollbar_animation_controller.h index a3b6100bc52..bb3f810a4c2 100644 --- a/chromium/cc/input/scrollbar_animation_controller.h +++ b/chromium/cc/input/scrollbar_animation_controller.h @@ -23,6 +23,7 @@ class CC_EXPORT ScrollbarAnimationControllerClient { base::TimeDelta delay) = 0; virtual void SetNeedsRedrawForScrollbarAnimation() = 0; virtual void SetNeedsAnimateForScrollbarAnimation() = 0; + virtual void DidChangeScrollbarVisibility() = 0; virtual ScrollbarSet ScrollbarsFor(int scroll_layer_id) const = 0; protected: @@ -41,19 +42,20 @@ class CC_EXPORT ScrollbarAnimationController { virtual void DidScrollBegin(); virtual void DidScrollUpdate(bool on_resize); virtual void DidScrollEnd(); - virtual void DidCaptureScrollbarBegin() {} - virtual void DidCaptureScrollbarEnd() {} - virtual void DidMouseMoveOffScrollbar() {} + virtual void DidMouseDown() {} + virtual void DidMouseUp() {} + virtual void DidMouseLeave() {} virtual void DidMouseMoveNear(float distance) {} + virtual bool ScrollbarsHidden() const; protected: ScrollbarAnimationController(int scroll_layer_id, ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, - base::TimeDelta resize_delay_before_starting, - base::TimeDelta duration); + base::TimeDelta resize_delay_before_starting); virtual void RunAnimationFrame(float progress) = 0; + virtual const base::TimeDelta& Duration() = 0; void StartAnimation(); void StopAnimation(); @@ -61,17 +63,18 @@ class CC_EXPORT ScrollbarAnimationController { ScrollbarAnimationControllerClient* client_; + void PostDelayedAnimationTask(bool on_resize); + + int scroll_layer_id() const { return scroll_layer_id_; } + private: // Returns how far through the animation we are as a progress value from // 0 to 1. float AnimationProgressAtTime(base::TimeTicks now); - void PostDelayedAnimationTask(bool on_resize); - base::TimeTicks last_awaken_time_; base::TimeDelta delay_before_starting_; base::TimeDelta resize_delay_before_starting_; - base::TimeDelta duration_; bool is_animating_; diff --git a/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc b/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc index 8695bfaf6cf..ee7f4afe648 100644 --- a/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc +++ b/chromium/cc/input/scrollbar_animation_controller_linear_fade.cc @@ -33,8 +33,8 @@ ScrollbarAnimationControllerLinearFade::ScrollbarAnimationControllerLinearFade( : ScrollbarAnimationController(scroll_layer_id, client, delay_before_starting, - resize_delay_before_starting, - duration) {} + resize_delay_before_starting), + duration_(duration) {} ScrollbarAnimationControllerLinearFade:: ~ScrollbarAnimationControllerLinearFade() {} @@ -46,6 +46,10 @@ void ScrollbarAnimationControllerLinearFade::RunAnimationFrame(float progress) { StopAnimation(); } +const base::TimeDelta& ScrollbarAnimationControllerLinearFade::Duration() { + return duration_; +} + void ScrollbarAnimationControllerLinearFade::DidScrollUpdate(bool on_resize) { ScrollbarAnimationController::DidScrollUpdate(on_resize); ApplyOpacityToScrollbars(1.f); diff --git a/chromium/cc/input/scrollbar_animation_controller_linear_fade.h b/chromium/cc/input/scrollbar_animation_controller_linear_fade.h index f5993e7149a..d3acc8255ec 100644 --- a/chromium/cc/input/scrollbar_animation_controller_linear_fade.h +++ b/chromium/cc/input/scrollbar_animation_controller_linear_fade.h @@ -12,7 +12,6 @@ #include "cc/input/scrollbar_animation_controller.h" namespace cc { -class LayerImpl; class CC_EXPORT ScrollbarAnimationControllerLinearFade : public ScrollbarAnimationController { @@ -37,11 +36,14 @@ class CC_EXPORT ScrollbarAnimationControllerLinearFade base::TimeDelta duration); void RunAnimationFrame(float progress) override; + const base::TimeDelta& Duration() override; private: float OpacityAtTime(base::TimeTicks now) const; void ApplyOpacityToScrollbars(float opacity); + base::TimeDelta duration_; + DISALLOW_COPY_AND_ASSIGN(ScrollbarAnimationControllerLinearFade); }; diff --git a/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc index d4c4df22ac1..cc79c3761e9 100644 --- a/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc +++ b/chromium/cc/input/scrollbar_animation_controller_linear_fade_unittest.cc @@ -8,7 +8,6 @@ #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_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -22,7 +21,6 @@ class ScrollbarAnimationControllerLinearFadeTest public: ScrollbarAnimationControllerLinearFadeTest() : host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_), did_request_redraw_(false), did_request_animate_(false) {} @@ -41,6 +39,7 @@ class ScrollbarAnimationControllerLinearFadeTest ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override { return host_impl_.ScrollbarsFor(scroll_layer_id); } + void DidChangeScrollbarVisibility() override {} protected: void SetUp() override { @@ -79,7 +78,6 @@ class ScrollbarAnimationControllerLinearFadeTest virtual ScrollbarOrientation orientation() const { return HORIZONTAL; } FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; std::unique_ptr<ScrollbarAnimationControllerLinearFade> scrollbar_controller_; diff --git a/chromium/cc/input/scrollbar_animation_controller_thinning.cc b/chromium/cc/input/scrollbar_animation_controller_thinning.cc index 4324a4347bf..2006d98fddb 100644 --- a/chromium/cc/input/scrollbar_animation_controller_thinning.cc +++ b/chromium/cc/input/scrollbar_animation_controller_thinning.cc @@ -12,7 +12,6 @@ namespace { const float kIdleThicknessScale = 0.4f; -const float kIdleOpacity = 0.7f; const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f; } @@ -24,10 +23,11 @@ ScrollbarAnimationControllerThinning::Create( ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, - base::TimeDelta duration) { + base::TimeDelta fade_duration, + base::TimeDelta thinning_duration) { return base::WrapUnique(new ScrollbarAnimationControllerThinning( scroll_layer_id, client, delay_before_starting, - resize_delay_before_starting, duration)); + resize_delay_before_starting, fade_duration, thinning_duration)); } ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning( @@ -35,116 +35,141 @@ ScrollbarAnimationControllerThinning::ScrollbarAnimationControllerThinning( ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, - base::TimeDelta duration) + base::TimeDelta fade_duration, + base::TimeDelta thinning_duration) : ScrollbarAnimationController(scroll_layer_id, client, delay_before_starting, - resize_delay_before_starting, - duration), + resize_delay_before_starting), + opacity_(0.0f), captured_(false), mouse_is_over_scrollbar_(false), mouse_is_near_scrollbar_(false), thickness_change_(NONE), - opacity_change_(NONE), mouse_move_distance_to_trigger_animation_( - kDefaultMouseMoveDistanceToTriggerAnimation) { - ApplyOpacityAndThumbThicknessScale(kIdleOpacity, kIdleThicknessScale); + kDefaultMouseMoveDistanceToTriggerAnimation), + fade_duration_(fade_duration), + thinning_duration_(thinning_duration), + current_animating_property_(OPACITY) { + ApplyOpacity(0.f); + ApplyThumbThicknessScale(kIdleThicknessScale); } ScrollbarAnimationControllerThinning::~ScrollbarAnimationControllerThinning() {} void ScrollbarAnimationControllerThinning::RunAnimationFrame(float progress) { - float opacity = OpacityAtAnimationProgress(progress); - float thumb_thickness_scale = - ThumbThicknessScaleAtAnimationProgress(progress); - ApplyOpacityAndThumbThicknessScale(opacity, thumb_thickness_scale); + if (captured_) + return; + + if (current_animating_property_ == OPACITY) + ApplyOpacity(1.f - progress); + else + ApplyThumbThicknessScale(ThumbThicknessScaleAt(progress)); + client_->SetNeedsRedrawForScrollbarAnimation(); if (progress == 1.f) { - opacity_change_ = NONE; - thickness_change_ = NONE; StopAnimation(); + if (current_animating_property_ == THICKNESS) { + thickness_change_ = NONE; + SetCurrentAnimatingProperty(OPACITY); + PostDelayedAnimationTask(false); + } } } -void ScrollbarAnimationControllerThinning::DidCaptureScrollbarBegin() { +const base::TimeDelta& ScrollbarAnimationControllerThinning::Duration() { + if (current_animating_property_ == OPACITY) + return fade_duration_; + else + return thinning_duration_; +} + +void ScrollbarAnimationControllerThinning::DidMouseDown() { + if (!mouse_is_over_scrollbar_ || opacity_ == 0.0f) + return; + + StopAnimation(); captured_ = true; - ApplyOpacityAndThumbThicknessScale(1, 1.f); + ApplyOpacity(1.f); + ApplyThumbThicknessScale(1.f); } -void ScrollbarAnimationControllerThinning::DidCaptureScrollbarEnd() { +void ScrollbarAnimationControllerThinning::DidMouseUp() { + if (!captured_ || opacity_ == 0.0f) + return; + captured_ = false; + StopAnimation(); - if (!mouse_is_over_scrollbar_) - opacity_change_ = DECREASE; - if (!mouse_is_near_scrollbar_) + if (!mouse_is_near_scrollbar_) { + SetCurrentAnimatingProperty(THICKNESS); thickness_change_ = DECREASE; - StartAnimation(); + StartAnimation(); + } else { + SetCurrentAnimatingProperty(OPACITY); + PostDelayedAnimationTask(false); + } } -void ScrollbarAnimationControllerThinning::DidMouseMoveOffScrollbar() { +void ScrollbarAnimationControllerThinning::DidMouseLeave() { + if (!mouse_is_over_scrollbar_ && !mouse_is_near_scrollbar_) + return; + mouse_is_over_scrollbar_ = false; mouse_is_near_scrollbar_ = false; - if (captured_) + if (captured_ || opacity_ == 0.0f) return; - opacity_change_ = DECREASE; thickness_change_ = DECREASE; + SetCurrentAnimatingProperty(THICKNESS); StartAnimation(); } void ScrollbarAnimationControllerThinning::DidScrollUpdate(bool on_resize) { - if (captured_) { + if (captured_) return; - } ScrollbarAnimationController::DidScrollUpdate(on_resize); - ApplyOpacityAndThumbThicknessScale( - 1, mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale); - - if (!mouse_is_over_scrollbar_) - opacity_change_ = DECREASE; + ApplyOpacity(1.f); + ApplyThumbThicknessScale(mouse_is_near_scrollbar_ ? 1.f + : kIdleThicknessScale); + SetCurrentAnimatingProperty(OPACITY); } void ScrollbarAnimationControllerThinning::DidMouseMoveNear(float distance) { - bool mouse_is_over_scrollbar = distance == 0.0; + bool mouse_is_over_scrollbar = distance == 0.0f; bool mouse_is_near_scrollbar = distance < mouse_move_distance_to_trigger_animation_; - if (captured_) { + if (captured_ || opacity_ == 0.0f) { mouse_is_near_scrollbar_ = mouse_is_near_scrollbar; mouse_is_over_scrollbar_ = mouse_is_over_scrollbar; return; - } else { - if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ && - mouse_is_near_scrollbar == mouse_is_near_scrollbar_) - return; + } - if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar) { - mouse_is_over_scrollbar_ = mouse_is_over_scrollbar; - opacity_change_ = mouse_is_over_scrollbar_ ? INCREASE : DECREASE; - } + if (mouse_is_over_scrollbar == mouse_is_over_scrollbar_ && + mouse_is_near_scrollbar == mouse_is_near_scrollbar_) + return; - if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) { - mouse_is_near_scrollbar_ = mouse_is_near_scrollbar; - thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE; - } + if (mouse_is_over_scrollbar_ != mouse_is_over_scrollbar) + mouse_is_over_scrollbar_ = mouse_is_over_scrollbar; - StartAnimation(); + if (mouse_is_near_scrollbar_ != mouse_is_near_scrollbar) { + mouse_is_near_scrollbar_ = mouse_is_near_scrollbar; + thickness_change_ = mouse_is_near_scrollbar_ ? INCREASE : DECREASE; } + + SetCurrentAnimatingProperty(THICKNESS); + StartAnimation(); } -float ScrollbarAnimationControllerThinning::OpacityAtAnimationProgress( - float progress) { - if (opacity_change_ == NONE) - return mouse_is_over_scrollbar_ ? 1.f : kIdleOpacity; - float factor = opacity_change_ == INCREASE ? progress : (1.f - progress); - float ret = ((1.f - kIdleOpacity) * factor) + kIdleOpacity; - return ret; +bool ScrollbarAnimationControllerThinning::ScrollbarsHidden() const { + return opacity_ == 0.0f; } -float ScrollbarAnimationControllerThinning:: - ThumbThicknessScaleAtAnimationProgress(float progress) { +float ScrollbarAnimationControllerThinning::ThumbThicknessScaleAt( + float progress) { if (thickness_change_ == NONE) return mouse_is_near_scrollbar_ ? 1.f : kIdleThicknessScale; float factor = thickness_change_ == INCREASE ? progress : (1.f - progress); @@ -171,17 +196,11 @@ float ScrollbarAnimationControllerThinning::AdjustScale( return result; } -void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale( - float opacity, - float thumb_thickness_scale) { +void ScrollbarAnimationControllerThinning::ApplyOpacity(float opacity) { for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) { if (!scrollbar->is_overlay_scrollbar()) continue; - float effective_opacity = - scrollbar->CanScrollOrientation() - ? AdjustScale(opacity, scrollbar->Opacity(), opacity_change_, - kIdleOpacity, 1) - : 0; + float effective_opacity = scrollbar->CanScrollOrientation() ? opacity : 0; PropertyTrees* property_trees = scrollbar->layer_tree_impl()->property_trees(); // If this method is called during LayerImpl::PushPropertiesTo, we may not @@ -196,10 +215,38 @@ void ScrollbarAnimationControllerThinning::ApplyOpacityAndThumbThicknessScale( property_trees->effect_id_to_index_map[scrollbar->id()], scrollbar->layer_tree_impl()); } + } + + bool previouslyVisible = opacity_ > 0.0f; + bool currentlyVisible = opacity > 0.0f; + + opacity_ = opacity; + + if (previouslyVisible != currentlyVisible) + client_->DidChangeScrollbarVisibility(); +} + +void ScrollbarAnimationControllerThinning::ApplyThumbThicknessScale( + float thumb_thickness_scale) { + for (ScrollbarLayerImplBase* scrollbar : Scrollbars()) { + if (!scrollbar->is_overlay_scrollbar()) + continue; + scrollbar->SetThumbThicknessScaleFactor(AdjustScale( thumb_thickness_scale, scrollbar->thumb_thickness_scale_factor(), thickness_change_, kIdleThicknessScale, 1)); } } +void ScrollbarAnimationControllerThinning::SetCurrentAnimatingProperty( + AnimatingProperty property) { + if (current_animating_property_ == property) + return; + + StopAnimation(); + current_animating_property_ = property; + if (current_animating_property_ == THICKNESS) + ApplyOpacity(1.f); +} + } // namespace cc diff --git a/chromium/cc/input/scrollbar_animation_controller_thinning.h b/chromium/cc/input/scrollbar_animation_controller_thinning.h index d1d4ee0bac8..0b393088b89 100644 --- a/chromium/cc/input/scrollbar_animation_controller_thinning.h +++ b/chromium/cc/input/scrollbar_animation_controller_thinning.h @@ -12,7 +12,6 @@ #include "cc/input/scrollbar_animation_controller.h" namespace cc { -class LayerImpl; // Scrollbar animation that partially fades and thins after an idle delay, // and reacts to mouse movements. @@ -24,7 +23,8 @@ class CC_EXPORT ScrollbarAnimationControllerThinning ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, - base::TimeDelta duration); + base::TimeDelta fade_duration, + base::TimeDelta thinning_duration); ~ScrollbarAnimationControllerThinning() override; @@ -36,10 +36,11 @@ class CC_EXPORT ScrollbarAnimationControllerThinning void DidScrollUpdate(bool on_resize) override; - void DidCaptureScrollbarBegin() override; - void DidCaptureScrollbarEnd() override; - void DidMouseMoveOffScrollbar() override; + void DidMouseDown() override; + void DidMouseUp() override; + void DidMouseLeave() override; void DidMouseMoveNear(float distance) override; + bool ScrollbarsHidden() const override; protected: ScrollbarAnimationControllerThinning( @@ -47,34 +48,42 @@ class CC_EXPORT ScrollbarAnimationControllerThinning ScrollbarAnimationControllerClient* client, base::TimeDelta delay_before_starting, base::TimeDelta resize_delay_before_starting, - base::TimeDelta duration); + base::TimeDelta fade_duration, + base::TimeDelta thinning_duration); void RunAnimationFrame(float progress) override; + const base::TimeDelta& Duration() override; private: - // Describes whether the current animation should INCREASE (darken / thicken) - // a bar or DECREASE it (lighten / thin). + // Describes whether the current animation should INCREASE (thicken) + // a bar or DECREASE it (thin). enum AnimationChange { NONE, INCREASE, DECREASE }; - float OpacityAtAnimationProgress(float progress); - float ThumbThicknessScaleAtAnimationProgress(float progress); + enum AnimatingProperty { OPACITY, THICKNESS }; + float ThumbThicknessScaleAt(float progress); float AdjustScale(float new_value, float current_value, AnimationChange animation_change, float min_value, float max_value); - void ApplyOpacityAndThumbThicknessScale(float opacity, - float thumb_thickness_scale); + void ApplyOpacity(float opacity); + void ApplyThumbThicknessScale(float thumb_thickness_scale); + void SetCurrentAnimatingProperty(AnimatingProperty property); + + float opacity_; bool captured_; bool mouse_is_over_scrollbar_; bool mouse_is_near_scrollbar_; // Are we narrowing or thickening the bars. AnimationChange thickness_change_; - // Are we darkening or lightening the bars. - AnimationChange opacity_change_; // How close should the mouse be to the scrollbar before we thicken it. float mouse_move_distance_to_trigger_animation_; + base::TimeDelta fade_duration_; + base::TimeDelta thinning_duration_; + + AnimatingProperty current_animating_property_; + DISALLOW_COPY_AND_ASSIGN(ScrollbarAnimationControllerThinning); }; diff --git a/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc b/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc index 4824879f67a..243602ba6ad 100644 --- a/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc +++ b/chromium/cc/input/scrollbar_animation_controller_thinning_unittest.cc @@ -8,42 +8,64 @@ #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_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" +#include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +using testing::AtLeast; +using testing::Mock; +using testing::NiceMock; +using testing::_; + namespace cc { namespace { -class ScrollbarAnimationControllerThinningTest - : public testing::Test, - public ScrollbarAnimationControllerClient { +// These constants are hard-coded and should match the values in +// scrollbar_animation_controller_thinning.cc. +const float kIdleThicknessScale = 0.4f; +const float kDefaultMouseMoveDistanceToTriggerAnimation = 25.f; + +class MockScrollbarAnimationControllerClient + : public ScrollbarAnimationControllerClient { public: - ScrollbarAnimationControllerThinningTest() - : host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_) {} + explicit MockScrollbarAnimationControllerClient(LayerTreeHostImpl* host_impl) + : host_impl_(host_impl) {} + virtual ~MockScrollbarAnimationControllerClient() {} void PostDelayedScrollbarAnimationTask(const base::Closure& start_fade, base::TimeDelta delay) override { start_fade_ = start_fade; delay_ = delay; } - void SetNeedsRedrawForScrollbarAnimation() override { - did_request_redraw_ = true; - } - void SetNeedsAnimateForScrollbarAnimation() override { - did_request_animate_ = true; - } + void SetNeedsRedrawForScrollbarAnimation() override {} + void SetNeedsAnimateForScrollbarAnimation() override {} ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override { - return host_impl_.ScrollbarsFor(scroll_layer_id); + return host_impl_->ScrollbarsFor(scroll_layer_id); } + MOCK_METHOD0(DidChangeScrollbarVisibility, void()); + + base::Closure& start_fade() { return start_fade_; } + base::TimeDelta& delay() { return delay_; } + + private: + base::Closure start_fade_; + base::TimeDelta delay_; + LayerTreeHostImpl* host_impl_; +}; + +class ScrollbarAnimationControllerThinningTest : public testing::Test { + public: + ScrollbarAnimationControllerThinningTest() + : host_impl_(&task_runner_provider_, &task_graph_runner_), + client_(&host_impl_) {} protected: - const int kDelayBeforeStarting = 2; - const int kResizeDelayBeforeStarting = 5; - const int kDuration = 3; + const base::TimeDelta kDelayBeforeStarting = base::TimeDelta::FromSeconds(2); + const base::TimeDelta kResizeDelayBeforeStarting = + base::TimeDelta::FromSeconds(5); + const base::TimeDelta kFadeDuration = base::TimeDelta::FromSeconds(3); + const base::TimeDelta kThinningDuration = base::TimeDelta::FromSeconds(2); void SetUp() override { std::unique_ptr<LayerImpl> scroll_layer = @@ -77,44 +99,41 @@ class ScrollbarAnimationControllerThinningTest host_impl_.active_tree()->BuildLayerListAndPropertyTreesForTesting(); scrollbar_controller_ = ScrollbarAnimationControllerThinning::Create( - scroll_layer_ptr->id(), this, - base::TimeDelta::FromSeconds(kDelayBeforeStarting), - base::TimeDelta::FromSeconds(kResizeDelayBeforeStarting), - base::TimeDelta::FromSeconds(kDuration)); + scroll_layer_ptr->id(), &client_, kDelayBeforeStarting, + kResizeDelayBeforeStarting, kFadeDuration, kThinningDuration); } FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; std::unique_ptr<ScrollbarAnimationControllerThinning> scrollbar_controller_; LayerImpl* clip_layer_; SolidColorScrollbarLayerImpl* scrollbar_layer_; - - base::Closure start_fade_; - base::TimeDelta delay_; - bool did_request_redraw_; - bool did_request_animate_; + NiceMock<MockScrollbarAnimationControllerClient> client_; }; -// Check initialization of scrollbar. +// Check initialization of scrollbar. Should start off invisible and thin. TEST_F(ScrollbarAnimationControllerThinningTest, Idle) { - scrollbar_controller_->Animate(base::TimeTicks()); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); } -// Check that scrollbar appears again, when the layer becomes scrollable. +// Check that scrollbar appears again when the layer becomes scrollable. TEST_F(ScrollbarAnimationControllerThinningTest, AppearOnResize) { + scrollbar_controller_->DidScrollBegin(); scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + // Make the Layer non-scrollable, scrollbar disappears. clip_layer_->SetBounds(gfx::Size(200, 200)); scrollbar_controller_->DidScrollUpdate(false); EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); + // Make the layer scrollable, scrollbar appears again. clip_layer_->SetBounds(gfx::Size(100, 100)); scrollbar_controller_->DidScrollUpdate(false); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); } // Check that scrollbar disappears when the layer becomes non-scrollable. @@ -149,373 +168,825 @@ TEST_F(ScrollbarAnimationControllerThinningTest, HideOnResize) { scrollbar_controller_->DidScrollEnd(); } -// Scroll content. Confirm the scrollbar gets dark and then becomes light -// after stopping. -TEST_F(ScrollbarAnimationControllerThinningTest, AwakenByProgrammaticScroll) { +// Scroll content. Confirm the scrollbar appears and fades out. +TEST_F(ScrollbarAnimationControllerThinningTest, BasicAppearAndFadeOut) { base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + // Scrollbar should be invisible by default. + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); + + // Scrollbar should appear only on scroll update. + scrollbar_controller_->DidScrollBegin(); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); + scrollbar_controller_->DidScrollUpdate(false); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - // Scrollbar doesn't change size if triggered by scroll. - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); - start_fade_.Run(); + scrollbar_controller_->DidScrollEnd(); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + + // An animation should have been enqueued. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + client_.start_fade().Run(); - time += base::TimeDelta::FromSeconds(1); + // Scrollbar should fade out over kFadeDuration. + scrollbar_controller_->Animate(time); + time += kFadeDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); - // Subsequent scroll restarts animation. + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); +} + +// Scroll content. Move the mouse near the scrollbar and confirm it becomes +// thick. Ensure it fades out after that. +TEST_F(ScrollbarAnimationControllerThinningTest, MoveNearAndFadeOut) { + base::TimeTicks time; + time += base::TimeDelta::FromSeconds(1); + + scrollbar_controller_->DidScrollBegin(); scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); - start_fade_.Run(); + // An animation should have been enqueued. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); - time += base::TimeDelta::FromSeconds(2); - scrollbar_controller_->Animate(time); + // Now move the mouse near the scrollbar. This should cancel the currently + // queued fading animation and start animating thickness. + scrollbar_controller_->DidMouseMoveNear(1); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_TRUE(client_.start_fade().IsCancelled()); - time += base::TimeDelta::FromSeconds(1); + // Scrollbar should become thick. scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); - - time += base::TimeDelta::FromSeconds(1); + time += kThinningDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + // Once the thickening animation is complete, it should enqueue the delayed + // fade animation. + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_FALSE(client_.start_fade().IsCancelled()); } -// Initiate a scroll when the pointer is already near the scrollbar. It should -// remain thick. -TEST_F(ScrollbarAnimationControllerThinningTest, ScrollWithMouseNear) { +// Scroll content. Move the mouse over the scrollbar and confirm it becomes +// thick. Ensure it fades out after that. +TEST_F(ScrollbarAnimationControllerThinningTest, MoveOverAndFadeOut) { base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->DidMouseMoveNear(1); - scrollbar_controller_->Animate(time); - time += base::TimeDelta::FromSeconds(3); + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + // An animation should have been enqueued. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + + // Now move the mouse over the scrollbar. This should cancel the currently + // queued fading animation and start animating thickness. + scrollbar_controller_->DidMouseMoveNear(0); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_TRUE(client_.start_fade().IsCancelled()); + // Scrollbar should become thick. + scrollbar_controller_->Animate(time); + time += kThinningDuration; scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + // Once the thickening animation is complete, it should enqueue the delayed + // fade animation. + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_FALSE(client_.start_fade().IsCancelled()); +} + +// Make sure a scrollbar captured before the thickening animation doesn't try +// to fade out. +TEST_F(ScrollbarAnimationControllerThinningTest, + DontFadeWhileCapturedBeforeThick) { + base::TimeTicks time; + time += base::TimeDelta::FromSeconds(1); + + scrollbar_controller_->DidScrollBegin(); scrollbar_controller_->DidScrollUpdate(false); - start_fade_.Run(); - scrollbar_controller_->Animate(time); + scrollbar_controller_->DidScrollEnd(); + + // An animation should have been enqueued. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + + // Now move the mouse over the scrollbar and capture it. It should become + // thick without need for an animation. + scrollbar_controller_->DidMouseMoveNear(0); + scrollbar_controller_->DidMouseDown(); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - // Scrollbar should still be thick. EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(5); - scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + // The fade animation should have been cancelled. + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_TRUE(client_.start_fade().IsCancelled()); } -// Move the pointer near the scrollbar. Confirm it gets thick and narrow when -// moved away. -TEST_F(ScrollbarAnimationControllerThinningTest, MouseNear) { +// Make sure a scrollbar captured after a thickening animation doesn't try to +// fade out. +TEST_F(ScrollbarAnimationControllerThinningTest, DontFadeWhileCaptured) { base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->DidMouseMoveNear(1); + + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + // An animation should have been enqueued. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + + // Now move the mouse over the scrollbar and animate it until it's thick. + scrollbar_controller_->DidMouseMoveNear(0); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // Should animate to thickened but not darken. + // Since the scrollbar became thick, it should have queued up a fade. + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_FALSE(client_.start_fade().IsCancelled()); + + // Make sure capturing the scrollbar stops the fade. + scrollbar_controller_->DidMouseDown(); + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_TRUE(client_.start_fade().IsCancelled()); +} + +// Make sure releasing a captured scrollbar causes it to fade out. +TEST_F(ScrollbarAnimationControllerThinningTest, FadeAfterReleased) { + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + // An animation should have been enqueued. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + + // Now move the mouse over the scrollbar and capture it. + scrollbar_controller_->DidMouseMoveNear(0); + scrollbar_controller_->DidMouseDown(); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + + // Since the scrollbar became thick, it should have queued up a fade. + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_TRUE(client_.start_fade().IsCancelled()); + + scrollbar_controller_->DidMouseUp(); + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_FALSE(client_.start_fade().IsCancelled()); +} + +// Make sure moving near a scrollbar while it's fading out causes it to reset +// the opacity and thicken. +TEST_F(ScrollbarAnimationControllerThinningTest, MoveNearScrollbarWhileFading) { + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + // An animation should have been enqueued. Start it. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + client_.start_fade().Run(); + scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - time += base::TimeDelta::FromSeconds(1); + // Proceed half way through the fade out animation. + time += kFadeDuration / 2; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(0.5f, scrollbar_layer_->Opacity()); - // Subsequent moves should not change anything. + // Now move the mouse near the scrollbar. It should reset opacity to 1 + // instantly and start animating to thick. scrollbar_controller_->DidMouseMoveNear(1); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); + + scrollbar_controller_->Animate(time); + time += kThinningDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); +} - // Now move away from bar. +// Make sure capturing a scrollbar while it's fading out causes it to reset the +// opacity and thicken instantly. +TEST_F(ScrollbarAnimationControllerThinningTest, CaptureScrollbarWhileFading) { + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->DidMouseMoveNear(26); + + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + // Move mouse over the scrollbar. + scrollbar_controller_->DidMouseMoveNear(0); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // Animate to narrow. - time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + // A fade animation should have been enqueued. Start it. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + client_.start_fade().Run(); - time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - time += base::TimeDelta::FromSeconds(1); + // Proceed half way through the fade out animation. + time += kFadeDuration / 2; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(0.5f, scrollbar_layer_->Opacity()); + + // Now capture the scrollbar. It should reset opacity to 1 instantly. + scrollbar_controller_->DidMouseDown(); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); } -// Move the pointer over the scrollbar. Make sure it gets thick and dark -// and that it gets thin and light when moved away. -TEST_F(ScrollbarAnimationControllerThinningTest, MouseOver) { +// Make sure we can't capture scrollbar that's completely faded out +TEST_F(ScrollbarAnimationControllerThinningTest, TestCantCaptureWhenFaded) { base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + // Move mouse over the scrollbar. scrollbar_controller_->DidMouseMoveNear(0); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // Should animate to thickened and darkened. - time += base::TimeDelta::FromSeconds(1); + // A fade animation should have been enqueued. Start it. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + client_.start_fade().Run(); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - time += base::TimeDelta::FromSeconds(1); + // Fade the scrollbar out completely. + time += kFadeDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + + client_.start_fade().Reset(); + + // Now try to capture the scrollbar. It shouldn't do anything since it's + // completely faded out. + scrollbar_controller_->DidMouseDown(); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_TRUE(client_.start_fade().is_null()); + // Similarly, releasing the scrollbar should have no effect. + scrollbar_controller_->DidMouseUp(); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_TRUE(client_.start_fade().is_null()); +} + +// Initiate a scroll when the pointer is already near the scrollbar. It should +// appear thick and remain thick. +TEST_F(ScrollbarAnimationControllerThinningTest, ScrollWithMouseNear) { + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + scrollbar_controller_->DidMouseMoveNear(1); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + time += kThinningDuration; + + // Since the scrollbar isn't visible yet (because we haven't scrolled), we + // shouldn't have applied the thickening. + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); + + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + + // Now that we've received a scroll, we should be thick without an animation. EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // Subsequent moves should not change anything. - scrollbar_controller_->DidMouseMoveNear(0); + // An animation for the fade should have been enqueued. + scrollbar_controller_->DidScrollEnd(); + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + + client_.start_fade().Run(); scrollbar_controller_->Animate(time); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // Now move away from bar. - time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->DidMouseMoveNear(26); + // Scrollbar should still be thick, even though the scrollbar fades out. + time += kFadeDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); +} - // Animate to narrow. +// Move the pointer near the scrollbar. Confirm it gets thick and narrow when +// moved away. +TEST_F(ScrollbarAnimationControllerThinningTest, MouseNear) { + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + scrollbar_controller_->DidMouseMoveNear(1); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); + // Should animate to thickened. + time += kThinningDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); + // Subsequent moves within the nearness threshold should not change anything. + scrollbar_controller_->DidMouseMoveNear(2); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + time += base::TimeDelta::FromSeconds(10); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + + // Now move away from bar. + scrollbar_controller_->DidMouseMoveNear( + kDefaultMouseMoveDistanceToTriggerAnimation); + scrollbar_controller_->Animate(time); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); } -// First move the pointer near the scrollbar, then over it, then back near -// then far away. Confirm that first the bar gets thick, then dark, then light, -// then narrow. -TEST_F(ScrollbarAnimationControllerThinningTest, MouseNearThenOver) { +// Move the pointer over the scrollbar. Make sure it gets thick that it gets +// thin when moved away. +TEST_F(ScrollbarAnimationControllerThinningTest, MouseOver) { + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->DidMouseMoveNear(1); + + scrollbar_controller_->DidMouseMoveNear(0); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); - // Should animate to thickened but not darken. - time += base::TimeDelta::FromSeconds(3); + // Should animate to thickened. + time += kThinningDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // Now move over. + // Subsequent moves should not change anything. scrollbar_controller_->DidMouseMoveNear(0); scrollbar_controller_->Animate(time); - - // Should animate to darkened. - time += base::TimeDelta::FromSeconds(1); + time += base::TimeDelta::FromSeconds(10); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); + // Moving off the scrollbar but still withing the "near" threshold should do + // nothing. + scrollbar_controller_->DidMouseMoveNear( + kDefaultMouseMoveDistanceToTriggerAnimation - 1.f); + scrollbar_controller_->Animate(time); + time += base::TimeDelta::FromSeconds(10); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + // Now move away from bar. + scrollbar_controller_->DidMouseMoveNear( + kDefaultMouseMoveDistanceToTriggerAnimation); + scrollbar_controller_->Animate(time); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); +} + +// First move the pointer over the scrollbar off of it. Make sure the thinning +// animation kicked off in DidMouseMoveOffScrollbar gets overridden by the +// thickening animation in the DidMouseMoveNear call. +TEST_F(ScrollbarAnimationControllerThinningTest, + MouseNearThenAwayWhileAnimating) { + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + scrollbar_controller_->DidMouseMoveNear(0); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); + + // Should animate to thickened. + time += kThinningDuration; scrollbar_controller_->Animate(time); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // This is tricky. The DidMouseMoveOffScrollbar() is sent before the + // This is tricky. The DidMouseLeave() is sent before the // subsequent DidMouseMoveNear(), if the mouse moves in that direction. // This results in the thumb thinning. We want to make sure that when the // thumb starts expanding it doesn't first narrow to the idle thinness. time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->DidMouseMoveOffScrollbar(); + scrollbar_controller_->DidMouseLeave(); scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); + // Let the animation run half of the way through the thinning animation. + time += kThinningDuration / 2; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f, + scrollbar_layer_->thumb_thickness_scale_factor()); + // Now we get a notification for the mouse moving over the scroller. The + // animation is reset to the thickening direction but we won't start + // thickening until the new animation catches up to the current thickness. scrollbar_controller_->DidMouseMoveNear(1); scrollbar_controller_->Animate(time); - // A new animation is kicked off. + EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f, + scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); + // Until we reach the half way point, the animation will have no effect. + time += kThinningDuration / 4; scrollbar_controller_->Animate(time); - // We will initiate the narrowing again, but it won't get decremented until - // the new animation catches up to it. - EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->Opacity()); - // Now the thickness should be increasing, but it shouldn't happen until the - // animation catches up. - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f, + scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); + time += kThinningDuration / 4; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->Opacity()); - // The thickness now gets big again. - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f, + scrollbar_layer_->thumb_thickness_scale_factor()); - time += base::TimeDelta::FromSeconds(1); + // We're now at three quarters of the way through so it should now started + // thickening again. + time += kThinningDuration / 4; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(kIdleThicknessScale + 3 * (1.0f - kIdleThicknessScale) / 4.0f, + scrollbar_layer_->thumb_thickness_scale_factor()); + + // And all the way to the end. + time += kThinningDuration / 4; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - // The thickness now gets big again. EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); } // First move the pointer on the scrollbar, then press it, then away. -// Confirm that the bar gets thick and dark. Then mouse up. Confirm that -// the bar gets thin and light. +// Confirm that the bar gets thick. Then mouse up. Confirm that +// the bar gets thin. TEST_F(ScrollbarAnimationControllerThinningTest, MouseCaptureAndReleaseOutOfBar) { + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - // Move in + // Move over the scrollbar. scrollbar_controller_->DidMouseMoveNear(0); - - // Jump X seconds, first we need to make the time not 0, second we need to - // call Animate once to start the animation(initial the last_awaken_time_), - // now you can jump x seconds. scrollbar_controller_->Animate(time); - time += base::TimeDelta::FromSeconds(kDuration); + time += kFadeDuration; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); // Capture - scrollbar_controller_->DidCaptureScrollbarBegin(); + scrollbar_controller_->DidMouseDown(); time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->Animate(time); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // test for 10 seconds, stay thick and dark - for (int i = 0; i < 10; ++i) { - // move away from bar. - scrollbar_controller_->DidMouseMoveNear(26 + i); - time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - } + // Should stay thick for a while. + time += base::TimeDelta::FromSeconds(10); + scrollbar_controller_->Animate(time); + + // Move outside the "near" threshold. Because the scrollbar is captured it + // should remain thick. + scrollbar_controller_->DidMouseMoveNear( + kDefaultMouseMoveDistanceToTriggerAnimation); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + + // Release. + scrollbar_controller_->DidMouseUp(); + + // Should become thin. + time += base::TimeDelta::FromSeconds(1); + scrollbar_controller_->Animate(time); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); +} - // release - scrollbar_controller_->DidCaptureScrollbarEnd(); +// First move the pointer on the scrollbar, then press it, then away. Confirm +// that the bar gets thick. Then move point on the scrollbar and mouse up. +// Confirm that the bar stays thick. +TEST_F(ScrollbarAnimationControllerThinningTest, MouseCaptureAndReleaseOnBar) { + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); - // get thickness and light + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + // Move over scrollbar. + scrollbar_controller_->DidMouseMoveNear(0); + scrollbar_controller_->Animate(time); + time += kThinningDuration; scrollbar_controller_->Animate(time); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + // Capture. Nothing should change. + scrollbar_controller_->DidMouseDown(); time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.9f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->thumb_thickness_scale_factor()); + time += base::TimeDelta::FromSeconds(10); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + // Move away from scrollbar. Nothing should change. + scrollbar_controller_->DidMouseMoveNear( + kDefaultMouseMoveDistanceToTriggerAnimation); time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.8f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.6f, scrollbar_layer_->thumb_thickness_scale_factor()); + time += base::TimeDelta::FromSeconds(10); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + // Move over scrollbar and release. Since we're near the scrollbar, it should + // remain thick. + scrollbar_controller_->DidMouseMoveNear(0); + scrollbar_controller_->DidMouseUp(); time += base::TimeDelta::FromSeconds(1); scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(0.7f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(0.4f, scrollbar_layer_->thumb_thickness_scale_factor()); + time += base::TimeDelta::FromSeconds(10); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); } -// First move the pointer on the scrollbar, then press it, then away. -// Confirm that the bar gets thick and dark. Then move point on the -// scrollbar and mouse up. Confirm that the bar gets thick and dark. -TEST_F(ScrollbarAnimationControllerThinningTest, MouseCaptureAndReleaseOnBar) { +// Move mouse on scrollbar and capture then move out of window. Confirm that +// the bar stays thick. +TEST_F(ScrollbarAnimationControllerThinningTest, + MouseCapturedAndExitWindowFromScrollbar) { + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); - // Move in + // Move mouse over scrollbar. scrollbar_controller_->DidMouseMoveNear(0); + scrollbar_controller_->Animate(time); + time += kThinningDuration; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + + // Capture. + scrollbar_controller_->DidMouseDown(); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); + // Move out of window. Since the scrollbar is capture, it shouldn't change in + // any way. + scrollbar_controller_->DidMouseLeave(); scrollbar_controller_->Animate(time); - time += base::TimeDelta::FromSeconds(kDuration); + time += kThinningDuration; scrollbar_controller_->Animate(time); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); +} - // Capture - scrollbar_controller_->DidCaptureScrollbarBegin(); +// Tests that the thickening/thinning effects are animated. +TEST_F(ScrollbarAnimationControllerThinningTest, ThicknessAnimated) { + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + base::TimeTicks time; time += base::TimeDelta::FromSeconds(1); + + // Move mouse near scrollbar. Test that at half the duration time, the + // thickness is half way through its animation. + scrollbar_controller_->DidMouseMoveNear(1); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); + + time += kThinningDuration / 2; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(kIdleThicknessScale + (1.0f - kIdleThicknessScale) / 2.0f, + scrollbar_layer_->thumb_thickness_scale_factor()); + + time += kThinningDuration / 2; scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // test for 10 seconds, stay thick and dark - for (int i = 0; i < 10; ++i) { - // move away from bar. - scrollbar_controller_->DidMouseMoveNear(26 + i); - time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - } + // Move mouse away from scrollbar. Same check. + time += base::TimeDelta::FromSeconds(1); + scrollbar_controller_->DidMouseMoveNear( + kDefaultMouseMoveDistanceToTriggerAnimation); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - // move to the bar. - scrollbar_controller_->DidMouseMoveNear(0); + time += kThinningDuration / 2; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f - (1.0f - kIdleThicknessScale) / 2.0f, + scrollbar_layer_->thumb_thickness_scale_factor()); + + time += kThinningDuration / 2; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(kIdleThicknessScale, + scrollbar_layer_->thumb_thickness_scale_factor()); +} - // release - scrollbar_controller_->DidCaptureScrollbarEnd(); +// Tests that main thread scroll updates immediatley queue a fade animation +// without requiring a ScrollEnd. +TEST_F(ScrollbarAnimationControllerThinningTest, MainThreadScrollQueuesFade) { + ASSERT_TRUE(client_.start_fade().is_null()); - // stay thick and dark - // test for 10 seconds, stay thick and dark - for (int i = 0; i < 10; ++i) { - time += base::TimeDelta::FromSeconds(1); - scrollbar_controller_->Animate(time); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); - EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->thumb_thickness_scale_factor()); - } + // A ScrollUpdate without a ScrollBegin indicates a main thread scroll update + // so we should schedule a fade animation without waiting for a ScrollEnd + // (which will never come). + scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + + client_.start_fade().Reset(); + + // If we got a ScrollBegin, we shouldn't schedule the fade animation until we + // get a corresponding ScrollEnd. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + EXPECT_TRUE(client_.start_fade().is_null()); + scrollbar_controller_->DidScrollEnd(); + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); +} + +// Make sure that if the scroll update is as a result of a resize, we use the +// resize delay time instead of the default one. +TEST_F(ScrollbarAnimationControllerThinningTest, ResizeFadeDuration) { + ASSERT_TRUE(client_.delay().is_zero()); + + scrollbar_controller_->DidScrollUpdate(true); + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_EQ(kResizeDelayBeforeStarting, client_.delay()); + + client_.delay() = base::TimeDelta(); + + // We should use the gesture delay rather than the resize delay if we're in a + // gesture scroll, even if the resize param is set. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(true); + scrollbar_controller_->DidScrollEnd(); + + EXPECT_FALSE(client_.start_fade().is_null()); + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); +} + +// Tests that the fade effect is animated. +TEST_F(ScrollbarAnimationControllerThinningTest, FadeAnimated) { + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + scrollbar_controller_->DidScrollEnd(); + + // Appearance is instant. + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + + // An animation should have been enqueued. + EXPECT_EQ(kDelayBeforeStarting, client_.delay()); + EXPECT_FALSE(client_.start_fade().is_null()); + client_.start_fade().Run(); + + base::TimeTicks time; + time += base::TimeDelta::FromSeconds(1); + + // Test that at half the fade duration time, the opacity is at half. + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(1.0f, scrollbar_layer_->Opacity()); + + time += kFadeDuration / 2; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(0.5f, scrollbar_layer_->Opacity()); + + time += kFadeDuration / 2; + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); +} + +// Tests that the controller tells the client when the scrollbars hide/show. +TEST_F(ScrollbarAnimationControllerThinningTest, NotifyChangedVisibility) { + base::TimeTicks time; + time += base::TimeDelta::FromSeconds(1); + + EXPECT_CALL(client_, DidChangeScrollbarVisibility()).Times(1); + // Scroll to make the scrollbars visible. + scrollbar_controller_->DidScrollBegin(); + scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(scrollbar_controller_->ScrollbarsHidden()); + Mock::VerifyAndClearExpectations(&client_); + + scrollbar_controller_->DidScrollEnd(); + + // Play out the fade animation. We shouldn't notify that the scrollbars are + // hidden until the animation is completly over. We can (but don't have to) + // notify during the animation that the scrollbars are still visible. + EXPECT_CALL(client_, DidChangeScrollbarVisibility()).Times(0); + ASSERT_FALSE(client_.start_fade().is_null()); + client_.start_fade().Run(); + scrollbar_controller_->Animate(time); + time += kFadeDuration / 4; + EXPECT_FALSE(scrollbar_controller_->ScrollbarsHidden()); + scrollbar_controller_->Animate(time); + time += kFadeDuration / 4; + EXPECT_FALSE(scrollbar_controller_->ScrollbarsHidden()); + scrollbar_controller_->Animate(time); + time += kFadeDuration / 4; + EXPECT_FALSE(scrollbar_controller_->ScrollbarsHidden()); + scrollbar_controller_->Animate(time); + EXPECT_FLOAT_EQ(0.25f, scrollbar_layer_->Opacity()); + Mock::VerifyAndClearExpectations(&client_); + + EXPECT_CALL(client_, DidChangeScrollbarVisibility()).Times(1); + time += kFadeDuration / 4; + scrollbar_controller_->Animate(time); + EXPECT_TRUE(scrollbar_controller_->ScrollbarsHidden()); + EXPECT_FLOAT_EQ(0.0f, scrollbar_layer_->Opacity()); + Mock::VerifyAndClearExpectations(&client_); + + // Calling DidScrollUpdate without a begin (i.e. update from commit) should + // also notify. + EXPECT_CALL(client_, DidChangeScrollbarVisibility()).Times(1); + scrollbar_controller_->DidScrollUpdate(false); + EXPECT_FALSE(scrollbar_controller_->ScrollbarsHidden()); + Mock::VerifyAndClearExpectations(&client_); } } // namespace diff --git a/chromium/cc/input/top_controls_manager_client.h b/chromium/cc/input/top_controls_manager_client.h deleted file mode 100644 index ee0ca0e3d1a..00000000000 --- a/chromium/cc/input/top_controls_manager_client.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_INPUT_TOP_CONTROLS_MANAGER_CLIENT_H_ -#define CC_INPUT_TOP_CONTROLS_MANAGER_CLIENT_H_ - -namespace cc { - -class LayerTreeImpl; - -class CC_EXPORT TopControlsManagerClient { - public: - virtual float TopControlsHeight() const = 0; - virtual float BottomControlsHeight() const = 0; - virtual void SetCurrentTopControlsShownRatio(float ratio) = 0; - virtual float CurrentTopControlsShownRatio() const = 0; - virtual void DidChangeTopControlsPosition() = 0; - virtual bool HaveRootScrollLayer() const = 0; - - protected: - virtual ~TopControlsManagerClient() {} -}; - -} // namespace cc - -#endif // CC_INPUT_TOP_CONTROLS_MANAGER_CLIENT_H_ diff --git a/chromium/cc/input/top_controls_state.h b/chromium/cc/input/top_controls_state.h deleted file mode 100644 index 87b86c02691..00000000000 --- a/chromium/cc/input/top_controls_state.h +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 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_INPUT_TOP_CONTROLS_STATE_H_ -#define CC_INPUT_TOP_CONTROLS_STATE_H_ - -namespace cc { -enum TopControlsState { - SHOWN = 1, - HIDDEN = 2, - BOTH = 3 -}; -} - -#endif // CC_INPUT_TOP_CONTROLS_STATE_H_ - diff --git a/chromium/cc/ipc/BUILD.gn b/chromium/cc/ipc/BUILD.gn index 53b3fec7e6d..71cb00b6115 100644 --- a/chromium/cc/ipc/BUILD.gn +++ b/chromium/cc/ipc/BUILD.gn @@ -57,7 +57,7 @@ mojom("interfaces") { "transferable_resource.mojom", ] - deps = [ + public_deps = [ "//gpu/ipc/common:interfaces", "//mojo/common:common_custom_types", "//skia/public/interfaces", @@ -67,6 +67,18 @@ mojom("interfaces") { ] } +# Interfaces between two privileged services. +mojom("internal_interfaces") { + sources = [ + "display_compositor.mojom", + ] + + public_deps = [ + ":interfaces", + "//ui/gfx/geometry/mojo", + ] +} + mojom("test_interfaces") { testonly = true sources = [ @@ -80,6 +92,7 @@ mojom("test_interfaces") { source_set("struct_traits") { sources = [ + "begin_frame_args_struct_traits.h", "compositor_frame_metadata_struct_traits.cc", "compositor_frame_metadata_struct_traits.h", "compositor_frame_struct_traits.cc", diff --git a/chromium/cc/ipc/DEPS b/chromium/cc/ipc/DEPS index 86d0543146b..32a63b8414a 100644 --- a/chromium/cc/ipc/DEPS +++ b/chromium/cc/ipc/DEPS @@ -1,5 +1,6 @@ include_rules = [ "+gpu/ipc/common", + "+mojo/common", "+mojo/public", "+skia/public", "+ui/events/ipc", diff --git a/chromium/cc/ipc/begin_frame_args_struct_traits.h b/chromium/cc/ipc/begin_frame_args_struct_traits.h index 3d3e88400fc..bf3c5a802ed 100644 --- a/chromium/cc/ipc/begin_frame_args_struct_traits.h +++ b/chromium/cc/ipc/begin_frame_args_struct_traits.h @@ -5,7 +5,7 @@ #ifndef CC_IPC_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_ #define CC_IPC_BEGIN_FRAME_ARGS_STRUCT_TRAITS_H_ -#include "cc/ipc/begin_frame_args.mojom.h" +#include "cc/ipc/begin_frame_args.mojom-shared.h" #include "cc/output/begin_frame_args.h" namespace mojo { diff --git a/chromium/cc/ipc/cc_param_traits.cc b/chromium/cc/ipc/cc_param_traits.cc index fc734204281..e621e3fc7a2 100644 --- a/chromium/cc/ipc/cc_param_traits.cc +++ b/chromium/cc/ipc/cc_param_traits.cc @@ -9,6 +9,7 @@ #include "base/numerics/safe_conversions.h" #include "base/time/time.h" +#include "base/unguessable_token.h" #include "cc/output/compositor_frame.h" #include "cc/output/filter_operations.h" #include "cc/quads/debug_border_draw_quad.h" @@ -621,7 +622,7 @@ bool ParamTraits<cc::LocalFrameId>::Read(const base::Pickle* m, if (!ReadParam(m, iter, &local_id)) return false; - uint64_t nonce; + base::UnguessableToken nonce; if (!ReadParam(m, iter, &nonce)) return false; diff --git a/chromium/cc/ipc/cc_param_traits.h b/chromium/cc/ipc/cc_param_traits.h index f546b07f74e..f1711493544 100644 --- a/chromium/cc/ipc/cc_param_traits.h +++ b/chromium/cc/ipc/cc_param_traits.h @@ -17,10 +17,6 @@ #include "gpu/ipc/common/gpu_command_buffer_traits.h" #include "ipc/ipc_message_macros.h" -namespace gfx { -class Transform; -} - namespace cc { class FilterOperations; } diff --git a/chromium/cc/ipc/cc_param_traits_unittest.cc b/chromium/cc/ipc/cc_param_traits_unittest.cc index 6bb3c302244..bc2472060f4 100644 --- a/chromium/cc/ipc/cc_param_traits_unittest.cc +++ b/chromium/cc/ipc/cc_param_traits_unittest.cc @@ -361,8 +361,9 @@ TEST_F(CCParamTraitsTest, AllQuads) { pass_cmp->CopyFromAndAppendDrawQuad(streamvideo_in, streamvideo_in->shared_quad_state); - cc::SurfaceId arbitrary_surface_id(kArbitraryFrameSinkId, - cc::LocalFrameId(3, 0)); + cc::SurfaceId arbitrary_surface_id( + kArbitraryFrameSinkId, + cc::LocalFrameId(3, base::UnguessableToken::Create())); SurfaceDrawQuad* surface_in = pass_in->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); surface_in->SetAll(shared_state3_in, arbitrary_rect2, @@ -563,14 +564,10 @@ TEST_F(CCParamTraitsTest, Resources) { arbitrary_token2.SetVerifyFlush(); GLbyte arbitrary_mailbox1[GL_MAILBOX_SIZE_CHROMIUM] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, - 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, - 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4}; + 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6}; GLbyte arbitrary_mailbox2[GL_MAILBOX_SIZE_CHROMIUM] = { - 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, - 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7, - 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7}; + 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2}; TransferableResource arbitrary_resource1; arbitrary_resource1.id = 2178312; diff --git a/chromium/cc/ipc/display_compositor.mojom b/chromium/cc/ipc/display_compositor.mojom new file mode 100644 index 00000000000..c3ae783e6de --- /dev/null +++ b/chromium/cc/ipc/display_compositor.mojom @@ -0,0 +1,20 @@ +// 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. + +module cc.mojom; + +import "cc/ipc/surface_id.mojom"; +import "ui/gfx/geometry/mojo/geometry.mojom"; + +// The DisplayCompositorClient interface is implemented by the Display +// Compositor Host, a stable, and privileged peer service to the display +// compositor. The display compositor host is either the browser process in +// Chrome or the window server process. +interface DisplayCompositorClient { + // Called by the display compositor immediately upon receiving a + // CompositorFrame with a new SurfaceId for the first time. + OnSurfaceCreated(cc.mojom.SurfaceId surface_id, + gfx.mojom.Size frame_size, + float device_scale_factor); +}; diff --git a/chromium/cc/ipc/local_frame_id.mojom b/chromium/cc/ipc/local_frame_id.mojom index feca9b0fcc1..6b25b6b7da3 100644 --- a/chromium/cc/ipc/local_frame_id.mojom +++ b/chromium/cc/ipc/local_frame_id.mojom @@ -3,14 +3,13 @@ // found in the LICENSE file. module cc.mojom; +import "mojo/common/common_custom_types.mojom"; struct LocalFrameId { // An identifier allocated by the client uniquely identifying a surface within // a client process. uint32 local_id; - // A cryptographically secure random int chosen to make the LocalFrameId - // unguessable by other clients. - uint64 nonce; + mojo.common.mojom.UnguessableToken nonce; }; diff --git a/chromium/cc/ipc/local_frame_id_struct_traits.h b/chromium/cc/ipc/local_frame_id_struct_traits.h index 50af9a9cc64..514bd4cbeae 100644 --- a/chromium/cc/ipc/local_frame_id_struct_traits.h +++ b/chromium/cc/ipc/local_frame_id_struct_traits.h @@ -7,6 +7,7 @@ #include "cc/ipc/local_frame_id.mojom-shared.h" #include "cc/surfaces/local_frame_id.h" +#include "mojo/common/common_custom_types_struct_traits.h" namespace mojo { @@ -16,13 +17,18 @@ struct StructTraits<cc::mojom::LocalFrameIdDataView, cc::LocalFrameId> { return local_frame_id.local_id(); } - static uint64_t nonce(const cc::LocalFrameId& local_frame_id) { + static const base::UnguessableToken& nonce( + const cc::LocalFrameId& local_frame_id) { return local_frame_id.nonce(); } static bool Read(cc::mojom::LocalFrameIdDataView data, cc::LocalFrameId* out) { - *out = cc::LocalFrameId(data.local_id(), data.nonce()); + base::UnguessableToken nonce; + if (!data.ReadNonce(&nonce)) + return false; + + *out = cc::LocalFrameId(data.local_id(), nonce); return true; } }; diff --git a/chromium/cc/ipc/mojo_compositor_frame_sink.mojom b/chromium/cc/ipc/mojo_compositor_frame_sink.mojom index 902eefab033..58f69d61916 100644 --- a/chromium/cc/ipc/mojo_compositor_frame_sink.mojom +++ b/chromium/cc/ipc/mojo_compositor_frame_sink.mojom @@ -4,7 +4,9 @@ module cc.mojom; +import "cc/ipc/begin_frame_args.mojom"; import "cc/ipc/compositor_frame.mojom"; +import "cc/ipc/frame_sink_id.mojom"; import "cc/ipc/returned_resource.mojom"; // A MojoCompositorFrameSink is an interface for receiving CompositorFrame @@ -13,19 +15,43 @@ import "cc/ipc/returned_resource.mojom"; // is responsible for creating a CompositorFrame to update its portion of the // screen. interface MojoCompositorFrameSink { - // After the submitted frame is either drawn for the first time by the display - // compositor or discarded, the callback will be called. Clients should use - // this acknowledgement to ratelimit frame submissions. - // TODO(fsamuel): We should support identifying the CF in the callback. - SubmitCompositorFrame(cc.mojom.CompositorFrame frame) => (); - // Lets the display compositor know that the client wishes to receive the next // BeginFrame event. SetNeedsBeginFrame(bool needs_begin_frame); + // Submits a CompositorFrame to the display compositor that will be presented + // to screen the next time frames from all CompositorFrameSinks are aggregated + // to produce a display CompositorFrame. + // For successful swaps, the implementation must call + // DidReceiveCompositorFrameAck() asynchronously when the frame has been + // processed in order to unthrottle the next frame. + SubmitCompositorFrame(cc.mojom.CompositorFrame frame); + // TODO(fsamuel): ReadbackBitmap API would be useful here. }; interface MojoCompositorFrameSinkClient { - ReturnResources(array<cc.mojom.ReturnedResource> resources); + // Notification that the previous CompositorFrame given to + // SubmitCompositorFrame() has been processed and that another frame + // can be submitted. This provides backpressure from the display compositor + // so that frames are submitted only at the rate it can handle them. + // TODO(fsamuel): This method ought not be necessary with unified BeginFrame. + // However, there's a fair amount of cleanup and refactoring necessary to get + // rid of it. + DidReceiveCompositorFrameAck(); + + // Notification for the client to generate a CompositorFrame. + OnBeginFrame(BeginFrameArgs args); + + // Returns resources sent to SubmitCompositorFrame to be reused or freed. + ReclaimResources(ReturnedResourceArray resources); +}; + +// MojoCompositorFrameSinkPrivate is used by the display compositor host to set +// up BeginFrameSource hierarchies. This API lives in SurfaceManager but is +// called from here in order to ensure that hierarchy registration does not race +// CompositorFrameSink creation. +interface MojoCompositorFrameSinkPrivate { + AddChildFrameSink(FrameSinkId child_frame_sink_id); + RemoveChildFrameSink(FrameSinkId child_frame_sink_id); }; diff --git a/chromium/cc/ipc/returned_resource.mojom b/chromium/cc/ipc/returned_resource.mojom index 396d2e6f683..16e673e0dad 100644 --- a/chromium/cc/ipc/returned_resource.mojom +++ b/chromium/cc/ipc/returned_resource.mojom @@ -13,3 +13,7 @@ struct ReturnedResource { int32 count; bool lost; }; + +struct ReturnedResourceArray { + array<ReturnedResource> returned_resources; +}; diff --git a/chromium/cc/ipc/returned_resource.typemap b/chromium/cc/ipc/returned_resource.typemap index 153b7b8d022..94349a503ed 100644 --- a/chromium/cc/ipc/returned_resource.typemap +++ b/chromium/cc/ipc/returned_resource.typemap @@ -5,5 +5,11 @@ mojom = "//cc/ipc/returned_resource.mojom" public_headers = [ "//cc/resources/returned_resource.h" ] traits_headers = [ "//cc/ipc/returned_resource_struct_traits.h" ] -deps = [ "//cc", "//gpu/command_buffer/common" ] -type_mappings = [ "cc.mojom.ReturnedResource=cc::ReturnedResource" ] +deps = [ + "//cc", + "//gpu/command_buffer/common", +] +type_mappings = [ + "cc.mojom.ReturnedResource=cc::ReturnedResource", + "cc.mojom.ReturnedResourceArray=cc::ReturnedResourceArray", +] diff --git a/chromium/cc/ipc/returned_resource_struct_traits.h b/chromium/cc/ipc/returned_resource_struct_traits.h index 8925304f778..e7a1f1ef6e9 100644 --- a/chromium/cc/ipc/returned_resource_struct_traits.h +++ b/chromium/cc/ipc/returned_resource_struct_traits.h @@ -5,7 +5,7 @@ #ifndef CC_IPC_RETURNED_RESOURCE_STRUCT_TRAITS_H_ #define CC_IPC_RETURNED_RESOURCE_STRUCT_TRAITS_H_ -#include "cc/ipc/returned_resource.mojom.h" +#include "cc/ipc/returned_resource.mojom-shared.h" #include "cc/resources/returned_resource.h" namespace mojo { @@ -40,6 +40,20 @@ struct StructTraits<cc::mojom::ReturnedResourceDataView, cc::ReturnedResource> { } }; +template <> +struct StructTraits<cc::mojom::ReturnedResourceArrayDataView, + cc::ReturnedResourceArray> { + static const cc::ReturnedResourceArray& returned_resources( + const cc::ReturnedResourceArray& resource_array) { + return resource_array; + } + + static bool Read(cc::mojom::ReturnedResourceArrayDataView data, + cc::ReturnedResourceArray* out) { + return data.ReadReturnedResources(out); + } +}; + } // namespace mojo #endif // CC_IPC_RETURNED_RESOURCE_STRUCT_TRAITS_H_ diff --git a/chromium/cc/ipc/struct_traits_unittest.cc b/chromium/cc/ipc/struct_traits_unittest.cc index c5655cf88c4..b4af777af59 100644 --- a/chromium/cc/ipc/struct_traits_unittest.cc +++ b/chromium/cc/ipc/struct_traits_unittest.cc @@ -286,7 +286,8 @@ TEST_F(StructTraitsTest, CompositorFrameMetadata) { std::vector<ui::LatencyInfo> latency_infos = {latency_info}; std::vector<uint32_t> satisfies_sequences = {1234, 1337}; std::vector<SurfaceId> referenced_surfaces; - SurfaceId id(FrameSinkId(1234, 4321), LocalFrameId(5678, 9101112)); + SurfaceId id(FrameSinkId(1234, 4321), + LocalFrameId(5678, base::UnguessableToken::Create())); referenced_surfaces.push_back(id); CompositorFrameMetadata input; @@ -438,7 +439,9 @@ TEST_F(StructTraitsTest, QuadListBasic) { solid_quad->SetNew(sqs, rect2, rect2, color2, force_anti_aliasing_off); const gfx::Rect rect3(1029, 3847, 5610, 2938); - const SurfaceId surface_id(FrameSinkId(1234, 4321), LocalFrameId(5678, 2468)); + const SurfaceId surface_id( + FrameSinkId(1234, 4321), + LocalFrameId(5678, base::UnguessableToken::Create())); SurfaceDrawQuad* surface_quad = render_pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); surface_quad->SetNew(sqs, rect3, rect3, surface_id); @@ -611,7 +614,8 @@ TEST_F(StructTraitsTest, RenderPass) { const gfx::Rect surface_quad_rect(1337, 2448, 1234, 5678); surface_quad->SetNew( shared_state_2, surface_quad_rect, surface_quad_rect, - SurfaceId(FrameSinkId(1337, 1234), LocalFrameId(1234, 2468))); + SurfaceId(FrameSinkId(1337, 1234), + LocalFrameId(1234, base::UnguessableToken::Create()))); std::unique_ptr<RenderPass> output; mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); @@ -766,7 +770,8 @@ TEST_F(StructTraitsTest, Selection) { TEST_F(StructTraitsTest, SurfaceId) { static constexpr FrameSinkId frame_sink_id(1337, 1234); - static constexpr LocalFrameId local_frame_id(0xfbadbeef, 0xdeadbeef); + static LocalFrameId local_frame_id(0xfbadbeef, + base::UnguessableToken::Create()); SurfaceId input(frame_sink_id, local_frame_id); mojom::TraitsTestServicePtr proxy = GetTraitsTestProxy(); SurfaceId output; @@ -820,9 +825,7 @@ TEST_F(StructTraitsTest, TransferableResource) { const uint32_t filter = 1234; const gfx::Size size(1234, 5678); const int8_t mailbox_name[GL_MAILBOX_SIZE_CHROMIUM] = { - 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, - 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7, - 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2, 4, 6, 8, 0, 0, 9, 8, 7}; + 0, 9, 8, 7, 6, 5, 4, 3, 2, 1, 9, 7, 5, 3, 1, 2}; const gpu::CommandBufferNamespace command_buffer_namespace = gpu::IN_PROCESS; const int32_t extra_data_field = 0xbeefbeef; const gpu::CommandBufferId command_buffer_id( diff --git a/chromium/cc/layers/heads_up_display_layer.cc b/chromium/cc/layers/heads_up_display_layer.cc index b37e4e1bd40..fc5718b894a 100644 --- a/chromium/cc/layers/heads_up_display_layer.cc +++ b/chromium/cc/layers/heads_up_display_layer.cc @@ -8,7 +8,6 @@ #include "base/trace_event/trace_event.h" #include "cc/layers/heads_up_display_layer_impl.h" -#include "cc/proto/layer.pb.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_settings.h" @@ -62,11 +61,6 @@ std::unique_ptr<LayerImpl> HeadsUpDisplayLayer::CreateLayerImpl( return HeadsUpDisplayLayerImpl::Create(tree_impl, id()); } -void HeadsUpDisplayLayer::SetTypeForProtoSerialization( - proto::LayerNode* proto) const { - proto->set_type(proto::LayerNode::HEADS_UP_DISPLAY_LAYER); -} - void HeadsUpDisplayLayer::PushPropertiesTo(LayerImpl* layer) { Layer::PushPropertiesTo(layer); TRACE_EVENT0("cc", "HeadsUpDisplayLayer::PushPropertiesTo"); diff --git a/chromium/cc/layers/heads_up_display_layer.h b/chromium/cc/layers/heads_up_display_layer.h index da8f05a0bc5..2cde7e87beb 100644 --- a/chromium/cc/layers/heads_up_display_layer.h +++ b/chromium/cc/layers/heads_up_display_layer.h @@ -16,10 +16,6 @@ namespace cc { -namespace proto { -class LayerNode; -} // namespace proto - class CC_EXPORT HeadsUpDisplayLayer : public Layer { public: static scoped_refptr<HeadsUpDisplayLayer> Create(); @@ -29,8 +25,6 @@ class CC_EXPORT HeadsUpDisplayLayer : public Layer { std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; - void SetTypeForProtoSerialization(proto::LayerNode* proto) const override; - // Layer overrides. void PushPropertiesTo(LayerImpl* layer) override; diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc index abd1f320cb4..73593631d95 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl.cc +++ b/chromium/cc/layers/heads_up_display_layer_impl.cc @@ -342,7 +342,7 @@ void HeadsUpDisplayLayerImpl::DrawGraphLines(SkCanvas* canvas, // Draw indicator line (additive blend mode to increase contrast when drawn on // top of graph). paint->setColor(DebugColors::HUDIndicatorLineColor()); - paint->setXfermodeMode(SkXfermode::kPlus_Mode); + paint->setBlendMode(SkBlendMode::kPlus); const double indicator_top = bounds.height() * (1.0 - graph.indicator / graph.current_upper_bound) - 1.0; @@ -351,7 +351,7 @@ void HeadsUpDisplayLayerImpl::DrawGraphLines(SkCanvas* canvas, bounds.right(), bounds.top() + indicator_top, *paint); - paint->setXfermode(nullptr); + paint->setBlendMode(SkBlendMode::kSrcOver); } SkRect HeadsUpDisplayLayerImpl::DrawFPSDisplay( diff --git a/chromium/cc/layers/heads_up_display_layer_impl.h b/chromium/cc/layers/heads_up_display_layer_impl.h index 174d1bfda7e..68175009367 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl.h +++ b/chromium/cc/layers/heads_up_display_layer_impl.h @@ -27,7 +27,6 @@ struct SkRect; namespace cc { class FrameRateCounter; -class PaintTimeCounter; class CC_EXPORT HeadsUpDisplayLayerImpl : public LayerImpl { public: 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 201f387ad4f..722e5615fc8 100644 --- a/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc +++ b/chromium/cc/layers/heads_up_display_layer_impl_unittest.cc @@ -9,7 +9,6 @@ #include "cc/test/fake_compositor_frame_sink.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host_impl.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -35,12 +34,10 @@ void CheckDrawLayer(HeadsUpDisplayLayerImpl* layer, TEST(HeadsUpDisplayLayerImplTest, ResourcelessSoftwareDrawAfterResourceLoss) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.CreatePendingTree(); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc index c477da3aadb..67c099c8253 100644 --- a/chromium/cc/layers/layer.cc +++ b/chromium/cc/layers/layer.cc @@ -15,14 +15,11 @@ #include "base/single_thread_task_runner.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" -#include "cc/animation/animation_host.h" -#include "cc/animation/mutable_properties.h" #include "cc/base/simple_enclosed_region.h" #include "cc/debug/frame_viewer_instrumentation.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/layer_client.h" #include "cc/layers/layer_impl.h" -#include "cc/layers/layer_proto_converter.h" #include "cc/layers/scrollbar_layer_interface.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" @@ -34,6 +31,8 @@ #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/mutable_properties.h" +#include "cc/trees/mutator_host.h" #include "cc/trees/transform_node.h" #include "third_party/skia/include/core/SkImageFilter.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -67,6 +66,7 @@ Layer::Inputs::Inputs(int layer_id) scroll_parent(nullptr), clip_parent(nullptr), has_will_change_transform_hint(false), + has_preferred_raster_bounds(false), hide_layer_and_subtree(false), client(nullptr) {} @@ -77,15 +77,12 @@ scoped_refptr<Layer> Layer::Create() { } Layer::Layer() - // Layer IDs start from 1. - : Layer(g_next_layer_id.GetNext() + 1) {} - -Layer::Layer(int layer_id) : ignore_set_needs_commit_(false), parent_(nullptr), layer_tree_host_(nullptr), layer_tree_(nullptr), - inputs_(layer_id), + // Layer IDs start from 1. + inputs_(g_next_layer_id.GetNext() + 1), num_descendants_that_draw_content_(0), transform_tree_index_(TransformTree::kInvalidNodeId), effect_tree_index_(EffectTree::kInvalidNodeId), @@ -159,7 +156,7 @@ void Layer::SetLayerTreeHost(LayerTreeHost* host) { inputs_.mask_layer->SetLayerTreeHost(host); const bool has_any_animation = - layer_tree_host_ ? GetAnimationHost()->HasAnyAnimation(element_id()) + layer_tree_host_ ? GetMutatorHost()->HasAnyAnimation(element_id()) : false; if (host && has_any_animation) @@ -422,6 +419,9 @@ void Layer::SetMaskLayer(Layer* mask_layer) { } inputs_.mask_layer = mask_layer; if (inputs_.mask_layer.get()) { + // The mask layer should not have any children. + DCHECK(inputs_.mask_layer->children().empty()); + inputs_.mask_layer->RemoveFromParent(); DCHECK(!inputs_.mask_layer->parent()); inputs_.mask_layer->SetParent(this); @@ -589,7 +589,7 @@ void Layer::SetPosition(const gfx::PointF& position) { transform_tree_index()); sticky_data->main_thread_offset = position.OffsetFromOrigin() - - sticky_data->constraints.scroll_container_relative_sticky_box_rect + sticky_data->constraints.parent_relative_sticky_box_offset .OffsetFromOrigin(); } transform_node->needs_local_transform_update = true; @@ -693,11 +693,11 @@ void Layer::SetTransformOrigin(const gfx::Point3F& transform_origin) { } bool Layer::ScrollOffsetAnimationWasInterrupted() const { - return GetAnimationHost()->ScrollOffsetAnimationWasInterrupted(element_id()); + return GetMutatorHost()->ScrollOffsetAnimationWasInterrupted(element_id()); } bool Layer::HasOnlyTranslationTransforms() const { - return GetAnimationHost()->HasOnlyTranslationTransforms( + return GetMutatorHost()->HasOnlyTranslationTransforms( element_id(), GetElementTypeForAnimation()); } @@ -1115,6 +1115,10 @@ static void PostCopyCallbackToMainThread( base::Passed(&result))); } +bool Layer::IsSnapped() { + return scrollable(); +} + void Layer::PushPropertiesTo(LayerImpl* layer) { TRACE_EVENT0("cc", "Layer::PushPropertiesTo"); DCHECK(layer_tree_host_); @@ -1185,6 +1189,10 @@ void Layer::PushPropertiesTo(LayerImpl* layer) { layer->SetUpdateRect(inputs_.update_rect); layer->SetHasWillChangeTransformHint(has_will_change_transform_hint()); + if (has_preferred_raster_bounds()) + layer->SetPreferredRasterBounds(preferred_raster_bounds()); + else + layer->ClearPreferredRasterBounds(); layer->SetNeedsPushProperties(); // Reset any state that should be cleared for the next update. @@ -1236,88 +1244,10 @@ void Layer::ToLayerNodeProto(proto::LayerNode* proto) const { inputs_.mask_layer->ToLayerNodeProto(proto->mutable_mask_layer()); } -void Layer::ClearLayerTreePropertiesForDeserializationAndAddToMap( - LayerIdMap* layer_map) { - (*layer_map)[inputs_.layer_id] = this; - - if (layer_tree_) - layer_tree_->UnregisterLayer(this); - - layer_tree_host_ = nullptr; - layer_tree_ = nullptr; - - parent_ = nullptr; - - // Clear these properties for all the children and add them to the map. - for (auto& child : inputs_.children) { - child->ClearLayerTreePropertiesForDeserializationAndAddToMap(layer_map); - } - - inputs_.children.clear(); - - if (inputs_.mask_layer) { - inputs_.mask_layer->ClearLayerTreePropertiesForDeserializationAndAddToMap( - layer_map); - inputs_.mask_layer = nullptr; - } -} - -void Layer::FromLayerNodeProto(const proto::LayerNode& proto, - const LayerIdMap& layer_map, - LayerTreeHost* layer_tree_host) { - DCHECK(!layer_tree_host_); - DCHECK(inputs_.children.empty()); - DCHECK(!inputs_.mask_layer); - DCHECK(layer_tree_host); - DCHECK(proto.has_id()); - - inputs_.layer_id = proto.id(); - - layer_tree_host_ = layer_tree_host; - layer_tree_ = layer_tree_host->GetLayerTree(); - layer_tree_->RegisterLayer(this); - - for (int i = 0; i < proto.children_size(); ++i) { - const proto::LayerNode& child_proto = proto.children(i); - DCHECK(child_proto.has_type()); - scoped_refptr<Layer> child = - LayerProtoConverter::FindOrAllocateAndConstruct(child_proto, layer_map); - // The child must now refer to this layer as its parent, and must also have - // the same LayerTreeHost. This must be done before deserializing children. - DCHECK(!child->parent_); - child->parent_ = this; - child->FromLayerNodeProto(child_proto, layer_map, layer_tree_host_); - inputs_.children.push_back(child); - } - - if (proto.has_mask_layer()) { - inputs_.mask_layer = LayerProtoConverter::FindOrAllocateAndConstruct( - proto.mask_layer(), layer_map); - inputs_.mask_layer->parent_ = this; - inputs_.mask_layer->FromLayerNodeProto(proto.mask_layer(), layer_map, - layer_tree_host_); - } -} - -void Layer::ToLayerPropertiesProto(proto::LayerUpdate* layer_update, - bool inputs_only) { - // Always set properties metadata for serialized layers. - proto::LayerProperties* proto = layer_update->add_layers(); +void Layer::ToLayerPropertiesProto(proto::LayerProperties* proto) { proto->set_id(inputs_.layer_id); - LayerSpecificPropertiesToProto(proto, inputs_only); -} - -void Layer::FromLayerPropertiesProto(const proto::LayerProperties& proto) { - DCHECK(proto.has_id()); - DCHECK_EQ(inputs_.layer_id, proto.id()); - FromLayerSpecificPropertiesProto(proto); -} -void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto, - bool inputs_only) { proto::BaseLayerProperties* base = proto->mutable_base(); - - // Layer::Inputs Serialization --------------------------------- RectToProto(inputs_.update_rect, base->mutable_update_rect()); inputs_.update_rect = gfx::Rect(); @@ -1372,160 +1302,6 @@ void Layer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto, // TODO(nyquist): Add support for serializing FilterOperations for // |filters_| and |background_filters_|. See crbug.com/541321. - - if (inputs_only) - return; - // ----------------------------------------------------------- - - // TODO(khushalsagar): Stop serializing the data below when crbug.com/648442. - - base->set_safe_opaque_background_color(safe_opaque_background_color_); - // TODO(nyquist): Figure out what to do with debug info. See crbug.com/570372. - base->set_transform_free_index(transform_tree_index_); - base->set_effect_tree_index(effect_tree_index_); - base->set_clip_tree_index(clip_tree_index_); - base->set_scroll_tree_index(scroll_tree_index_); - Vector2dFToProto(offset_to_transform_parent_, - base->mutable_offset_to_transform_parent()); - base->set_draws_content(draws_content_); - base->set_may_contain_video(may_contain_video_); - base->set_hide_layer_and_subtree(inputs_.hide_layer_and_subtree); - base->set_subtree_property_changed(subtree_property_changed_); - - // TODO(nyquist): Add support for serializing FilterOperations for - // |filters_| and |background_filters_|. See crbug.com/541321. - - base->set_masks_to_bounds(inputs_.masks_to_bounds); - base->set_main_thread_scrolling_reasons( - inputs_.main_thread_scrolling_reasons); - RegionToProto(inputs_.non_fast_scrollable_region, - base->mutable_non_fast_scrollable_region()); - RegionToProto(inputs_.touch_event_handler_region, - base->mutable_touch_event_handler_region()); - base->set_contents_opaque(inputs_.contents_opaque); - base->set_opacity(inputs_.opacity); - base->set_blend_mode(SkXfermodeModeToProto(inputs_.blend_mode)); - base->set_is_root_for_isolated_group(inputs_.is_root_for_isolated_group); - PointFToProto(inputs_.position, base->mutable_position()); - base->set_is_container_for_fixed_position_layers( - inputs_.is_container_for_fixed_position_layers); - inputs_.position_constraint.ToProtobuf(base->mutable_position_constraint()); - base->set_should_flatten_transform(inputs_.should_flatten_transform); - base->set_should_flatten_transform_from_property_tree( - should_flatten_transform_from_property_tree_); - base->set_draw_blend_mode(SkXfermodeModeToProto(draw_blend_mode_)); - base->set_num_descendants_that_draw_content( - num_descendants_that_draw_content_); - if (scroll_children_) { - for (auto* child : *scroll_children_) - base->add_scroll_children_ids(child->id()); - } - if (clip_children_) { - for (auto* child : *clip_children_) - base->add_clip_children_ids(child->id()); - } - - // TODO(nyquist): Figure out what to do with CopyRequests. - // See crbug.com/570374. - - // TODO(nyquist): Figure out what to do with ElementAnimations. - // See crbug.com/570376. -} - -void Layer::FromLayerSpecificPropertiesProto( - const proto::LayerProperties& proto) { - DCHECK(proto.has_base()); - DCHECK(layer_tree_host_); - const proto::BaseLayerProperties& base = proto.base(); - - inputs_.transform_origin = ProtoToPoint3F(base.transform_origin()); - inputs_.background_color = base.background_color(); - safe_opaque_background_color_ = base.safe_opaque_background_color(); - inputs_.bounds = ProtoToSize(base.bounds()); - - transform_tree_index_ = base.transform_free_index(); - effect_tree_index_ = base.effect_tree_index(); - clip_tree_index_ = base.clip_tree_index(); - scroll_tree_index_ = base.scroll_tree_index(); - offset_to_transform_parent_ = - ProtoToVector2dF(base.offset_to_transform_parent()); - inputs_.double_sided = base.double_sided(); - draws_content_ = base.draws_content(); - may_contain_video_ = base.may_contain_video(); - inputs_.hide_layer_and_subtree = base.hide_layer_and_subtree(); - subtree_property_changed_ = base.subtree_property_changed(); - inputs_.masks_to_bounds = base.masks_to_bounds(); - inputs_.main_thread_scrolling_reasons = base.main_thread_scrolling_reasons(); - inputs_.non_fast_scrollable_region = - RegionFromProto(base.non_fast_scrollable_region()); - inputs_.touch_event_handler_region = - RegionFromProto(base.touch_event_handler_region()); - inputs_.contents_opaque = base.contents_opaque(); - inputs_.opacity = base.opacity(); - inputs_.blend_mode = SkXfermodeModeFromProto(base.blend_mode()); - inputs_.is_root_for_isolated_group = base.is_root_for_isolated_group(); - inputs_.position = ProtoToPointF(base.position()); - inputs_.is_container_for_fixed_position_layers = - base.is_container_for_fixed_position_layers(); - inputs_.position_constraint.FromProtobuf(base.position_constraint()); - inputs_.should_flatten_transform = base.should_flatten_transform(); - should_flatten_transform_from_property_tree_ = - base.should_flatten_transform_from_property_tree(); - draw_blend_mode_ = SkXfermodeModeFromProto(base.draw_blend_mode()); - inputs_.use_parent_backface_visibility = - base.use_parent_backface_visibility(); - inputs_.transform = ProtoToTransform(base.transform()); - inputs_.sorting_context_id = base.sorting_context_id(); - num_descendants_that_draw_content_ = base.num_descendants_that_draw_content(); - - inputs_.scroll_clip_layer_id = base.scroll_clip_layer_id(); - inputs_.user_scrollable_horizontal = base.user_scrollable_horizontal(); - inputs_.user_scrollable_vertical = base.user_scrollable_vertical(); - - inputs_.scroll_parent = base.scroll_parent_id() == INVALID_ID - ? nullptr - : layer_tree_->LayerById(base.scroll_parent_id()); - - // If there have been scroll children entries in previous deserializations, - // clear out the set. If there have been none, initialize the set of children. - // After this, the set is in the correct state to only add the new children. - // If the set of children has not changed, for now this code still rebuilds - // the set. - if (scroll_children_) - scroll_children_->clear(); - else if (base.scroll_children_ids_size() > 0) - scroll_children_.reset(new std::set<Layer*>); - for (int i = 0; i < base.scroll_children_ids_size(); ++i) { - int child_id = base.scroll_children_ids(i); - scoped_refptr<Layer> child = layer_tree_->LayerById(child_id); - scroll_children_->insert(child.get()); - } - - inputs_.clip_parent = base.clip_parent_id() == INVALID_ID - ? nullptr - : layer_tree_->LayerById(base.clip_parent_id()); - - // If there have been clip children entries in previous deserializations, - // clear out the set. If there have been none, initialize the set of children. - // After this, the set is in the correct state to only add the new children. - // If the set of children has not changed, for now this code still rebuilds - // the set. - if (clip_children_) - clip_children_->clear(); - else if (base.clip_children_ids_size() > 0) - clip_children_.reset(new std::set<Layer*>); - for (int i = 0; i < base.clip_children_ids_size(); ++i) { - int child_id = base.clip_children_ids(i); - scoped_refptr<Layer> child = layer_tree_->LayerById(child_id); - clip_children_->insert(child.get()); - } - - inputs_.scroll_offset = ProtoToScrollOffset(base.scroll_offset()); - - inputs_.update_rect.Union(ProtoToRect(base.update_rect())); - - inputs_.has_will_change_transform_hint = - base.has_will_change_transform_hint(); } std::unique_ptr<LayerImpl> Layer::CreateLayerImpl(LayerTreeImpl* tree_impl) { @@ -1605,13 +1381,18 @@ void Layer::SetMayContainVideo(bool yes) { SetNeedsPushProperties(); } +void Layer::SetScrollbarsHiddenFromImplSide(bool hidden) { + if (inputs_.client) + inputs_.client->didChangeScrollbarsHidden(hidden); +} + bool Layer::FilterIsAnimating() const { - return GetAnimationHost()->IsAnimatingFilterProperty( + return GetMutatorHost()->IsAnimatingFilterProperty( element_id(), GetElementTypeForAnimation()); } bool Layer::TransformIsAnimating() const { - return GetAnimationHost()->IsAnimatingTransformProperty( + return GetMutatorHost()->IsAnimatingTransformProperty( element_id(), GetElementTypeForAnimation()); } @@ -1752,7 +1533,7 @@ void Layer::OnIsAnimatingChanged(const PropertyAnimationState& mask, bool Layer::HasActiveAnimationForTesting() const { return layer_tree_host_ - ? GetAnimationHost()->HasActiveAnimationForTesting(element_id()) + ? GetMutatorHost()->HasActiveAnimationForTesting(element_id()) : false; } @@ -1763,8 +1544,26 @@ void Layer::SetHasWillChangeTransformHint(bool has_will_change) { SetNeedsCommit(); } -AnimationHost* Layer::GetAnimationHost() const { - return layer_tree_ ? layer_tree_->animation_host() : nullptr; +void Layer::SetPreferredRasterBounds(const gfx::Size& preferred_raster_bounds) { + if (inputs_.has_preferred_raster_bounds && + inputs_.preferred_raster_bounds == preferred_raster_bounds) + return; + + inputs_.has_preferred_raster_bounds = true; + inputs_.preferred_raster_bounds = preferred_raster_bounds; + SetNeedsCommit(); +} + +void Layer::ClearPreferredRasterBounds() { + if (!inputs_.has_preferred_raster_bounds) + return; + inputs_.has_preferred_raster_bounds = false; + inputs_.preferred_raster_bounds = gfx::Size(); + SetNeedsCommit(); +} + +MutatorHost* Layer::GetMutatorHost() const { + return layer_tree_ ? layer_tree_->mutator_host() : nullptr; } ElementListType Layer::GetElementTypeForAnimation() const { @@ -1867,4 +1666,8 @@ LayerTree* Layer::GetLayerTree() const { return layer_tree_; } +void Layer::SetLayerIdForTesting(int id) { + inputs_.layer_id = id; +} + } // namespace cc diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h index cb4f1cb6fbd..44c274ff13c 100644 --- a/chromium/cc/layers/layer.h +++ b/chromium/cc/layers/layer.h @@ -17,8 +17,6 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/observer_list.h" -#include "cc/animation/element_id.h" -#include "cc/animation/target_property.h" #include "cc/base/cc_export.h" #include "cc/base/region.h" #include "cc/debug/micro_benchmark.h" @@ -27,9 +25,11 @@ #include "cc/layers/layer_position_constraint.h" #include "cc/layers/paint_properties.h" #include "cc/output/filter_operations.h" +#include "cc/trees/element_id.h" #include "cc/trees/layer_tree.h" #include "cc/trees/mutator_host_client.h" #include "cc/trees/property_tree.h" +#include "cc/trees/target_property.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkPicture.h" #include "third_party/skia/include/core/SkXfermode.h" @@ -39,10 +39,6 @@ #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/transform.h" -namespace gfx { -class BoxF; -} - namespace base { namespace trace_event { class ConvertableToTraceFormat; @@ -51,24 +47,18 @@ class ConvertableToTraceFormat; namespace cc { -class AnimationHost; class CopyOutputRequest; -class LayerAnimationEventObserver; class LayerClient; class LayerImpl; class LayerTreeHost; class LayerTreeHostCommon; class LayerTreeImpl; -class LayerTreeSettings; -class RenderingStatsInstrumentation; -class ResourceUpdateQueue; +class MutatorHost; class ScrollbarLayerInterface; -class SimpleEnclosedRegion; namespace proto { class LayerNode; class LayerProperties; -class LayerUpdate; } // namespace proto // Base class for composited layers. Special layer types are derived from @@ -206,7 +196,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void SetScrollParent(Layer* parent); Layer* scroll_parent() { return inputs_.scroll_parent; } - const Layer* scroll_parent() const { return inputs_.scroll_parent; } std::set<Layer*>* scroll_children() { return scroll_children_.get(); } const std::set<Layer*>* scroll_children() const { @@ -216,7 +205,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void SetClipParent(Layer* ancestor); Layer* clip_parent() { return inputs_.clip_parent; } - const Layer* clip_parent() const { return inputs_.clip_parent; } std::set<Layer*>* clip_children() { return clip_children_.get(); } const std::set<Layer*>* clip_children() const { @@ -318,8 +306,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void SetFiltersOrigin(const gfx::PointF& origin); gfx::PointF filters_origin() const { return inputs_.filters_origin; } - bool has_mask() const { return !!inputs_.mask_layer.get(); } - int NumDescendantsThatDrawContent() const; // This is only virtual for tests. @@ -341,6 +327,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { void SetLayerClient(LayerClient* client) { inputs_.client = client; } + virtual bool IsSnapped(); + virtual void PushPropertiesTo(LayerImpl* layer); // Sets the type proto::LayerType that should be used for serialization @@ -358,35 +346,13 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { // hierarchical structure to the given LayerNode proto. In addition to the // structure itself, the Layer id and type is also written to facilitate // construction of the correct layer on the client. - void ToLayerNodeProto(proto::LayerNode* proto) const; - - // Recursively iterate over this layer and all children and reset the - // properties sent with the hierarchical structure in the LayerNode protos. - // This must be done before deserializing the new LayerTree from the Layernode - // protos. - void ClearLayerTreePropertiesForDeserializationAndAddToMap( - LayerIdMap* layer_map); - - // Recursively iterate over the given LayerNode proto and read the structure - // into this node and its children. The |layer_map| should be used to look - // for previously existing Layers, since they should be re-used between each - // hierarchy update. - void FromLayerNodeProto(const proto::LayerNode& proto, - const LayerIdMap& layer_map, - LayerTreeHost* layer_tree_host); + virtual void ToLayerNodeProto(proto::LayerNode* proto) const; // This method is similar to PushPropertiesTo, but instead of pushing to // a LayerImpl, it pushes the properties to proto::LayerProperties. It is // called only on layers that have changed properties. The properties // themselves are pushed to proto::LayerProperties. - void ToLayerPropertiesProto(proto::LayerUpdate* layer_update, - bool inputs_only); - - // Read all property values from the given LayerProperties object and update - // the current layer. The values for |needs_push_properties_| and - // |num_dependents_need_push_properties_| are always updated, but the rest - // of |proto| is only read if |needs_push_properties_| is set. - void FromLayerPropertiesProto(const proto::LayerProperties& proto); + virtual void ToLayerPropertiesProto(proto::LayerProperties* proto); LayerTreeHost* GetLayerTreeHostForTesting() const { return layer_tree_host_; } LayerTree* GetLayerTree() const; @@ -460,8 +426,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { visible_layer_rect_ = rect; } - void set_clip_rect(const gfx::Rect& rect) {} - void SetSubtreePropertyChanged(); bool subtree_property_changed() const { return subtree_property_changed_; } @@ -484,22 +448,39 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { return inputs_.has_will_change_transform_hint; } - AnimationHost* GetAnimationHost() const; + // The preferred raster bounds are the ideal resolution at which to raster the + // contents of this Layer's bitmap. This may not be the same size as the Layer + // bounds, in cases where the contents have an "intrinsic" size that differs. + // Consider for example an image with a given intrinsic size that is being + // scaled into a Layer of a different size. + void SetPreferredRasterBounds(const gfx::Size& preferred_Raster_bounds); + bool has_preferred_raster_bounds() const { + return inputs_.has_preferred_raster_bounds; + } + const gfx::Size& preferred_raster_bounds() const { + return inputs_.preferred_raster_bounds; + } + void ClearPreferredRasterBounds(); + + MutatorHost* GetMutatorHost() const; ElementListType GetElementTypeForAnimation() const; + // Tests in remote mode need to explicitly set the layer id so it matches the + // layer id for the corresponding Layer on the engine. + void SetLayerIdForTesting(int id); + + void SetScrollbarsHiddenFromImplSide(bool hidden); + + const gfx::Rect& update_rect() const { return inputs_.update_rect; } + protected: friend class LayerImpl; friend class TreeSynchronizer; virtual ~Layer(); Layer(); - // Tests in remote mode need to explicitly set the layer id so it matches the - // layer id for the corresponding Layer on the engine. - explicit Layer(int layer_id); - LayerTreeHost* layer_tree_host() { return layer_tree_host_; } - const LayerTreeHost* layer_tree_host() const { return layer_tree_host_; } // These SetNeeds functions are in order of severity of update: // @@ -533,29 +514,13 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { bool IsPropertyChangeAllowed() const; - // Serialize all the necessary properties to be able to reconstruct this Layer - // into proto::LayerProperties. This method is not marked as const - // as some implementations need reset member fields, similarly to - // PushPropertiesTo(). - virtual void LayerSpecificPropertiesToProto(proto::LayerProperties* proto, - bool inputs_only); - - // Deserialize all the necessary properties from proto::LayerProperties into - // this Layer. - virtual void FromLayerSpecificPropertiesProto( - const proto::LayerProperties& proto); - - gfx::Rect& update_rect() { return inputs_.update_rect; } - // 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_; private: friend class base::RefCounted<Layer>; - friend class LayerSerializationTest; friend class LayerTreeHostCommon; - friend class LayerTreeHost; friend class LayerTree; friend class LayerInternalsForTest; @@ -678,6 +643,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { Layer* clip_parent; bool has_will_change_transform_hint : 1; + bool has_preferred_raster_bounds : 1; bool hide_layer_and_subtree : 1; @@ -685,6 +651,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> { LayerClient* client; base::Closure did_scroll_callback; std::vector<std::unique_ptr<CopyOutputRequest>> copy_requests; + + gfx::Size preferred_raster_bounds; }; Layer* parent_; diff --git a/chromium/cc/layers/layer_client.h b/chromium/cc/layers/layer_client.h index f44e4c278fd..165c4367389 100644 --- a/chromium/cc/layers/layer_client.h +++ b/chromium/cc/layers/layer_client.h @@ -31,6 +31,7 @@ class CC_EXPORT LayerClient { virtual std::unique_ptr<base::trace_event::ConvertableToTraceFormat> TakeDebugInfo(Layer* layer) = 0; virtual void didUpdateMainThreadScrollingReasons() = 0; + virtual void didChangeScrollbarsHidden(bool) = 0; protected: virtual ~LayerClient() {} diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc index 46125c2da8e..70d7df70aaf 100644 --- a/chromium/cc/layers/layer_impl.cc +++ b/chromium/cc/layers/layer_impl.cc @@ -16,8 +16,6 @@ #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" -#include "cc/animation/animation_host.h" -#include "cc/animation/mutable_properties.h" #include "cc/base/math_util.h" #include "cc/base/simple_enclosed_region.h" #include "cc/debug/debug_colors.h" @@ -37,6 +35,8 @@ #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/mutable_properties.h" +#include "cc/trees/mutator_host.h" #include "cc/trees/proxy.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" @@ -79,9 +79,10 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl, int id) current_draw_mode_(DRAW_MODE_NONE), mutable_properties_(MutableProperty::kNone), debug_info_(nullptr), - scrolls_drawn_descendant_(false), + has_preferred_raster_bounds_(false), has_will_change_transform_hint_(false), - needs_push_properties_(false) { + needs_push_properties_(false), + scrollbars_hidden_(false) { DCHECK_GT(layer_id_, 0); DCHECK(layer_tree_impl_); @@ -107,8 +108,19 @@ void LayerImpl::SetHasWillChangeTransformHint(bool has_will_change) { has_will_change_transform_hint_ = has_will_change; } -AnimationHost* LayerImpl::GetAnimationHost() const { - return layer_tree_impl_ ? layer_tree_impl_->animation_host() : nullptr; +void LayerImpl::SetPreferredRasterBounds( + const gfx::Size& preferred_raster_bounds) { + has_preferred_raster_bounds_ = true; + preferred_raster_bounds_ = preferred_raster_bounds; +} + +void LayerImpl::ClearPreferredRasterBounds() { + has_preferred_raster_bounds_ = false; + preferred_raster_bounds_ = gfx::Size(); +} + +MutatorHost* LayerImpl::GetMutatorHost() const { + return layer_tree_impl_ ? layer_tree_impl_->mutator_host() : nullptr; } ElementListType LayerImpl::GetElementTypeForAnimation() const { @@ -125,14 +137,7 @@ void LayerImpl::SetDebugInfo( void LayerImpl::DistributeScroll(ScrollState* scroll_state) { ScrollTree& scroll_tree = layer_tree_impl()->property_trees()->scroll_tree; ScrollNode* scroll_node = scroll_tree.Node(scroll_tree_index()); - return scroll_tree.DistributeScroll(scroll_node, scroll_state); -} - -void LayerImpl::ApplyScroll(ScrollState* scroll_state) { - DCHECK(scroll_state); - ScrollNode* node = layer_tree_impl()->property_trees()->scroll_tree.Node( - scroll_tree_index()); - layer_tree_impl()->ApplyScroll(node, scroll_state); + scroll_tree.DistributeScroll(scroll_node, scroll_state); } void LayerImpl::SetTransformTreeIndex(int index) { @@ -317,6 +322,10 @@ std::unique_ptr<LayerImpl> LayerImpl::CreateLayerImpl( return LayerImpl::Create(tree_impl, layer_id_); } +bool LayerImpl::IsSnapped() { + return scrollable(); +} + void LayerImpl::PushPropertiesTo(LayerImpl* layer) { DCHECK(layer->IsActive()); @@ -346,6 +355,7 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) { layer->scroll_tree_index_ = scroll_tree_index_; layer->sorting_context_id_ = sorting_context_id_; layer->has_will_change_transform_hint_ = has_will_change_transform_hint_; + layer->scrollbars_hidden_ = scrollbars_hidden_; if (layer_property_changed_) { layer->layer_tree_impl()->set_needs_update_draw_properties(); @@ -697,12 +707,12 @@ SkColor LayerImpl::SafeOpaqueBackgroundColor() const { } bool LayerImpl::FilterIsAnimating() const { - return GetAnimationHost()->IsAnimatingFilterProperty( + return GetMutatorHost()->IsAnimatingFilterProperty( element_id(), GetElementTypeForAnimation()); } bool LayerImpl::HasPotentiallyRunningFilterAnimation() const { - return GetAnimationHost()->HasPotentiallyRunningFilterAnimation( + return GetMutatorHost()->HasPotentiallyRunningFilterAnimation( element_id(), GetElementTypeForAnimation()); } @@ -768,49 +778,49 @@ void LayerImpl::Set3dSortingContextId(int id) { } bool LayerImpl::TransformIsAnimating() const { - return GetAnimationHost()->IsAnimatingTransformProperty( + return GetMutatorHost()->IsAnimatingTransformProperty( element_id(), GetElementTypeForAnimation()); } bool LayerImpl::HasPotentiallyRunningTransformAnimation() const { - return GetAnimationHost()->HasPotentiallyRunningTransformAnimation( + return GetMutatorHost()->HasPotentiallyRunningTransformAnimation( element_id(), GetElementTypeForAnimation()); } bool LayerImpl::HasOnlyTranslationTransforms() const { - return GetAnimationHost()->HasOnlyTranslationTransforms( + return GetMutatorHost()->HasOnlyTranslationTransforms( element_id(), GetElementTypeForAnimation()); } bool LayerImpl::HasAnyAnimationTargetingProperty( TargetProperty::Type property) const { - return GetAnimationHost()->HasAnyAnimationTargetingProperty(element_id(), - property); + return GetMutatorHost()->HasAnyAnimationTargetingProperty(element_id(), + property); } bool LayerImpl::HasFilterAnimationThatInflatesBounds() const { - return GetAnimationHost()->HasFilterAnimationThatInflatesBounds(element_id()); + return GetMutatorHost()->HasFilterAnimationThatInflatesBounds(element_id()); } bool LayerImpl::HasTransformAnimationThatInflatesBounds() const { - return GetAnimationHost()->HasTransformAnimationThatInflatesBounds( + return GetMutatorHost()->HasTransformAnimationThatInflatesBounds( element_id()); } bool LayerImpl::HasAnimationThatInflatesBounds() const { - return GetAnimationHost()->HasAnimationThatInflatesBounds(element_id()); + return GetMutatorHost()->HasAnimationThatInflatesBounds(element_id()); } bool LayerImpl::FilterAnimationBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) const { - return GetAnimationHost()->FilterAnimationBoundsForBox(element_id(), box, - bounds); + return GetMutatorHost()->FilterAnimationBoundsForBox(element_id(), box, + bounds); } bool LayerImpl::TransformAnimationBoundsForBox(const gfx::BoxF& box, gfx::BoxF* bounds) const { - return GetAnimationHost()->TransformAnimationBoundsForBox(element_id(), box, - bounds); + return GetMutatorHost()->TransformAnimationBoundsForBox(element_id(), box, + bounds); } void LayerImpl::SetUpdateRect(const gfx::Rect& update_rect) { diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h index 9f0a8b1723a..1e522beea9a 100644 --- a/chromium/cc/layers/layer_impl.h +++ b/chromium/cc/layers/layer_impl.h @@ -18,8 +18,6 @@ #include "base/macros.h" #include "base/memory/ptr_util.h" #include "base/values.h" -#include "cc/animation/element_id.h" -#include "cc/animation/target_property.h" #include "cc/base/cc_export.h" #include "cc/base/region.h" #include "cc/base/synced_property.h" @@ -33,7 +31,9 @@ #include "cc/quads/shared_quad_state.h" #include "cc/resources/resource_provider.h" #include "cc/tiles/tile_priority.h" +#include "cc/trees/element_id.h" #include "cc/trees/mutator_host_client.h" +#include "cc/trees/target_property.h" #include "third_party/skia/include/core/SkColor.h" #include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/geometry/point3_f.h" @@ -52,20 +52,14 @@ class DictionaryValue; namespace cc { -class AnimationHost; -class LayerTreeHostImpl; class LayerTreeImpl; class MicroBenchmarkImpl; -class Occlusion; -class EffectTree; +class MutatorHost; class PrioritizedTile; class RenderPass; -class RenderPassId; -class Renderer; class ScrollbarLayerImplBase; class SimpleEnclosedRegion; class Tile; -class TransformTree; class ScrollState; struct AppendQuadsData; @@ -98,7 +92,6 @@ class CC_EXPORT LayerImpl { bool IsActive() const; void DistributeScroll(ScrollState* scroll_state); - void ApplyScroll(ScrollState* scroll_state); void set_property_tree_sequence_number(int sequence_number) {} @@ -388,6 +381,7 @@ class CC_EXPORT LayerImpl { virtual void RecreateTileResources(); virtual std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl); + virtual bool IsSnapped(); virtual void PushPropertiesTo(LayerImpl* layer); virtual void GetAllPrioritizedTilesForTracing( @@ -423,12 +417,6 @@ class CC_EXPORT LayerImpl { virtual gfx::Rect GetEnclosingRectInTargetSpace() const; - void set_scrolls_drawn_descendant(bool scrolls_drawn_descendant) { - scrolls_drawn_descendant_ = scrolls_drawn_descendant; - } - - bool scrolls_drawn_descendant() { return scrolls_drawn_descendant_; } - int num_copy_requests_in_target_subtree(); void UpdatePropertyTreeForScrollingAndAnimationIfNeeded(); @@ -452,7 +440,16 @@ class CC_EXPORT LayerImpl { return has_will_change_transform_hint_; } - AnimationHost* GetAnimationHost() const; + void SetPreferredRasterBounds(const gfx::Size& preferred_raster_bounds); + bool has_preferred_raster_bounds() const { + return has_preferred_raster_bounds_; + } + const gfx::Size& preferred_raster_scale() const { + return preferred_raster_bounds_; + } + void ClearPreferredRasterBounds(); + + MutatorHost* GetMutatorHost() const; ElementListType GetElementTypeForAnimation() const; @@ -567,11 +564,17 @@ class CC_EXPORT LayerImpl { std::unique_ptr<base::trace_event::ConvertableToTraceFormat> owned_debug_info_; base::trace_event::ConvertableToTraceFormat* debug_info_; + // TODO(http://crbug.com/557160): EffectNode instead of LayerImpl should + // own RenderSurfaceImpl. Currently SPv2 creates dummy layers for the sole + // purpose of holding a render surface. Once done, remember to remove dummy + // layers from PaintArtifactCompositor as well std::unique_ptr<RenderSurfaceImpl> render_surface_; + gfx::Size preferred_raster_bounds_; - bool scrolls_drawn_descendant_ : 1; + bool has_preferred_raster_bounds_ : 1; bool has_will_change_transform_hint_ : 1; bool needs_push_properties_ : 1; + bool scrollbars_hidden_ : 1; DISALLOW_COPY_AND_ASSIGN(LayerImpl); }; diff --git a/chromium/cc/layers/layer_impl_unittest.cc b/chromium/cc/layers/layer_impl_unittest.cc index 89de6f89fef..174f2e2ce4f 100644 --- a/chromium/cc/layers/layer_impl_unittest.cc +++ b/chromium/cc/layers/layer_impl_unittest.cc @@ -4,7 +4,6 @@ #include "cc/layers/layer_impl.h" -#include "cc/animation/mutable_properties.h" #include "cc/layers/painted_scrollbar_layer_impl.h" #include "cc/layers/solid_color_scrollbar_layer_impl.h" #include "cc/output/filter_operation.h" @@ -14,9 +13,9 @@ #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_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/mutable_properties.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/tree_synchronizer.h" #include "testing/gmock/include/gmock/gmock.h" @@ -124,12 +123,10 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { // The constructor on this will fake that we are on the correct thread. // Create a simple LayerImpl tree: FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); std::unique_ptr<LayerImpl> root_clip_ptr = @@ -244,12 +241,10 @@ TEST(LayerImplTest, VerifyLayerChangesAreTrackedProperly) { TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); host_impl.active_tree()->SetRootLayerForTesting( @@ -374,12 +369,10 @@ TEST(LayerImplTest, VerifyNeedsUpdateDrawProperties) { TEST(LayerImplTest, SafeOpaqueBackgroundColor) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); host_impl.active_tree()->SetRootLayerForTesting( @@ -417,7 +410,6 @@ class LayerImplScrollTest : public testing::Test { LayerImplScrollTest() : host_impl_(settings(), &task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_), root_id_(7) { host_impl_.active_tree()->SetRootLayerForTesting( @@ -455,13 +447,11 @@ class LayerImplScrollTest : public testing::Test { LayerTreeSettings settings() { LayerTreeSettings settings; settings.verify_clip_tree_calculations = true; - settings.verify_transform_tree_calculations = true; return settings; } private: FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; int root_id_; diff --git a/chromium/cc/layers/layer_iterator_unittest.cc b/chromium/cc/layers/layer_iterator_unittest.cc index eb7db0754d4..ea51d6fd735 100644 --- a/chromium/cc/layers/layer_iterator_unittest.cc +++ b/chromium/cc/layers/layer_iterator_unittest.cc @@ -94,10 +94,7 @@ void IterateFrontToBack(LayerImplList* render_surface_layer_list) { class LayerIteratorTest : public testing::Test { public: LayerIteratorTest() - : host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_), - id_(1) {} + : host_impl_(&task_runner_provider_, &task_graph_runner_), id_(1) {} std::unique_ptr<TestLayerImpl> CreateLayer() { return TestLayerImpl::Create(host_impl_.active_tree(), id_++); @@ -105,7 +102,6 @@ class LayerIteratorTest : public testing::Test { protected: FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; diff --git a/chromium/cc/layers/layer_list_iterator.h b/chromium/cc/layers/layer_list_iterator.h index 948ec25ea64..bde0ffb3282 100644 --- a/chromium/cc/layers/layer_list_iterator.h +++ b/chromium/cc/layers/layer_list_iterator.h @@ -12,7 +12,6 @@ namespace cc { -class Layer; class LayerImpl; // Unlike LayerIterator and friends, these iterators are not intended to permit diff --git a/chromium/cc/layers/layer_list_iterator_unittest.cc b/chromium/cc/layers/layer_list_iterator_unittest.cc index d69a9ff959c..38cedf5c7da 100644 --- a/chromium/cc/layers/layer_list_iterator_unittest.cc +++ b/chromium/cc/layers/layer_list_iterator_unittest.cc @@ -7,11 +7,11 @@ #include <memory> #include "base/containers/adapters.h" +#include "cc/animation/animation_host.h" #include "cc/test/fake_compositor_frame_sink.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_impl.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" #include "testing/gtest/include/gtest/gtest.h" @@ -25,8 +25,9 @@ TEST(LayerListIteratorTest, VerifyTraversalOrder) { // Unfortunate preamble. FakeLayerTreeHostClient client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host_ptr = - FakeLayerTreeHost::Create(&client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( + &client, &task_graph_runner, animation_host.get()); FakeLayerTreeHost* host = host_ptr.get(); // This test constructs the following tree. @@ -77,8 +78,9 @@ TEST(LayerListIteratorTest, VerifySingleLayer) { // Unfortunate preamble. FakeLayerTreeHostClient client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host_ptr = - FakeLayerTreeHost::Create(&client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( + &client, &task_graph_runner, animation_host.get()); FakeLayerTreeHost* host = host_ptr.get(); // This test constructs a tree consisting of a single layer. @@ -110,8 +112,9 @@ TEST(LayerListReverseIteratorTest, VerifyTraversalOrder) { // Unfortunate preamble. FakeLayerTreeHostClient client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host_ptr = - FakeLayerTreeHost::Create(&client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( + &client, &task_graph_runner, animation_host.get()); FakeLayerTreeHost* host = host_ptr.get(); // This test constructs the following tree. @@ -164,8 +167,9 @@ TEST(LayerListReverseIteratorTest, VerifySingleLayer) { // Unfortunate preamble. FakeLayerTreeHostClient client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host_ptr = - FakeLayerTreeHost::Create(&client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host_ptr = FakeLayerTreeHost::Create( + &client, &task_graph_runner, animation_host.get()); FakeLayerTreeHost* host = host_ptr.get(); // This test constructs a tree consisting of a single layer. @@ -198,12 +202,10 @@ TEST(LayerListReverseIteratorTest, VerifyNullFirstLayer) { TEST(LayerListIteratorTest, VerifyTraversalOrderImpl) { // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); @@ -253,12 +255,10 @@ TEST(LayerListIteratorTest, VerifyTraversalOrderImpl) { TEST(LayerListIteratorTest, VerifySingleLayerImpl) { // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); @@ -290,12 +290,10 @@ TEST(LayerListIteratorTest, VerifyNullFirstLayerImpl) { TEST(LayerListReverseIteratorTest, VerifyTraversalOrderImpl) { // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); @@ -347,12 +345,10 @@ TEST(LayerListReverseIteratorTest, VerifyTraversalOrderImpl) { TEST(LayerListReverseIteratorTest, VerifySingleLayerImpl) { // Unfortunate preamble. FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); diff --git a/chromium/cc/layers/layer_perftest.cc b/chromium/cc/layers/layer_perftest.cc index df5e52636b2..adb86ece63e 100644 --- a/chromium/cc/layers/layer_perftest.cc +++ b/chromium/cc/layers/layer_perftest.cc @@ -5,6 +5,7 @@ #include "cc/layers/layer.h" #include "base/threading/thread_task_runner_handle.h" +#include "cc/animation/animation_host.h" #include "cc/debug/lap_timer.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host.h" @@ -25,17 +26,16 @@ static const int kTimeCheckInterval = 10; class LayerPerfTest : public testing::Test { public: LayerPerfTest() - : host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_), + : host_impl_(&task_runner_provider_, &task_graph_runner_), timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), kTimeCheckInterval) {} protected: void SetUp() override { - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + layer_tree_host_ = FakeLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host_.get()); layer_tree_host_->InitializeSingleThreaded( &single_thread_client_, base::ThreadTaskRunnerHandle::Get()); } @@ -46,12 +46,12 @@ class LayerPerfTest : public testing::Test { } FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; StubLayerTreeHostSingleThreadClient single_thread_client_; FakeLayerTreeHostClient fake_client_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; LapTimer timer_; }; diff --git a/chromium/cc/layers/layer_position_constraint_unittest.cc b/chromium/cc/layers/layer_position_constraint_unittest.cc index 842d20b6549..b4bea8e2c44 100644 --- a/chromium/cc/layers/layer_position_constraint_unittest.cc +++ b/chromium/cc/layers/layer_position_constraint_unittest.cc @@ -6,6 +6,7 @@ #include <vector> +#include "cc/animation/animation_host.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" #include "cc/proto/layer_position_constraint.pb.h" @@ -61,8 +62,10 @@ void ExecuteCalculateDrawProperties(LayerImpl* root_layer) { class LayerPositionConstraintTest : public testing::Test { public: LayerPositionConstraintTest() - : layer_tree_host_( - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_)), + : animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)), + layer_tree_host_(FakeLayerTreeHost::Create(&fake_client_, + &task_graph_runner_, + animation_host_.get())), root_impl_(nullptr), inner_viewport_container_layer_impl_(nullptr), scroll_layer_impl_(nullptr), @@ -170,6 +173,7 @@ class LayerPositionConstraintTest : public testing::Test { protected: FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; scoped_refptr<Layer> root_; scoped_refptr<Layer> inner_viewport_container_layer_; diff --git a/chromium/cc/layers/layer_proto_converter.cc b/chromium/cc/layers/layer_proto_converter.cc deleted file mode 100644 index cf65dfdc7c8..00000000000 --- a/chromium/cc/layers/layer_proto_converter.cc +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2015 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_proto_converter.h" - -#include "base/stl_util.h" -#include "base/trace_event/trace_event.h" -#include "cc/layers/empty_content_layer_client.h" -#include "cc/layers/heads_up_display_layer.h" -#include "cc/layers/layer.h" -#include "cc/layers/picture_layer.h" -#include "cc/layers/solid_color_scrollbar_layer.h" -#include "cc/proto/layer.pb.h" -#include "cc/trees/layer_tree_host.h" -#include "cc/trees/layer_tree_host_common.h" -#include "cc/trees/layer_tree_settings.h" - -namespace cc { - -LayerProtoConverter::LayerProtoConverter() {} - -LayerProtoConverter::~LayerProtoConverter() {} - -// static -scoped_refptr<Layer> LayerProtoConverter::DeserializeLayerHierarchy( - scoped_refptr<Layer> existing_root, - const proto::LayerNode& root_node, - LayerTreeHost* layer_tree_host) { - LayerIdMap layer_id_map; - if (existing_root) { - existing_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &layer_id_map); - } - - scoped_refptr<Layer> new_root = existing_root; - if (!existing_root || - (root_node.has_id() && root_node.id() != existing_root->id())) { - // The root node has changed or there was no root node, - // so find or create the new root. - new_root = FindOrAllocateAndConstruct(root_node, layer_id_map); - } - new_root->FromLayerNodeProto(root_node, layer_id_map, layer_tree_host); - return new_root; -} - -// static -void LayerProtoConverter::SerializeLayerProperties( - LayerTreeHost* host, - proto::LayerUpdate* layer_update) { - TRACE_EVENT0("cc.remote", "LayerProtoConverter::SerializeLayerProperties"); - const bool inputs_only = false; - for (auto* layer : host->GetLayerTree()->LayersThatShouldPushProperties()) - layer->ToLayerPropertiesProto(layer_update, inputs_only); - host->GetLayerTree()->LayersThatShouldPushProperties().clear(); -} - -// static -void LayerProtoConverter::DeserializeLayerProperties( - Layer* existing_root, - const proto::LayerUpdate& layer_update) { - DCHECK(existing_root); - LayerIdMap layer_id_map; - RecursivelyFindAllLayers(existing_root, &layer_id_map); - - for (int i = 0; i < layer_update.layers_size(); ++i) { - const proto::LayerProperties& layer_properties = layer_update.layers(i); - - Layer::LayerIdMap::const_iterator iter = - layer_id_map.find(layer_properties.id()); - DCHECK(iter != layer_id_map.end()); - - iter->second->FromLayerPropertiesProto(layer_properties); - } -} - -// static -void LayerProtoConverter::RecursivelyFindAllLayers(Layer* root_layer, - LayerIdMap* layer_id_map) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - root_layer->GetLayerTree(), - [layer_id_map](Layer* layer) { (*layer_id_map)[layer->id()] = layer; }); -} - -// static -scoped_refptr<Layer> LayerProtoConverter::FindOrAllocateAndConstruct( - const proto::LayerNode& proto, - const Layer::LayerIdMap& layer_id_map) { - DCHECK(proto.has_id()); - Layer::LayerIdMap::const_iterator iter = layer_id_map.find(proto.id()); - if (iter != layer_id_map.end()) - return iter->second; - DCHECK(proto.has_type()); - switch (proto.type()) { - // Fall through and build a base layer. This won't have any special layer - // properties but still maintains the layer hierarchy if we run into a - // layer type we don't support. - case proto::LayerNode::UNKNOWN: - case proto::LayerNode::LAYER: - return Layer::Create().get(); - case proto::LayerNode::PICTURE_LAYER: - return PictureLayer::Create(EmptyContentLayerClient::GetInstance()); - case proto::LayerNode::HEADS_UP_DISPLAY_LAYER: - return HeadsUpDisplayLayer::Create(); - case proto::LayerNode::SOLID_COLOR_SCROLLBAR_LAYER: - // Create and return a SolidColorScrollbarLayer with invalid properties - // (orientation, thumb thickness, starting track, left_side_scroll, layer - // id etc.). - // These properties will be set correctly in the later step when we run - // through LayerTreeHost and deserialize them for each layer. - return SolidColorScrollbarLayer::Create(ScrollbarOrientation::HORIZONTAL, - -1, -1, false, Layer::INVALID_ID); - } - // TODO(nyquist): Add the rest of the necessary LayerTypes. This function - // should not return null. - NOTREACHED(); - return nullptr; -} - -} // namespace cc diff --git a/chromium/cc/layers/layer_proto_converter.h b/chromium/cc/layers/layer_proto_converter.h deleted file mode 100644 index 2ee4593c4f5..00000000000 --- a/chromium/cc/layers/layer_proto_converter.h +++ /dev/null @@ -1,76 +0,0 @@ -// Copyright 2015 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_PROTO_CONVERTER_H_ -#define CC_LAYERS_LAYER_PROTO_CONVERTER_H_ - -#include <unordered_map> - -#include "base/macros.h" -#include "cc/base/cc_export.h" -#include "cc/layers/layer.h" - -namespace cc { - -namespace proto { -class LayerNode; -class LayerUpdate; -} - -// A class to faciliate (de)serialization of a Layer tree to protocol buffers. -class CC_EXPORT LayerProtoConverter { - public: - // Recursively iterate over the given LayerNode proto and read the structure - // into a local Layer structure, re-using existing Layers. returns the new - // root Layer after updating the hierarchy (may be the same as - // |existing_root|). |existing_root| may be null, which might happen during - // the first deserialize. - static scoped_refptr<Layer> DeserializeLayerHierarchy( - const scoped_refptr<Layer> existing_root, - const proto::LayerNode& root_node, - LayerTreeHost* layer_tree); - - // Serializes the properties of all the dirty nodes in the Layer hierarchy. - // The proto::LayerUpdate will contain all nodes that are dirty. These nodes - // will contain the list of dirty properties. This function also resets the - // layers that need push properties set. - static void SerializeLayerProperties(LayerTreeHost* host, - proto::LayerUpdate* layer_update); - - // Iterate over all updated layers from the LayerUpdate, and update the - // local Layers. |existing_root| must not be null, as that will make it - // impossible to find the layer to apply the properties to. - static void DeserializeLayerProperties( - Layer* existing_root, - const proto::LayerUpdate& layer_update); - - // Returns the Layer with proto.id() as the Layer id, if it exists in - // |layer_id_map|. Otherwise, a new Layer is constructed of the type given - // from proto.type(). - static scoped_refptr<Layer> FindOrAllocateAndConstruct( - const proto::LayerNode& proto, - const Layer::LayerIdMap& layer_id_map); - - private: - LayerProtoConverter(); - ~LayerProtoConverter(); - - // This method is the inner recursive function for SerializeLayerProperties - // declared above. - static void RecursivelySerializeLayerProperties( - Layer* root_layer, - proto::LayerUpdate* layer_update); - - using LayerIdMap = std::unordered_map<int, scoped_refptr<Layer>>; - // Start at |root_layer| and recursively add the layer and all its children - // and special layers to |layer_id_map|. - // TODO(vmpstr): LayerIdMap ref counts layers, so this function needs to deal - // with ref counted objects instead of iterating over raw pointers. - static void RecursivelyFindAllLayers(Layer* root_layer, - LayerIdMap* layer_id_map); -}; - -} // namespace cc - -#endif // CC_LAYERS_LAYER_PROTO_CONVERTER_H_ diff --git a/chromium/cc/layers/layer_proto_converter_unittest.cc b/chromium/cc/layers/layer_proto_converter_unittest.cc deleted file mode 100644 index 04ac5da21cc..00000000000 --- a/chromium/cc/layers/layer_proto_converter_unittest.cc +++ /dev/null @@ -1,383 +0,0 @@ -// Copyright 2015 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_proto_converter.h" - -#include "cc/layers/empty_content_layer_client.h" -#include "cc/layers/heads_up_display_layer.h" -#include "cc/layers/layer.h" -#include "cc/layers/picture_layer.h" -#include "cc/proto/layer.pb.h" -#include "cc/test/fake_layer_tree_host.h" -#include "cc/test/fake_layer_tree_host_client.h" -#include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_settings.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { -class LayerProtoConverterTest : public testing::Test { - protected: - void SetUp() override { - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); - } - - void TearDown() override { - layer_tree_host_->SetRootLayer(nullptr); - layer_tree_host_ = nullptr; - } - - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostClient fake_client_; - std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; -}; - -TEST_F(LayerProtoConverterTest, TestKeepingRoot) { - /* Test deserialization of a tree that looks like: - root - / \ - a b - \ - c - The old root node will be reused during deserialization. - */ - scoped_refptr<Layer> old_root = Layer::Create(); - proto::LayerNode root_node; - root_node.set_id(old_root->id()); - root_node.set_type(proto::LayerNode::LAYER); - - proto::LayerNode* child_a_node = root_node.add_children(); - child_a_node->set_id(442); - child_a_node->set_type(proto::LayerNode::LAYER); - child_a_node->set_parent_id(old_root->id()); // root_node - - proto::LayerNode* child_b_node = root_node.add_children(); - child_b_node->set_id(443); - child_b_node->set_type(proto::LayerNode::LAYER); - child_b_node->set_parent_id(old_root->id()); // root_node - - proto::LayerNode* child_c_node = child_b_node->add_children(); - child_c_node->set_id(444); - child_c_node->set_type(proto::LayerNode::LAYER); - child_c_node->set_parent_id(child_b_node->id()); - - scoped_refptr<Layer> new_root = - LayerProtoConverter::DeserializeLayerHierarchy(old_root, root_node, - layer_tree_host_.get()); - - // The new root should not be the same as the old root. - EXPECT_EQ(old_root->id(), new_root->id()); - ASSERT_EQ(2u, new_root->children().size()); - scoped_refptr<Layer> child_a = new_root->children()[0]; - scoped_refptr<Layer> child_b = new_root->children()[1]; - - EXPECT_EQ(child_a_node->id(), child_a->id()); - EXPECT_EQ(child_b_node->id(), child_b->id()); - - EXPECT_EQ(0u, child_a->children().size()); - ASSERT_EQ(1u, child_b->children().size()); - - scoped_refptr<Layer> child_c = child_b->children()[0]; - EXPECT_EQ(child_c_node->id(), child_c->id()); - - new_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerProtoConverterTest, TestNoExistingRoot) { - /* Test deserialization of a tree that looks like: - root - / - a - There is no existing root node before serialization. - */ - int new_root_id = 244; - proto::LayerNode root_node; - root_node.set_id(new_root_id); - root_node.set_type(proto::LayerNode::LAYER); - - proto::LayerNode* child_a_node = root_node.add_children(); - child_a_node->set_id(442); - child_a_node->set_type(proto::LayerNode::LAYER); - child_a_node->set_parent_id(new_root_id); // root_node - - scoped_refptr<Layer> new_root = - LayerProtoConverter::DeserializeLayerHierarchy(nullptr, root_node, - layer_tree_host_.get()); - - // The new root should not be the same as the old root. - EXPECT_EQ(new_root_id, new_root->id()); - ASSERT_EQ(1u, new_root->children().size()); - scoped_refptr<Layer> child_a = new_root->children()[0]; - - EXPECT_EQ(child_a_node->id(), child_a->id()); - EXPECT_EQ(0u, child_a->children().size()); - - new_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerProtoConverterTest, TestSwappingRoot) { - /* Test deserialization of a tree that looks like: - root - / \ - a b - \ - c - The old root node will be swapped out during deserialization. - */ - proto::LayerNode root_node; - root_node.set_id(441); - root_node.set_type(proto::LayerNode::LAYER); - - proto::LayerNode* child_a_node = root_node.add_children(); - child_a_node->set_id(442); - child_a_node->set_type(proto::LayerNode::LAYER); - child_a_node->set_parent_id(root_node.id()); - - proto::LayerNode* child_b_node = root_node.add_children(); - child_b_node->set_id(443); - child_b_node->set_type(proto::LayerNode::LAYER); - child_b_node->set_parent_id(root_node.id()); - - proto::LayerNode* child_c_node = child_b_node->add_children(); - child_c_node->set_id(444); - child_c_node->set_type(proto::LayerNode::LAYER); - child_c_node->set_parent_id(child_b_node->id()); - - scoped_refptr<Layer> old_root = Layer::Create(); - scoped_refptr<Layer> new_root = - LayerProtoConverter::DeserializeLayerHierarchy(old_root, root_node, - layer_tree_host_.get()); - - // The new root should not be the same as the old root. - EXPECT_EQ(root_node.id(), new_root->id()); - ASSERT_EQ(2u, new_root->children().size()); - scoped_refptr<Layer> child_a = new_root->children()[0]; - scoped_refptr<Layer> child_b = new_root->children()[1]; - - EXPECT_EQ(child_a_node->id(), child_a->id()); - EXPECT_EQ(child_b_node->id(), child_b->id()); - - EXPECT_EQ(0u, child_a->children().size()); - ASSERT_EQ(1u, child_b->children().size()); - - scoped_refptr<Layer> child_c = child_b->children()[0]; - EXPECT_EQ(child_c_node->id(), child_c->id()); - - new_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerProtoConverterTest, RecursivePropertiesSerialization) { - /* Testing serialization of properties for a tree that looks like this: - root+ - / \ - a* b*+[mask:*] - / \ - c d* - Layers marked with * have changed properties. - Layers marked with + have descendants with changed properties. - Layer b also has a mask layer layer. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_b_mask = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - scoped_refptr<Layer> layer_src_d = Layer::Create(); - layer_src_root->SetLayerTreeHost(layer_tree_host_.get()); - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - layer_src_a->AddChild(layer_src_c); - layer_src_b->AddChild(layer_src_d); - layer_src_b->SetMaskLayer(layer_src_b_mask.get()); - - proto::LayerUpdate layer_update; - LayerProtoConverter::SerializeLayerProperties( - layer_src_root->GetLayerTreeHostForTesting(), &layer_update); - - // All flags for pushing properties should have been cleared. - EXPECT_FALSE( - layer_src_root->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_root.get())); - EXPECT_FALSE(layer_src_a->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_a.get())); - EXPECT_FALSE(layer_src_b->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_b.get())); - EXPECT_FALSE( - layer_src_b_mask->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_b_mask.get())); - EXPECT_FALSE(layer_src_c->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_c.get())); - EXPECT_FALSE(layer_src_d->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_d.get())); - - // All layers needs to push properties as their layer tree host changed. - ASSERT_EQ(6, layer_update.layers_size()); - layer_update.Clear(); - - std::unordered_set<int> dirty_layer_ids; - layer_src_a->SetNeedsPushProperties(); - dirty_layer_ids.insert(layer_src_a->id()); - layer_src_b->SetNeedsPushProperties(); - dirty_layer_ids.insert(layer_src_b->id()); - layer_src_b_mask->SetNeedsPushProperties(); - dirty_layer_ids.insert(layer_src_b_mask->id()); - layer_src_d->SetNeedsPushProperties(); - dirty_layer_ids.insert(layer_src_d->id()); - - LayerProtoConverter::SerializeLayerProperties( - layer_src_root->GetLayerTreeHostForTesting(), &layer_update); - - // All flags for pushing properties should have been cleared. - EXPECT_FALSE( - layer_src_root->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_root.get())); - EXPECT_FALSE(layer_src_a->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_a.get())); - EXPECT_FALSE(layer_src_b->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_b.get())); - EXPECT_FALSE( - layer_src_b_mask->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_b_mask.get())); - EXPECT_FALSE(layer_src_c->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_c.get())); - EXPECT_FALSE(layer_src_d->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_d.get())); - - // Only 4 of the layers should have been serialized. - ASSERT_EQ(4, layer_update.layers_size()); - for (int index = 0; index < layer_update.layers_size(); index++) - EXPECT_NE(dirty_layer_ids.find(layer_update.layers(index).id()), - dirty_layer_ids.end()); - layer_src_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerProtoConverterTest, RecursivePropertiesSerializationSingleChild) { - /* Testing serialization of properties for a tree that looks like this: - root+ - \ - b*+[mask:*] - \ - c - Layers marked with * have changed properties. - Layers marked with + have descendants with changed properties. - Layer b also has a mask layer. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_b_mask = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - layer_src_root->AddChild(layer_src_b); - layer_src_b->AddChild(layer_src_c); - layer_src_b->SetMaskLayer(layer_src_b_mask.get()); - layer_src_root->SetLayerTreeHost(layer_tree_host_.get()); - - proto::LayerUpdate layer_update; - LayerProtoConverter::SerializeLayerProperties( - layer_src_root->GetLayerTreeHostForTesting(), &layer_update); - // All layers need to push properties as their layer tree host changed. - ASSERT_EQ(4, layer_update.layers_size()); - layer_update.Clear(); - - std::unordered_set<int> dirty_layer_ids; - layer_src_b->SetNeedsPushProperties(); - dirty_layer_ids.insert(layer_src_b->id()); - layer_src_b_mask->SetNeedsPushProperties(); - dirty_layer_ids.insert(layer_src_b_mask->id()); - - LayerProtoConverter::SerializeLayerProperties( - layer_src_root->GetLayerTreeHostForTesting(), &layer_update); - - // All flags for pushing properties should have been cleared. - EXPECT_FALSE( - layer_src_root->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_root.get())); - EXPECT_FALSE(layer_src_b->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_b.get())); - EXPECT_FALSE( - layer_src_b_mask->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_b_mask.get())); - EXPECT_FALSE(layer_src_c->GetLayerTree()->LayerNeedsPushPropertiesForTesting( - layer_src_c.get())); - - // Only 2 of the layers should have been serialized. - ASSERT_EQ(2, layer_update.layers_size()); - for (int index = 0; index < layer_update.layers_size(); index++) - EXPECT_NE(dirty_layer_ids.find(layer_update.layers(index).id()), - dirty_layer_ids.end()); - layer_src_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerProtoConverterTest, PictureLayerTypeSerialization) { - // Make sure that PictureLayers serialize to the - // proto::LayerType::PICTURE_LAYER type. - scoped_refptr<PictureLayer> layer = - PictureLayer::Create(EmptyContentLayerClient::GetInstance()); - - proto::LayerNode layer_hierarchy; - layer->ToLayerNodeProto(&layer_hierarchy); - EXPECT_EQ(proto::LayerNode::PICTURE_LAYER, layer_hierarchy.type()); -} - -TEST_F(LayerProtoConverterTest, PictureLayerTypeDeserialization) { - // Make sure that proto::LayerType::PICTURE_LAYER ends up building a - // PictureLayer. - scoped_refptr<Layer> old_root = - PictureLayer::Create(EmptyContentLayerClient::GetInstance()); - proto::LayerNode root_node; - root_node.set_id(old_root->id()); - root_node.set_type(proto::LayerNode::PICTURE_LAYER); - - scoped_refptr<Layer> new_root = - LayerProtoConverter::DeserializeLayerHierarchy(old_root, root_node, - layer_tree_host_.get()); - - // Validate that the ids are equal. - EXPECT_EQ(old_root->id(), new_root->id()); - - // Check that the layer type is equal by using the type this layer would - // serialize to. - proto::LayerNode layer_node; - new_root->SetTypeForProtoSerialization(&layer_node); - EXPECT_EQ(proto::LayerNode::PICTURE_LAYER, layer_node.type()); - - new_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerProtoConverterTest, HudLayerTypeSerialization) { - // Make sure that PictureLayers serialize to the - // proto::LayerType::HEADS_UP_DISPLAY_LAYER type. - scoped_refptr<HeadsUpDisplayLayer> layer = HeadsUpDisplayLayer::Create(); - - proto::LayerNode layer_hierarchy; - layer->ToLayerNodeProto(&layer_hierarchy); - EXPECT_EQ(proto::LayerNode::HEADS_UP_DISPLAY_LAYER, layer_hierarchy.type()); -} - -TEST_F(LayerProtoConverterTest, HudLayerTypeDeserialization) { - // Make sure that proto::LayerType::HEADS_UP_DISPLAY_LAYER ends up building a - // HeadsUpDisplayLayer. - scoped_refptr<Layer> old_root = HeadsUpDisplayLayer::Create(); - proto::LayerNode root_node; - root_node.set_id(old_root->id()); - root_node.set_type(proto::LayerNode::HEADS_UP_DISPLAY_LAYER); - - scoped_refptr<Layer> new_root = - LayerProtoConverter::DeserializeLayerHierarchy(old_root, root_node, - layer_tree_host_.get()); - - // Validate that the ids are equal. - EXPECT_EQ(old_root->id(), new_root->id()); - - // Check that the layer type is equal by using the type this layer would - // serialize to. - proto::LayerNode layer_node; - new_root->SetTypeForProtoSerialization(&layer_node); - EXPECT_EQ(proto::LayerNode::HEADS_UP_DISPLAY_LAYER, layer_node.type()); - - new_root->SetLayerTreeHost(nullptr); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/layers/layer_sticky_position_constraint.cc b/chromium/cc/layers/layer_sticky_position_constraint.cc index 0fc0af84a8e..2b6b33295db 100644 --- a/chromium/cc/layers/layer_sticky_position_constraint.cc +++ b/chromium/cc/layers/layer_sticky_position_constraint.cc @@ -30,6 +30,8 @@ LayerStickyPositionConstraint::LayerStickyPositionConstraint( right_offset(other.right_offset), top_offset(other.top_offset), bottom_offset(other.bottom_offset), + parent_relative_sticky_box_offset( + other.parent_relative_sticky_box_offset), scroll_container_relative_sticky_box_rect( other.scroll_container_relative_sticky_box_rect), scroll_container_relative_containing_block_rect( @@ -46,6 +48,8 @@ void LayerStickyPositionConstraint::ToProtobuf( proto->set_right_offset(right_offset); proto->set_top_offset(top_offset); proto->set_bottom_offset(bottom_offset); + PointToProto(parent_relative_sticky_box_offset, + proto->mutable_parent_relative_sticky_box_offset()); RectToProto(scroll_container_relative_sticky_box_rect, proto->mutable_scroll_container_relative_sticky_box_rect()); RectToProto(scroll_container_relative_containing_block_rect, @@ -63,6 +67,8 @@ void LayerStickyPositionConstraint::FromProtobuf( right_offset = proto.right_offset(); top_offset = proto.top_offset(); bottom_offset = proto.bottom_offset(); + parent_relative_sticky_box_offset = + ProtoToPoint(proto.parent_relative_sticky_box_offset()); scroll_container_relative_sticky_box_rect = ProtoToRect(proto.scroll_container_relative_sticky_box_rect()); scroll_container_relative_containing_block_rect = @@ -81,6 +87,8 @@ bool LayerStickyPositionConstraint::operator==( left_offset == other.left_offset && right_offset == other.right_offset && top_offset == other.top_offset && bottom_offset == other.bottom_offset && + parent_relative_sticky_box_offset == + other.parent_relative_sticky_box_offset && scroll_container_relative_sticky_box_rect == other.scroll_container_relative_sticky_box_rect && scroll_container_relative_containing_block_rect == diff --git a/chromium/cc/layers/layer_sticky_position_constraint.h b/chromium/cc/layers/layer_sticky_position_constraint.h index b575a23aa26..51a4da0c0b2 100644 --- a/chromium/cc/layers/layer_sticky_position_constraint.h +++ b/chromium/cc/layers/layer_sticky_position_constraint.h @@ -32,6 +32,11 @@ struct CC_EXPORT LayerStickyPositionConstraint { float top_offset; float bottom_offset; + // The layout offset of the sticky box relative to its containing layer. + // This is used to detect the sticky offset the main thread has applied + // to the layer. + gfx::Point parent_relative_sticky_box_offset; + // The rectangle corresponding to original layout position of the sticky box // relative to the scroll ancestor. The sticky box is only offset once the // scroll has passed its initial position (e.g. top_offset will only push diff --git a/chromium/cc/layers/layer_unittest.cc b/chromium/cc/layers/layer_unittest.cc index 11d6facce8d..0c2858f5505 100644 --- a/chromium/cc/layers/layer_unittest.cc +++ b/chromium/cc/layers/layer_unittest.cc @@ -10,14 +10,12 @@ #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" #include "cc/animation/keyframed_animation_curve.h" -#include "cc/animation/mutable_properties.h" #include "cc/base/math_util.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/layers/layer_impl.h" #include "cc/layers/solid_color_scrollbar_layer.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" -#include "cc/proto/layer.pb.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host.h" @@ -27,10 +25,9 @@ #include "cc/test/layer_internals_for_test.h" #include "cc/test/layer_test_common.h" #include "cc/test/stub_layer_tree_host_single_thread_client.h" -#include "cc/test/test_gpu_memory_buffer_manager.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host.h" +#include "cc/trees/mutable_properties.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" #include "testing/gmock/include/gmock/gmock.h" @@ -84,799 +81,13 @@ using ::testing::_; namespace cc { -// This class is a friend of Layer, and is used as a wrapper for all the tests -// related to proto serialization. This is done so that it is unnecessary to -// add FRIEND_TEST_ALL_PREFIXES in //cc/layers/layer.h for all the tests. -// It is in the cc namespace so that it can be a friend of Layer. -// The tests still have helpful names, and a test with the name FooBar would -// have a wrapper method in this class called RunFooBarTest. -class LayerSerializationTest : public testing::Test { - protected: - void SetUp() override { - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); - } - - void TearDown() override { - layer_tree_host_->SetRootLayer(nullptr); - layer_tree_host_ = nullptr; - } - - // Serializes |src| to proto and back again to a Layer, then verifies that - // the two Layers are equal for serialization purposes. - void VerifyBaseLayerPropertiesSerializationAndDeserialization(Layer* src) { - // This is required to ensure that properties are serialized. - src->SetNeedsPushProperties(); - src->SetLayerTreeHost(layer_tree_host_.get()); - - // The following member is reset during serialization, so store the original - // values. - gfx::Rect update_rect = src->inputs_.update_rect; - - // Serialize |src| to protobuf and read the first entry in the - // LayerUpdate. There are no descendants, so the serialization - // of |src| is the only entry. - proto::LayerUpdate layer_update; - src->ToLayerPropertiesProto(&layer_update, false); - ASSERT_EQ(1, layer_update.layers_size()); - proto::LayerProperties props = layer_update.layers(0); - - // The |dest| layer needs to be able to lookup the scroll and clip parents. - LayerTree* layer_tree = layer_tree_host_->GetLayerTree(); - if (src->inputs_.scroll_parent) - layer_tree->RegisterLayer(src->inputs_.scroll_parent); - if (src->scroll_children_) { - for (auto* child : *(src->scroll_children_)) - layer_tree->RegisterLayer(child); - } - if (src->inputs_.clip_parent) - layer_tree->RegisterLayer(src->inputs_.clip_parent); - if (src->clip_children_) { - for (auto* child : *(src->clip_children_)) - layer_tree->RegisterLayer(child); - } - // Reset the LayerTreeHost registration for the |src| layer so - // it can be re-used for the |dest| layer. - src->SetLayerTreeHost(nullptr); - - scoped_refptr<Layer> dest = Layer::Create(); - dest->inputs_.layer_id = src->inputs_.layer_id; - dest->SetLayerTreeHost(layer_tree_host_.get()); - dest->FromLayerPropertiesProto(props); - - // Verify that both layers are equal. - EXPECT_EQ(src->inputs_.transform_origin, dest->inputs_.transform_origin); - EXPECT_EQ(src->inputs_.background_color, dest->inputs_.background_color); - EXPECT_EQ(src->inputs_.bounds, dest->inputs_.bounds); - EXPECT_EQ(src->transform_tree_index_, dest->transform_tree_index_); - EXPECT_EQ(src->effect_tree_index_, dest->effect_tree_index_); - EXPECT_EQ(src->clip_tree_index_, dest->clip_tree_index_); - EXPECT_EQ(src->offset_to_transform_parent_, - dest->offset_to_transform_parent_); - EXPECT_EQ(src->inputs_.double_sided, dest->inputs_.double_sided); - EXPECT_EQ(src->draws_content_, dest->draws_content_); - EXPECT_EQ(src->may_contain_video_, dest->may_contain_video_); - EXPECT_EQ(src->inputs_.hide_layer_and_subtree, - dest->inputs_.hide_layer_and_subtree); - EXPECT_EQ(src->inputs_.masks_to_bounds, dest->inputs_.masks_to_bounds); - EXPECT_EQ(src->inputs_.main_thread_scrolling_reasons, - dest->inputs_.main_thread_scrolling_reasons); - EXPECT_EQ(src->inputs_.non_fast_scrollable_region, - dest->inputs_.non_fast_scrollable_region); - EXPECT_EQ(src->inputs_.touch_event_handler_region, - dest->inputs_.touch_event_handler_region); - EXPECT_EQ(src->inputs_.contents_opaque, dest->inputs_.contents_opaque); - EXPECT_EQ(src->inputs_.opacity, dest->inputs_.opacity); - EXPECT_EQ(src->inputs_.blend_mode, dest->inputs_.blend_mode); - EXPECT_EQ(src->inputs_.is_root_for_isolated_group, - dest->inputs_.is_root_for_isolated_group); - EXPECT_EQ(src->inputs_.position, dest->inputs_.position); - EXPECT_EQ(src->inputs_.is_container_for_fixed_position_layers, - dest->inputs_.is_container_for_fixed_position_layers); - EXPECT_EQ(src->inputs_.position_constraint, - dest->inputs_.position_constraint); - EXPECT_EQ(src->inputs_.should_flatten_transform, - dest->inputs_.should_flatten_transform); - EXPECT_EQ(src->should_flatten_transform_from_property_tree_, - dest->should_flatten_transform_from_property_tree_); - EXPECT_EQ(src->draw_blend_mode_, dest->draw_blend_mode_); - EXPECT_EQ(src->inputs_.use_parent_backface_visibility, - dest->inputs_.use_parent_backface_visibility); - EXPECT_EQ(src->inputs_.transform, dest->inputs_.transform); - EXPECT_EQ(src->inputs_.sorting_context_id, - dest->inputs_.sorting_context_id); - EXPECT_EQ(src->num_descendants_that_draw_content_, - dest->num_descendants_that_draw_content_); - EXPECT_EQ(src->inputs_.scroll_clip_layer_id, - dest->inputs_.scroll_clip_layer_id); - EXPECT_EQ(src->inputs_.user_scrollable_horizontal, - dest->inputs_.user_scrollable_horizontal); - EXPECT_EQ(src->inputs_.user_scrollable_vertical, - dest->inputs_.user_scrollable_vertical); - EXPECT_EQ(src->inputs_.scroll_offset, dest->inputs_.scroll_offset); - EXPECT_EQ(update_rect, dest->inputs_.update_rect); - - if (src->inputs_.scroll_parent) { - ASSERT_TRUE(dest->inputs_.scroll_parent); - EXPECT_EQ(src->inputs_.scroll_parent->id(), - dest->inputs_.scroll_parent->id()); - } else { - EXPECT_FALSE(dest->inputs_.scroll_parent); - } - if (src->scroll_children_) { - ASSERT_TRUE(dest->scroll_children_); - EXPECT_EQ(*(src->scroll_children_), *(dest->scroll_children_)); - } else { - EXPECT_FALSE(dest->scroll_children_); - } - - if (src->inputs_.clip_parent) { - ASSERT_TRUE(dest->inputs_.clip_parent); - EXPECT_EQ(src->inputs_.clip_parent->id(), - dest->inputs_.clip_parent->id()); - } else { - ASSERT_FALSE(dest->inputs_.clip_parent); - } - if (src->clip_children_) { - ASSERT_TRUE(dest->clip_children_); - EXPECT_EQ(*(src->clip_children_), *(dest->clip_children_)); - } else { - EXPECT_FALSE(dest->clip_children_); - } - - // The following member should have been reset during serialization. - EXPECT_EQ(gfx::Rect(), src->inputs_.update_rect); - - // Before deleting |dest|, the LayerTreeHost must be unset. - dest->SetLayerTreeHost(nullptr); - - // Cleanup scroll tree. - if (src->inputs_.scroll_parent) - layer_tree->UnregisterLayer(src->inputs_.scroll_parent); - src->inputs_.scroll_parent = nullptr; - dest->inputs_.scroll_parent = nullptr; - if (src->scroll_children_) { - for (auto* child : *(src->scroll_children_)) - layer_tree->UnregisterLayer(child); - src->scroll_children_.reset(); - dest->scroll_children_.reset(); - } - - // Cleanup clip tree. - if (src->inputs_.clip_parent) - layer_tree->UnregisterLayer(src->inputs_.clip_parent); - src->inputs_.clip_parent = nullptr; - dest->inputs_.clip_parent = nullptr; - if (src->clip_children_) { - for (auto* child : *(src->clip_children_)) - layer_tree->UnregisterLayer(child); - src->clip_children_.reset(); - dest->clip_children_.reset(); - } - } - - void RunNoMembersChangedTest() { - scoped_refptr<Layer> layer = Layer::Create(); - VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get()); - } - - void RunArbitraryMembersChangedTest() { - scoped_refptr<Layer> layer = Layer::Create(); - layer->inputs_.transform_origin = gfx::Point3F(3.0f, 1.0f, 4.0f); - layer->inputs_.background_color = SK_ColorRED; - layer->inputs_.bounds = gfx::Size(3, 14); - layer->transform_tree_index_ = -1; - layer->effect_tree_index_ = -1; - layer->clip_tree_index_ = 71; - layer->offset_to_transform_parent_ = gfx::Vector2dF(3.14f, 1.618f); - layer->inputs_.double_sided = true; - layer->draws_content_ = true; - layer->may_contain_video_ = true; - layer->inputs_.hide_layer_and_subtree = false; - layer->inputs_.masks_to_bounds = true; - layer->inputs_.main_thread_scrolling_reasons = - MainThreadScrollingReason::kNotScrollingOnMain; - layer->inputs_.non_fast_scrollable_region = Region(gfx::Rect(5, 1, 14, 3)); - layer->inputs_.touch_event_handler_region = Region(gfx::Rect(3, 14, 1, 5)); - layer->inputs_.contents_opaque = true; - layer->inputs_.opacity = 1.f; - layer->inputs_.blend_mode = SkXfermode::kSrcOver_Mode; - layer->inputs_.is_root_for_isolated_group = true; - layer->inputs_.position = gfx::PointF(3.14f, 6.28f); - layer->inputs_.is_container_for_fixed_position_layers = true; - LayerPositionConstraint pos_con; - pos_con.set_is_fixed_to_bottom_edge(true); - layer->inputs_.position_constraint = pos_con; - layer->inputs_.should_flatten_transform = true; - layer->should_flatten_transform_from_property_tree_ = true; - layer->draw_blend_mode_ = SkXfermode::kSrcOut_Mode; - layer->inputs_.use_parent_backface_visibility = true; - gfx::Transform transform; - transform.Rotate(90); - layer->inputs_.transform = transform; - layer->inputs_.sorting_context_id = 0; - layer->num_descendants_that_draw_content_ = 5; - layer->inputs_.scroll_clip_layer_id = Layer::INVALID_ID; - layer->inputs_.user_scrollable_horizontal = false; - layer->inputs_.user_scrollable_vertical = true; - layer->inputs_.scroll_offset = gfx::ScrollOffset(3, 14); - layer->inputs_.update_rect = gfx::Rect(14, 15); - - VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get()); - } - - void RunAllMembersChangedTest() { - scoped_refptr<Layer> layer = Layer::Create(); - layer->inputs_.transform_origin = gfx::Point3F(3.0f, 1.0f, 4.0f); - layer->inputs_.background_color = SK_ColorRED; - layer->inputs_.bounds = gfx::Size(3, 14); - layer->transform_tree_index_ = 39; - layer->effect_tree_index_ = 17; - layer->clip_tree_index_ = 71; - layer->offset_to_transform_parent_ = gfx::Vector2dF(3.14f, 1.618f); - layer->inputs_.double_sided = !layer->inputs_.double_sided; - layer->draws_content_ = !layer->draws_content_; - layer->may_contain_video_ = !layer->may_contain_video_; - layer->inputs_.hide_layer_and_subtree = - !layer->inputs_.hide_layer_and_subtree; - layer->inputs_.masks_to_bounds = !layer->inputs_.masks_to_bounds; - layer->inputs_.main_thread_scrolling_reasons = - MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects; - layer->inputs_.non_fast_scrollable_region = Region(gfx::Rect(5, 1, 14, 3)); - layer->inputs_.touch_event_handler_region = Region(gfx::Rect(3, 14, 1, 5)); - layer->inputs_.contents_opaque = !layer->inputs_.contents_opaque; - layer->inputs_.opacity = 3.14f; - layer->inputs_.blend_mode = SkXfermode::kSrcIn_Mode; - layer->inputs_.is_root_for_isolated_group = - !layer->inputs_.is_root_for_isolated_group; - layer->inputs_.position = gfx::PointF(3.14f, 6.28f); - layer->inputs_.is_container_for_fixed_position_layers = - !layer->inputs_.is_container_for_fixed_position_layers; - LayerPositionConstraint pos_con; - pos_con.set_is_fixed_to_bottom_edge(true); - layer->inputs_.position_constraint = pos_con; - layer->inputs_.should_flatten_transform = - !layer->inputs_.should_flatten_transform; - layer->should_flatten_transform_from_property_tree_ = - !layer->should_flatten_transform_from_property_tree_; - layer->draw_blend_mode_ = SkXfermode::kSrcOut_Mode; - layer->inputs_.use_parent_backface_visibility = - !layer->inputs_.use_parent_backface_visibility; - gfx::Transform transform; - transform.Rotate(90); - layer->inputs_.transform = transform; - layer->inputs_.sorting_context_id = 42; - layer->num_descendants_that_draw_content_ = 5; - layer->inputs_.scroll_clip_layer_id = 17; - layer->inputs_.user_scrollable_horizontal = - !layer->inputs_.user_scrollable_horizontal; - layer->inputs_.user_scrollable_vertical = - !layer->inputs_.user_scrollable_vertical; - layer->inputs_.scroll_offset = gfx::ScrollOffset(3, 14); - layer->inputs_.update_rect = gfx::Rect(14, 15); - - VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get()); - } - - void VerifySolidColorScrollbarLayerAfterSerializationAndDeserialization( - scoped_refptr<SolidColorScrollbarLayer> source_scrollbar) { - proto::LayerProperties serialized_scrollbar; - source_scrollbar->LayerSpecificPropertiesToProto(&serialized_scrollbar, - false); - - scoped_refptr<SolidColorScrollbarLayer> deserialized_scrollbar = - SolidColorScrollbarLayer::Create(ScrollbarOrientation::HORIZONTAL, -1, - -1, false, Layer::INVALID_ID); - deserialized_scrollbar->inputs_.layer_id = - source_scrollbar->inputs_.layer_id; - - // FromLayerSpecificPropertiesProto expects a non-null LayerTreeHost to be - // set. - deserialized_scrollbar->SetLayerTreeHost(layer_tree_host_.get()); - deserialized_scrollbar->FromLayerSpecificPropertiesProto( - serialized_scrollbar); - - EXPECT_EQ(source_scrollbar->solid_color_scrollbar_layer_inputs_.track_start, - deserialized_scrollbar->solid_color_scrollbar_layer_inputs_ - .track_start); - EXPECT_EQ( - source_scrollbar->solid_color_scrollbar_layer_inputs_.thumb_thickness, - deserialized_scrollbar->solid_color_scrollbar_layer_inputs_ - .thumb_thickness); - EXPECT_EQ( - source_scrollbar->solid_color_scrollbar_layer_inputs_.scroll_layer_id, - deserialized_scrollbar->solid_color_scrollbar_layer_inputs_ - .scroll_layer_id); - EXPECT_EQ(source_scrollbar->solid_color_scrollbar_layer_inputs_ - .is_left_side_vertical_scrollbar, - deserialized_scrollbar->solid_color_scrollbar_layer_inputs_ - .is_left_side_vertical_scrollbar); - EXPECT_EQ(source_scrollbar->solid_color_scrollbar_layer_inputs_.orientation, - deserialized_scrollbar->solid_color_scrollbar_layer_inputs_ - .orientation); - - deserialized_scrollbar->SetLayerTreeHost(nullptr); - } - - void RunScrollAndClipLayersTest() { - scoped_refptr<Layer> layer = Layer::Create(); - - scoped_refptr<Layer> scroll_parent = Layer::Create(); - layer->inputs_.scroll_parent = scroll_parent.get(); - scoped_refptr<Layer> scroll_child = Layer::Create(); - layer->scroll_children_.reset(new std::set<Layer*>); - layer->scroll_children_->insert(scroll_child.get()); - - scoped_refptr<Layer> clip_parent = Layer::Create(); - layer->inputs_.clip_parent = clip_parent.get(); - layer->clip_children_.reset(new std::set<Layer*>); - scoped_refptr<Layer> clip_child1 = Layer::Create(); - layer->clip_children_->insert(clip_child1.get()); - scoped_refptr<Layer> clip_child2 = Layer::Create(); - layer->clip_children_->insert(clip_child2.get()); - - VerifyBaseLayerPropertiesSerializationAndDeserialization(layer.get()); - } - - void RunHierarchyDeserializationWithLayerTreeHostTest() { - /* Testing serialization and deserialization of a tree that looks like this: - root - \ - a - \ - b - \ - c - The root layer has a LayerTreeHost, and it should propagate to all the - children. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - layer_src_a->AddChild(layer_src_b); - layer_src_b->AddChild(layer_src_c); - - proto::LayerNode proto; - layer_src_root->ToLayerNodeProto(&proto); - - Layer::LayerIdMap empty_dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - - layer_dest_root->FromLayerNodeProto(proto, empty_dest_layer_map, - layer_tree_host_.get()); - - EXPECT_EQ(layer_src_root->id(), layer_dest_root->id()); - EXPECT_EQ(nullptr, layer_dest_root->parent()); - ASSERT_EQ(1u, layer_dest_root->children().size()); - EXPECT_EQ(layer_tree_host_.get(), layer_dest_root->layer_tree_host_); - - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(layer_src_root->id(), layer_dest_a->parent()->id()); - EXPECT_EQ(1u, layer_dest_a->children().size()); - EXPECT_EQ(layer_tree_host_.get(), layer_dest_a->layer_tree_host_); - - scoped_refptr<Layer> layer_dest_b = layer_dest_a->children()[0]; - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - EXPECT_EQ(layer_src_a->id(), layer_dest_b->parent()->id()); - ASSERT_EQ(1u, layer_dest_b->children().size()); - EXPECT_EQ(layer_tree_host_.get(), layer_dest_b->layer_tree_host_); - - scoped_refptr<Layer> layer_dest_c = layer_dest_b->children()[0]; - EXPECT_EQ(layer_src_c->id(), layer_dest_c->id()); - EXPECT_EQ(layer_src_b->id(), layer_dest_c->parent()->id()); - EXPECT_EQ(0u, layer_dest_c->children().size()); - EXPECT_EQ(layer_tree_host_.get(), layer_dest_c->layer_tree_host_); - - // The layers have not been added to the LayerTreeHost layer map, so the - // LTH pointers must be cleared manually. - layer_dest_root->layer_tree_host_ = nullptr; - layer_dest_a->layer_tree_host_ = nullptr; - layer_dest_b->layer_tree_host_ = nullptr; - layer_dest_c->layer_tree_host_ = nullptr; - } - - void RunNonDestructiveDeserializationBaseCaseTest() { - /* Testing serialization and deserialization of a tree that initially looks - like this: - root - / - a - The source tree is then deserialized from the same structure which should - re-use the Layers from last deserialization and importantly it should - not have called InvalidatePropertyTreesIndices() for any of the layers, - which would happen in for example SetLayerTreeHost(...) calls. - */ - scoped_refptr<Layer> layer_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - layer_root->AddChild(layer_src_a); - layer_root->transform_tree_index_ = 33; - layer_src_a->transform_tree_index_ = 42; - - proto::LayerNode root_proto; - layer_root->ToLayerNodeProto(&root_proto); - - Layer::LayerIdMap dest_layer_map; - layer_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map); - layer_root->FromLayerNodeProto(root_proto, dest_layer_map, - layer_tree_host_.get()); - - EXPECT_EQ(33, layer_root->transform_tree_index_); - ASSERT_EQ(1u, layer_root->children().size()); - scoped_refptr<Layer> layer_dest_a = layer_root->children()[0]; - EXPECT_EQ(layer_src_a, layer_dest_a); - EXPECT_EQ(42, layer_dest_a->transform_tree_index_); - - // Clear the reference to the LTH for all the layers. - layer_root->SetLayerTreeHost(nullptr); - } - - void RunNonDestructiveDeserializationReorderChildrenTest() { - /* Testing serialization and deserialization of a tree that initially looks - like this: - root - / \ - a b - The children are then re-ordered to: - root - / \ - b a - The tree is then serialized and deserialized again, and the the end - result should have the same structure and importantly it should - not have called InvalidatePropertyTreesIndices() for any of the layers, - which would happen in for example SetLayerTreeHost(...) calls. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - - // Copy tree-structure to new root. - proto::LayerNode root_proto_1; - layer_src_root->ToLayerNodeProto(&root_proto_1); - Layer::LayerIdMap dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(root_proto_1, dest_layer_map, - layer_tree_host_.get()); - - // Ensure initial copy is correct. - ASSERT_EQ(2u, layer_dest_root->children().size()); - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - scoped_refptr<Layer> layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - - // Swap order of the children. - scoped_refptr<Layer> tmp_a = layer_src_root->inputs_.children[0]; - layer_src_root->inputs_.children[0] = layer_src_root->inputs_.children[1]; - layer_src_root->inputs_.children[1] = tmp_a; - - // Fake the fact that the destination layers have valid indexes. - layer_dest_root->transform_tree_index_ = 33; - layer_dest_a->transform_tree_index_ = 42; - layer_dest_b->transform_tree_index_ = 24; - - // Now serialize and deserialize again. - proto::LayerNode root_proto_2; - layer_src_root->ToLayerNodeProto(&root_proto_2); - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map); - layer_dest_root->FromLayerNodeProto(root_proto_2, dest_layer_map, - layer_tree_host_.get()); - - // Ensure second copy is correct. - EXPECT_EQ(33, layer_dest_root->transform_tree_index_); - ASSERT_EQ(2u, layer_dest_root->children().size()); - layer_dest_b = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - EXPECT_EQ(24, layer_dest_b->transform_tree_index_); - layer_dest_a = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(42, layer_dest_a->transform_tree_index_); - - layer_dest_root->SetLayerTreeHost(nullptr); - } - - void RunNonDestructiveDeserializationAddChildTest() { - /* Testing serialization and deserialization of a tree that initially looks - like this: - root - / - a - A child is then added to the root: - root - / \ - b a - The tree is then serialized and deserialized again, and the the end - result should have the same structure and importantly it should - not have called InvalidatePropertyTreesIndices() for any of the layers, - which would happen in for example SetLayerTreeHost(...) calls. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - - // Copy tree-structure to new root. - proto::LayerNode root_proto_1; - layer_src_root->ToLayerNodeProto(&root_proto_1); - Layer::LayerIdMap dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(root_proto_1, dest_layer_map, - layer_tree_host_.get()); - - // Ensure initial copy is correct. - ASSERT_EQ(1u, layer_dest_root->children().size()); - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - - // Fake the fact that the destination layer |a| now has a valid index. - layer_dest_root->transform_tree_index_ = 33; - layer_dest_a->transform_tree_index_ = 42; - - // Add another child. - scoped_refptr<Layer> layer_src_b = Layer::Create(); - layer_src_root->AddChild(layer_src_b); - - // Now serialize and deserialize again. - proto::LayerNode root_proto_2; - layer_src_root->ToLayerNodeProto(&root_proto_2); - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map); - layer_dest_root->FromLayerNodeProto(root_proto_2, dest_layer_map, - layer_tree_host_.get()); - - // Ensure second copy is correct. - EXPECT_EQ(33, layer_dest_root->transform_tree_index_); - ASSERT_EQ(2u, layer_dest_root->children().size()); - layer_dest_a = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(42, layer_dest_a->transform_tree_index_); - scoped_refptr<Layer> layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - - layer_dest_root->SetLayerTreeHost(nullptr); - } - - void RunNonDestructiveDeserializationRemoveChildTest() { - /* Testing serialization and deserialization of a tree that initially looks - like this: - root - / \ - a b - The |b| child is the removed from the root: - root - / - b - The tree is then serialized and deserialized again, and the the end - result should have the same structure and importantly it should - not have called InvalidatePropertyTreesIndices() for any of the layers, - which would happen in for example SetLayerTreeHost(...) calls. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - - // Copy tree-structure to new root. - proto::LayerNode root_proto_1; - layer_src_root->ToLayerNodeProto(&root_proto_1); - Layer::LayerIdMap dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(root_proto_1, dest_layer_map, - layer_tree_host_.get()); - - // Ensure initial copy is correct. - ASSERT_EQ(2u, layer_dest_root->children().size()); - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - scoped_refptr<Layer> layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - - // Remove one child. - layer_src_b->RemoveFromParent(); - - // Fake the fact that the destination layers have valid indexes. - layer_dest_root->transform_tree_index_ = 33; - layer_dest_a->transform_tree_index_ = 42; - layer_dest_b->transform_tree_index_ = 24; - - // Now serialize and deserialize again. - proto::LayerNode root_proto_2; - layer_src_root->ToLayerNodeProto(&root_proto_2); - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map); - layer_dest_root->FromLayerNodeProto(root_proto_2, dest_layer_map, - layer_tree_host_.get()); - - // Ensure second copy is correct. - EXPECT_EQ(33, layer_dest_root->transform_tree_index_); - ASSERT_EQ(1u, layer_dest_root->children().size()); - layer_dest_a = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(42, layer_dest_a->transform_tree_index_); - - layer_dest_root->SetLayerTreeHost(nullptr); - } - - void RunNonDestructiveDeserializationMoveChildEarlierTest() { - /* Testing serialization and deserialization of a tree that initially looks - like this: - root - / \ - a b - \ - c - The |c| child of |b| is then moved to become a child of |a|: - root - / \ - a b - / - c - The tree is then serialized and deserialized again, and the the end - result should have the same structure and importantly it should - not have called InvalidatePropertyTreesIndices() for any of the layers, - which would happen in for example SetLayerTreeHost(...) calls. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - layer_src_b->AddChild(layer_src_c); - - // Copy tree-structure to new root. - proto::LayerNode root_proto_1; - layer_src_root->ToLayerNodeProto(&root_proto_1); - Layer::LayerIdMap dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(root_proto_1, dest_layer_map, - layer_tree_host_.get()); - - // Ensure initial copy is correct. - ASSERT_EQ(2u, layer_dest_root->children().size()); - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - scoped_refptr<Layer> layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - ASSERT_EQ(1u, layer_dest_b->children().size()); - scoped_refptr<Layer> layer_dest_c = layer_dest_b->children()[0]; - EXPECT_EQ(layer_src_c->id(), layer_dest_c->id()); - - // Move child |c| from |b| to |a|. - layer_src_c->RemoveFromParent(); - layer_src_a->AddChild(layer_src_c); - - // Moving a child invalidates the |transform_tree_index_|, so forcefully - // set it afterwards on the destination layer. - layer_dest_root->transform_tree_index_ = 33; - layer_dest_a->transform_tree_index_ = 42; - layer_dest_b->transform_tree_index_ = 24; - layer_dest_c->transform_tree_index_ = 99; - - // Now serialize and deserialize again. - proto::LayerNode root_proto_2; - layer_src_root->ToLayerNodeProto(&root_proto_2); - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map); - layer_dest_root->FromLayerNodeProto(root_proto_2, dest_layer_map, - layer_tree_host_.get()); - - // Ensure second copy is correct. - EXPECT_EQ(33, layer_dest_root->transform_tree_index_); - ASSERT_EQ(2u, layer_dest_root->children().size()); - layer_dest_a = layer_dest_root->children()[0]; - layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(42, layer_dest_a->transform_tree_index_); - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - EXPECT_EQ(24, layer_dest_b->transform_tree_index_); - ASSERT_EQ(1u, layer_dest_a->children().size()); - layer_dest_c = layer_dest_a->children()[0]; - EXPECT_EQ(layer_src_c->id(), layer_dest_c->id()); - EXPECT_EQ(99, layer_dest_c->transform_tree_index_); - - layer_dest_root->SetLayerTreeHost(nullptr); - } - - void RunNonDestructiveDeserializationMoveChildLaterTest() { - /* Testing serialization and deserialization of a tree that initially looks - like this: - root - / \ - a b - / - c - The |c| child of |a| is then moved to become a child of |b|: - root - / \ - a b - \ - c - The tree is then serialized and deserialized again, and the the end - result should have the same structure and importantly it should - not have called InvalidatePropertyTreesIndices() for any of the layers, - which would happen in for example SetLayerTreeHost(...) calls. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - layer_src_a->AddChild(layer_src_c); - - // Copy tree-structure to new root. - proto::LayerNode root_proto_1; - layer_src_root->ToLayerNodeProto(&root_proto_1); - Layer::LayerIdMap dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(root_proto_1, dest_layer_map, - layer_tree_host_.get()); - - // Ensure initial copy is correct. - ASSERT_EQ(2u, layer_dest_root->children().size()); - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - scoped_refptr<Layer> layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - ASSERT_EQ(1u, layer_dest_a->children().size()); - scoped_refptr<Layer> layer_dest_c = layer_dest_a->children()[0]; - EXPECT_EQ(layer_src_c->id(), layer_dest_c->id()); - - // Move child |c| from |b| to |a|. - layer_src_c->RemoveFromParent(); - layer_src_b->AddChild(layer_src_c); - - // Moving a child invalidates the |transform_tree_index_|, so forcefully - // set it afterwards on the destination layer. - layer_dest_root->transform_tree_index_ = 33; - layer_dest_a->transform_tree_index_ = 42; - layer_dest_b->transform_tree_index_ = 24; - layer_dest_c->transform_tree_index_ = 99; - - // Now serialize and deserialize again. - proto::LayerNode root_proto_2; - layer_src_root->ToLayerNodeProto(&root_proto_2); - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map); - layer_dest_root->FromLayerNodeProto(root_proto_2, dest_layer_map, - layer_tree_host_.get()); - - // Ensure second copy is correct. - EXPECT_EQ(33, layer_dest_root->transform_tree_index_); - ASSERT_EQ(2u, layer_dest_root->children().size()); - layer_dest_a = layer_dest_root->children()[0]; - layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(42, layer_dest_a->transform_tree_index_); - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - EXPECT_EQ(24, layer_dest_b->transform_tree_index_); - ASSERT_EQ(1u, layer_dest_b->children().size()); - layer_dest_c = layer_dest_b->children()[0]; - EXPECT_EQ(layer_src_c->id(), layer_dest_c->id()); - EXPECT_EQ(99, layer_dest_c->transform_tree_index_); - - layer_dest_root->SetLayerTreeHost(nullptr); - } - - TestTaskGraphRunner task_graph_runner_; - FakeLayerTreeHostClient fake_client_; - std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; -}; - namespace { class MockLayerTree : public LayerTree { public: MockLayerTree(LayerTreeHostInProcess::InitParams* params, LayerTreeHost* layer_tree_host) - : LayerTree(std::move(params->animation_host), layer_tree_host) {} + : LayerTree(params->mutator_host, layer_tree_host) {} ~MockLayerTree() override {} MOCK_METHOD0(SetNeedsFullTreeSync, void()); @@ -903,7 +114,6 @@ class LayerTest : public testing::Test { LayerTest() : host_impl_(LayerTreeSettings(), &task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_) { timeline_impl_ = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); @@ -916,12 +126,13 @@ class LayerTest : public testing::Test { protected: void SetUp() override { + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + LayerTreeHostInProcess::InitParams params; params.client = &fake_client_; params.settings = &settings_; params.task_graph_runner = &task_graph_runner_; - params.animation_host = - AnimationHost::CreateForTesting(ThreadInstance::MAIN); + params.mutator_host = animation_host_.get(); layer_tree_host_.reset( new StrictMock<MockLayerTreeHost>(&single_thread_client_, ¶ms)); @@ -942,7 +153,9 @@ class LayerTest : public testing::Test { grand_child3_ = nullptr; layer_tree_->SetRootLayer(nullptr); + animation_host_->SetMutatorHostClient(nullptr); layer_tree_host_ = nullptr; + animation_host_ = nullptr; layer_tree_ = nullptr; } @@ -993,13 +206,13 @@ class LayerTest : public testing::Test { } FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; StubLayerTreeHostSingleThreadClient single_thread_client_; FakeLayerTreeHostClient fake_client_; std::unique_ptr<StrictMock<MockLayerTreeHost>> layer_tree_host_; + std::unique_ptr<AnimationHost> animation_host_; StrictMock<MockLayerTree>* layer_tree_; scoped_refptr<Layer> parent_; scoped_refptr<Layer> child1_; @@ -1819,20 +1032,19 @@ TEST_F(LayerTest, MaskHasParent) { class LayerTreeHostFactory { public: - std::unique_ptr<LayerTreeHost> Create() { - return Create(LayerTreeSettings()); + std::unique_ptr<LayerTreeHost> Create(MutatorHost* mutator_host) { + return Create(LayerTreeSettings(), mutator_host); } - std::unique_ptr<LayerTreeHost> Create(LayerTreeSettings settings) { + std::unique_ptr<LayerTreeHost> Create(LayerTreeSettings settings, + MutatorHost* mutator_host) { LayerTreeHostInProcess::InitParams params; params.client = &client_; - params.shared_bitmap_manager = &shared_bitmap_manager_; params.task_graph_runner = &task_graph_runner_; - params.gpu_memory_buffer_manager = &gpu_memory_buffer_manager_; params.settings = &settings; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); - params.animation_host = - AnimationHost::CreateForTesting(ThreadInstance::MAIN); + params.mutator_host = mutator_host; + return LayerTreeHostInProcess::CreateSingleThreaded(&single_thread_client_, ¶ms); } @@ -1840,9 +1052,7 @@ class LayerTreeHostFactory { private: FakeLayerTreeHostClient client_; StubLayerTreeHostSingleThreadClient single_thread_client_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; - TestGpuMemoryBufferManager gpu_memory_buffer_manager_; }; void AssertLayerTreeHostMatchesForSubtree(Layer* layer, LayerTreeHost* host) { @@ -1870,7 +1080,10 @@ TEST_F(LayerLayerTreeHostTest, EnteringTree) { AssertLayerTreeHostMatchesForSubtree(parent.get(), nullptr); LayerTreeHostFactory factory; - std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> layer_tree_host = + factory.Create(animation_host.get()); LayerTree* layer_tree = layer_tree_host->GetLayerTree(); // Setting the root layer should set the host pointer for all layers in the // tree. @@ -1888,7 +1101,10 @@ TEST_F(LayerLayerTreeHostTest, EnteringTree) { TEST_F(LayerLayerTreeHostTest, AddingLayerSubtree) { scoped_refptr<Layer> parent = Layer::Create(); LayerTreeHostFactory factory; - std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> layer_tree_host = + factory.Create(animation_host.get()); LayerTree* layer_tree = layer_tree_host->GetLayerTree(); layer_tree->SetRootLayer(parent.get()); @@ -1921,7 +1137,9 @@ TEST_F(LayerLayerTreeHostTest, ChangeHost) { child->SetMaskLayer(mask.get()); LayerTreeHostFactory factory; - std::unique_ptr<LayerTreeHost> first_layer_tree_host = factory.Create(); + auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> first_layer_tree_host = + factory.Create(animation_host1.get()); first_layer_tree_host->GetLayerTree()->SetRootLayer(parent.get()); AssertLayerTreeHostMatchesForSubtree(parent.get(), @@ -1929,7 +1147,9 @@ TEST_F(LayerLayerTreeHostTest, ChangeHost) { // Now re-root the tree to a new host (simulating what we do on a context lost // event). This should update the host pointers for all layers in the tree. - std::unique_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(); + auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> second_layer_tree_host = + factory.Create(animation_host2.get()); second_layer_tree_host->GetLayerTree()->SetRootLayer(parent.get()); AssertLayerTreeHostMatchesForSubtree(parent.get(), @@ -1951,7 +1171,9 @@ TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) { first_parent->AddChild(second_child); LayerTreeHostFactory factory; - std::unique_ptr<LayerTreeHost> first_layer_tree_host = factory.Create(); + auto animation_host1 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> first_layer_tree_host = + factory.Create(animation_host1.get()); first_layer_tree_host->GetLayerTree()->SetRootLayer(first_parent.get()); AssertLayerTreeHostMatchesForSubtree(first_parent.get(), @@ -1959,7 +1181,9 @@ TEST_F(LayerLayerTreeHostTest, ChangeHostInSubtree) { // Now reparent the subtree starting at second_child to a layer in a different // tree. - std::unique_ptr<LayerTreeHost> second_layer_tree_host = factory.Create(); + auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> second_layer_tree_host = + factory.Create(animation_host2.get()); second_layer_tree_host->GetLayerTree()->SetRootLayer(second_parent.get()); second_parent->AddChild(second_child); @@ -1985,7 +1209,9 @@ TEST_F(LayerLayerTreeHostTest, ReplaceMaskLayer) { mask->AddChild(mask_child); LayerTreeHostFactory factory; - std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> layer_tree_host = + factory.Create(animation_host.get()); layer_tree_host->GetLayerTree()->SetRootLayer(parent.get()); AssertLayerTreeHostMatchesForSubtree(parent.get(), layer_tree_host.get()); @@ -2004,13 +1230,17 @@ TEST_F(LayerLayerTreeHostTest, DestroyHostWithNonNullRootLayer) { scoped_refptr<Layer> child = Layer::Create(); root->AddChild(child); LayerTreeHostFactory factory; - std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> layer_tree_host = + factory.Create(animation_host.get()); layer_tree_host->GetLayerTree()->SetRootLayer(root); } TEST_F(LayerTest, SafeOpaqueBackgroundColor) { LayerTreeHostFactory factory; - std::unique_ptr<LayerTreeHost> layer_tree_host = factory.Create(); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<LayerTreeHost> layer_tree_host = + factory.Create(animation_host.get()); LayerTree* layer_tree = layer_tree_host->GetLayerTree(); scoped_refptr<Layer> layer = Layer::Create(); @@ -2179,286 +1409,6 @@ TEST_F(LayerTest, AnimationSchedulesLayerUpdate) { Mock::VerifyAndClearExpectations(layer_tree_host_.get()); } -TEST_F(LayerTest, RecursiveHierarchySerialization) { - /* Testing serialization and deserialization of a tree that looks like this: - root - / \ - a b - \ - c - Layer c also has a mask layer. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - scoped_refptr<Layer> layer_src_c_mask = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - layer_src_b->AddChild(layer_src_c); - layer_src_c->SetMaskLayer(layer_src_c_mask.get()); - - proto::LayerNode proto; - layer_src_root->ToLayerNodeProto(&proto); - - Layer::LayerIdMap empty_dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(proto, empty_dest_layer_map, - layer_tree_host_.get()); - - EXPECT_EQ(layer_src_root->id(), layer_dest_root->id()); - EXPECT_EQ(nullptr, layer_dest_root->parent()); - ASSERT_EQ(2u, layer_dest_root->children().size()); - - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a->id()); - EXPECT_EQ(layer_src_root->id(), layer_dest_a->parent()->id()); - EXPECT_EQ(0u, layer_dest_a->children().size()); - - scoped_refptr<Layer> layer_dest_b = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_b->id(), layer_dest_b->id()); - EXPECT_EQ(layer_src_root->id(), layer_dest_b->parent()->id()); - ASSERT_EQ(1u, layer_dest_b->children().size()); - - scoped_refptr<Layer> layer_dest_c = layer_dest_b->children()[0]; - EXPECT_EQ(layer_src_c->id(), layer_dest_c->id()); - EXPECT_EQ(layer_src_b->id(), layer_dest_c->parent()->id()); - EXPECT_EQ(0u, layer_dest_c->children().size()); - EXPECT_EQ(layer_src_c_mask->id(), layer_dest_c->mask_layer()->id()); - - layer_dest_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerTest, RecursiveHierarchySerializationWithNodeReuse) { - /* Testing serialization and deserialization of a tree that initially looks - like this: - root - / - a - The source tree is then updated by adding layer |b|: - root - / \ - a b - The deserialization should then re-use the Layers from last - deserialization. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - - proto::LayerNode root_proto_1; - layer_src_root->ToLayerNodeProto(&root_proto_1); - - Layer::LayerIdMap dest_layer_map_1; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(root_proto_1, dest_layer_map_1, - layer_tree_host_.get()); - - EXPECT_EQ(layer_src_root->id(), layer_dest_root->id()); - ASSERT_EQ(1u, layer_dest_root->children().size()); - scoped_refptr<Layer> layer_dest_a_1 = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a_1->id()); - - // Setup new destination layer map. - Layer::LayerIdMap dest_layer_map_2; - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map_2); - - // Add Layer |b|. - scoped_refptr<Layer> layer_src_b = Layer::Create(); - layer_src_root->AddChild(layer_src_b); - - // Second serialization. - proto::LayerNode root_proto_2; - layer_src_root->ToLayerNodeProto(&root_proto_2); - - // Second deserialization. - layer_dest_root->FromLayerNodeProto(root_proto_2, dest_layer_map_2, - layer_tree_host_.get()); - - EXPECT_EQ(layer_src_root->id(), layer_dest_root->id()); - ASSERT_EQ(2u, layer_dest_root->children().size()); - - scoped_refptr<Layer> layer_dest_a_2 = layer_dest_root->children()[0]; - EXPECT_EQ(layer_src_a->id(), layer_dest_a_2->id()); - EXPECT_EQ(layer_src_root->id(), layer_dest_a_2->parent()->id()); - EXPECT_EQ(0u, layer_dest_a_2->children().size()); - - scoped_refptr<Layer> layer_dest_b_2 = layer_dest_root->children()[1]; - EXPECT_EQ(layer_src_b->id(), layer_dest_b_2->id()); - EXPECT_EQ(layer_src_root->id(), layer_dest_b_2->parent()->id()); - EXPECT_EQ(0u, layer_dest_b_2->children().size()); - - // Layer |a| should be the same. - EXPECT_EQ(layer_dest_a_1.get(), layer_dest_a_2.get()); - - layer_dest_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerTest, DeletingSubtreeDeletesLayers) { - /* Testing serialization and deserialization of a tree that initially - looks like this: - root - / \ - a b - \ - c - \ - d - Then the subtree rooted at node |b| is deleted in the next update. - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - scoped_refptr<Layer> layer_src_d = Layer::Create(); - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - layer_src_b->AddChild(layer_src_c); - layer_src_c->AddChild(layer_src_d); - - // Serialization 1. - proto::LayerNode proto1; - layer_src_root->ToLayerNodeProto(&proto1); - - // Deserialization 1. - Layer::LayerIdMap empty_dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(proto1, empty_dest_layer_map, - layer_tree_host_.get()); - - EXPECT_EQ(layer_src_root->id(), layer_dest_root->id()); - ASSERT_EQ(2u, layer_dest_root->children().size()); - scoped_refptr<Layer> layer_dest_a = layer_dest_root->children()[0]; - scoped_refptr<Layer> layer_dest_b = layer_dest_root->children()[1]; - ASSERT_EQ(1u, layer_dest_b->children().size()); - scoped_refptr<Layer> layer_dest_c = layer_dest_b->children()[0]; - ASSERT_EQ(1u, layer_dest_c->children().size()); - scoped_refptr<Layer> layer_dest_d = layer_dest_c->children()[0]; - - // Delete the Layer |b| subtree. - layer_src_b->RemoveAllChildren(); - - // Serialization 2. - proto::LayerNode proto2; - layer_src_root->ToLayerNodeProto(&proto2); - - // Deserialization 2. - Layer::LayerIdMap dest_layer_map_2; - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map_2); - layer_dest_root->FromLayerNodeProto(proto2, dest_layer_map_2, - layer_tree_host_.get()); - - EXPECT_EQ(0u, layer_dest_a->children().size()); - EXPECT_EQ(0u, layer_dest_b->children().size()); - - layer_dest_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerTest, DeleteMaskLayer) { - scoped_refptr<Layer> layer_src_root = Layer::Create(); - scoped_refptr<Layer> layer_src_mask = Layer::Create(); - layer_src_root->SetMaskLayer(layer_src_mask.get()); - - // Serialization 1. - proto::LayerNode proto1; - layer_src_root->ToLayerNodeProto(&proto1); - - // Deserialization 1. - Layer::LayerIdMap dest_layer_map; - scoped_refptr<Layer> layer_dest_root = Layer::Create(); - layer_dest_root->FromLayerNodeProto(proto1, dest_layer_map, - layer_tree_host_.get()); - - EXPECT_EQ(layer_src_root->id(), layer_dest_root->id()); - ASSERT_TRUE(layer_dest_root->mask_layer()); - EXPECT_EQ(layer_src_root->mask_layer()->id(), - layer_dest_root->mask_layer()->id()); - // TODO(nyquist): Add test for is_mask_ when PictureLayer is supported. - - // Clear mask layer. - layer_src_root->mask_layer()->RemoveFromParent(); - - // Serialization 2. - proto::LayerNode proto2; - layer_src_root->ToLayerNodeProto(&proto2); - - // Deserialization 2. - layer_dest_root->ClearLayerTreePropertiesForDeserializationAndAddToMap( - &dest_layer_map); - layer_dest_root->FromLayerNodeProto(proto2, dest_layer_map, - layer_tree_host_.get()); - - EXPECT_EQ(nullptr, layer_dest_root->mask_layer()); - - layer_dest_root->SetLayerTreeHost(nullptr); -} - -TEST_F(LayerSerializationTest, HierarchyDeserializationWithLayerTreeHost) { - RunHierarchyDeserializationWithLayerTreeHostTest(); -} - -TEST_F(LayerSerializationTest, NonDestructiveDeserializationBaseCase) { - RunNonDestructiveDeserializationBaseCaseTest(); -} - -TEST_F(LayerSerializationTest, NonDestructiveDeserializationReorderChildren) { - RunNonDestructiveDeserializationReorderChildrenTest(); -} - -TEST_F(LayerSerializationTest, NonDestructiveDeserializationAddChild) { - RunNonDestructiveDeserializationAddChildTest(); -} - -TEST_F(LayerSerializationTest, NonDestructiveDeserializationRemoveChild) { - RunNonDestructiveDeserializationRemoveChildTest(); -} - -TEST_F(LayerSerializationTest, - NonDestructiveDeserializationMoveChildEarlierTest) { - RunNonDestructiveDeserializationMoveChildEarlierTest(); -} - -TEST_F(LayerSerializationTest, - NonDestructiveDeserializationMoveChildLaterTest) { - RunNonDestructiveDeserializationMoveChildLaterTest(); -} - -TEST_F(LayerSerializationTest, NoMembersChanged) { - RunNoMembersChangedTest(); -} - -TEST_F(LayerSerializationTest, ArbitraryMembersChanged) { - RunArbitraryMembersChangedTest(); -} - -TEST_F(LayerSerializationTest, AllMembersChanged) { - RunAllMembersChangedTest(); -} - -TEST_F(LayerSerializationTest, ScrollAndClipLayers) { - RunScrollAndClipLayersTest(); -} - -TEST_F(LayerSerializationTest, SolidColorScrollbarSerialization) { - std::vector<scoped_refptr<SolidColorScrollbarLayer>> scrollbar_layers; - - scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( - ScrollbarOrientation::HORIZONTAL, 20, 5, true, 3)); - scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( - ScrollbarOrientation::VERTICAL, 20, 5, false, 3)); - scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( - ScrollbarOrientation::HORIZONTAL, 0, 0, true, 0)); - scrollbar_layers.push_back(SolidColorScrollbarLayer::Create( - ScrollbarOrientation::VERTICAL, 10, 35, true, 3)); - - for (size_t i = 0; i < scrollbar_layers.size(); i++) { - VerifySolidColorScrollbarLayerAfterSerializationAndDeserialization( - scrollbar_layers[i]); - } -} - TEST_F(LayerTest, ElementIdAndMutablePropertiesArePushed) { scoped_refptr<Layer> test_layer = Layer::Create(); std::unique_ptr<LayerImpl> impl_layer = diff --git a/chromium/cc/layers/layer_utils_unittest.cc b/chromium/cc/layers/layer_utils_unittest.cc index b00404cf9e7..119ce90ea9a 100644 --- a/chromium/cc/layers/layer_utils_unittest.cc +++ b/chromium/cc/layers/layer_utils_unittest.cc @@ -11,7 +11,6 @@ #include "cc/test/animation_test_common.h" #include "cc/test/fake_impl_task_runner_provider.h" #include "cc/test/fake_layer_tree_host_impl.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" @@ -29,9 +28,7 @@ float diagonal(float width, float height) { class LayerUtilsGetAnimationBoundsTest : public testing::Test { public: LayerUtilsGetAnimationBoundsTest() - : host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_), + : host_impl_(&task_runner_provider_, &task_graph_runner_), root_(CreateTwoForkTree(&host_impl_)), parent1_(root_->test_properties()->children[0]), parent2_(root_->test_properties()->children[1]), @@ -88,7 +85,6 @@ class LayerUtilsGetAnimationBoundsTest : public testing::Test { } FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; LayerImpl* root_; diff --git a/chromium/cc/layers/nine_patch_layer.h b/chromium/cc/layers/nine_patch_layer.h index accdc70437b..cf9edf99c72 100644 --- a/chromium/cc/layers/nine_patch_layer.h +++ b/chromium/cc/layers/nine_patch_layer.h @@ -16,9 +16,6 @@ namespace cc { -class LayerTreeHost; -class ScopedUIResource; - class CC_EXPORT NinePatchLayer : public UIResourceLayer { public: static scoped_refptr<NinePatchLayer> Create(); diff --git a/chromium/cc/layers/nine_patch_layer_impl_unittest.cc b/chromium/cc/layers/nine_patch_layer_impl_unittest.cc index 0fe9bf20f55..9f7bcf46093 100644 --- a/chromium/cc/layers/nine_patch_layer_impl_unittest.cc +++ b/chromium/cc/layers/nine_patch_layer_impl_unittest.cc @@ -44,12 +44,11 @@ void NinePatchLayerLayoutTest(const gfx::Size& bitmap_size, layer_size.height() - border.height()); FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeUIResourceLayerTreeHostImpl host_impl( - &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); + FakeUIResourceLayerTreeHostImpl host_impl(&task_runner_provider, + &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); @@ -149,12 +148,11 @@ void NinePatchLayerLayoutTestWithOcclusion(const gfx::Size& bitmap_size, bitmap_size.height() - image_remaining_bottom - image_remaining_top); FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeUIResourceLayerTreeHostImpl host_impl( - &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); + FakeUIResourceLayerTreeHostImpl host_impl(&task_runner_provider, + &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); diff --git a/chromium/cc/layers/nine_patch_layer_unittest.cc b/chromium/cc/layers/nine_patch_layer_unittest.cc index c85857011d6..440b608f9df 100644 --- a/chromium/cc/layers/nine_patch_layer_unittest.cc +++ b/chromium/cc/layers/nine_patch_layer_unittest.cc @@ -4,6 +4,7 @@ #include "cc/layers/nine_patch_layer.h" +#include "cc/animation/animation_host.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_ui_resource.h" #include "cc/test/fake_layer_tree_host.h" @@ -29,8 +30,9 @@ namespace { class NinePatchLayerTest : public testing::Test { protected: void SetUp() override { - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + layer_tree_host_ = FakeLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host_.get()); } void TearDown() override { @@ -39,6 +41,7 @@ class NinePatchLayerTest : public testing::Test { FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc index 6cfe92d9257..164a75eef5b 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.cc +++ b/chromium/cc/layers/painted_scrollbar_layer.cc @@ -26,7 +26,8 @@ namespace cc { std::unique_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl( LayerTreeImpl* tree_impl) { return PaintedScrollbarLayerImpl::Create( - tree_impl, id(), scrollbar_->Orientation()); + tree_impl, id(), scrollbar_->Orientation(), + scrollbar_->IsLeftSideVerticalScrollbar(), scrollbar_->IsOverlay()); } scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create( @@ -277,7 +278,7 @@ UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart( SkRect layer_skrect = RectToSkRect(layer_rect); SkPaint paint; paint.setAntiAlias(false); - paint.setXfermodeMode(SkXfermode::kClear_Mode); + paint.setBlendMode(SkBlendMode::kClear); skcanvas.drawRect(layer_skrect, paint); skcanvas.clipRect(layer_skrect); diff --git a/chromium/cc/layers/painted_scrollbar_layer.h b/chromium/cc/layers/painted_scrollbar_layer.h index 89133a68240..8446a390202 100644 --- a/chromium/cc/layers/painted_scrollbar_layer.h +++ b/chromium/cc/layers/painted_scrollbar_layer.h @@ -14,7 +14,6 @@ #include "cc/resources/scoped_ui_resource.h" namespace cc { -class ScrollbarThemeComposite; class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerInterface, public Layer { diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc index 8014576a403..6df7e4a86d2 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc @@ -21,16 +21,24 @@ namespace cc { std::unique_ptr<PaintedScrollbarLayerImpl> PaintedScrollbarLayerImpl::Create( LayerTreeImpl* tree_impl, int id, - ScrollbarOrientation orientation) { - return base::WrapUnique( - new PaintedScrollbarLayerImpl(tree_impl, id, orientation)); + ScrollbarOrientation orientation, + bool is_left_side_vertical_scrollbar, + bool is_overlay) { + return base::WrapUnique(new PaintedScrollbarLayerImpl( + tree_impl, id, orientation, is_left_side_vertical_scrollbar, is_overlay)); } PaintedScrollbarLayerImpl::PaintedScrollbarLayerImpl( LayerTreeImpl* tree_impl, int id, - ScrollbarOrientation orientation) - : ScrollbarLayerImplBase(tree_impl, id, orientation, false, false), + ScrollbarOrientation orientation, + bool is_left_side_vertical_scrollbar, + bool is_overlay) + : ScrollbarLayerImplBase(tree_impl, + id, + orientation, + is_left_side_vertical_scrollbar, + is_overlay), track_ui_resource_id_(0), thumb_ui_resource_id_(0), thumb_opacity_(1.f), @@ -44,7 +52,9 @@ PaintedScrollbarLayerImpl::~PaintedScrollbarLayerImpl() {} std::unique_ptr<LayerImpl> PaintedScrollbarLayerImpl::CreateLayerImpl( LayerTreeImpl* tree_impl) { - return PaintedScrollbarLayerImpl::Create(tree_impl, id(), orientation()); + return PaintedScrollbarLayerImpl::Create(tree_impl, id(), orientation(), + is_left_side_vertical_scrollbar(), + is_overlay_scrollbar()); } void PaintedScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) { diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.h b/chromium/cc/layers/painted_scrollbar_layer_impl.h index 10c6ba63af9..19fd8500cc5 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl.h +++ b/chromium/cc/layers/painted_scrollbar_layer_impl.h @@ -14,12 +14,15 @@ namespace cc { class LayerTreeImpl; -class ScrollView; class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { public: - static std::unique_ptr<PaintedScrollbarLayerImpl> - Create(LayerTreeImpl* tree_impl, int id, ScrollbarOrientation orientation); + static std::unique_ptr<PaintedScrollbarLayerImpl> Create( + LayerTreeImpl* tree_impl, + int id, + ScrollbarOrientation orientation, + bool is_left_side_vertical_scrollbar, + bool is_overlay); ~PaintedScrollbarLayerImpl() override; // LayerImpl implementation. @@ -55,7 +58,9 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase { protected: PaintedScrollbarLayerImpl(LayerTreeImpl* tree_impl, int id, - ScrollbarOrientation orientation); + ScrollbarOrientation orientation, + bool is_left_side_vertical_scrollbar, + bool is_overlay); // ScrollbarLayerImplBase implementation. int ThumbThickness() const override; diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc index 4e76ec10246..2dd6d0b77e7 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc @@ -41,7 +41,7 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) { ScrollbarOrientation orientation = VERTICAL; PaintedScrollbarLayerImpl* scrollbar_layer_impl = - impl.AddChildToRoot<PaintedScrollbarLayerImpl>(orientation); + impl.AddChildToRoot<PaintedScrollbarLayerImpl>(orientation, false, false); scrollbar_layer_impl->SetBounds(layer_size); scrollbar_layer_impl->SetContentsOpaque(true); scrollbar_layer_impl->set_internal_contents_scale_and_bounds( diff --git a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc index b43c7379e78..e249607a9e9 100644 --- a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc @@ -4,6 +4,7 @@ #include "cc/layers/painted_scrollbar_layer.h" +#include "cc/animation/animation_host.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/fake_scrollbar.h" @@ -29,10 +30,10 @@ class MockScrollbar : public FakeScrollbar { TEST(PaintedScrollbarLayerTest, NeedsPaint) { FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; - std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + auto layer_tree_host = FakeLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host.get()); MockScrollbar* scrollbar = new MockScrollbar(); scoped_refptr<PaintedScrollbarLayer> scrollbar_layer = @@ -41,9 +42,9 @@ TEST(PaintedScrollbarLayerTest, NeedsPaint) { scrollbar_layer->SetIsDrawable(true); scrollbar_layer->SetBounds(gfx::Size(100, 100)); - layer_tree_host_->SetRootLayer(scrollbar_layer); + layer_tree_host->SetRootLayer(scrollbar_layer); EXPECT_EQ(scrollbar_layer->GetLayerTreeHostForTesting(), - layer_tree_host_.get()); + layer_tree_host.get()); scrollbar_layer->SavePaintProperties(); // Request no paint, but expect them to be painted because they have not diff --git a/chromium/cc/layers/picture_image_layer_unittest.cc b/chromium/cc/layers/picture_image_layer_unittest.cc index 572ee7a0a3a..2280494bd4c 100644 --- a/chromium/cc/layers/picture_image_layer_unittest.cc +++ b/chromium/cc/layers/picture_image_layer_unittest.cc @@ -4,6 +4,7 @@ #include "cc/layers/picture_image_layer.h" +#include "cc/animation/animation_host.h" #include "cc/playback/display_item.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/skia_common.h" @@ -21,8 +22,9 @@ TEST(PictureImageLayerTest, PaintContentsToDisplayList) { scoped_refptr<PictureImageLayer> layer = PictureImageLayer::Create(); FakeLayerTreeHostClient client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &client, &task_graph_runner, animation_host.get()); layer->SetLayerTreeHost(host.get()); gfx::Rect layer_rect(200, 200); diff --git a/chromium/cc/layers/picture_layer.cc b/chromium/cc/layers/picture_layer.cc index 25e6c3e679b..8ed4c8b768a 100644 --- a/chromium/cc/layers/picture_layer.cc +++ b/chromium/cc/layers/picture_layer.cc @@ -206,14 +206,15 @@ void PictureLayer::SetTypeForProtoSerialization(proto::LayerNode* proto) const { proto->set_type(proto::LayerNode::PICTURE_LAYER); } -void PictureLayer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto, - bool inputs_only) { - Layer::LayerSpecificPropertiesToProto(proto, inputs_only); - DropRecordingSourceContentIfInvalid(); +void PictureLayer::ToLayerPropertiesProto(proto::LayerProperties* proto) { + DCHECK(GetLayerTree()); + DCHECK(GetLayerTree()->engine_picture_cache()); + Layer::ToLayerPropertiesProto(proto); + DropRecordingSourceContentIfInvalid(); proto::PictureLayerProperties* picture = proto->mutable_picture(); - recording_source_->ToProtobuf(picture->mutable_recording_source()); + picture->set_nearest_neighbor(picture_layer_inputs_.nearest_neighbor); RectToProto(picture_layer_inputs_.recorded_viewport, picture->mutable_recorded_viewport()); if (picture_layer_inputs_.display_list) { @@ -228,58 +229,6 @@ void PictureLayer::LayerSpecificPropertiesToProto(proto::LayerProperties* proto, GetLayerTree()->engine_picture_cache()->MarkUsed(picture.get()); } } - - RegionToProto(last_updated_invalidation_, picture->mutable_invalidation()); - picture->set_is_mask(is_mask_); - picture->set_nearest_neighbor(picture_layer_inputs_.nearest_neighbor); - - picture->set_update_source_frame_number(update_source_frame_number_); - - last_updated_invalidation_.Clear(); -} - -void PictureLayer::FromLayerSpecificPropertiesProto( - const proto::LayerProperties& proto) { - Layer::FromLayerSpecificPropertiesProto(proto); - const proto::PictureLayerProperties& picture = proto.picture(); - // If this is a new layer, ensure it has a recording source. During layer - // hierarchy deserialization, ::SetLayerTreeHost(...) is not called, but - // instead the member is set directly, so it needs to be set here explicitly. - if (!recording_source_) - recording_source_.reset(new RecordingSource); - - std::vector<uint32_t> used_engine_picture_ids; - - picture_layer_inputs_.recorded_viewport = - ProtoToRect(picture.recorded_viewport()); - - ClientPictureCache* client_picture_cache = - GetLayerTree()->client_picture_cache(); - DCHECK(client_picture_cache); - // This might not exist if the |input_.display_list| of the serialized - // RecordingSource was null, which can happen if |Clear()| is - // called. - if (picture.has_display_list()) { - picture_layer_inputs_.display_list = DisplayItemList::CreateFromProto( - picture.display_list(), client_picture_cache, &used_engine_picture_ids); - } else { - picture_layer_inputs_.display_list = nullptr; - } - - recording_source_->FromProtobuf(picture.recording_source(), - picture_layer_inputs_.display_list, - picture_layer_inputs_.recorded_viewport); - - // Inform picture cache about which SkPictures are now in use. - for (uint32_t engine_picture_id : used_engine_picture_ids) - GetLayerTree()->client_picture_cache()->MarkUsed(engine_picture_id); - - Region new_invalidation = RegionFromProto(picture.invalidation()); - last_updated_invalidation_.Swap(&new_invalidation); - is_mask_ = picture.is_mask(); - picture_layer_inputs_.nearest_neighbor = picture.nearest_neighbor(); - - update_source_frame_number_ = picture.update_source_frame_number(); } void PictureLayer::RunMicroBenchmark(MicroBenchmark* benchmark) { diff --git a/chromium/cc/layers/picture_layer.h b/chromium/cc/layers/picture_layer.h index 1aa5303c48d..15d5825508e 100644 --- a/chromium/cc/layers/picture_layer.h +++ b/chromium/cc/layers/picture_layer.h @@ -13,14 +13,9 @@ namespace cc { -namespace proto { -class PictureLayerProperties; -} - class ContentLayerClient; class DisplayItemList; class RecordingSource; -class ResourceUpdateQueue; class CC_EXPORT PictureLayer : public Layer { public: @@ -29,6 +24,9 @@ class CC_EXPORT PictureLayer : public Layer { void ClearClient(); void SetNearestNeighbor(bool nearest_neighbor); + bool nearest_neighbor() const { + return picture_layer_inputs_.nearest_neighbor; + } // Layer interface. std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override; @@ -39,6 +37,9 @@ class CC_EXPORT PictureLayer : public Layer { void SetIsMask(bool is_mask) override; sk_sp<SkPicture> GetPicture() const override; + void SetTypeForProtoSerialization(proto::LayerNode* proto) const override; + void ToLayerPropertiesProto(proto::LayerProperties* proto) override; + bool IsSuitableForGpuRasterization() const override; void RunMicroBenchmark(MicroBenchmark* benchmark) override; @@ -71,11 +72,6 @@ class CC_EXPORT PictureLayer : public Layer { ~PictureLayer() override; bool HasDrawableContent() const override; - void SetTypeForProtoSerialization(proto::LayerNode* proto) const override; - void LayerSpecificPropertiesToProto(proto::LayerProperties* proto, - bool inputs_only) override; - void FromLayerSpecificPropertiesProto( - const proto::LayerProperties& proto) override; bool is_mask() const { return is_mask_; } diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc index 47ddf3fb060..c2de32a75ce 100644 --- a/chromium/cc/layers/picture_layer_impl.cc +++ b/chromium/cc/layers/picture_layer_impl.cc @@ -272,7 +272,7 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass, } else if (iter.resolution() == LOW_RESOLUTION) { color = DebugColors::LowResTileBorderColor(); width = DebugColors::LowResTileBorderWidth(layer_tree_impl()); - } else if (iter->contents_scale() > max_contents_scale) { + } else if (iter->contents_scale_key() > max_contents_scale) { color = DebugColors::ExtraHighResTileBorderColor(); width = DebugColors::ExtraHighResTileBorderWidth(layer_tree_impl()); } else { @@ -340,8 +340,8 @@ void PictureLayerImpl::AppendQuads(RenderPass* render_pass, // complete. But if a tile is ideal scale, we don't want to consider // it incomplete and trying to replace it with a tile at a worse // scale. - if (iter->contents_scale() != raster_contents_scale_ && - iter->contents_scale() != ideal_contents_scale_ && + if (iter->contents_scale_key() != raster_contents_scale_ && + iter->contents_scale_key() != ideal_contents_scale_ && geometry_rect.Intersects(scaled_viewport_for_tile_priority)) { append_quads_data->num_incomplete_tiles++; } @@ -477,9 +477,6 @@ bool PictureLayerImpl::UpdateTiles() { was_screen_space_transform_animating_ = draw_properties().screen_space_transform_is_animating; - if (screen_space_transform_is_animating()) - raster_source_->SetShouldAttemptToUseDistanceFieldText(); - double current_frame_time_in_seconds = (layer_tree_impl()->CurrentBeginFrameArgs().frame_time - base::TimeTicks()).InSecondsF(); @@ -648,12 +645,13 @@ bool PictureLayerImpl::RasterSourceUsesLCDText() const { void PictureLayerImpl::NotifyTileStateChanged(const Tile* tile) { if (layer_tree_impl()->IsActiveTree()) { gfx::Rect layer_damage_rect = gfx::ScaleToEnclosingRect( - tile->content_rect(), 1.f / tile->contents_scale()); + tile->content_rect(), 1.f / tile->raster_scales().width(), + 1.f / tile->raster_scales().height()); AddDamageRect(layer_damage_rect); } if (tile->draw_info().NeedsRaster()) { PictureLayerTiling* tiling = - tilings_->FindTilingWithScale(tile->contents_scale()); + tilings_->FindTilingWithScaleKey(tile->contents_scale_key()); if (tiling) tiling->set_all_tiles_done(false); } @@ -723,7 +721,8 @@ const PictureLayerTiling* PictureLayerImpl::GetPendingOrActiveTwinTiling( PictureLayerImpl* twin_layer = GetPendingOrActiveTwinLayer(); if (!twin_layer) return nullptr; - return twin_layer->tilings_->FindTilingWithScale(tiling->contents_scale()); + return twin_layer->tilings_->FindTilingWithScaleKey( + tiling->contents_scale_key()); } bool PictureLayerImpl::RequiresHighResToDraw() const { @@ -891,7 +890,7 @@ void PictureLayerImpl::AddTilingsForRasterScale() { tilings_->MarkAllTilingsNonIdeal(); PictureLayerTiling* high_res = - tilings_->FindTilingWithScale(raster_contents_scale_); + tilings_->FindTilingWithScaleKey(raster_contents_scale_); if (!high_res) { // We always need a high res tiling, so create one if it doesn't exist. high_res = AddTiling(raster_contents_scale_); @@ -981,7 +980,7 @@ void PictureLayerImpl::AddLowResolutionTilingIfNeeded() { return; PictureLayerTiling* low_res = - tilings_->FindTilingWithScale(low_res_raster_contents_scale_); + tilings_->FindTilingWithScaleKey(low_res_raster_contents_scale_); DCHECK(!low_res || low_res->resolution() != HIGH_RESOLUTION); // Only create new low res tilings when the transform is static. This @@ -1045,7 +1044,7 @@ void PictureLayerImpl::RecalculateRasterScales() { while (desired_contents_scale < ideal_contents_scale_) desired_contents_scale *= kMaxScaleRatioDuringPinch; } - raster_contents_scale_ = tilings_->GetSnappedContentsScale( + raster_contents_scale_ = tilings_->GetSnappedContentsScaleKey( desired_contents_scale, kSnapToExistingTilingRatio); raster_page_scale_ = raster_contents_scale_ / raster_device_scale_ / raster_source_scale_; diff --git a/chromium/cc/layers/picture_layer_impl_perftest.cc b/chromium/cc/layers/picture_layer_impl_perftest.cc index 3159ec5c526..f0c113ddda5 100644 --- a/chromium/cc/layers/picture_layer_impl_perftest.cc +++ b/chromium/cc/layers/picture_layer_impl_perftest.cc @@ -12,7 +12,6 @@ #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_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/tiles/tiling_set_raster_queue_all.h" #include "cc/trees/layer_tree_impl.h" @@ -45,7 +44,6 @@ class PictureLayerImplPerfTest : public testing::Test { compositor_frame_sink_(FakeCompositorFrameSink::Create3d()), host_impl_(LayerTreeSettings(), &task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_), timer_(kWarmupRuns, base::TimeDelta::FromMilliseconds(kTimeLimitMillis), @@ -172,7 +170,6 @@ class PictureLayerImplPerfTest : public testing::Test { } protected: - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeImplTaskRunnerProvider task_runner_provider_; std::unique_ptr<CompositorFrameSink> compositor_frame_sink_; diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc index b721d3e1058..679098463ed 100644 --- a/chromium/cc/layers/picture_layer_impl_unittest.cc +++ b/chromium/cc/layers/picture_layer_impl_unittest.cc @@ -14,6 +14,7 @@ #include "base/location.h" #include "base/macros.h" #include "base/threading/thread_task_runner_handle.h" +#include "cc/animation/animation_host.h" #include "cc/base/math_util.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/picture_layer.h" @@ -34,7 +35,6 @@ #include "cc/test/gpu_rasterization_enabled_settings.h" #include "cc/test/layer_test_common.h" #include "cc/test/test_layer_tree_host_base.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/tiles/tiling_set_raster_queue_all.h" @@ -96,7 +96,6 @@ class PictureLayerImplTest : public TestLayerTreeHostBase { settings.layer_transforms_should_scale_layer_contents = true; settings.create_low_res_tiling = true; settings.verify_clip_tree_calculations = true; - settings.verify_transform_tree_calculations = true; settings.renderer_settings.buffer_to_texture_target_map = DefaultBufferToTextureTargetMapForTesting(); return settings; @@ -203,11 +202,9 @@ class PictureLayerImplTest : public TestLayerTreeHostBase { auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); for (PictureLayerTiling::CoverageIterator iter( - tiling, - tiling->contents_scale(), + tiling, tiling->contents_scale_key(), gfx::Rect(tiling->tiling_size())); - iter; - ++iter) { + iter; ++iter) { EXPECT_TRUE(*iter); EXPECT_EQ(raster_source, prioritized_tiles[*iter].raster_source()); } @@ -345,7 +342,8 @@ TEST_F(PictureLayerImplTest, TileGridAlignment) { MockCanvas mock_canvas(1000, 1000); const gfx::Rect& content_rect = (*tile_iter)->content_rect(); updated_active_raster_source->RasterSource::PlaybackToCanvas( - &mock_canvas, content_rect, content_rect, 1.0f, playback_settings); + &mock_canvas, content_rect, content_rect, gfx::SizeF(1.f, 1.f), + playback_settings); // This test verifies that when drawing the contents of a specific tile // at content scale 1.0, the playback canvas never receives content from @@ -402,7 +400,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { EXPECT_EQ( tiling->GetCurrentVisibleRectForTesting(), gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space, - tiling->contents_scale())); + tiling->contents_scale_key())); } // Update tiles with viewport for tile priority as (200, 200, 100, 100) in @@ -438,7 +436,7 @@ TEST_F(PictureLayerImplTest, ExternalViewportRectForPrioritizingTiles) { EXPECT_EQ( tiling->GetCurrentVisibleRectForTesting(), gfx::ScaleToEnclosingRect(viewport_rect_for_tile_priority_in_view_space, - tiling->contents_scale())); + tiling->contents_scale_key())); } } @@ -515,16 +513,13 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { for (size_t i = 0; i < tilings->num_tilings(); ++i) { const PictureLayerTiling* tiling = tilings->tiling_at(i); gfx::Rect content_invalidation = gfx::ScaleToEnclosingRect( - layer_invalidation, - tiling->contents_scale()); + layer_invalidation, tiling->contents_scale_key()); auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); for (PictureLayerTiling::CoverageIterator iter( - tiling, - tiling->contents_scale(), + tiling, tiling->contents_scale_key(), gfx::Rect(tiling->tiling_size())); - iter; - ++iter) { + iter; ++iter) { // We don't always have a tile, but when we do it's because it was // invalidated and it has the latest raster source. if (*iter) { @@ -546,11 +541,9 @@ TEST_F(PictureLayerImplTest, ClonePartialInvalidation) { auto prioritized_tiles = tiling->UpdateAndGetAllPrioritizedTilesForTesting(); for (PictureLayerTiling::CoverageIterator iter( - tiling, - tiling->contents_scale(), + tiling, tiling->contents_scale_key(), gfx::Rect(tiling->tiling_size())); - iter; - ++iter) { + iter; ++iter) { EXPECT_TRUE(*iter); EXPECT_FALSE(iter.geometry_rect().IsEmpty()); // Raster source will be updated upon activation. @@ -602,10 +595,11 @@ TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(6.f * low_res_factor, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 6.f * low_res_factor, + active_layer()->tilings()->tiling_at(1)->contents_scale_key()); // If we change the page scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(active_layer(), @@ -616,10 +610,11 @@ TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.6f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(6.6f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.6f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 6.6f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); // If we change the device scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(active_layer(), @@ -630,10 +625,11 @@ TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(6u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(7.26f * low_res_factor, - active_layer()->tilings()->tiling_at(3)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 7.26f * low_res_factor, + active_layer()->tilings()->tiling_at(3)->contents_scale_key()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. @@ -645,10 +641,11 @@ TEST_F(PictureLayerImplTest, UpdateTilesCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(6u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(7.26f * low_res_factor, - active_layer()->tilings()->tiling_at(3)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 7.26f * low_res_factor, + active_layer()->tilings()->tiling_at(3)->contents_scale_key()); } TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { @@ -671,8 +668,8 @@ TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the page scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(pending_layer(), @@ -683,8 +680,8 @@ TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.6f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.6f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the device scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(pending_layer(), @@ -695,8 +692,8 @@ TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. @@ -708,8 +705,8 @@ TEST_F(PictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); } TEST_F(PictureLayerImplTest, CreateTilingsEvenIfTwinHasNone) { @@ -776,7 +773,7 @@ TEST_F(PictureLayerImplTest, ZoomOutCrash) { ResetTilingsAndRasterScales(); EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); SetContentsScaleOnBothLayers(32.0f, 1.0f, 32.0f, 1.0f, 0.f, false); - EXPECT_EQ(32.f, active_layer()->HighResTiling()->contents_scale()); + EXPECT_EQ(32.f, active_layer()->HighResTiling()->contents_scale_key()); host_impl()->PinchGestureBegin(); SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, 0.f, false); SetContentsScaleOnBothLayers(1.0f, 1.0f, 1.0f, 1.0f, 0.f, false); @@ -794,8 +791,8 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { 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); - EXPECT_EQ(active_layer()->tilings()->tiling_at(0)->contents_scale(), 2.f); - EXPECT_EQ(active_layer()->tilings()->tiling_at(1)->contents_scale(), + 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); // One of the tilings has to be a low resolution one. EXPECT_EQ(LOW_RESOLUTION, @@ -811,12 +808,13 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { // the scale (2/kMaxScaleRatioDuringPinch). SetContentsScaleOnBothLayers(1.8f, 1.0f, 1.8f, 1.0f, 0.f, false); EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(2.0f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.0f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(2.0f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ( + 2.0f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.0f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 2.0f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); // Since we're pinching, we shouldn't create a low resolution tiling. EXPECT_FALSE( active_layer()->tilings()->FindTilingWithResolution(LOW_RESOLUTION)); @@ -836,12 +834,12 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { // 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()); - EXPECT_FLOAT_EQ(4.0f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); + 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 // shouldn't be marked as low resolution since we're pinching. auto* low_res_tiling = - active_layer()->tilings()->FindTilingWithScale(4.f * low_res_factor); + active_layer()->tilings()->FindTilingWithScaleKey(4.f * low_res_factor); EXPECT_TRUE(low_res_tiling); EXPECT_NE(LOW_RESOLUTION, low_res_tiling->resolution()); @@ -855,12 +853,12 @@ TEST_F(PictureLayerImplTest, PinchGestureTilings) { // (checked above). SetContentsScaleOnBothLayers(4.0f, 1.0f, 4.0f, 1.f, 0.f, false); EXPECT_EQ(4u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(4.0f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); + 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 // now be marked as low resolution. low_res_tiling = - active_layer()->tilings()->FindTilingWithScale(4.f * low_res_factor); + active_layer()->tilings()->FindTilingWithScaleKey(4.f * low_res_factor); EXPECT_TRUE(low_res_tiling); EXPECT_EQ(LOW_RESOLUTION, low_res_tiling->resolution()); } @@ -875,10 +873,10 @@ 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()); - EXPECT_FLOAT_EQ(0.24f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(0.0625f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 0.24f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 0.0625f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); // Ensure UpdateTiles won't remove any tilings. active_layer()->MarkAllTilingsUsed(); @@ -890,12 +888,12 @@ TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) { // the scale (1/kMaxScaleRatioDuringPinch). SetContentsScaleOnBothLayers(0.2f, 1.0f, 0.2f, 1.0f, 0.f, false); EXPECT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(0.24f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(0.12f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(0.0625, - active_layer()->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ( + 0.24f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 0.12f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 0.0625, active_layer()->tilings()->tiling_at(2)->contents_scale_key()); // Ensure UpdateTiles won't remove any tilings. active_layer()->MarkAllTilingsUsed(); @@ -914,8 +912,8 @@ TEST_F(PictureLayerImplTest, SnappedTilingDuringZoom) { // 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()); - EXPECT_FLOAT_EQ(1.92f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.92f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); } TEST_F(PictureLayerImplTest, CleanUpTilings) { @@ -932,10 +930,11 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { SetupDefaultTrees(layer_bounds); active_layer()->SetHasWillChangeTransformHint(true); EXPECT_FLOAT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f * low_res_factor, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f * low_res_factor, + active_layer()->tilings()->tiling_at(1)->contents_scale_key()); // Ensure UpdateTiles won't remove any tilings. Note this is unrelated to // |used_tilings| variable, and it's here only to ensure that active_layer() @@ -946,10 +945,11 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { used_tilings.clear(); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); EXPECT_FLOAT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f * low_res_factor, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f * low_res_factor, + active_layer()->tilings()->tiling_at(1)->contents_scale_key()); host_impl()->PinchGestureBegin(); @@ -958,19 +958,21 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { page_scale = 1.5f; SetContentsScaleOnBothLayers(scale, 1.f, page_scale, 1.f, 0.f, false); EXPECT_FLOAT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f * low_res_factor, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f * low_res_factor, + active_layer()->tilings()->tiling_at(1)->contents_scale_key()); // The tilings are still our target scale, so they aren't removed. used_tilings.clear(); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f * low_res_factor, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f * low_res_factor, + active_layer()->tilings()->tiling_at(1)->contents_scale_key()); host_impl()->PinchGestureEnd(); @@ -979,14 +981,16 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { page_scale = 1.2f; SetContentsScaleOnBothLayers(1.2f, 1.f, page_scale, 1.f, 0.f, false); ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.2f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(1.2f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); - EXPECT_FLOAT_EQ(1.f * low_res_factor, - active_layer()->tilings()->tiling_at(3)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.2f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.2f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f * low_res_factor, + active_layer()->tilings()->tiling_at(3)->contents_scale_key()); // Ensure UpdateTiles won't remove any tilings. active_layer()->MarkAllTilingsUsed(); @@ -997,14 +1001,16 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { used_tilings.push_back(active_layer()->tilings()->tiling_at(3)); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(4u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.2f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(1.2f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); - EXPECT_FLOAT_EQ(1.f * low_res_factor, - active_layer()->tilings()->tiling_at(3)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.2f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.2f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f * low_res_factor, + active_layer()->tilings()->tiling_at(3)->contents_scale_key()); // Now move the ideal scale to 0.5. Our target stays 1.2. SetContentsScaleOnBothLayers(0.5f, 1.f, page_scale, 1.f, 0.f, false); @@ -1014,12 +1020,13 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { used_tilings.clear(); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.2f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(1.2f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.2f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.2f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); // Now move the ideal scale to 1.0. Our target stays 1.2. SetContentsScaleOnBothLayers(1.f, 1.f, page_scale, 1.f, 0.f, false); @@ -1029,12 +1036,13 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { used_tilings.clear(); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.2f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(1.2f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.2f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.2f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); // Now move the ideal scale to 1.1 on the active layer. Our target stays 1.2. SetupDrawPropertiesAndUpdateTiles(active_layer(), 1.1f, 1.f, page_scale, 1.f, @@ -1045,12 +1053,13 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { used_tilings.clear(); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.2f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(1.2f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.2f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.2f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); // Move the ideal scale on the pending layer to 1.1 as well. Our target stays // 1.2 still. @@ -1064,22 +1073,24 @@ TEST_F(PictureLayerImplTest, CleanUpTilings) { used_tilings.push_back(active_layer()->tilings()->tiling_at(1)); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.2f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); - EXPECT_FLOAT_EQ(1.2f * low_res_factor, - active_layer()->tilings()->tiling_at(2)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.2f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.2f * low_res_factor, + active_layer()->tilings()->tiling_at(2)->contents_scale_key()); // If we remove it from our used tilings set, it is outside the range to keep // so it is deleted. used_tilings.clear(); active_layer()->CleanUpTilingsOnActiveLayer(used_tilings); ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.2f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_FLOAT_EQ(1.2 * low_res_factor, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.2f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_FLOAT_EQ( + 1.2 * low_res_factor, + active_layer()->tilings()->tiling_at(1)->contents_scale_key()); } TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { @@ -1104,7 +1115,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f); EXPECT_BOTH_EQ(num_tilings(), 1u); // Stop animating, low res gets created. @@ -1112,8 +1123,9 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); - EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(), low_res_factor); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f); + EXPECT_EQ(active_layer()->LowResTiling()->contents_scale_key(), + low_res_factor); EXPECT_EQ(active_layer()->num_tilings(), 2u); EXPECT_EQ(pending_layer()->num_tilings(), 1u); @@ -1130,7 +1142,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f); EXPECT_FALSE(active_layer()->LowResTiling()); EXPECT_FALSE(pending_layer()->LowResTiling()); EXPECT_EQ(3u, active_layer()->num_tilings()); @@ -1141,8 +1153,8 @@ TEST_F(PictureLayerImplTest, DontAddLowResDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); - EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(), + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f); + EXPECT_EQ(active_layer()->LowResTiling()->contents_scale_key(), 2.f * low_res_factor); EXPECT_EQ(4u, active_layer()->num_tilings()); EXPECT_EQ(1u, pending_layer()->num_tilings()); @@ -1170,7 +1182,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), contents_scale); EXPECT_BOTH_EQ(num_tilings(), 1u); ResetTilingsAndRasterScales(); @@ -1180,7 +1192,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), contents_scale); EXPECT_BOTH_EQ(num_tilings(), 1u); // TODO(danakj): Remove these when raster scale doesn't get fixed? @@ -1192,8 +1204,8 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), contents_scale); - EXPECT_EQ(active_layer()->LowResTiling()->contents_scale(), + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), contents_scale); + EXPECT_EQ(active_layer()->LowResTiling()->contents_scale_key(), contents_scale * low_res_factor); EXPECT_FALSE(pending_layer()->LowResTiling()); EXPECT_EQ(active_layer()->num_tilings(), 2u); @@ -1220,7 +1232,7 @@ TEST_F(PictureLayerImplTest, DontAddLowResForSmallLayers) { SetupDrawPropertiesAndUpdateTiles( mask_raw, contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_EQ(mask_raw->HighResTiling()->contents_scale(), contents_scale); + EXPECT_EQ(mask_raw->HighResTiling()->contents_scale_key(), contents_scale); EXPECT_EQ(mask_raw->num_tilings(), 1u); } @@ -1249,7 +1261,7 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { FakePictureLayerImpl* pending_mask = static_cast<FakePictureLayerImpl*>( pending_layer()->test_properties()->mask_layer); - EXPECT_EQ(1.f, pending_mask->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, pending_mask->HighResTiling()->contents_scale_key()); EXPECT_EQ(1u, pending_mask->num_tilings()); host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( @@ -1295,7 +1307,7 @@ TEST_F(PictureLayerImplTest, HugeMasksGetScaledDown) { host_impl()->pending_tree()->UpdateDrawProperties(update_lcd_text); // The mask tiling gets scaled down. - EXPECT_LT(pending_mask->HighResTiling()->contents_scale(), 1.f); + EXPECT_LT(pending_mask->HighResTiling()->contents_scale_key(), 1.f); EXPECT_EQ(1u, pending_mask->num_tilings()); host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( @@ -1379,7 +1391,7 @@ TEST_F(PictureLayerImplTest, ScaledMaskLayer) { pending_layer()->test_properties()->mask_layer); // Masks are scaled, and do not have a low res tiling. - EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale()); + EXPECT_EQ(1.3f, pending_mask->HighResTiling()->contents_scale_key()); EXPECT_EQ(1u, pending_mask->num_tilings()); host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( @@ -1714,7 +1726,7 @@ TEST_F(NoLowResPictureLayerImplTest, SetupDefaultTreesWithFixedTileSize(layer_bounds, tile_size, Region()); ASSERT_EQ(1u, pending_layer()->num_tilings()); - ASSERT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale()); + ASSERT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale_key()); // Set external viewport for tile priority. gfx::Transform transform; @@ -1912,7 +1924,7 @@ TEST_F(PictureLayerImplTest, // One ideal tile exists, this will get used when drawing. std::vector<Tile*> ideal_tiles; - EXPECT_EQ(2.f, active_layer()->HighResTiling()->contents_scale()); + EXPECT_EQ(2.f, active_layer()->HighResTiling()->contents_scale_key()); ideal_tiles.push_back(active_layer()->HighResTiling()->TileAt(0, 0)); host_impl()->tile_manager()->InitializeTilesWithResourcesForTesting( ideal_tiles); @@ -1924,13 +1936,13 @@ TEST_F(PictureLayerImplTest, SetupDrawPropertiesAndUpdateTiles(active_layer(), 2.f, 1.f, 1.f, 1.f, 0.f, false); - EXPECT_EQ(1.f, active_layer()->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, active_layer()->HighResTiling()->contents_scale_key()); EXPECT_EQ(1.f, active_layer()->raster_contents_scale()); EXPECT_EQ(2.f, active_layer()->ideal_contents_scale()); // Both tilings still exist. - EXPECT_EQ(2.f, active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_EQ(1.f, active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_EQ(2.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_EQ(1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); // All high res tiles have resources. std::vector<Tile*> high_tiles = @@ -2345,8 +2357,8 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { SetupTrees(pending_raster_source, active_raster_source); - EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(1.f)); - EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScale(1.f)); + 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()); @@ -2364,14 +2376,14 @@ TEST_F(PictureLayerImplTest, SyncTilingAfterGpuRasterizationToggles) { EXPECT_EQ(1u, active_layer()->release_resources_count()); // But the pending layer gets a tiling back, and can activate it. - EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(1.f)); + EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f)); EXPECT_EQ(0u, active_layer()->tilings()->num_tilings()); ActivateTree(); - EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScale(1.f)); + EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f)); SetupPendingTree(pending_raster_source); - EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(1.f)); + 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()); @@ -2401,7 +2413,7 @@ TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) { // Sanity checks. EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScale(0.5f)); + EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(0.5f)); ActivateTree(); @@ -2416,7 +2428,7 @@ TEST_F(PictureLayerImplTest, HighResCreatedWhenBoundsShrink) { // by a 1.0 tiling during the UDP in SetupPendingTree. EXPECT_EQ(1u, pending_layer()->tilings()->num_tilings()); PictureLayerTiling* tiling = - pending_layer()->tilings()->FindTilingWithScale(1.0f); + pending_layer()->tilings()->FindTilingWithScaleKey(1.0f); ASSERT_TRUE(tiling); EXPECT_EQ(HIGH_RESOLUTION, tiling->resolution()); } @@ -2504,7 +2516,7 @@ TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) { SetupDefaultTrees(gfx::Size(10, 10)); // We start with a tiling at scale 1. - EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale_key()); // When we page scale up by 2.3, we get a new tiling that is a power of 2, in // this case 4. @@ -2512,14 +2524,14 @@ TEST_F(PictureLayerImplTest, FirstTilingDuringPinch) { float high_res_scale = 2.3f; SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, 0.f, false); - EXPECT_EQ(4.f, pending_layer()->HighResTiling()->contents_scale()); + EXPECT_EQ(4.f, pending_layer()->HighResTiling()->contents_scale_key()); } TEST_F(PictureLayerImplTest, PinchingTooSmall) { SetupDefaultTrees(gfx::Size(10, 10)); // We start with a tiling at scale 1. - EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, pending_layer()->HighResTiling()->contents_scale_key()); host_impl()->PinchGestureBegin(); float high_res_scale = 0.0001f; @@ -2528,7 +2540,7 @@ TEST_F(PictureLayerImplTest, PinchingTooSmall) { SetContentsScaleOnBothLayers(high_res_scale, 1.f, high_res_scale, 1.f, 0.f, false); EXPECT_FLOAT_EQ(pending_layer()->MinimumContentsScale(), - pending_layer()->HighResTiling()->contents_scale()); + pending_layer()->HighResTiling()->contents_scale_key()); } TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) { @@ -2541,7 +2553,7 @@ TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) { ASSERT_GE(pending_layer()->num_tilings(), 0u); EXPECT_FLOAT_EQ(contents_scale, - pending_layer()->HighResTiling()->contents_scale()); + pending_layer()->HighResTiling()->contents_scale_key()); host_impl()->PinchGestureBegin(); @@ -2553,7 +2565,7 @@ TEST_F(PictureLayerImplTest, PinchingTooSmallWithContentsScale) { 1.f, 0.f, false); ASSERT_GE(pending_layer()->num_tilings(), 0u); EXPECT_FLOAT_EQ(pending_layer()->MinimumContentsScale(), - pending_layer()->HighResTiling()->contents_scale()); + pending_layer()->HighResTiling()->contents_scale_key()); } TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { @@ -2570,13 +2582,13 @@ TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { float starting_animation_scale = 1.f; bool animating_transform = true; - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f); // Maximum animation scale is greater than starting animation scale SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); animating_transform = false; @@ -2584,7 +2596,7 @@ TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f); // Starting animation scale greater than maximum animation scale // Bounds at starting scale within the viewport @@ -2594,14 +2606,14 @@ TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 5.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 5.f); // Once we stop animating, a new high-res tiling should be created. animating_transform = false; SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f); // Starting Animation scale greater than maximum animation scale // Bounds at starting scale outisde the viewport @@ -2611,7 +2623,7 @@ TEST_F(PictureLayerImplTest, ConsiderAnimationStartScaleForRasterScale) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); } TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { @@ -2628,7 +2640,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { float starting_animation_scale = 0.f; bool animating_transform = false; - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 1.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 1.f); // Starting an animation should cause tiling resolution to get set to the // maximum animation scale factor. @@ -2639,8 +2651,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f); - EXPECT_BOTH_TRUE(GetRasterSource()->ShouldAttemptToUseDistanceFieldText()); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); // Further changes to scale during the animation should not cause a new // high-res tiling to get created. @@ -2650,7 +2661,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); // Once we stop animating, a new high-res tiling should be created. animating_transform = false; @@ -2658,7 +2669,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 4.f); // When animating with an unknown maximum animation scale factor, a new // high-res tiling should be created at a source scale of 1. @@ -2669,7 +2680,8 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), page_scale * device_scale); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), + page_scale * device_scale); // Further changes to scale during the animation should not cause a new // high-res tiling to get created. @@ -2678,7 +2690,8 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), page_scale * device_scale); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), + page_scale * device_scale); // Once we stop animating, a new high-res tiling should be created. animating_transform = false; @@ -2687,7 +2700,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 4.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 4.f); // When animating with a maxmium animation scale factor that is so large // that the layer grows larger than the viewport at this scale, a new @@ -2700,7 +2713,8 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), page_scale * device_scale); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), + page_scale * device_scale); // Once we stop animating, a new high-res tiling should be created. animating_transform = false; @@ -2709,7 +2723,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 11.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 11.f); // When animating with a maxmium animation scale factor that is so large // that the layer grows larger than the viewport at this scale, and where @@ -2722,7 +2736,8 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), device_scale * page_scale); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), + device_scale * page_scale); // Once we stop animating, a new high-res tiling should be created. animating_transform = false; @@ -2731,7 +2746,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 12.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 12.f); // When animating toward a smaller scale, but that is still so large that the // layer grows larger than the viewport at this scale, a new high-res tiling @@ -2743,7 +2758,8 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), device_scale * page_scale); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), + device_scale * page_scale); // Once we stop animating, a new high-res tiling should be created. animating_transform = false; @@ -2752,7 +2768,7 @@ TEST_F(PictureLayerImplTest, HighResTilingDuringAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 11.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 11.f); } TEST_F(PictureLayerImplTest, TilingSetRasterQueue) { @@ -3017,18 +3033,19 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { EXPECT_FALSE(tile->required_for_activation()); - while (std::abs(tile->contents_scale() - expected_scales[scale_index]) > + while (std::abs(tile->contents_scale_key() - expected_scales[scale_index]) > std::numeric_limits<float>::epsilon()) { ++scale_index; ASSERT_LT(scale_index, arraysize(expected_scales)); } - EXPECT_FLOAT_EQ(tile->contents_scale(), expected_scales[scale_index]); + EXPECT_FLOAT_EQ(tile->contents_scale_key(), expected_scales[scale_index]); unique_tiles.insert(tile); if (tile->required_for_activation() == last_tile.tile()->required_for_activation() && - std::abs(tile->contents_scale() - last_tile.tile()->contents_scale()) < + std::abs(tile->contents_scale_key() - + last_tile.tile()->contents_scale_key()) < std::numeric_limits<float>::epsilon()) { if (priority.distance_to_visible <= last_tile.priority().distance_to_visible) @@ -3064,13 +3081,13 @@ TEST_F(PictureLayerImplTest, TilingSetEvictionQueue) { scale_index = 0; } - while (std::abs(tile->contents_scale() - expected_scales[scale_index]) > + while (std::abs(tile->contents_scale_key() - expected_scales[scale_index]) > std::numeric_limits<float>::epsilon()) { ++scale_index; ASSERT_LT(scale_index, arraysize(expected_scales)); } - EXPECT_FLOAT_EQ(tile->contents_scale(), expected_scales[scale_index]); + EXPECT_FLOAT_EQ(tile->contents_scale_key(), expected_scales[scale_index]); unique_tiles.insert(tile); queue->Pop(); } @@ -3145,7 +3162,7 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 2.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 2.f); // Changing the source scale without being in an animation will cause // the layer to change scale. @@ -3154,14 +3171,14 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); contents_scale = 0.5f; SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 0.5f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 0.5f); // However, if the layer has a will-change property, then the raster scale // will get fixed at the last value. @@ -3173,7 +3190,7 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 0.5f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 0.5f); // Further changes to the source scale will no longer be reflected in the // contents scale. @@ -3182,7 +3199,7 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 0.5f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 0.5f); // Disabling the will-change hint will once again make the raster scale update // with the ideal scale. @@ -3194,7 +3211,7 @@ TEST_F(PictureLayerImplTest, RasterScaleChangeWithoutAnimation) { SetContentsScaleOnBothLayers(contents_scale, device_scale, page_scale, maximum_animation_scale, starting_animation_scale, animating_transform); - EXPECT_BOTH_EQ(HighResTiling()->contents_scale(), 3.f); + EXPECT_BOTH_EQ(HighResTiling()->contents_scale_key(), 3.f); } TEST_F(PictureLayerImplTest, LowResReadyToDrawNotEnoughToActivate) { @@ -3277,8 +3294,8 @@ TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(1u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the page scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(active_layer(), @@ -3289,8 +3306,8 @@ TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.6f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.6f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the device scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(active_layer(), @@ -3301,8 +3318,8 @@ TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. @@ -3314,8 +3331,8 @@ TEST_F(NoLowResPictureLayerImplTest, ManageTilingsCreatesTilings) { 0.f, // starting animation scale false); ASSERT_EQ(3u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - active_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, active_layer()->tilings()->tiling_at(0)->contents_scale_key()); } TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { @@ -3335,8 +3352,8 @@ TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the page scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(pending_layer(), @@ -3347,8 +3364,8 @@ TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(6.6f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 6.6f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the device scale factor, then we should get new tilings. SetupDrawPropertiesAndUpdateTiles(pending_layer(), @@ -3359,8 +3376,8 @@ TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); // If we change the device scale factor, but end up at the same total scale // factor somehow, then we don't get new tilings. @@ -3372,8 +3389,8 @@ TEST_F(NoLowResPictureLayerImplTest, PendingLayerOnlyHasHighResTiling) { 0.f, // starting animation scale false); ASSERT_EQ(1u, pending_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(7.26f, - pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_FLOAT_EQ( + 7.26f, pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); } TEST_F(NoLowResPictureLayerImplTest, AllHighResRequiredEvenIfNotChanged) { @@ -3483,8 +3500,8 @@ TEST_F(NoLowResPictureLayerImplTest, CleanUpTilings) { page_scale /= 4.f; SetContentsScaleOnBothLayers(1.2f, device_scale, page_scale, 1.f, 0.f, false); ASSERT_EQ(2u, active_layer()->tilings()->num_tilings()); - EXPECT_FLOAT_EQ(1.f, - active_layer()->tilings()->tiling_at(1)->contents_scale()); + EXPECT_FLOAT_EQ( + 1.f, active_layer()->tilings()->tiling_at(1)->contents_scale_key()); // Ensure UpdateTiles won't remove any tilings. active_layer()->MarkAllTilingsUsed(); @@ -3705,8 +3722,8 @@ class OcclusionTrackingPictureLayerImplTest : public PictureLayerImplTest { EXPECT_TRUE(tile_priority_bin < last_tile_priority_bin || tile->required_for_activation() || - tile->contents_scale() != - last_tile.tile()->contents_scale()) + tile->contents_scale_key() != + last_tile.tile()->contents_scale_key()) << "line: " << source_line; } } @@ -3984,7 +4001,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, OcclusionForDifferentScales) { for (size_t j = 0; j < tiles.size(); ++j) { if (prioritized_tiles[tiles[j]].is_occluded()) { gfx::Rect scaled_content_rect = ScaleToEnclosingRect( - tiles[j]->content_rect(), 1.0f / tiles[j]->contents_scale()); + tiles[j]->content_rect(), 1.f / tiles[j]->raster_scales().width(), + 1.f / tiles[j]->raster_scales().height()); EXPECT_GE(scaled_content_rect.x(), occluding_layer_position.x()); occluded_tile_count++; } @@ -4048,7 +4066,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { const Tile* tile = *iter; gfx::Rect scaled_content_rect = ScaleToEnclosingRect( - tile->content_rect(), 1.0f / tile->contents_scale()); + tile->content_rect(), 1.f / tile->raster_scales().width(), + 1.f / tile->raster_scales().height()); // Tiles are occluded on the active tree iff they lie beneath the // occluding layer. EXPECT_EQ(prioritized_tiles[tile].is_occluded(), @@ -4084,7 +4103,8 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, DifferentOcclusionOnTrees) { active_layer()->GetPendingOrActiveTwinTiling(tiling)->TileAt( iter.i(), iter.j()); gfx::Rect scaled_content_rect = ScaleToEnclosingRect( - tile->content_rect(), 1.0f / tile->contents_scale()); + tile->content_rect(), 1.f / tile->raster_scales().height(), + 1.f / tile->raster_scales().width()); if (scaled_content_rect.Intersects(invalidation_rect)) { // Tiles inside the invalidation rect exist on both trees. @@ -4192,7 +4212,7 @@ TEST_F(OcclusionTrackingPictureLayerImplTest, } EXPECT_EQ(expected_occluded_tile_count_on_pending[i], occluded_tile_count_on_pending) - << tiling->contents_scale(); + << tiling->contents_scale_key(); } // Verify number of occluded tiles on the active layer for each tiling. @@ -4315,8 +4335,9 @@ void PictureLayerImplTest::TestQuadsForSolidColor(bool test_for_solid) { scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); host->SetRootLayer(layer); RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); @@ -4376,8 +4397,9 @@ TEST_F(PictureLayerImplTest, NonSolidToSolidNoTilings) { scoped_refptr<PictureLayer> layer = PictureLayer::Create(&client); FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); host->SetRootLayer(layer); RecordingSource* recording_source = layer->GetRecordingSourceForTesting(); @@ -4780,7 +4802,7 @@ TEST_F(NoLowResPictureLayerImplTest, LowResWasHighResCollision) { float page_scale = 2.f; SetContentsScaleOnBothLayers(page_scale, 1.0f, page_scale, 1.0f, 0.f, false); EXPECT_BOTH_EQ(num_tilings(), 1u); - EXPECT_BOTH_EQ(tilings()->tiling_at(0)->contents_scale(), page_scale); + EXPECT_BOTH_EQ(tilings()->tiling_at(0)->contents_scale_key(), page_scale); host_impl()->PinchGestureBegin(); @@ -4789,7 +4811,8 @@ TEST_F(NoLowResPictureLayerImplTest, LowResWasHighResCollision) { float zoomed = page_scale / low_res_factor; SetContentsScaleOnBothLayers(zoomed, 1.0f, zoomed, 1.0f, 0.f, false); EXPECT_EQ(1u, pending_layer()->num_tilings()); - EXPECT_EQ(zoomed, pending_layer()->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(zoomed, + pending_layer()->tilings()->tiling_at(0)->contents_scale_key()); } TEST_F(PictureLayerImplTest, HighResWasLowResCollision) { @@ -4807,8 +4830,9 @@ TEST_F(PictureLayerImplTest, HighResWasLowResCollision) { page_scale, 1.0f, 0.f, false); EXPECT_EQ(2u, active_layer()->tilings()->num_tilings()); EXPECT_EQ(page_scale, - active_layer()->tilings()->tiling_at(0)->contents_scale()); - EXPECT_EQ(low_res, active_layer()->tilings()->tiling_at(1)->contents_scale()); + active_layer()->tilings()->tiling_at(0)->contents_scale_key()); + EXPECT_EQ(low_res, + active_layer()->tilings()->tiling_at(1)->contents_scale_key()); // Grab a current low res tile. PictureLayerTiling* old_low_res_tiling = @@ -4833,9 +4857,9 @@ TEST_F(PictureLayerImplTest, HighResWasLowResCollision) { EXPECT_EQ(3u, active_layer()->num_tilings()); PictureLayerTilingSet* tilings = active_layer()->tilings(); - EXPECT_EQ(page_scale, tilings->tiling_at(0)->contents_scale()); - EXPECT_EQ(low_res, tilings->tiling_at(1)->contents_scale()); - EXPECT_EQ(extra_low_res, tilings->tiling_at(2)->contents_scale()); + EXPECT_EQ(page_scale, tilings->tiling_at(0)->contents_scale_key()); + EXPECT_EQ(low_res, tilings->tiling_at(1)->contents_scale_key()); + EXPECT_EQ(extra_low_res, tilings->tiling_at(2)->contents_scale_key()); EXPECT_EQ(NON_IDEAL_RESOLUTION, tilings->tiling_at(0)->resolution()); EXPECT_EQ(HIGH_RESOLUTION, tilings->tiling_at(1)->resolution()); @@ -4906,7 +4930,8 @@ TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) { pending_layer_ptr, suggested_ideal_contents_scale, device_scale_factor, page_scale_factor, animation_contents_scale, animation_contents_scale, animating_transform_to_screen); - EXPECT_EQ(1.f, pending_layer_ptr->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(1.f, + pending_layer_ptr->tilings()->tiling_at(0)->contents_scale_key()); // Push to active layer. host_impl()->ActivateSyncTree(); @@ -4917,7 +4942,7 @@ TEST_F(PictureLayerImplTest, CompositedImageIgnoreIdealContentsScale) { active_layer, suggested_ideal_contents_scale, device_scale_factor, page_scale_factor, animation_contents_scale, animation_contents_scale, animating_transform_to_screen); - EXPECT_EQ(1.f, active_layer->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(1.f, active_layer->tilings()->tiling_at(0)->contents_scale_key()); active_layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); // Create resources for the tiles. @@ -4973,7 +4998,7 @@ TEST_F(PictureLayerImplTest, CompositedImageRasterScaleChanges) { EXPECT_FLOAT_EQ(expected_contents_scale, pending_layer_ptr->picture_layer_tiling_set() ->FindTilingWithResolution(HIGH_RESOLUTION) - ->contents_scale()) + ->contents_scale_key()) << "ideal_contents_scale: " << ideal_contents_scale; } @@ -4995,7 +5020,7 @@ TEST_F(PictureLayerImplTest, CompositedImageRasterScaleChanges) { EXPECT_FLOAT_EQ(expected_contents_scale, pending_layer_ptr->picture_layer_tiling_set() ->FindTilingWithResolution(HIGH_RESOLUTION) - ->contents_scale()) + ->contents_scale_key()) << "ideal_contents_scale: " << ideal_contents_scale; } } diff --git a/chromium/cc/layers/picture_layer_unittest.cc b/chromium/cc/layers/picture_layer_unittest.cc index c3645ed549b..bda0e41b916 100644 --- a/chromium/cc/layers/picture_layer_unittest.cc +++ b/chromium/cc/layers/picture_layer_unittest.cc @@ -27,7 +27,6 @@ #include "cc/test/layer_tree_settings_for_testing.h" #include "cc/test/skia_common.h" #include "cc/test/stub_layer_tree_host_single_thread_client.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/single_thread_proxy.h" #include "testing/gmock/include/gmock/gmock.h" @@ -36,197 +35,8 @@ namespace cc { -class TestSerializationPictureLayer : public PictureLayer { - public: - static scoped_refptr<TestSerializationPictureLayer> Create( - const gfx::Size& recording_source_viewport) { - return make_scoped_refptr(new TestSerializationPictureLayer( - EmptyContentLayerClient::GetInstance(), - FakeRecordingSource::CreateFilledRecordingSource( - recording_source_viewport), - recording_source_viewport)); - } - - FakeRecordingSource* recording_source() { - return static_cast<FakeRecordingSource*>(recording_source_.get()); - } - - void set_invalidation(const Region& invalidation) { - last_updated_invalidation_ = invalidation; - } - - void set_update_source_frame_number(int number) { - update_source_frame_number_ = number; - } - - void set_is_mask(bool is_mask) { is_mask_ = is_mask; } - - void set_nearest_neighbor(bool nearest_neighbor) { - picture_layer_inputs_.nearest_neighbor = nearest_neighbor; - } - - void ValidateSerialization( - ImageSerializationProcessor* image_serialization_processor, - LayerTreeHostInProcess* host) { - std::vector<uint32_t> engine_picture_ids = GetPictureIds(); - proto::LayerProperties proto; - LayerSpecificPropertiesToProto(&proto, false); - - FakeEnginePictureCache* engine_picture_cache = - static_cast<FakeEnginePictureCache*>(host->engine_picture_cache()); - EXPECT_THAT(engine_picture_ids, - testing::UnorderedElementsAreArray( - engine_picture_cache->GetAllUsedPictureIds())); - - scoped_refptr<TestSerializationPictureLayer> layer = - TestSerializationPictureLayer::Create(recording_source_viewport_); - host->GetLayerTree()->SetRootLayer(layer); - - layer->FromLayerSpecificPropertiesProto(proto); - - FakeClientPictureCache* client_picture_cache = - static_cast<FakeClientPictureCache*>(host->client_picture_cache()); - EXPECT_THAT(engine_picture_ids, - testing::UnorderedElementsAreArray( - client_picture_cache->GetAllUsedPictureIds())); - - // Validate that the PictureLayer specific fields are properly set. - EXPECT_TRUE(recording_source()->EqualsTo(*layer->recording_source())); - EXPECT_EQ(update_source_frame_number_, layer->update_source_frame_number_); - EXPECT_EQ(is_mask_, layer->is_mask_); - EXPECT_EQ(picture_layer_inputs_.nearest_neighbor, - layer->picture_layer_inputs_.nearest_neighbor); - EXPECT_EQ(picture_layer_inputs_.recorded_viewport, - layer->picture_layer_inputs_.recorded_viewport); - - // The DisplayItemLists are equal if they are both null or they are both not - // null and render to the same thing. - bool display_lists_equal = !picture_layer_inputs_.display_list && - !layer->picture_layer_inputs_.display_list; - if (picture_layer_inputs_.display_list && - layer->picture_layer_inputs_.display_list) { - display_lists_equal = AreDisplayListDrawingResultsSame( - picture_layer_inputs_.recorded_viewport, - picture_layer_inputs_.display_list.get(), - layer->picture_layer_inputs_.display_list.get()); - } - EXPECT_TRUE(display_lists_equal); - } - - std::vector<uint32_t> GetPictureIds() { - std::vector<uint32_t> ids; - const DisplayItemList* display_list = - picture_layer_inputs_.display_list.get(); - if (!display_list) - return ids; - - for (auto it = display_list->begin(); it != display_list->end(); ++it) { - sk_sp<const SkPicture> picture = it->GetPicture(); - if (!picture) - continue; - - ids.push_back(picture->uniqueID()); - } - return ids; - } - - private: - TestSerializationPictureLayer(ContentLayerClient* client, - std::unique_ptr<RecordingSource> source, - const gfx::Size& recording_source_viewport) - : PictureLayer(client, std::move(source)), - recording_source_viewport_(recording_source_viewport) {} - ~TestSerializationPictureLayer() override {} - - gfx::Size recording_source_viewport_; - - DISALLOW_COPY_AND_ASSIGN(TestSerializationPictureLayer); -}; - namespace { -TEST(PictureLayerTest, TestSetAllPropsSerializationDeserialization) { - FakeLayerTreeHostClient host_client; - TestTaskGraphRunner task_graph_runner; - LayerTreeSettings settings = LayerTreeSettingsForTesting(); - std::unique_ptr<FakeImageSerializationProcessor> - fake_image_serialization_processor = - base::WrapUnique(new FakeImageSerializationProcessor); - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner, settings, - CompositorMode::SINGLE_THREADED, - fake_image_serialization_processor.get()); - host->InitializePictureCacheForTesting(); - - gfx::Size recording_source_viewport(256, 256); - scoped_refptr<TestSerializationPictureLayer> layer = - TestSerializationPictureLayer::Create(recording_source_viewport); - host->GetLayerTree()->SetRootLayer(layer); - - Region region(gfx::Rect(14, 15, 16, 17)); - layer->set_invalidation(region); - layer->set_is_mask(true); - layer->set_nearest_neighbor(true); - - layer->SetBounds(recording_source_viewport); - layer->set_update_source_frame_number(0); - layer->recording_source()->SetDisplayListUsesCachedPicture(false); - layer->recording_source()->add_draw_rect( - gfx::Rect(recording_source_viewport)); - layer->recording_source()->SetGenerateDiscardableImagesMetadata(true); - layer->recording_source()->Rerecord(); - layer->ValidateSerialization(fake_image_serialization_processor.get(), - host.get()); -} - -TEST(PictureLayerTest, TestSerializationDeserialization) { - FakeLayerTreeHostClient host_client; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeImageSerializationProcessor> - fake_image_serialization_processor = - base::WrapUnique(new FakeImageSerializationProcessor); - std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( - &host_client, &task_graph_runner, LayerTreeSettings(), - CompositorMode::SINGLE_THREADED, - fake_image_serialization_processor.get()); - host->InitializePictureCacheForTesting(); - - gfx::Size recording_source_viewport(256, 256); - scoped_refptr<TestSerializationPictureLayer> layer = - TestSerializationPictureLayer::Create(recording_source_viewport); - host->GetLayerTree()->SetRootLayer(layer); - - layer->SetBounds(recording_source_viewport); - layer->set_update_source_frame_number(0); - layer->recording_source()->SetDisplayListUsesCachedPicture(false); - layer->recording_source()->add_draw_rect( - gfx::Rect(recording_source_viewport)); - layer->recording_source()->SetGenerateDiscardableImagesMetadata(true); - layer->recording_source()->Rerecord(); - layer->ValidateSerialization(fake_image_serialization_processor.get(), - host.get()); -} - -TEST(PictureLayerTest, TestEmptySerializationDeserialization) { - std::unique_ptr<FakeImageSerializationProcessor> - fake_image_serialization_processor = - base::WrapUnique(new FakeImageSerializationProcessor); - FakeLayerTreeHostClient host_client; - TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( - &host_client, &task_graph_runner, LayerTreeSettings(), - CompositorMode::SINGLE_THREADED, - fake_image_serialization_processor.get()); - host->InitializePictureCacheForTesting(); - - gfx::Size recording_source_viewport(256, 256); - scoped_refptr<TestSerializationPictureLayer> layer = - TestSerializationPictureLayer::Create(recording_source_viewport); - host->GetLayerTree()->SetRootLayer(layer); - layer->ValidateSerialization(fake_image_serialization_processor.get(), - host.get()); -} - TEST(PictureLayerTest, NoTilesIfEmptyBounds) { ContentLayerClient* client = EmptyContentLayerClient::GetInstance(); scoped_refptr<PictureLayer> layer = PictureLayer::Create(client); @@ -234,8 +44,9 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) { FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); host->GetLayerTree()->SetRootLayer(layer); layer->SetIsDrawable(true); layer->SavePaintProperties(); @@ -252,12 +63,10 @@ TEST(PictureLayerTest, NoTilesIfEmptyBounds) { FakeImplTaskRunnerProvider impl_task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; std::unique_ptr<FakeCompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::CreateSoftware(); - FakeLayerTreeHostImpl host_impl(LayerTreeSettings(), - &impl_task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + FakeLayerTreeHostImpl host_impl( + LayerTreeSettings(), &impl_task_runner_provider, &task_graph_runner); host_impl.InitializeRenderer(compositor_frame_sink.get()); host_impl.CreatePendingTree(); std::unique_ptr<FakePictureLayerImpl> layer_impl = @@ -279,8 +88,9 @@ TEST(PictureLayerTest, InvalidateRasterAfterUpdate) { FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); host->GetLayerTree()->SetRootLayer(layer); layer->SetIsDrawable(true); layer->SavePaintProperties(); @@ -293,14 +103,12 @@ TEST(PictureLayerTest, InvalidateRasterAfterUpdate) { host->CommitComplete(); FakeImplTaskRunnerProvider impl_task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; std::unique_ptr<CompositorFrameSink> compositor_frame_sink( FakeCompositorFrameSink::Create3d()); LayerTreeSettings layer_tree_settings = LayerTreeSettingsForTesting(); layer_tree_settings.image_decode_tasks_enabled = true; - FakeLayerTreeHostImpl host_impl(layer_tree_settings, - &impl_task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + FakeLayerTreeHostImpl host_impl( + layer_tree_settings, &impl_task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); host_impl.CreatePendingTree(); @@ -324,8 +132,9 @@ TEST(PictureLayerTest, InvalidateRasterWithoutUpdate) { FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); host->GetLayerTree()->SetRootLayer(layer); layer->SetIsDrawable(true); layer->SavePaintProperties(); @@ -337,14 +146,12 @@ TEST(PictureLayerTest, InvalidateRasterWithoutUpdate) { host->CommitComplete(); FakeImplTaskRunnerProvider impl_task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; std::unique_ptr<CompositorFrameSink> compositor_frame_sink( FakeCompositorFrameSink::Create3d()); LayerTreeSettings layer_tree_settings = LayerTreeSettingsForTesting(); layer_tree_settings.image_decode_tasks_enabled = true; - FakeLayerTreeHostImpl host_impl(layer_tree_settings, - &impl_task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + FakeLayerTreeHostImpl host_impl( + layer_tree_settings, &impl_task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); host_impl.CreatePendingTree(); @@ -369,8 +176,9 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); host->GetLayerTree()->SetRootLayer(layer); layer->SetIsDrawable(true); layer->SavePaintProperties(); @@ -385,14 +193,12 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) { FakeImplTaskRunnerProvider impl_task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; std::unique_ptr<CompositorFrameSink> compositor_frame_sink( FakeCompositorFrameSink::Create3d()); LayerTreeSettings layer_tree_settings = LayerTreeSettingsForTesting(); layer_tree_settings.image_decode_tasks_enabled = true; - FakeLayerTreeHostImpl host_impl(layer_tree_settings, - &impl_task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + FakeLayerTreeHostImpl host_impl( + layer_tree_settings, &impl_task_runner_provider, &task_graph_runner); host_impl.SetVisible(true); EXPECT_TRUE(host_impl.InitializeRenderer(compositor_frame_sink.get())); @@ -451,8 +257,9 @@ TEST(PictureLayerTest, SuitableForGpuRasterization) { FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get()); host->GetLayerTree()->SetRootLayer(layer); // Update layers to initialize the recording source. @@ -491,35 +298,35 @@ TEST(PictureLayerTest, NonMonotonicSourceFrameNumber) { StubLayerTreeHostSingleThreadClient single_thread_client; FakeLayerTreeHostClient host_client1; FakeLayerTreeHostClient host_client2; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; ContentLayerClient* client = EmptyContentLayerClient::GetInstance(); scoped_refptr<FakePictureLayer> layer = FakePictureLayer::Create(client); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + LayerTreeHostInProcess::InitParams params; params.client = &host_client1; - params.shared_bitmap_manager = &shared_bitmap_manager; params.settings = &settings; params.task_graph_runner = &task_graph_runner; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); - params.animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + params.mutator_host = animation_host.get(); std::unique_ptr<LayerTreeHost> host1 = LayerTreeHostInProcess::CreateSingleThreaded(&single_thread_client, ¶ms); host1->SetVisible(true); host_client1.SetLayerTreeHost(host1.get()); + auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + // TODO(sad): InitParams will be movable. LayerTreeHostInProcess::InitParams params2; params2.client = &host_client1; - params2.shared_bitmap_manager = &shared_bitmap_manager; params2.settings = &settings; params2.task_graph_runner = &task_graph_runner; params2.main_task_runner = base::ThreadTaskRunnerHandle::Get(); params2.client = &host_client2; - params2.animation_host = - AnimationHost::CreateForTesting(ThreadInstance::MAIN); + params2.mutator_host = animation_host2.get(); std::unique_ptr<LayerTreeHost> host2 = LayerTreeHostInProcess::CreateSingleThreaded(&single_thread_client, ¶ms2); @@ -551,6 +358,9 @@ TEST(PictureLayerTest, NonMonotonicSourceFrameNumber) { host2->Composite(base::TimeTicks::Now()); EXPECT_EQ(3, layer->update_count()); EXPECT_EQ(1, host2->SourceFrameNumber()); + + animation_host->SetMutatorHostClient(nullptr); + animation_host2->SetMutatorHostClient(nullptr); } } // namespace diff --git a/chromium/cc/layers/render_surface_impl.cc b/chromium/cc/layers/render_surface_impl.cc index 4a08fa1de9a..483ad01162f 100644 --- a/chromium/cc/layers/render_surface_impl.cc +++ b/chromium/cc/layers/render_surface_impl.cc @@ -361,13 +361,17 @@ void RenderSurfaceImpl::AppendQuads(RenderPass* render_pass, if (visible_layer_rect.IsEmpty()) return; + const PropertyTrees* property_trees = + owning_layer_->layer_tree_impl()->property_trees(); + int sorting_context_id = + property_trees->transform_tree.Node(TransformTreeIndex()) + ->sorting_context_id; SharedQuadState* shared_quad_state = render_pass->CreateAndAppendSharedQuadState(); - shared_quad_state->SetAll(draw_transform, content_rect().size(), - content_rect(), draw_properties_.clip_rect, - draw_properties_.is_clipped, - draw_properties_.draw_opacity, BlendMode(), - owning_layer_->sorting_context_id()); + shared_quad_state->SetAll( + draw_transform, content_rect().size(), content_rect(), + draw_properties_.clip_rect, draw_properties_.is_clipped, + draw_properties_.draw_opacity, BlendMode(), sorting_context_id); if (owning_layer_->ShowDebugBorders()) { DebugBorderDrawQuad* debug_border_quad = diff --git a/chromium/cc/layers/render_surface_unittest.cc b/chromium/cc/layers/render_surface_unittest.cc index 898e2353ecb..dda0fb206f8 100644 --- a/chromium/cc/layers/render_surface_unittest.cc +++ b/chromium/cc/layers/render_surface_unittest.cc @@ -12,7 +12,6 @@ #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/mock_occlusion_tracker.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/single_thread_proxy.h" @@ -39,10 +38,8 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) { // FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> owning_layer = LayerImpl::Create(host_impl.active_tree(), 1); owning_layer->SetHasRenderSurface(true); @@ -90,12 +87,10 @@ TEST(RenderSurfaceTest, VerifySurfaceChangesAreTrackedProperly) { TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectSharedQuadState) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root_layer = LayerImpl::Create(host_impl.active_tree(), 1); @@ -163,10 +158,8 @@ class TestRenderPassSink : public RenderPassSink { TEST(RenderSurfaceTest, SanityCheckSurfaceCreatesCorrectRenderPass) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root_layer = LayerImpl::Create(host_impl.active_tree(), 1); diff --git a/chromium/cc/layers/scrollbar_layer_interface.h b/chromium/cc/layers/scrollbar_layer_interface.h index 5a386b05c02..acb73924409 100644 --- a/chromium/cc/layers/scrollbar_layer_interface.h +++ b/chromium/cc/layers/scrollbar_layer_interface.h @@ -11,9 +11,6 @@ namespace cc { -class Layer; -class LayerImpl; - class CC_EXPORT ScrollbarLayerInterface { public: virtual int ScrollLayerId() const = 0; diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc index 021efb54c20..f301435593a 100644 --- a/chromium/cc/layers/scrollbar_layer_unittest.cc +++ b/chromium/cc/layers/scrollbar_layer_unittest.cc @@ -103,19 +103,21 @@ class ScrollbarLayerTest : public testing::Test { layer_tree_settings_.single_thread_proxy_scheduler = false; layer_tree_settings_.use_zero_copy = true; layer_tree_settings_.scrollbar_animator = LayerTreeSettings::LINEAR_FADE; - layer_tree_settings_.scrollbar_fade_delay_ms = 20; - layer_tree_settings_.scrollbar_fade_duration_ms = 20; - layer_tree_settings_.verify_transform_tree_calculations = true; + layer_tree_settings_.scrollbar_fade_delay = + base::TimeDelta::FromMilliseconds(20); + layer_tree_settings_.scrollbar_fade_duration = + base::TimeDelta::FromMilliseconds(20); layer_tree_settings_.verify_clip_tree_calculations = true; scrollbar_layer_id_ = -1; + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + LayerTreeHostInProcess::InitParams params; params.client = &fake_client_; params.settings = &layer_tree_settings_; params.task_graph_runner = &task_graph_runner_; - params.animation_host = - AnimationHost::CreateForTesting(ThreadInstance::MAIN); + params.mutator_host = animation_host_.get(); std::unique_ptr<FakeResourceTrackingUIResourceManager> fake_ui_resource_manager = @@ -166,6 +168,7 @@ class ScrollbarLayerTest : public testing::Test { StubLayerTreeHostSingleThreadClient single_thread_client_; TestTaskGraphRunner task_graph_runner_; LayerTreeSettings layer_tree_settings_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; LayerTree* layer_tree_; int scrollbar_layer_id_; @@ -400,6 +403,56 @@ TEST_F(ScrollbarLayerTest, ThumbRect) { scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); } +TEST_F(ScrollbarLayerTest, ThumbRectForOverlayLeftSideVerticalScrollbar) { + scoped_refptr<Layer> root_clip_layer = Layer::Create(); + scoped_refptr<Layer> root_layer = Layer::Create(); + // Create an overlay left side vertical scrollbar. + scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer = + FakePaintedScrollbarLayer::Create(false, true, VERTICAL, true, true, + root_layer->id()); + root_layer->SetScrollClipLayerId(root_clip_layer->id()); + root_clip_layer->SetBounds(gfx::Size(50, 20)); + root_layer->SetBounds(gfx::Size(50, 100)); + + layer_tree_->SetRootLayer(root_clip_layer); + root_clip_layer->AddChild(root_layer); + root_layer->AddChild(scrollbar_layer); + + root_layer->SetScrollOffset(gfx::ScrollOffset(0, 0)); + scrollbar_layer->SetBounds(gfx::Size(10, 20)); + scrollbar_layer->SetScrollLayer(root_layer->id()); + scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 0, 10, 20)); + scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10); + scrollbar_layer->fake_scrollbar()->set_thumb_length(4); + layer_tree_host_->UpdateLayers(); + LayerImpl* root_clip_layer_impl = nullptr; + PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr; + + // Thumb is at the edge of the scrollbar (should be inset to + // the start of the track within the scrollbar layer's + // position). + UPDATE_AND_EXTRACT_LAYER_POINTERS(); + EXPECT_EQ(gfx::Rect(0, 0, 10, 4).ToString(), + scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); + + // Change thumb thickness scale factor. + scrollbar_layer_impl->SetThumbThicknessScaleFactor(0.5); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); + // For overlay scrollbars thumb_rect.width = thumb_thickness * + // thumb_thickness_scale_factor. + EXPECT_EQ(gfx::Rect(0, 0, 5, 4).ToString(), + scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); + + // Change thumb thickness and length. + scrollbar_layer->fake_scrollbar()->set_thumb_thickness(4); + scrollbar_layer->fake_scrollbar()->set_thumb_length(6); + UPDATE_AND_EXTRACT_LAYER_POINTERS(); + // For left side vertical scrollbars thumb_rect.x = bounds.width() - + // thumb_thickness. + EXPECT_EQ(gfx::Rect(6, 0, 2, 6).ToString(), + scrollbar_layer_impl->ComputeThumbQuadRect().ToString()); +} + TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) { const int kThumbThickness = 3; const int kTrackStart = 1; @@ -642,11 +695,9 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { public: ScrollbarLayerSolidColorThumbTest() { LayerTreeSettings layer_tree_settings; - layer_tree_settings.verify_transform_tree_calculations = true; layer_tree_settings.verify_clip_tree_calculations = true; host_impl_.reset(new FakeLayerTreeHostImpl( - layer_tree_settings, &task_runner_provider_, &shared_bitmap_manager_, - &task_graph_runner_)); + layer_tree_settings, &task_runner_provider_, &task_graph_runner_)); const int kThumbThickness = 3; const int kTrackStart = 0; @@ -673,7 +724,6 @@ class ScrollbarLayerSolidColorThumbTest : public testing::Test { protected: FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; std::unique_ptr<FakeLayerTreeHostImpl> host_impl_; std::unique_ptr<SolidColorScrollbarLayerImpl> horizontal_scrollbar_layer_; diff --git a/chromium/cc/layers/solid_color_layer_impl_unittest.cc b/chromium/cc/layers/solid_color_layer_impl_unittest.cc index f02e0d294f6..312449b2d88 100644 --- a/chromium/cc/layers/solid_color_layer_impl_unittest.cc +++ b/chromium/cc/layers/solid_color_layer_impl_unittest.cc @@ -8,6 +8,7 @@ #include <vector> +#include "cc/animation/animation_host.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/solid_color_layer.h" #include "cc/quads/solid_color_draw_quad.h" @@ -31,8 +32,7 @@ TEST(SolidColorLayerImplTest, VerifyTilingCompleteAndNoOverlap) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, - &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; @@ -56,8 +56,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBackgroundColorInQuad) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, - &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; @@ -84,8 +83,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectOpacityInQuad) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, - &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; @@ -111,8 +109,7 @@ TEST(SolidColorLayerImplTest, VerifyCorrectBlendModeInQuad) { FakeImplTaskRunnerProvider task_runner_provider; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, nullptr, - &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->SetBounds(layer_size); @@ -139,8 +136,9 @@ TEST(SolidColorLayerImplTest, VerifyOpaqueRect) { FakeLayerTreeHostClient client; TestTaskGraphRunner task_graph_runner; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&client, &task_graph_runner); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &client, &task_graph_runner, animation_host.get()); host->SetRootLayer(root); LayerTreeHostCommon::CalcDrawPropsMainInputsForTesting inputs( diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.cc b/chromium/cc/layers/solid_color_scrollbar_layer.cc index 123b7ae677a..5c276b37ea4 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer.cc +++ b/chromium/cc/layers/solid_color_scrollbar_layer.cc @@ -70,6 +70,22 @@ ScrollbarLayerInterface* SolidColorScrollbarLayer::ToScrollbarLayer() { return this; } +void SolidColorScrollbarLayer::ToLayerNodeProto(proto::LayerNode* proto) const { + Layer::ToLayerNodeProto(proto); + + proto::SolidColorScrollbarLayerProperties* scrollbar = + proto->mutable_solid_scrollbar(); + scrollbar->set_scroll_layer_id( + solid_color_scrollbar_layer_inputs_.scroll_layer_id); + scrollbar->set_thumb_thickness( + solid_color_scrollbar_layer_inputs_.thumb_thickness); + scrollbar->set_track_start(solid_color_scrollbar_layer_inputs_.track_start); + scrollbar->set_is_left_side_vertical_scrollbar( + solid_color_scrollbar_layer_inputs_.is_left_side_vertical_scrollbar); + scrollbar->set_orientation(ScrollbarOrientationToProto( + solid_color_scrollbar_layer_inputs_.orientation)); +} + void SolidColorScrollbarLayer::SetOpacity(float opacity) { // The opacity of a solid color scrollbar layer is always 0 on main thread. DCHECK_EQ(opacity, 0.f); @@ -118,39 +134,4 @@ void SolidColorScrollbarLayer::SetTypeForProtoSerialization( proto->set_type(proto::LayerNode::SOLID_COLOR_SCROLLBAR_LAYER); } -void SolidColorScrollbarLayer::LayerSpecificPropertiesToProto( - proto::LayerProperties* proto, - bool inputs_only) { - Layer::LayerSpecificPropertiesToProto(proto, inputs_only); - - proto::SolidColorScrollbarLayerProperties* scrollbar = - proto->mutable_solid_scrollbar(); - scrollbar->set_scroll_layer_id( - solid_color_scrollbar_layer_inputs_.scroll_layer_id); - scrollbar->set_thumb_thickness( - solid_color_scrollbar_layer_inputs_.thumb_thickness); - scrollbar->set_track_start(solid_color_scrollbar_layer_inputs_.track_start); - scrollbar->set_is_left_side_vertical_scrollbar( - solid_color_scrollbar_layer_inputs_.is_left_side_vertical_scrollbar); - scrollbar->set_orientation(ScrollbarOrientationToProto( - solid_color_scrollbar_layer_inputs_.orientation)); -} - -void SolidColorScrollbarLayer::FromLayerSpecificPropertiesProto( - const proto::LayerProperties& proto) { - Layer::FromLayerSpecificPropertiesProto(proto); - - const proto::SolidColorScrollbarLayerProperties& scrollbar = - proto.solid_scrollbar(); - solid_color_scrollbar_layer_inputs_.scroll_layer_id = - scrollbar.scroll_layer_id(); - solid_color_scrollbar_layer_inputs_.thumb_thickness = - scrollbar.thumb_thickness(); - solid_color_scrollbar_layer_inputs_.track_start = scrollbar.track_start(); - solid_color_scrollbar_layer_inputs_.is_left_side_vertical_scrollbar = - scrollbar.is_left_side_vertical_scrollbar(); - solid_color_scrollbar_layer_inputs_.orientation = - ScrollbarOrientationFromProto(scrollbar.orientation()); -} - } // namespace cc diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.h b/chromium/cc/layers/solid_color_scrollbar_layer.h index 2855753af5d..2d90f116fc1 100644 --- a/chromium/cc/layers/solid_color_scrollbar_layer.h +++ b/chromium/cc/layers/solid_color_scrollbar_layer.h @@ -28,6 +28,7 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, bool OpacityCanAnimateOnImplThread() const override; bool AlwaysUseActiveTreeOpacity() const override; ScrollbarLayerInterface* ToScrollbarLayer() override; + void ToLayerNodeProto(proto::LayerNode* proto) const override; void SetOpacity(float opacity) override; void PushPropertiesTo(LayerImpl* layer) override; @@ -40,6 +41,18 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, ScrollbarOrientation orientation() const override; + int thumb_thickness() const { + return solid_color_scrollbar_layer_inputs_.thumb_thickness; + } + + int track_start() const { + return solid_color_scrollbar_layer_inputs_.track_start; + } + + bool is_left_side_vertical_scrollbar() const { + return solid_color_scrollbar_layer_inputs_.is_left_side_vertical_scrollbar; + } + protected: SolidColorScrollbarLayer(ScrollbarOrientation orientation, int thumb_thickness, @@ -50,10 +63,6 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerInterface, // Layer overrides for proto conversions. void SetTypeForProtoSerialization(proto::LayerNode* proto) const override; - void LayerSpecificPropertiesToProto(proto::LayerProperties* proto, - bool inputs_only) override; - void FromLayerSpecificPropertiesProto( - const proto::LayerProperties& proto) override; private: friend class LayerSerializationTest; diff --git a/chromium/cc/layers/surface_layer.cc b/chromium/cc/layers/surface_layer.cc index 984a56e684a..0f8bd3380be 100644 --- a/chromium/cc/layers/surface_layer.cc +++ b/chromium/cc/layers/surface_layer.cc @@ -57,7 +57,7 @@ SurfaceLayer::SurfaceLayer(const SatisfyCallback& satisfy_callback, SurfaceLayer::~SurfaceLayer() { DCHECK(!layer_tree_host()); - DCHECK(destroy_sequence_.is_null()); + DCHECK(!destroy_sequence_.is_valid()); } void SurfaceLayer::SetSurfaceId(const SurfaceId& surface_id, @@ -79,7 +79,7 @@ std::unique_ptr<LayerImpl> SurfaceLayer::CreateLayerImpl( } bool SurfaceLayer::HasDrawableContent() const { - return !surface_id_.is_null() && Layer::HasDrawableContent(); + return surface_id_.is_valid() && Layer::HasDrawableContent(); } void SurfaceLayer::SetLayerTreeHost(LayerTreeHost* host) { @@ -104,7 +104,7 @@ void SurfaceLayer::PushPropertiesTo(LayerImpl* layer) { } void SurfaceLayer::CreateNewDestroySequence() { - DCHECK(destroy_sequence_.is_null()); + DCHECK(!destroy_sequence_.is_valid()); if (layer_tree_host()) { destroy_sequence_ = layer_tree_host() ->GetSurfaceSequenceGenerator() @@ -116,7 +116,7 @@ void SurfaceLayer::CreateNewDestroySequence() { void SurfaceLayer::SatisfyDestroySequence() { if (!layer_tree_host()) return; - DCHECK(!destroy_sequence_.is_null()); + DCHECK(destroy_sequence_.is_valid()); std::unique_ptr<SatisfySwapPromise> satisfy( new SatisfySwapPromise(destroy_sequence_, satisfy_callback_)); layer_tree_host()->GetSwapPromiseManager()->QueueSwapPromise( diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc index a474d87d7dd..2289a29326f 100644 --- a/chromium/cc/layers/surface_layer_impl.cc +++ b/chromium/cc/layers/surface_layer_impl.cc @@ -70,7 +70,7 @@ void SurfaceLayerImpl::AppendQuads(RenderPass* render_pass, render_pass->CreateAndAppendSharedQuadState(); PopulateScaledSharedQuadState(shared_quad_state, surface_scale_); - if (surface_id_.is_null()) + if (!surface_id_.is_valid()) return; gfx::Rect quad_rect(surface_size_); diff --git a/chromium/cc/layers/surface_layer_impl_unittest.cc b/chromium/cc/layers/surface_layer_impl_unittest.cc index 954aaf81367..ea556d8dae1 100644 --- a/chromium/cc/layers/surface_layer_impl_unittest.cc +++ b/chromium/cc/layers/surface_layer_impl_unittest.cc @@ -17,6 +17,8 @@ static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); TEST(SurfaceLayerImplTest, Occlusion) { gfx::Size layer_size(1000, 1000); gfx::Size viewport_size(1000, 1000); + const LocalFrameId kArbitraryLocalFrameId(9, + base::UnguessableToken::Create()); LayerTestCommon::LayerImplTest impl; @@ -24,7 +26,7 @@ TEST(SurfaceLayerImplTest, Occlusion) { impl.AddChildToRoot<SurfaceLayerImpl>(); surface_layer_impl->SetBounds(layer_size); surface_layer_impl->SetDrawsContent(true); - SurfaceId surface_id(kArbitraryFrameSinkId, LocalFrameId(9, 0)); + SurfaceId surface_id(kArbitraryFrameSinkId, kArbitraryLocalFrameId); surface_layer_impl->SetSurfaceId(surface_id); surface_layer_impl->SetSurfaceScale(1.f); surface_layer_impl->SetSurfaceSize(layer_size); diff --git a/chromium/cc/layers/surface_layer_unittest.cc b/chromium/cc/layers/surface_layer_unittest.cc index 3ed3d7e8e61..5b688676e02 100644 --- a/chromium/cc/layers/surface_layer_unittest.cc +++ b/chromium/cc/layers/surface_layer_unittest.cc @@ -10,6 +10,7 @@ #include "base/location.h" #include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" +#include "cc/animation/animation_host.h" #include "cc/layers/solid_color_layer.h" #include "cc/layers/surface_layer.h" #include "cc/output/compositor_frame.h" @@ -32,8 +33,9 @@ static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); class SurfaceLayerTest : public testing::Test { protected: void SetUp() override { - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + layer_tree_host_ = FakeLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host_.get()); layer_tree_ = layer_tree_host_->GetLayerTree(); layer_tree_->SetViewportSize(gfx::Size(10, 10)); } @@ -47,6 +49,7 @@ class SurfaceLayerTest : public testing::Test { FakeLayerTreeHostClient fake_client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; LayerTree* layer_tree_; }; @@ -66,6 +69,8 @@ void RequireCallback(SurfaceId* out_id, // Check that one surface can be referenced by multiple LayerTreeHosts, and // each will create its own SurfaceSequence that's satisfied on destruction. TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) { + const base::UnguessableToken kArbitraryToken = + base::UnguessableToken::Create(); SurfaceSequence blank_change; // Receives sequence if commit doesn't happen. SurfaceId required_id; @@ -73,31 +78,36 @@ TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) { scoped_refptr<SurfaceLayer> layer(SurfaceLayer::Create( base::Bind(&SatisfyCallback, &blank_change), base::Bind(&RequireCallback, &required_id, &required_seq))); - layer->SetSurfaceId(SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, 0)), 1.f, - gfx::Size(1, 1)); + layer->SetSurfaceId( + SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, kArbitraryToken)), 1.f, + gfx::Size(1, 1)); layer_tree_host_->GetSurfaceSequenceGenerator()->set_frame_sink_id( FrameSinkId(1, 1)); layer_tree_->SetRootLayer(layer); + auto animation_host2 = AnimationHost::CreateForTesting(ThreadInstance::MAIN); std::unique_ptr<FakeLayerTreeHost> layer_tree_host2 = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_, + animation_host2.get()); scoped_refptr<SurfaceLayer> layer2(SurfaceLayer::Create( base::Bind(&SatisfyCallback, &blank_change), base::Bind(&RequireCallback, &required_id, &required_seq))); - layer2->SetSurfaceId(SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, 0)), - 1.f, gfx::Size(1, 1)); + layer2->SetSurfaceId( + SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, kArbitraryToken)), 1.f, + gfx::Size(1, 1)); layer_tree_host2->GetSurfaceSequenceGenerator()->set_frame_sink_id( FrameSinkId(2, 2)); layer_tree_host2->SetRootLayer(layer2); // Layers haven't been removed, so no sequence should be satisfied. - EXPECT_TRUE(blank_change.is_null()); + EXPECT_FALSE(blank_change.is_valid()); SurfaceSequence expected1(FrameSinkId(1, 1), 1u); SurfaceSequence expected2(FrameSinkId(2, 2), 1u); layer_tree_host2->SetRootLayer(nullptr); layer_tree_host2.reset(); + animation_host2 = nullptr; // Layer was removed so sequence from second LayerTreeHost should be // satisfied. @@ -105,8 +115,8 @@ TEST_F(SurfaceLayerTest, MultipleFramesOneSurface) { // Set of sequences that need to be satisfied should include sequences from // both trees. - EXPECT_TRUE(required_id == - SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, 0))); + EXPECT_TRUE(required_id == SurfaceId(kArbitraryFrameSinkId, + LocalFrameId(1, kArbitraryToken))); EXPECT_EQ(2u, required_seq.size()); EXPECT_TRUE(required_seq.count(expected1)); EXPECT_TRUE(required_seq.count(expected2)); @@ -135,8 +145,9 @@ class SurfaceLayerSwapPromise : public LayerTreeTest { layer_ = SurfaceLayer::Create( base::Bind(&SatisfyCallback, &satisfied_sequence_), base::Bind(&RequireCallback, &required_id_, &required_set_)); - layer_->SetSurfaceId(SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, 0)), - 1.f, gfx::Size(1, 1)); + layer_->SetSurfaceId( + SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, kArbitraryToken)), 1.f, + gfx::Size(1, 1)); // Layer hasn't been added to tree so no SurfaceSequence generated yet. EXPECT_EQ(0u, required_set_.size()); @@ -145,8 +156,8 @@ class SurfaceLayerSwapPromise : public LayerTreeTest { // Should have SurfaceSequence from first tree. SurfaceSequence expected(kArbitraryFrameSinkId, 1u); - EXPECT_TRUE(required_id_ == - SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, 0))); + EXPECT_TRUE(required_id_ == SurfaceId(kArbitraryFrameSinkId, + LocalFrameId(1, kArbitraryToken))); EXPECT_EQ(1u, required_set_.size()); EXPECT_TRUE(required_set_.count(expected)); @@ -177,6 +188,8 @@ class SurfaceLayerSwapPromise : public LayerTreeTest { SurfaceId required_id_; std::set<SurfaceSequence> required_set_; + const base::UnguessableToken kArbitraryToken = + base::UnguessableToken::Create(); }; // Check that SurfaceSequence is sent through swap promise. @@ -213,12 +226,12 @@ class SurfaceLayerSwapPromiseWithDraw : public SurfaceLayerSwapPromise { } void AfterTest() override { - EXPECT_TRUE(required_id_ == - SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, 0))); + EXPECT_TRUE(required_id_ == SurfaceId(kArbitraryFrameSinkId, + LocalFrameId(1, kArbitraryToken))); EXPECT_EQ(1u, required_set_.size()); // Sequence should have been satisfied through Swap, not with the // callback. - EXPECT_TRUE(satisfied_sequence_.is_null()); + EXPECT_FALSE(satisfied_sequence_.is_valid()); } }; @@ -253,8 +266,8 @@ class SurfaceLayerSwapPromiseWithoutDraw : public SurfaceLayerSwapPromise { } void AfterTest() override { - EXPECT_TRUE(required_id_ == - SurfaceId(kArbitraryFrameSinkId, LocalFrameId(1, 0))); + EXPECT_TRUE(required_id_ == SurfaceId(kArbitraryFrameSinkId, + LocalFrameId(1, kArbitraryToken))); EXPECT_EQ(1u, required_set_.size()); // Sequence should have been satisfied with the callback. EXPECT_TRUE(satisfied_sequence_ == diff --git a/chromium/cc/layers/texture_layer.cc b/chromium/cc/layers/texture_layer.cc index ed62bc4b0ce..802fb8d6164 100644 --- a/chromium/cc/layers/texture_layer.cc +++ b/chromium/cc/layers/texture_layer.cc @@ -201,6 +201,10 @@ bool TextureLayer::Update() { return updated || !update_rect().IsEmpty(); } +bool TextureLayer::IsSnapped() { + return true; +} + void TextureLayer::PushPropertiesTo(LayerImpl* layer) { Layer::PushPropertiesTo(layer); TRACE_EVENT0("cc", "TextureLayer::PushPropertiesTo"); diff --git a/chromium/cc/layers/texture_layer.h b/chromium/cc/layers/texture_layer.h index 2d5b6bbb4af..1b42e976ef0 100644 --- a/chromium/cc/layers/texture_layer.h +++ b/chromium/cc/layers/texture_layer.h @@ -137,6 +137,7 @@ class CC_EXPORT TextureLayer : public Layer { void SetLayerTreeHost(LayerTreeHost* layer_tree_host) override; bool Update() override; + bool IsSnapped() override; void PushPropertiesTo(LayerImpl* layer) override; protected: diff --git a/chromium/cc/layers/texture_layer_client.h b/chromium/cc/layers/texture_layer_client.h index 475309ae8ed..247946429ef 100644 --- a/chromium/cc/layers/texture_layer_client.h +++ b/chromium/cc/layers/texture_layer_client.h @@ -8,7 +8,6 @@ #include "cc/resources/single_release_callback.h" namespace cc { -class ResourceUpdateQueue; class TextureMailbox; class TextureLayerClient { diff --git a/chromium/cc/layers/texture_layer_impl.cc b/chromium/cc/layers/texture_layer_impl.cc index ed7b8d876fb..98d1ee2f640 100644 --- a/chromium/cc/layers/texture_layer_impl.cc +++ b/chromium/cc/layers/texture_layer_impl.cc @@ -57,6 +57,10 @@ std::unique_ptr<LayerImpl> TextureLayerImpl::CreateLayerImpl( return TextureLayerImpl::Create(tree_impl, id()); } +bool TextureLayerImpl::IsSnapped() { + return true; +} + void TextureLayerImpl::PushPropertiesTo(LayerImpl* layer) { LayerImpl::PushPropertiesTo(layer); diff --git a/chromium/cc/layers/texture_layer_impl.h b/chromium/cc/layers/texture_layer_impl.h index 233c14e1f6a..2fc7cd30bb1 100644 --- a/chromium/cc/layers/texture_layer_impl.h +++ b/chromium/cc/layers/texture_layer_impl.h @@ -27,6 +27,7 @@ class CC_EXPORT TextureLayerImpl : public LayerImpl { std::unique_ptr<LayerImpl> CreateLayerImpl( LayerTreeImpl* layer_tree_impl) override; + bool IsSnapped() override; void PushPropertiesTo(LayerImpl* layer) override; bool WillDraw(DrawMode draw_mode, diff --git a/chromium/cc/layers/texture_layer_unittest.cc b/chromium/cc/layers/texture_layer_unittest.cc index 9292aa4d9b5..7d10bf7ee4a 100644 --- a/chromium/cc/layers/texture_layer_unittest.cc +++ b/chromium/cc/layers/texture_layer_unittest.cc @@ -69,14 +69,13 @@ class MockLayerTreeHost : public LayerTreeHostInProcess { public: static std::unique_ptr<MockLayerTreeHost> Create( FakeLayerTreeHostClient* client, - TaskGraphRunner* task_graph_runner) { + TaskGraphRunner* task_graph_runner, + MutatorHost* mutator_host) { LayerTreeHostInProcess::InitParams params; params.client = client; params.task_graph_runner = task_graph_runner; - params.animation_host = - AnimationHost::CreateForTesting(ThreadInstance::MAIN); + params.mutator_host = mutator_host; LayerTreeSettings settings; - settings.verify_transform_tree_calculations = true; settings.verify_clip_tree_calculations = true; params.settings = &settings; return base::WrapUnique(new MockLayerTreeHost(¶ms)); @@ -211,14 +210,14 @@ class TextureLayerTest : public testing::Test { TextureLayerTest() : compositor_frame_sink_(FakeCompositorFrameSink::Create3d()), host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_), test_data_(&shared_bitmap_manager_) {} protected: void SetUp() override { - layer_tree_host_ = - MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + layer_tree_host_ = MockLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host_.get()); layer_tree_ = layer_tree_host_->GetLayerTree(); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); layer_tree_->SetViewportSize(gfx::Size(10, 10)); @@ -229,11 +228,14 @@ class TextureLayerTest : public testing::Test { Mock::VerifyAndClearExpectations(layer_tree_host_.get()); EXPECT_CALL(*layer_tree_host_, SetNeedsCommit()).Times(AnyNumber()); + animation_host_->SetMutatorHostClient(nullptr); layer_tree_->SetRootLayer(nullptr); layer_tree_host_ = nullptr; + animation_host_ = nullptr; } std::unique_ptr<MockLayerTreeHost> layer_tree_host_; + std::unique_ptr<AnimationHost> animation_host_; LayerTree* layer_tree_; FakeImplTaskRunnerProvider task_runner_provider_; FakeLayerTreeHostClient fake_client_; @@ -646,7 +648,6 @@ class TextureLayerImplWithMailboxThreadedCallback : public LayerTreeTest { bool force_disable_reclaim_resources = false; return base::MakeUnique<TestCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), - CreateDisplayOutputSurface(compositor_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, ImplThreadTaskRunner(), synchronous_composite, @@ -853,8 +854,8 @@ class TextureLayerImplWithMailboxTest : public TextureLayerTest { protected: void SetUp() override { TextureLayerTest::SetUp(); - layer_tree_host_ = - MockLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + layer_tree_host_ = MockLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host_.get()); layer_tree_ = layer_tree_host_->GetLayerTree(); host_impl_.SetVisible(true); EXPECT_TRUE(host_impl_.InitializeRenderer(compositor_frame_sink_.get())); diff --git a/chromium/cc/layers/ui_resource_layer.h b/chromium/cc/layers/ui_resource_layer.h index 8004d1e51a0..c97c60c1737 100644 --- a/chromium/cc/layers/ui_resource_layer.h +++ b/chromium/cc/layers/ui_resource_layer.h @@ -16,7 +16,6 @@ namespace cc { class LayerTreeHost; -class ScopedUIResource; class CC_EXPORT UIResourceLayer : public Layer { public: diff --git a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc index 727a6e1a6af..5acc56a117c 100644 --- a/chromium/cc/layers/ui_resource_layer_impl_unittest.cc +++ b/chromium/cc/layers/ui_resource_layer_impl_unittest.cc @@ -14,7 +14,6 @@ #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/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/single_thread_proxy.h" #include "testing/gmock/include/gmock/gmock.h" @@ -59,12 +58,11 @@ void QuadSizeTest(std::unique_ptr<UIResourceLayerImpl> layer, TEST(UIResourceLayerImplTest, VerifyDrawQuads) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeUIResourceLayerTreeHostImpl host_impl( - &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); + FakeUIResourceLayerTreeHostImpl host_impl(&task_runner_provider, + &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); @@ -105,12 +103,11 @@ void OpaqueBoundsTest(std::unique_ptr<UIResourceLayerImpl> layer, TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeUIResourceLayerTreeHostImpl host_impl( - &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); + FakeUIResourceLayerTreeHostImpl host_impl(&task_runner_provider, + &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); @@ -135,12 +132,11 @@ TEST(UIResourceLayerImplTest, VerifySetOpaqueOnSkBitmap) { TEST(UIResourceLayerImplTest, VerifySetOpaqueOnLayer) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeUIResourceLayerTreeHostImpl host_impl( - &task_runner_provider, &shared_bitmap_manager, &task_graph_runner); + FakeUIResourceLayerTreeHostImpl host_impl(&task_runner_provider, + &task_graph_runner); host_impl.SetVisible(true); host_impl.InitializeRenderer(compositor_frame_sink.get()); diff --git a/chromium/cc/layers/ui_resource_layer_unittest.cc b/chromium/cc/layers/ui_resource_layer_unittest.cc index f1ef05b7a83..a018e71628b 100644 --- a/chromium/cc/layers/ui_resource_layer_unittest.cc +++ b/chromium/cc/layers/ui_resource_layer_unittest.cc @@ -5,6 +5,7 @@ #include "cc/layers/ui_resource_layer.h" #include "base/threading/thread_task_runner_handle.h" +#include "cc/animation/animation_host.h" #include "cc/resources/resource_provider.h" #include "cc/resources/scoped_ui_resource.h" #include "cc/test/fake_layer_tree_host.h" @@ -48,8 +49,9 @@ class TestUIResourceLayer : public UIResourceLayer { class UIResourceLayerTest : public testing::Test { protected: void SetUp() override { - layer_tree_host_ = - FakeLayerTreeHost::Create(&fake_client_, &task_graph_runner_); + animation_host_ = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + layer_tree_host_ = FakeLayerTreeHost::Create( + &fake_client_, &task_graph_runner_, animation_host_.get()); layer_tree_host_->InitializeSingleThreaded( &single_thread_client_, base::ThreadTaskRunnerHandle::Get()); } @@ -61,6 +63,7 @@ class UIResourceLayerTest : public testing::Test { FakeLayerTreeHostClient fake_client_; StubLayerTreeHostSingleThreadClient single_thread_client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> layer_tree_host_; }; diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc index 8b58c5f3345..d690d851113 100644 --- a/chromium/cc/layers/viewport.cc +++ b/chromium/cc/layers/viewport.cc @@ -6,7 +6,7 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "cc/input/top_controls_manager.h" +#include "cc/input/browser_controls_offset_manager.h" #include "cc/trees/layer_tree_host_impl.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/scroll_node.h" @@ -36,14 +36,15 @@ void Viewport::Pan(const gfx::Vector2dF& delta) { Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta, const gfx::Point& viewport_point, bool is_direct_manipulation, - bool affect_top_controls) { + bool affect_browser_controls, + bool scroll_outer_viewport) { if (!OuterScrollLayer()) return ScrollResult(); gfx::Vector2dF content_delta = delta; - if (affect_top_controls && ShouldTopControlsConsumeScroll(delta)) - content_delta -= ScrollTopControls(delta); + if (affect_browser_controls && ShouldBrowserControlsConsumeScroll(delta)) + content_delta -= ScrollBrowserControls(delta); gfx::Vector2dF pending_content_delta = content_delta; @@ -57,11 +58,14 @@ Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& delta, ScrollResult result; - ScrollNode* outer_node = - scroll_tree.Node(OuterScrollLayer()->scroll_tree_index()); - pending_content_delta -= host_impl_->ScrollSingleNode( - outer_node, pending_content_delta, viewport_point, is_direct_manipulation, - &scroll_tree); + if (scroll_outer_viewport) { + ScrollNode* outer_node = + scroll_tree.Node(OuterScrollLayer()->scroll_tree_index()); + pending_content_delta -= host_impl_->ScrollSingleNode( + outer_node, pending_content_delta, viewport_point, + is_direct_manipulation, &scroll_tree); + } + result.consumed_delta = delta - AdjustOverscroll(pending_content_delta); result.content_scrolled_delta = content_delta - pending_content_delta; @@ -195,19 +199,19 @@ void Viewport::PinchEnd() { } LayerImpl* Viewport::MainScrollLayer() const { - return InnerScrollLayer(); + return OuterScrollLayer(); } -gfx::Vector2dF Viewport::ScrollTopControls(const gfx::Vector2dF& delta) { +gfx::Vector2dF Viewport::ScrollBrowserControls(const gfx::Vector2dF& delta) { gfx::Vector2dF excess_delta = - host_impl_->top_controls_manager()->ScrollBy(delta); + host_impl_->browser_controls_manager()->ScrollBy(delta); return delta - excess_delta; } -bool Viewport::ShouldTopControlsConsumeScroll( +bool Viewport::ShouldBrowserControlsConsumeScroll( const gfx::Vector2dF& scroll_delta) const { - // Always consume if it's in the direction to show the top controls. + // Always consume if it's in the direction to show the browser controls. if (scroll_delta.y() < 0) return true; diff --git a/chromium/cc/layers/viewport.h b/chromium/cc/layers/viewport.h index f8312fa61b0..5a254fe5136 100644 --- a/chromium/cc/layers/viewport.h +++ b/chromium/cc/layers/viewport.h @@ -38,19 +38,21 @@ class CC_EXPORT Viewport { static std::unique_ptr<Viewport> Create(LayerTreeHostImpl* host_impl); // Differs from scrolling in that only the visual viewport is moved, without - // affecting the top controls or outer viewport. + // affecting the browser controls or outer viewport. void Pan(const gfx::Vector2dF& delta); // Scrolls the viewport, applying the unique bubbling between the inner and - // outer viewport. Scrolls can be consumed by top controls. + // outer viewport unless the scroll_outer_viewport bit is off. Scrolls can be + // consumed by browser controls. ScrollResult ScrollBy(const gfx::Vector2dF& delta, const gfx::Point& viewport_point, bool is_wheel_scroll, - bool affect_top_controls); + bool affect_browser_controls, + bool scroll_outer_viewport); // Scrolls the viewport. Unlike the above method, scrolls the inner before - // the outer viewport. Doesn't affect top controls or return a result since - // callers don't need it. + // the outer viewport. Doesn't affect browser controls or return a result + // since callers don't need it. void ScrollByInnerFirst(const gfx::Vector2dF& delta); // Scrolls the viewport, bubbling the delta between the inner and outer @@ -72,11 +74,12 @@ class CC_EXPORT Viewport { // Returns true if viewport_delta is stricly less than pending_delta. static bool ShouldAnimateViewport(const gfx::Vector2dF& viewport_delta, const gfx::Vector2dF& pending_delta); - bool ShouldTopControlsConsumeScroll(const gfx::Vector2dF& scroll_delta) const; + bool ShouldBrowserControlsConsumeScroll( + const gfx::Vector2dF& scroll_delta) const; gfx::Vector2dF AdjustOverscroll(const gfx::Vector2dF& delta) const; - // Sends the delta to the top controls, returns the amount applied. - gfx::Vector2dF ScrollTopControls(const gfx::Vector2dF& delta); + // Sends the delta to the browser controls, returns the amount applied. + gfx::Vector2dF ScrollBrowserControls(const gfx::Vector2dF& delta); gfx::ScrollOffset MaxTotalScrollOffset() const; gfx::ScrollOffset TotalScrollOffset() const; diff --git a/chromium/cc/memory.md b/chromium/cc/memory.md index 1bac0f56ee7..b00d705a317 100644 --- a/chromium/cc/memory.md +++ b/chromium/cc/memory.md @@ -1,125 +1 @@ -# Memory Usage in CC - -This document gives an overview of memory usage in the CC component, as well as -information on how to analyze that memory. - -[TOC] - -## Types of Memory in Use - -CC uses a number of types of memory: - -1. Malloc Memory - Standard system memory used for all manner of objects in CC. -2. Discardable Memory - Memory allocated by the discardable memory system. - Designed to be freeable by the system at any time (under memory pressure). - In most cases, only pinned discardable memory should be considered to - have a cost; however, the implementation of discardable memory is platform - dependent, and on certain platforms unpinned memory can contribute to - memory pressure to some degree. -3. Shared Memory - Memory which is allocated by the Browser and can safely - be transferred between processes. This memory is allocated by the browser - but may count against a renderer process depending on who logically "owns" - the memory. -4. GPU Memory - Memory which is allocated on the GPU and typically does not - count against system memory. This mainly includes OpenGL objects. - -## Categories Of Memory - -Memory-infra tracing will grab dumps of CC memory in several categories. - -### CC Category - -The CC category contains resource allocations made by ResourceProvider. All -resource allocations are enumerated under cc/resource_memory. A subset of -resources are used as tile memory, and are also enumerated under cc/tile_memory. -For resources that appear in both cc/tile_memory and cc/resource_memory, the -size will be attributed to cc/tile_memory (effective_size of cc/resource_memory -will not include these resources). - -If the one-copy tile update path is in use, the cc category will also enumerate -staging resources used as intermediates when drawing tiles. These resources are -like tile_memory, in that they are shared with cc/resource_memory. - -Note that depending on the path being used, CC memory may be either shared -memory or GPU memory: - -Path | Tile Memory Type | Staging Memory Type --------------|------------------------------------------- -Bitmap | Shared Memory | N/A -One Copy | GPU Memory | Shared Memory -Zero Copy | GPU or Shared Memory | N/A -GPU | GPU Memory | N/A - -Note that these values can be determined from a memory-infra dump. For a given -resource, hover over the small green arrow next to it's "size". This will show -the other allocations that this resource is aliased with. If you see an -allocation in the GPU process, the memory is generally GPU memory. Otherwise, -the resource is typically Shared Memory. - -Tile and Staging memory managers are set up to evict any resource not used -within 1s. - -### GPU Category - -This category lists the memory allocations needed to support CC's GPU path. -Despite the name, the data in this category (within a Renderer process) is not -GPU memory but Shared Memory. - -Allocations tracked here include GL command buffer support allocations such as: - -1. Command Buffer Memory - memory used to send commands across the GL command - buffer. This is backed by Shared Memory. -2. Mapped Memory - memory used in certain image upload paths to share data - with the GPU process. This is backed by Shared Memory. -3. Transfer Buffer Memory - memory used to transfer data to the GPU - used in - different paths than mapped memory. Also backed by Shared Memory. - -### Discardable Category - -Cached images make use of Discardable memory. These allocations are managed by -Skia and a better summary of these allocations can likely be found in the Skia -category. - -### Malloc Category - -The malloc category shows a summary of all memory allocated through malloc. - -Currently the information here is not granular enough to be useful, and a -good project would be to track down and instrument any large pools of memory -using malloc. - -Some Skia caches also make use of malloc memory. For these allocations, a better -summary can be seen in the Skia category. - -### Skia Category - -The Skia category shows all resources used by the Skia rendering system. These -can be divided into a few subcategories. skia/gpu_resources/* includes all -resources using GPU memory. All other categories draw from either Shared or -malloc memory. To determine which type of memory a resource is using, hover -over the green arrow next to its size. This will show the other allocations -which the resource is aliased with. - -## Other Areas of Interest - -Many of the allocations under CC are aliased with memory in the Browser or GPU -process. When investigating CC memory it may be worth looking at the following -external categories: - -1. GPU Process / GPU Category - All GPU resources allocated by CC have a - counterpart in the GPU/GPU category. This includes GL Textures, buffers, and - other GPU backed objects such as Native GPU Memory Buffers. -2. Browser Process / GpuMemoryBuffer Category - Resources backed by Shared - Memory GpuMemoryBuffers are allocated by the browser and will be tracked - in this category. -3. Browser Process / SharedMemory Category - Resources backed by Bitmap and - Shared Memory GpuMemoryBuffer objects are allocated by the browser and will - also tracked in this category. - -## Memory TODOs - -The following areas have insufficient memory instrumentation. - -1. DisplayLists - DisplayLists can be quite large and are currently - un-instrumented. These use malloc memory and currently contribute to - malloc/allocated_objects/<unspecified>. [BUG](crbug.com/567465) +This document has moved to [//docs/memory-infra/probe-cc.md](/docs/memory-infra/probe-cc.md). diff --git a/chromium/cc/output/begin_frame_args.cc b/chromium/cc/output/begin_frame_args.cc index e25d2f55c27..7ef2c4842ac 100644 --- a/chromium/cc/output/begin_frame_args.cc +++ b/chromium/cc/output/begin_frame_args.cc @@ -6,7 +6,6 @@ #include "base/trace_event/trace_event_argument.h" #include "cc/proto/base_conversions.h" -#include "cc/proto/begin_main_frame_and_commit_state.pb.h" namespace cc { @@ -25,44 +24,6 @@ const char* BeginFrameArgs::TypeToString(BeginFrameArgsType type) { return "???"; } -void BeginFrameArgs::BeginFrameArgsTypeToProtobuf( - proto::BeginFrameArgs* proto) const { - switch (type) { - case BeginFrameArgs::INVALID: - proto->set_type(proto::BeginFrameArgs::INVALID); - return; - case BeginFrameArgs::NORMAL: - proto->set_type(proto::BeginFrameArgs::NORMAL); - return; - case BeginFrameArgs::MISSED: - proto->set_type(proto::BeginFrameArgs::MISSED); - return; - case BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX: - proto->set_type(proto::BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX); - return; - } - NOTREACHED(); -} - -void BeginFrameArgs::BeginFrameArgsTypeFromProtobuf( - const proto::BeginFrameArgs& proto) { - switch (proto.type()) { - case proto::BeginFrameArgs::INVALID: - type = BeginFrameArgs::INVALID; - return; - case proto::BeginFrameArgs::NORMAL: - type = BeginFrameArgs::NORMAL; - return; - case proto::BeginFrameArgs::MISSED: - type = BeginFrameArgs::MISSED; - return; - case proto::BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX: - type = BeginFrameArgs::BEGIN_FRAME_ARGS_TYPE_MAX; - return; - } - NOTREACHED(); -} - BeginFrameArgs::BeginFrameArgs() : frame_time(base::TimeTicks()), deadline(base::TimeTicks()), @@ -118,22 +79,6 @@ void BeginFrameArgs::AsValueInto(base::trace_event::TracedValue* state) const { state->SetBoolean("on_critical_path", on_critical_path); } -void BeginFrameArgs::ToProtobuf(proto::BeginFrameArgs* proto) const { - proto->set_frame_time(TimeTicksToProto(frame_time)); - proto->set_deadline(TimeTicksToProto(deadline)); - proto->set_interval(interval.ToInternalValue()); - BeginFrameArgsTypeToProtobuf(proto); - proto->set_on_critical_path(on_critical_path); -} - -void BeginFrameArgs::FromProtobuf(const proto::BeginFrameArgs& proto) { - frame_time = ProtoToTimeTicks(proto.frame_time()); - deadline = ProtoToTimeTicks(proto.deadline()); - interval = base::TimeDelta::FromInternalValue(proto.interval()); - BeginFrameArgsTypeFromProtobuf(proto); - on_critical_path = proto.on_critical_path(); -} - // This is a hard-coded deadline adjustment that assumes 60Hz, to be used in // cases where a good estimated draw time is not known. Using 1/3 of the vsync // as the default adjustment gives the Browser the last 1/3 of a frame to diff --git a/chromium/cc/output/begin_frame_args.h b/chromium/cc/output/begin_frame_args.h index c8c7b2f2277..78ddce99ddf 100644 --- a/chromium/cc/output/begin_frame_args.h +++ b/chromium/cc/output/begin_frame_args.h @@ -38,10 +38,6 @@ class TracedValue; namespace cc { -namespace proto { -class BeginFrameArgs; -} - struct CC_EXPORT BeginFrameArgs { enum BeginFrameArgsType { INVALID, @@ -52,8 +48,6 @@ struct CC_EXPORT BeginFrameArgs { BEGIN_FRAME_ARGS_TYPE_MAX, }; static const char* TypeToString(BeginFrameArgsType type); - void BeginFrameArgsTypeToProtobuf(proto::BeginFrameArgs* proto) const; - void BeginFrameArgsTypeFromProtobuf(const proto::BeginFrameArgs& proto); // Creates an invalid set of values. BeginFrameArgs(); @@ -87,9 +81,6 @@ struct CC_EXPORT BeginFrameArgs { std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const; void AsValueInto(base::trace_event::TracedValue* dict) const; - void ToProtobuf(proto::BeginFrameArgs* proto) const; - void FromProtobuf(const proto::BeginFrameArgs& proto); - base::TimeTicks frame_time; base::TimeTicks deadline; base::TimeDelta interval; diff --git a/chromium/cc/output/begin_frame_args_unittest.cc b/chromium/cc/output/begin_frame_args_unittest.cc index 60972017478..eb63cc769a1 100644 --- a/chromium/cc/output/begin_frame_args_unittest.cc +++ b/chromium/cc/output/begin_frame_args_unittest.cc @@ -5,7 +5,6 @@ #include <string> #include "cc/output/begin_frame_args.h" -#include "cc/proto/begin_main_frame_and_commit_state.pb.h" #include "cc/test/begin_frame_args_test.h" #include "testing/gtest/include/gtest/gtest-spi.h" #include "testing/gtest/include/gtest/gtest.h" @@ -85,37 +84,6 @@ TEST(BeginFrameArgsTest, Create) { EXPECT_EQ(BeginFrameArgs::NORMAL, args2.type) << args2; } -TEST(BeginFrameArgsSerializationTest, BeginFrameArgsType) { - for (size_t i = 0; - i < BeginFrameArgs::BeginFrameArgsType::BEGIN_FRAME_ARGS_TYPE_MAX; ++i) { - BeginFrameArgs::BeginFrameArgsType type = - static_cast<BeginFrameArgs::BeginFrameArgsType>(i); - BeginFrameArgs args; - args.type = type; - - proto::BeginFrameArgs proto; - args.BeginFrameArgsTypeToProtobuf(&proto); - - BeginFrameArgs new_args; - new_args.BeginFrameArgsTypeFromProtobuf(proto); - EXPECT_EQ(args.type, new_args.type); - } -} - -TEST(BeginFrameArgsSerializationTest, BeginFrameArgs) { - BeginFrameArgs args = BeginFrameArgs::Create( - BEGINFRAME_FROM_HERE, base::TimeTicks::FromInternalValue(1), - base::TimeTicks::FromInternalValue(2), - base::TimeDelta::FromInternalValue(3), BeginFrameArgs::NORMAL); - proto::BeginFrameArgs proto; - args.ToProtobuf(&proto); - - BeginFrameArgs new_args; - new_args.FromProtobuf(proto); - - EXPECT_EQ(args, new_args); -} - #ifndef NDEBUG TEST(BeginFrameArgsTest, Location) { tracked_objects::Location expected_location = BEGINFRAME_FROM_HERE; diff --git a/chromium/cc/output/bsp_tree_perftest.cc b/chromium/cc/output/bsp_tree_perftest.cc index ccf3d2ef5c3..2413058e25f 100644 --- a/chromium/cc/output/bsp_tree_perftest.cc +++ b/chromium/cc/output/bsp_tree_perftest.cc @@ -122,7 +122,6 @@ class BspTreePerfTest : public LayerTreeTest { host_impl->settings().layer_transforms_should_scale_layer_contents, false, // do not verify_clip_tree_calculation for perf tests false, // do not verify_visible_rect_calculation for perf tests - false, // do not verify_transform_tree_calculation for perf tests &update_list, active_tree->property_trees()); LayerTreeHostCommon::CalculateDrawProperties(&inputs); } diff --git a/chromium/cc/output/color_lut_cache.cc b/chromium/cc/output/color_lut_cache.cc index 60e44623d2c..21883c63ca5 100644 --- a/chromium/cc/output/color_lut_cache.cc +++ b/chromium/cc/output/color_lut_cache.cc @@ -21,7 +21,7 @@ ColorLUTCache::~ColorLUTCache() { GLuint textures[10]; size_t n = 0; for (const auto& cache_entry : lut_cache_) { - textures[n++] = cache_entry.second.first; + textures[n++] = cache_entry.second.texture; if (n == arraysize(textures)) { gl_->DeleteTextures(n, textures); n = 0; @@ -89,21 +89,21 @@ unsigned int ColorLUTCache::GetLUT(const gfx::ColorSpace& from, CacheKey key(from, std::make_pair(to, lut_samples)); auto iter = lut_cache_.Get(key); if (iter != lut_cache_.end()) { - iter->second.second = current_frame_; - return iter->second.first; + iter->second.last_used_frame = current_frame_; + return iter->second.texture; } unsigned int lut = MakeLUT(from, to, lut_samples); - lut_cache_.Put(key, std::make_pair(lut, current_frame_)); + lut_cache_.Put(key, CacheVal(lut, current_frame_)); return lut; } void ColorLUTCache::Swap() { current_frame_++; while (!lut_cache_.empty() && - current_frame_ - lut_cache_.rbegin()->second.first > + current_frame_ - lut_cache_.rbegin()->second.last_used_frame > kMaxFramesUnused) { - gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.first); + gl_->DeleteTextures(1, &lut_cache_.rbegin()->second.texture); lut_cache_.ShrinkToSize(lut_cache_.size() - 1); } } diff --git a/chromium/cc/output/color_lut_cache.h b/chromium/cc/output/color_lut_cache.h index 7d5effc9e4e..4ea5732b89d 100644 --- a/chromium/cc/output/color_lut_cache.h +++ b/chromium/cc/output/color_lut_cache.h @@ -33,10 +33,18 @@ class ColorLUTCache { unsigned int MakeLUT(const gfx::ColorSpace& from, gfx::ColorSpace to, int lut_samples); + typedef std::pair<gfx::ColorSpace, std::pair<gfx::ColorSpace, size_t>> CacheKey; - base::MRUCache<CacheKey, std::pair<unsigned int, size_t>> lut_cache_; + struct CacheVal { + CacheVal(unsigned int texture, uint32_t last_used_frame) + : texture(texture), last_used_frame(last_used_frame) {} + unsigned int texture; + uint32_t last_used_frame; + }; + + base::MRUCache<CacheKey, CacheVal> lut_cache_; uint32_t current_frame_; gpu::gles2::GLES2Interface* gl_; DISALLOW_COPY_AND_ASSIGN(ColorLUTCache); diff --git a/chromium/cc/output/compositor_frame_sink.cc b/chromium/cc/output/compositor_frame_sink.cc index c01efc35ebd..a42c3683eed 100644 --- a/chromium/cc/output/compositor_frame_sink.cc +++ b/chromium/cc/output/compositor_frame_sink.cc @@ -9,135 +9,38 @@ #include "base/bind.h" #include "base/location.h" #include "base/macros.h" -#include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" #include "cc/output/compositor_frame_sink_client.h" -#include "cc/output/managed_memory_policy.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "third_party/skia/include/core/SkTraceMemoryDump.h" -#include "third_party/skia/include/gpu/GrContext.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gl/trace_util.h" - -class SkDiscardableMemory; namespace cc { -namespace { - -// Constants used by SkiaGpuTraceMemoryDump to identify different memory types. -const char* kGLTextureBackingType = "gl_texture"; -const char* kGLBufferBackingType = "gl_buffer"; -const char* kGLRenderbufferBackingType = "gl_renderbuffer"; - -// Derives from SkTraceMemoryDump and implements graphics specific memory -// backing functionality. -class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump { - public: - // This should never outlive the provided ProcessMemoryDump, as it should - // always be scoped to a single OnMemoryDump funciton call. - explicit SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd, - uint64_t share_group_tracing_guid) - : pmd_(pmd), share_group_tracing_guid_(share_group_tracing_guid) {} - - // Overridden from SkTraceMemoryDump: - void dumpNumericValue(const char* dump_name, - const char* value_name, - const char* units, - uint64_t value) override { - auto* dump = GetOrCreateAllocatorDump(dump_name); - dump->AddScalar(value_name, units, value); - } - - void setMemoryBacking(const char* dump_name, - const char* backing_type, - const char* backing_object_id) override { - const uint64_t tracing_process_id = - base::trace_event::MemoryDumpManager::GetInstance() - ->GetTracingProcessId(); - - // For uniformity, skia provides this value as a string. Convert back to a - // uint32_t. - uint32_t gl_id = - std::strtoul(backing_object_id, nullptr /* str_end */, 10 /* base */); - - // Populated in if statements below. - base::trace_event::MemoryAllocatorDumpGuid guid; - - if (strcmp(backing_type, kGLTextureBackingType) == 0) { - guid = gl::GetGLTextureClientGUIDForTracing(share_group_tracing_guid_, - gl_id); - } else if (strcmp(backing_type, kGLBufferBackingType) == 0) { - guid = gl::GetGLBufferGUIDForTracing(tracing_process_id, gl_id); - } else if (strcmp(backing_type, kGLRenderbufferBackingType) == 0) { - guid = gl::GetGLRenderbufferGUIDForTracing(tracing_process_id, gl_id); - } - - if (!guid.empty()) { - pmd_->CreateSharedGlobalAllocatorDump(guid); - - auto* dump = GetOrCreateAllocatorDump(dump_name); - - const int kImportance = 2; - pmd_->AddOwnershipEdge(dump->guid(), guid, kImportance); - } - } - - void setDiscardableMemoryBacking( - const char* dump_name, - const SkDiscardableMemory& discardable_memory_object) override { - // We don't use this class for dumping discardable memory. - NOTREACHED(); - } - - LevelOfDetail getRequestedDetails() const override { - // TODO(ssid): Use MemoryDumpArgs to create light dumps when requested - // (crbug.com/499731). - return kObjectsBreakdowns_LevelOfDetail; - } - - private: - // Helper to create allocator dumps. - base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump( - const char* dump_name) { - auto* dump = pmd_->GetAllocatorDump(dump_name); - if (!dump) - dump = pmd_->CreateAllocatorDump(dump_name); - return dump; - } - - base::trace_event::ProcessMemoryDump* pmd_; - uint64_t share_group_tracing_guid_; - - DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump); -}; - -} // namespace - CompositorFrameSink::CompositorFrameSink( scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider) + scoped_refptr<ContextProvider> worker_context_provider, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + SharedBitmapManager* shared_bitmap_manager) : context_provider_(std::move(context_provider)), worker_context_provider_(std::move(worker_context_provider)), - weak_ptr_factory_(this) { + gpu_memory_buffer_manager_(gpu_memory_buffer_manager), + shared_bitmap_manager_(shared_bitmap_manager) { client_thread_checker_.DetachFromThread(); } CompositorFrameSink::CompositorFrameSink( scoped_refptr<VulkanContextProvider> vulkan_context_provider) : vulkan_context_provider_(vulkan_context_provider), - weak_ptr_factory_(this) { + gpu_memory_buffer_manager_(nullptr), + shared_bitmap_manager_(nullptr) { client_thread_checker_.DetachFromThread(); } CompositorFrameSink::~CompositorFrameSink() { if (client_) - DetachFromClientInternal(); + DetachFromClient(); } bool CompositorFrameSink::BindToClient(CompositorFrameSinkClient* client) { @@ -156,78 +59,26 @@ bool CompositorFrameSink::BindToClient(CompositorFrameSinkClient* client) { } } - // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). - // Don't register a dump provider in these cases. - // TODO(ericrk): Get this working in Android Webview. crbug.com/517156 - if (base::ThreadTaskRunnerHandle::IsSet()) { - // Now that we are on the context thread, register a dump provider with this - // thread's task runner. This will overwrite any previous dump provider - // registered. - base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( - this, "CompositorFrameSink", base::ThreadTaskRunnerHandle::Get()); + if (!success) { + // Destroy the ContextProvider on the thread attempted to be bound. + context_provider_ = nullptr; + client_ = nullptr; } - if (!success) - DetachFromClient(); return success; } void CompositorFrameSink::DetachFromClient() { - DetachFromClientInternal(); -} - -void CompositorFrameSink::PostSwapBuffersComplete() { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&CompositorFrameSink::OnSwapBuffersComplete, - weak_ptr_factory_.GetWeakPtr())); -} - -// We don't post tasks bound to the client directly since they might run -// after the CompositorFrameSink has been destroyed. -void CompositorFrameSink::OnSwapBuffersComplete() { - client_->DidSwapBuffersComplete(); -} - -bool CompositorFrameSink::OnMemoryDump( - const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) { - if (auto* context_provider = this->context_provider()) { - // No need to lock, main context provider is not shared. - if (auto* gr_context = context_provider->GrContext()) { - SkiaGpuTraceMemoryDump trace_memory_dump( - pmd, context_provider->ContextSupport()->ShareGroupTracingGUID()); - gr_context->dumpMemoryStatistics(&trace_memory_dump); - } - } - if (auto* context_provider = worker_context_provider()) { - ContextProvider::ScopedContextLock scoped_context(context_provider); - - if (auto* gr_context = context_provider->GrContext()) { - SkiaGpuTraceMemoryDump trace_memory_dump( - pmd, context_provider->ContextSupport()->ShareGroupTracingGUID()); - gr_context->dumpMemoryStatistics(&trace_memory_dump); - } - } - - return true; -} - -void CompositorFrameSink::DetachFromClientInternal() { DCHECK(client_thread_checker_.CalledOnValidThread()); DCHECK(client_); - // Unregister any dump provider. Safe to call (no-op) if we have not yet - // registered. - base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( - this); - if (context_provider_.get()) { context_provider_->SetLostContextCallback( ContextProvider::LostContextCallback()); } + // Destroy the ContextProvider on the bound thread. context_provider_ = nullptr; client_ = nullptr; - weak_ptr_factory_.InvalidateWeakPtrs(); } void CompositorFrameSink::DidLoseCompositorFrameSink() { diff --git a/chromium/cc/output/compositor_frame_sink.h b/chromium/cc/output/compositor_frame_sink.h index 5ed7448eb52..333363fdc76 100644 --- a/chromium/cc/output/compositor_frame_sink.h +++ b/chromium/cc/output/compositor_frame_sink.h @@ -10,9 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" -#include "base/trace_event/memory_dump_provider.h" #include "cc/base/cc_export.h" #include "cc/output/context_provider.h" #include "cc/output/overlay_candidate_validator.h" @@ -21,32 +19,23 @@ #include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/color_space.h" -namespace ui { -class LatencyInfo; -} - -namespace gfx { -class ColorSpace; -class Rect; -class Size; -class Transform; +namespace gpu { +class GpuMemoryBufferManager; } namespace cc { class CompositorFrame; -struct ManagedMemoryPolicy; class CompositorFrameSinkClient; - -// Represents the output surface for a compositor. The compositor owns -// and manages its destruction. Its lifetime is: -// 1. Created on the main thread by the LayerTreeHost through its client. -// 2. Passed to the compositor thread and bound to a client via BindToClient. -// From here on, it will only be used on the compositor thread. -// 3. If the 3D context is lost, then the compositor will delete the output -// surface (on the compositor thread) and go back to step 1. -class CC_EXPORT CompositorFrameSink - : public base::trace_event::MemoryDumpProvider { +class SharedBitmapManager; + +// An interface for submitting CompositorFrames to a display compositor +// which will compose frames from multiple CompositorFrameSinks to show +// on screen to the user. +// If a context_provider() is present, frames should be submitted with +// OpenGL resources (created with the context_provider()). If not, then +// SharedBitmap resources should be used. +class CC_EXPORT CompositorFrameSink { public: struct Capabilities { Capabilities() = default; @@ -59,15 +48,23 @@ class CC_EXPORT CompositorFrameSink bool delegated_sync_points_required = true; }; - // Constructor for GL-based and/or software compositing. + // Constructor for GL-based and/or software resources. + // gpu_memory_buffer_manager and shared_bitmap_manager must outlive the + // CompositorFrameSink. + // shared_bitmap_manager is optional (won't be used) if context_provider is + // present. + // gpu_memory_buffer_manager is optional (won't be used) if context_provider + // is not present. CompositorFrameSink(scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider); + scoped_refptr<ContextProvider> worker_context_provider, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + SharedBitmapManager* shared_bitmap_manager); - // Constructor for Vulkan-based compositing. + // Constructor for Vulkan-based resources. explicit CompositorFrameSink( scoped_refptr<VulkanContextProvider> vulkan_context_provider); - ~CompositorFrameSink() override; + virtual ~CompositorFrameSink(); // Called by the compositor on the compositor thread. This is a place where // thread-specific data for the output surface can be initialized, since from @@ -78,18 +75,18 @@ class CC_EXPORT CompositorFrameSink // should not be called twice for a given CompositorFrameSink. virtual bool BindToClient(CompositorFrameSinkClient* client); - // Called by the compositor on the compositor thread. This is a place where - // thread-specific data for the output surface can be uninitialized. + // Must be called from the thread where BindToClient was called if + // BindToClient succeeded, after which the CompositorFrameSink may be + // destroyed from any thread. This is a place where thread-specific data for + // the object can be uninitialized. virtual void DetachFromClient(); bool HasClient() { return !!client_; } const Capabilities& capabilities() const { return capabilities_; } - // Obtain the 3d context or the software device associated with this output - // surface. Either of these may return a null pointer, but not both. - // In the event of a lost context, the entire output surface should be - // recreated. + // The ContextProviders may be null if frames should be submitted with + // software SharedBitmap resources. ContextProvider* context_provider() const { return context_provider_.get(); } ContextProvider* worker_context_provider() const { return worker_context_provider_.get(); @@ -97,6 +94,12 @@ class CC_EXPORT CompositorFrameSink VulkanContextProvider* vulkan_context_provider() const { return vulkan_context_provider_.get(); } + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const { + return gpu_memory_buffer_manager_; + } + SharedBitmapManager* shared_bitmap_manager() const { + return shared_bitmap_manager_; + } // If supported, this causes a ReclaimResources for all resources that are // currently in use. @@ -108,19 +111,12 @@ class CC_EXPORT CompositorFrameSink // there's new content. virtual void Invalidate() {} - // For successful swaps, the implementation must call DidSwapBuffersComplete() - // (via OnSwapBuffersComplete()) eventually. - virtual void SwapBuffers(CompositorFrame frame) = 0; - virtual void OnSwapBuffersComplete(); - - // base::trace_event::MemoryDumpProvider implementation. - bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) override; + // For successful swaps, the implementation must call + // DidReceiveCompositorFrameAck() asynchronously when the frame has been + // processed in order to unthrottle the next frame. + virtual void SubmitCompositorFrame(CompositorFrame frame) = 0; protected: - // This is used by both display and delegating implementations. - void PostSwapBuffersComplete(); - // Bound to the ContextProvider to hear about when it is lost and inform the // |client_|. void DidLoseCompositorFrameSink(); @@ -131,13 +127,11 @@ class CC_EXPORT CompositorFrameSink scoped_refptr<ContextProvider> context_provider_; scoped_refptr<ContextProvider> worker_context_provider_; scoped_refptr<VulkanContextProvider> vulkan_context_provider_; + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; + SharedBitmapManager* shared_bitmap_manager_; base::ThreadChecker client_thread_checker_; private: - void DetachFromClientInternal(); - - base::WeakPtrFactory<CompositorFrameSink> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(CompositorFrameSink); }; diff --git a/chromium/cc/output/compositor_frame_sink_client.h b/chromium/cc/output/compositor_frame_sink_client.h index 07d428ff240..b67c6fc302c 100644 --- a/chromium/cc/output/compositor_frame_sink_client.h +++ b/chromium/cc/output/compositor_frame_sink_client.h @@ -27,40 +27,45 @@ class CC_EXPORT CompositorFrameSinkClient { public: // Pass the begin frame source for the client to observe. Client does not own // the BeginFrameSource. CompositorFrameSink should call this once after - // binding to - // the client and then call again with a null while detaching. + // binding to the client and then call again with a null while detaching. virtual void SetBeginFrameSource(BeginFrameSource* source) = 0; + + // Returns resources sent to SubmitCompositorFrame to be reused or freed. virtual void ReclaimResources(const ReturnedResourceArray& resources) = 0; - // For WebView. - virtual void SetExternalTilePriorityConstraints( - const gfx::Rect& viewport_rect, - const gfx::Transform& transform) = 0; + // If set, |callback| will be called subsequent to each new tree activation, // regardless of the compositor visibility or damage. |callback| must remain - // valid for the lifetime of the CompositorFrameSinkClient or until unregisted - // -- - // use SetTreeActivationCallback(base::Closure()) to unregister it. + // valid for the lifetime of the CompositorFrameSinkClient or until + // unregistered by giving a null base::Closure. virtual void SetTreeActivationCallback(const base::Closure& callback) = 0; - // This allows the output surface to ask its client for a draw. + + // Notification that the previous CompositorFrame given to + // SubmitCompositorFrame() has been processed and that another frame + // can be submitted. This provides backpressure from the display compositor + // so that frames are submitted only at the rate it can handle them. + virtual void DidReceiveCompositorFrameAck() = 0; + + // The CompositorFrameSink is lost when the ContextProviders held by it + // encounter an error. In this case the CompositorFrameSink (and the + // ContextProviders) must be recreated. + virtual void DidLoseCompositorFrameSink() = 0; + + // For SynchronousCompositor (WebView) to ask the layer compositor to submit + // a new CompositorFrame synchronously. virtual void OnDraw(const gfx::Transform& transform, const gfx::Rect& viewport, bool resourceless_software_draw) = 0; + // For SynchronousCompositor (WebView) to set how much memory the compositor // can use without changing visibility. virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0; - // ============== BOTH TYPES OF COMPOSITOR ====================== - - // For LayerTreeHostImpl, this is more of a OnSwapBuffersAck from the display - // compositor that it received and will use the frame, unblocking it from - // producing more frames. - // For the display compositor this is literally a notification that the swap - // to the hardware is complete. - virtual void DidSwapBuffersComplete() = 0; - - // Needs thought, if LTHI has only context providers, it needs to register a - // lost callback, so we need to support multiple callbacks. - virtual void DidLoseCompositorFrameSink() = 0; + // For SynchronousCompositor (WebView) to change which tiles should be + // included in submitted CompositorFrames independently of what the viewport + // is. + virtual void SetExternalTilePriorityConstraints( + const gfx::Rect& viewport_rect, + const gfx::Transform& transform) = 0; protected: virtual ~CompositorFrameSinkClient() {} diff --git a/chromium/cc/output/compositor_frame_sink_unittest.cc b/chromium/cc/output/compositor_frame_sink_unittest.cc index 80d3c6010ca..6a72c8d58bb 100644 --- a/chromium/cc/output/compositor_frame_sink_unittest.cc +++ b/chromium/cc/output/compositor_frame_sink_unittest.cc @@ -21,15 +21,13 @@ class TestCompositorFrameSink : public CompositorFrameSink { scoped_refptr<TestContextProvider> context_provider, scoped_refptr<TestContextProvider> worker_context_provider) : CompositorFrameSink(std::move(context_provider), - std::move(worker_context_provider)) {} + std::move(worker_context_provider), + nullptr, + nullptr) {} - void SwapBuffers(CompositorFrame frame) override { - client_->DidSwapBuffersComplete(); + void SubmitCompositorFrame(CompositorFrame frame) override { + client_->DidReceiveCompositorFrameAck(); } - - void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); } - - protected: }; TEST(CompositorFrameSinkTest, ContextLossInformsClient) { diff --git a/chromium/cc/output/context_cache_controller.cc b/chromium/cc/output/context_cache_controller.cc index 7401629e37c..79e85b3e033 100644 --- a/chromium/cc/output/context_cache_controller.cc +++ b/chromium/cc/output/context_cache_controller.cc @@ -7,7 +7,6 @@ #include "base/bind.h" #include "base/logging.h" #include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" #include "base/synchronization/lock.h" #include "gpu/command_buffer/client/context_support.h" #include "third_party/skia/include/gpu/GrContext.h" diff --git a/chromium/cc/output/context_cache_controller.h b/chromium/cc/output/context_cache_controller.h index 357e5daacb5..67b215e6305 100644 --- a/chromium/cc/output/context_cache_controller.h +++ b/chromium/cc/output/context_cache_controller.h @@ -11,13 +11,13 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/single_thread_task_runner.h" #include "cc/base/cc_export.h" class GrContext; namespace base { class Lock; -class SingleThreadTaskRunner; } namespace gpu { diff --git a/chromium/cc/output/context_provider.h b/chromium/cc/output/context_provider.h index 0c1310b2ef6..bc8f8c35ed8 100644 --- a/chromium/cc/output/context_provider.h +++ b/chromium/cc/output/context_provider.h @@ -27,7 +27,6 @@ namespace gles2 { class GLES2Interface; } } namespace cc { -struct ManagedMemoryPolicy; class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { public: @@ -74,6 +73,10 @@ class ContextProvider : public base::RefCountedThreadSafe<ContextProvider> { // Sets a callback to be called when the context is lost. This should be // called from the same thread that the context is bound to. To avoid races, // it should be called before BindToCurrentThread(). + // Implementation note: Implementations must avoid post-tasking the provided + // |lost_context_callback| directly as clients expect the method to not be + // called once they call SetLostContextCallback() again with a different + // callback. typedef base::Closure LostContextCallback; virtual void SetLostContextCallback( const LostContextCallback& lost_context_callback) = 0; diff --git a/chromium/cc/output/direct_renderer.cc b/chromium/cc/output/direct_renderer.cc index 4eb13ec146f..cc7fd12c670 100644 --- a/chromium/cc/output/direct_renderer.cc +++ b/chromium/cc/output/direct_renderer.cc @@ -233,14 +233,24 @@ void DirectRenderer::DrawFrame(RenderPassList* render_passes_in_draw_order, frame.root_damage_rect.Union(overlay_processor_->GetAndResetOverlayDamage()); frame.root_damage_rect.Intersect(gfx::Rect(device_viewport_size)); frame.device_viewport_size = device_viewport_size; + frame.device_color_space = device_color_space; // Only reshape when we know we are going to draw. Otherwise, the reshape // can leave the window at the wrong size if we never draw and the proper // viewport size is never set. - output_surface_->Reshape(device_viewport_size, device_scale_factor, - device_color_space, - frame.root_render_pass->has_transparent_background); - surface_size_for_swap_buffers_ = device_viewport_size; + bool frame_has_alpha = frame.root_render_pass->has_transparent_background; + if (device_viewport_size != reshape_surface_size_ || + device_scale_factor != reshape_device_scale_factor_ || + device_color_space != reshape_device_color_space_ || + frame_has_alpha != reshape_has_alpha_) { + reshape_surface_size_ = device_viewport_size; + reshape_device_scale_factor_ = device_scale_factor; + reshape_device_color_space_ = device_color_space; + reshape_has_alpha_ = frame.root_render_pass->has_transparent_background; + output_surface_->Reshape(reshape_surface_size_, + reshape_device_scale_factor_, + reshape_device_color_space_, reshape_has_alpha_); + } BeginDrawingFrame(&frame); @@ -542,10 +552,9 @@ bool DirectRenderer::UseRenderPass(DrawingFrame* frame, size.Enlarge(enlarge_pass_texture_amount_.width(), enlarge_pass_texture_amount_.height()); if (!texture->id()) { - texture->Allocate(size, - ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, - resource_provider_->best_texture_format(), - output_surface_->device_color_space()); + texture->Allocate( + size, ResourceProvider::TEXTURE_HINT_IMMUTABLE_FRAMEBUFFER, + resource_provider_->best_texture_format(), frame->device_color_space); } DCHECK(texture->id()); diff --git a/chromium/cc/output/direct_renderer.h b/chromium/cc/output/direct_renderer.h index 2b6674ea771..af732778468 100644 --- a/chromium/cc/output/direct_renderer.h +++ b/chromium/cc/output/direct_renderer.h @@ -81,6 +81,7 @@ class CC_EXPORT DirectRenderer { gfx::Rect root_damage_rect; gfx::Size device_viewport_size; + gfx::ColorSpace device_color_space; gfx::Transform projection_matrix; gfx::Transform window_matrix; @@ -168,6 +169,10 @@ class CC_EXPORT DirectRenderer { DrawingFrame* frame, std::unique_ptr<CopyOutputRequest> request) = 0; + gfx::Size surface_size_for_swap_buffers() const { + return reshape_surface_size_; + } + const RendererSettings* const settings_; OutputSurface* const output_surface_; ResourceProvider* const resource_provider_; @@ -190,9 +195,6 @@ class CC_EXPORT DirectRenderer { bool visible_ = false; - // The size of the surface produced by DrawFrame() for SwapBuffers() to use. - gfx::Size surface_size_for_swap_buffers_; - // For use in coordinate conversion, this stores the output rect, viewport // rect (= unflipped version of glViewport rect), the size of target // framebuffer, and the current window space viewport. During a draw, this @@ -207,6 +209,12 @@ class CC_EXPORT DirectRenderer { bool initialized_ = false; gfx::Size enlarge_pass_texture_amount_; + // Cached values given to Reshape(). + gfx::Size reshape_surface_size_; + float reshape_device_scale_factor_ = 0.f; + gfx::ColorSpace reshape_device_color_space_; + bool reshape_has_alpha_ = false; + DISALLOW_COPY_AND_ASSIGN(DirectRenderer); }; diff --git a/chromium/cc/output/dynamic_geometry_binding.h b/chromium/cc/output/dynamic_geometry_binding.h index 5f3e3fff51b..08a7a15af5b 100644 --- a/chromium/cc/output/dynamic_geometry_binding.h +++ b/chromium/cc/output/dynamic_geometry_binding.h @@ -8,6 +8,10 @@ #include "base/macros.h" #include "cc/output/geometry_binding.h" +namespace gfx { +class QuadF; +} + namespace cc { class DynamicGeometryBinding { diff --git a/chromium/cc/output/filter_operation.h b/chromium/cc/output/filter_operation.h index f813e0b001d..63edc3a6b24 100644 --- a/chromium/cc/output/filter_operation.h +++ b/chromium/cc/output/filter_operation.h @@ -19,7 +19,6 @@ namespace base { namespace trace_event { class TracedValue; } -class Value; } namespace gfx { diff --git a/chromium/cc/output/filter_operations.h b/chromium/cc/output/filter_operations.h index d0cd0e605a0..487962eb314 100644 --- a/chromium/cc/output/filter_operations.h +++ b/chromium/cc/output/filter_operations.h @@ -17,7 +17,6 @@ namespace base { namespace trace_event { class TracedValue; } -class Value; } namespace gfx { diff --git a/chromium/cc/output/filter_operations_unittest.cc b/chromium/cc/output/filter_operations_unittest.cc index 54fb974452a..89ed4608d4f 100644 --- a/chromium/cc/output/filter_operations_unittest.cc +++ b/chromium/cc/output/filter_operations_unittest.cc @@ -6,7 +6,6 @@ #include "cc/output/filter_operations.h" #include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkXfermode.h" #include "third_party/skia/include/effects/SkBlurImageFilter.h" #include "third_party/skia/include/effects/SkDropShadowImageFilter.h" #include "third_party/skia/include/effects/SkOffsetImageFilter.h" @@ -286,7 +285,7 @@ TEST(FilterOperationsTest, MapRectTypeConversionDoesNotOverflow) { FilterOperations ops; ops.Append(FilterOperation::CreateReferenceFilter(SkXfermodeImageFilter::Make( - SkXfermode::Make(SkXfermode::kSrcOver_Mode), + SkBlendMode::kSrcOver, SkOffsetImageFilter::Make(-big_offset, -big_offset, nullptr), SkOffsetImageFilter::Make(big_offset, big_offset, nullptr), nullptr))); gfx::Rect rect = ops.MapRect(gfx::Rect(-10, -10, 20, 20), SkMatrix::I()); diff --git a/chromium/cc/output/geometry_binding.h b/chromium/cc/output/geometry_binding.h index 473421640f5..0019013428b 100644 --- a/chromium/cc/output/geometry_binding.h +++ b/chromium/cc/output/geometry_binding.h @@ -12,13 +12,6 @@ #include "third_party/khronos/GLES2/gl2ext.h" #include "ui/gfx/geometry/rect_f.h" -namespace gfx { -class QuadF; -class Quad; -class QuadIndex; -class PointF; -} - namespace cc { struct GeometryBindingVertex { @@ -49,9 +42,6 @@ struct GeometryBindingQuadIndex { uint16_t data[6]; }; -class DrawQuad; -class DrawPolygon; - struct GeometryBinding { // All layer shaders share the same attribute locations for the vertex // positions and texture coordinates. This allows switching shaders without diff --git a/chromium/cc/output/gl_renderer.cc b/chromium/cc/output/gl_renderer.cc index 148a9649873..0a15e3056f0 100644 --- a/chromium/cc/output/gl_renderer.cc +++ b/chromium/cc/output/gl_renderer.cc @@ -888,14 +888,14 @@ gfx::Rect GLRenderer::GetBackdropBoundingBoxForRenderPassQuad( } std::unique_ptr<ScopedResource> GLRenderer::GetBackdropTexture( + DrawingFrame* frame, const gfx::Rect& bounding_rect) { std::unique_ptr<ScopedResource> device_background_texture = ScopedResource::Create(resource_provider_); // CopyTexImage2D fails when called on a texture having immutable storage. - device_background_texture->Allocate(bounding_rect.size(), - ResourceProvider::TEXTURE_HINT_DEFAULT, - resource_provider_->best_texture_format(), - output_surface_->device_color_space()); + device_background_texture->Allocate( + bounding_rect.size(), ResourceProvider::TEXTURE_HINT_DEFAULT, + resource_provider_->best_texture_format(), frame->device_color_space); { ResourceProvider::ScopedWriteLockGL lock( resource_provider_, device_background_texture->id(), false); @@ -998,8 +998,10 @@ const TileDrawQuad* GLRenderer::CanPassBeDrawnDirectly(const RenderPass* pass) { const DrawQuad* quad = *pass->quad_list.BackToFrontBegin(); // Hack: this could be supported by concatenating transforms, but - // in practice if there is one quad, it is at the origin of the render pass. - if (!quad->shared_quad_state->quad_to_target_transform.IsIdentity()) + // in practice if there is one quad, it is at the origin of the render pass + // and has the same size as the pass. + if (!quad->shared_quad_state->quad_to_target_transform.IsIdentity() || + quad->rect != pass->output_rect) return nullptr; // The quad is expected to be the entire layer so that AA edges are correct. if (gfx::Rect(quad->shared_quad_state->quad_layer_bounds) != quad->rect) @@ -1046,7 +1048,7 @@ void GLRenderer::DrawRenderPassQuad(DrawingFrame* frame, // RGBA_8888 here is arbitrary and unused. Resource tile_resource(tile_quad->resource_id(), tile_quad->texture_size, ResourceFormat::RGBA_8888, - output_surface_->device_color_space()); + frame->device_color_space); // The projection matrix used by GLRenderer has a flip. As tile texture // inputs are oriented opposite to framebuffer outputs, don't flip via // texture coords and let the projection matrix naturallyd o it. @@ -1153,7 +1155,8 @@ void GLRenderer::UpdateRPDQShadersForBlending( // This function allocates a texture, which should contribute to the // amount of memory used by render surfaces: // LayerTreeHost::CalculateMemoryForRenderSurfaces. - params->background_texture = GetBackdropTexture(params->background_rect); + params->background_texture = + GetBackdropTexture(params->frame, params->background_rect); if (ShouldApplyBackgroundFilters(quad) && params->background_texture) { // Apply the background filters to R, so that it is applied in the @@ -2407,7 +2410,7 @@ void GLRenderer::DrawYUVVideoQuad(const DrawingFrame* frame, if (lut_texture_location != -1) { unsigned int lut_texture = color_lut_cache_.GetLUT( - quad->video_color_space, output_surface_->device_color_space(), 32); + quad->video_color_space, frame->device_color_space, 17); gl_->ActiveTexture(GL_TEXTURE5); gl_->BindTexture(GL_TEXTURE_2D, lut_texture); gl_->Uniform1i(lut_texture_location, 5); @@ -2896,17 +2899,19 @@ void GLRenderer::DrawQuadGeometry(const gfx::Transform& projection_matrix, void GLRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { DCHECK(visible_); - TRACE_EVENT0("cc,benchmark", "GLRenderer::SwapBuffers"); + TRACE_EVENT0("cc", "GLRenderer::SwapBuffers"); // We're done! Time to swapbuffers! + gfx::Size surface_size = surface_size_for_swap_buffers(); + OutputSurfaceFrame output_frame; output_frame.latency_info = std::move(latency_info); - output_frame.size = surface_size_for_swap_buffers_; + output_frame.size = surface_size; if (use_partial_swap_) { // If supported, we can save significant bandwidth by only swapping the // damaged/scissored region (clamped to the viewport). - swap_buffer_rect_.Intersect(gfx::Rect(surface_size_for_swap_buffers_)); - int flipped_y_pos_of_rect_bottom = surface_size_for_swap_buffers_.height() - + swap_buffer_rect_.Intersect(gfx::Rect(surface_size)); + int flipped_y_pos_of_rect_bottom = surface_size.height() - swap_buffer_rect_.y() - swap_buffer_rect_.height(); output_frame.sub_buffer_rect = @@ -2918,7 +2923,7 @@ void GLRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { // Expand the swap rect to the full surface unless it's empty, and empty // swap is allowed. if (!swap_buffer_rect_.IsEmpty() || !allow_empty_swap_) { - swap_buffer_rect_ = gfx::Rect(surface_size_for_swap_buffers_); + swap_buffer_rect_ = gfx::Rect(surface_size); } output_frame.sub_buffer_rect = swap_buffer_rect_; } @@ -3922,7 +3927,7 @@ void GLRenderer::CopyRenderPassDrawQuadToOverlayResource( *resource = overlay_resource_pool_->AcquireResource( gfx::Size(iosurface_width, iosurface_height), ResourceFormat::RGBA_8888, - output_surface_->device_color_space()); + external_frame->device_color_space); *new_bounds = gfx::RectF(updated_dst_rect.x(), updated_dst_rect.y(), (*resource)->size().width(), (*resource)->size().height()); diff --git a/chromium/cc/output/gl_renderer.h b/chromium/cc/output/gl_renderer.h index 5e9c596d1c4..e666633cfa0 100644 --- a/chromium/cc/output/gl_renderer.h +++ b/chromium/cc/output/gl_renderer.h @@ -24,8 +24,6 @@ #include "ui/events/latency_info.h" #include "ui/gfx/geometry/quad_f.h" -class SkBitmap; - namespace gpu { namespace gles2 { class GLES2Interface; @@ -35,7 +33,6 @@ class GLES2Interface; namespace cc { class GLRendererShaderTest; class OutputSurface; -class PictureDrawQuad; class Resource; class ResourcePool; class ScopedResource; @@ -44,7 +41,6 @@ class TextureDrawQuad; class TextureMailboxDeleter; class StaticGeometryBinding; class DynamicGeometryBinding; -class ScopedEnsureFramebufferAllocation; struct DrawRenderPassDrawQuadParams; // Class that handles drawing of composited render layers using GL. @@ -171,6 +167,7 @@ class CC_EXPORT GLRenderer : public DirectRenderer { bool use_aa, gfx::Rect* unclipped_rect); std::unique_ptr<ScopedResource> GetBackdropTexture( + DrawingFrame* frame, const gfx::Rect& bounding_rect); static bool ShouldApplyBackgroundFilters(const RenderPassDrawQuad* quad); @@ -218,9 +215,6 @@ class CC_EXPORT GLRenderer : public DirectRenderer { void DrawYUVVideoQuad(const DrawingFrame* frame, const YUVVideoDrawQuad* quad, const gfx::QuadF* clip_region); - void DrawPictureQuad(const DrawingFrame* frame, - const PictureDrawQuad* quad, - const gfx::QuadF* clip_region); void SetShaderOpacity(float opacity, int alpha_location); void SetShaderQuadF(const gfx::QuadF& quad, int quad_location); diff --git a/chromium/cc/output/gl_renderer_unittest.cc b/chromium/cc/output/gl_renderer_unittest.cc index 3ae4ee74963..d9456b38a2d 100644 --- a/chromium/cc/output/gl_renderer_unittest.cc +++ b/chromium/cc/output/gl_renderer_unittest.cc @@ -340,9 +340,8 @@ class FakeRendererGL : public GLRenderer { class GLRendererWithDefaultHarnessTest : public GLRendererTest { protected: GLRendererWithDefaultHarnessTest() { - output_surface_ = - FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create()); - CHECK(output_surface_->BindToClient(&output_surface_client_)); + output_surface_ = FakeOutputSurface::Create3d(); + output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = FakeResourceProvider::Create( @@ -372,7 +371,7 @@ class GLRendererShaderTest : public GLRendererTest { protected: GLRendererShaderTest() { output_surface_ = FakeOutputSurface::Create3d(); - CHECK(output_surface_->BindToClient(&output_surface_client_)); + output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = FakeResourceProvider::Create( @@ -599,11 +598,14 @@ class ForbidSynchronousCallContext : public TestWebGraphicsContext3D { } }; TEST_F(GLRendererTest, InitializationDoesNotMakeSynchronousCalls) { + auto context = base::MakeUnique<ForbidSynchronousCallContext>(); + auto provider = TestContextProvider::Create(std::move(context)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(std::unique_ptr<TestWebGraphicsContext3D>( - new ForbidSynchronousCallContext))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -632,11 +634,14 @@ class LoseContextOnFirstGetContext : public TestWebGraphicsContext3D { }; TEST_F(GLRendererTest, InitializationWithQuicklyLostContextDoesNotAssert) { + auto context = base::MakeUnique<LoseContextOnFirstGetContext>(); + auto provider = TestContextProvider::Create(std::move(context)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(std::unique_ptr<TestWebGraphicsContext3D>( - new LoseContextOnFirstGetContext))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -664,10 +669,13 @@ TEST_F(GLRendererTest, OpaqueBackground) { std::unique_ptr<ClearCountingContext> context_owned(new ClearCountingContext); ClearCountingContext* context = context_owned.get(); + auto provider = TestContextProvider::Create(std::move(context_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(std::move(context_owned))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -705,10 +713,13 @@ TEST_F(GLRendererTest, TransparentBackground) { std::unique_ptr<ClearCountingContext> context_owned(new ClearCountingContext); ClearCountingContext* context = context_owned.get(); + auto provider = TestContextProvider::Create(std::move(context_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(std::move(context_owned))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -739,10 +750,13 @@ TEST_F(GLRendererTest, OffscreenOutputSurface) { std::unique_ptr<ClearCountingContext> context_owned(new ClearCountingContext); ClearCountingContext* context = context_owned.get(); + auto provider = TestContextProvider::Create(std::move(context_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::CreateOffscreen(std::move(context_owned))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::CreateOffscreen(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -795,10 +809,13 @@ TEST_F(GLRendererTest, ActiveTextureState) { new TextureStateTrackingContext); TextureStateTrackingContext* context = context_owned.get(); + auto provider = TestContextProvider::Create(std::move(context_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(std::move(context_owned))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -876,10 +893,13 @@ TEST_F(GLRendererTest, ShouldClearRootRenderPass) { new NoClearRootRenderPassMockContext); NoClearRootRenderPassMockContext* mock_context = mock_context_owned.get(); + auto provider = TestContextProvider::Create(std::move(mock_context_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(std::move(mock_context_owned))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -961,10 +981,13 @@ class ScissorTestOnClearCheckingGLES2Interface : public TestGLES2Interface { TEST_F(GLRendererTest, ScissorTestWhenClearing) { auto gl_owned = base::MakeUnique<ScissorTestOnClearCheckingGLES2Interface>(); + auto provider = TestContextProvider::Create(std::move(gl_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; - std::unique_ptr<OutputSurface> output_surface(FakeOutputSurface::Create3d( - TestContextProvider::Create(std::move(gl_owned)))); - CHECK(output_surface->BindToClient(&output_surface_client)); + std::unique_ptr<OutputSurface> output_surface( + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -1030,28 +1053,16 @@ class DiscardCheckingGLES2Interface : public TestGLES2Interface { int discarded_ = 0; }; -class NonReshapableOutputSurface : public FakeOutputSurface { - public: - explicit NonReshapableOutputSurface(std::unique_ptr<TestGLES2Interface> gl) - : FakeOutputSurface(TestContextProvider::Create(std::move(gl))) { - surface_size_ = gfx::Size(500, 500); - } - void Reshape(const gfx::Size& size, - float scale_factor, - const gfx::ColorSpace& color_space, - bool has_alpha) override {} - void set_fixed_size(const gfx::Size& size) { surface_size_ = size; } -}; - TEST_F(GLRendererTest, NoDiscardOnPartialUpdates) { auto gl_owned = base::MakeUnique<DiscardCheckingGLES2Interface>(); auto* gl = gl_owned.get(); + auto provider = TestContextProvider::Create(std::move(gl_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; - std::unique_ptr<NonReshapableOutputSurface> output_surface( - new NonReshapableOutputSurface(std::move(gl_owned))); - CHECK(output_surface->BindToClient(&output_surface_client)); - output_surface->set_fixed_size(gfx::Size(100, 100)); + auto output_surface = FakeOutputSurface::Create3d(std::move(provider)); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -1130,8 +1141,8 @@ TEST_F(GLRendererTest, DrawFramePreservesFramebuffer) { // has finished. FakeOutputSurfaceClient output_surface_client; std::unique_ptr<FakeOutputSurface> output_surface( - FakeOutputSurface::Create3d(TestWebGraphicsContext3D::Create())); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d()); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -1468,13 +1479,12 @@ class OutputSurfaceMockContext : public TestWebGraphicsContext3D { class MockOutputSurface : public OutputSurface { public: - MockOutputSurface() - : OutputSurface(TestContextProvider::Create( - base::MakeUnique<StrictMock<OutputSurfaceMockContext>>())) { - surface_size_ = gfx::Size(100, 100); - } + explicit MockOutputSurface(scoped_refptr<ContextProvider> provider) + : OutputSurface(std::move(provider)) {} virtual ~MockOutputSurface() {} + void BindToClient(OutputSurfaceClient*) override {} + MOCK_METHOD0(EnsureBackbuffer, void()); MOCK_METHOD0(DiscardBackbuffer, void()); MOCK_METHOD4(Reshape, @@ -1497,22 +1507,29 @@ class MockOutputSurface : public OutputSurface { class MockOutputSurfaceTest : public GLRendererTest { protected: - virtual void SetUp() { + void SetUp() override { + auto context = base::MakeUnique<StrictMock<OutputSurfaceMockContext>>(); + context_ = context.get(); + auto provider = TestContextProvider::Create(std::move(context)); + provider->BindToCurrentThread(); + output_surface_ = + base::MakeUnique<StrictMock<MockOutputSurface>>(std::move(provider)); + FakeOutputSurfaceClient output_surface_client_; - CHECK(output_surface_.BindToClient(&output_surface_client_)); + output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = FakeResourceProvider::Create( - output_surface_.context_provider(), shared_bitmap_manager_.get()); + output_surface_->context_provider(), shared_bitmap_manager_.get()); - renderer_.reset(new FakeRendererGL(&settings_, &output_surface_, + renderer_.reset(new FakeRendererGL(&settings_, output_surface_.get(), resource_provider_.get())); - EXPECT_CALL(output_surface_, GetOverlayCandidateValidator()).Times(1); + EXPECT_CALL(*output_surface_, GetOverlayCandidateValidator()).Times(1); renderer_->Initialize(); - EXPECT_CALL(output_surface_, EnsureBackbuffer()).Times(1); + EXPECT_CALL(*output_surface_, EnsureBackbuffer()).Times(1); renderer_->SetVisible(true); - Mock::VerifyAndClearExpectations(&output_surface_); + Mock::VerifyAndClearExpectations(output_surface_.get()); } void SwapBuffers() { renderer_->SwapBuffers(std::vector<ui::LatencyInfo>()); } @@ -1527,15 +1544,15 @@ class MockOutputSurfaceTest : public GLRendererTest { AddQuad(render_pass, gfx::Rect(viewport_size), SK_ColorGREEN); render_pass->has_transparent_background = transparent; - EXPECT_CALL(output_surface_, EnsureBackbuffer()).WillRepeatedly(Return()); + EXPECT_CALL(*output_surface_, EnsureBackbuffer()).WillRepeatedly(Return()); - EXPECT_CALL(output_surface_, + EXPECT_CALL(*output_surface_, Reshape(viewport_size, device_scale_factor, _, transparent)) .Times(1); - EXPECT_CALL(output_surface_, BindFramebuffer()).Times(1); + EXPECT_CALL(*output_surface_, BindFramebuffer()).Times(1); - EXPECT_CALL(*Context(), drawElements(_, _, _, _)).Times(1); + EXPECT_CALL(*context_, drawElements(_, _, _, _)).Times(1); renderer_->DecideRenderPassAllocationsForFrame( render_passes_in_draw_order_); @@ -1543,15 +1560,10 @@ class MockOutputSurfaceTest : public GLRendererTest { gfx::ColorSpace(), viewport_size); } - OutputSurfaceMockContext* Context() { - return static_cast<OutputSurfaceMockContext*>( - static_cast<TestContextProvider*>(output_surface_.context_provider()) - ->TestContext3d()); - } - RendererSettings settings_; FakeOutputSurfaceClient output_surface_client_; - StrictMock<MockOutputSurface> output_surface_; + OutputSurfaceMockContext* context_ = nullptr; + std::unique_ptr<StrictMock<MockOutputSurface>> output_surface_; std::unique_ptr<SharedBitmapManager> shared_bitmap_manager_; std::unique_ptr<ResourceProvider> resource_provider_; std::unique_ptr<FakeRendererGL> renderer_; @@ -1559,14 +1571,14 @@ class MockOutputSurfaceTest : public GLRendererTest { TEST_F(MockOutputSurfaceTest, BackbufferDiscard) { // Drop backbuffer on hide. - EXPECT_CALL(output_surface_, DiscardBackbuffer()).Times(1); + EXPECT_CALL(*output_surface_, DiscardBackbuffer()).Times(1); renderer_->SetVisible(false); - Mock::VerifyAndClearExpectations(&output_surface_); + Mock::VerifyAndClearExpectations(output_surface_.get()); // Restore backbuffer on show. - EXPECT_CALL(output_surface_, EnsureBackbuffer()).Times(1); + EXPECT_CALL(*output_surface_, EnsureBackbuffer()).Times(1); renderer_->SetVisible(true); - Mock::VerifyAndClearExpectations(&output_surface_); + Mock::VerifyAndClearExpectations(output_surface_.get()); } class TestOverlayProcessor : public OverlayProcessor { @@ -1618,7 +1630,7 @@ TEST_F(GLRendererTest, DontOverlayWithCopyRequests) { FakeOutputSurfaceClient output_surface_client; std::unique_ptr<FakeOutputSurface> output_surface( FakeOutputSurface::Create3d()); - CHECK(output_surface->BindToClient(&output_surface_client)); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -1766,16 +1778,17 @@ TEST_F(GLRendererTest, OverlaySyncTokensAreProcessed) { new WaitSyncTokenCountingContext); WaitSyncTokenCountingContext* context = context_owned.get(); + auto provider = TestContextProvider::Create(std::move(context_owned)); + provider->BindToCurrentThread(); + MockOverlayScheduler overlay_scheduler; - scoped_refptr<TestContextProvider> context_provider = - TestContextProvider::Create(std::move(context_owned)); - context_provider->support()->SetScheduleOverlayPlaneCallback(base::Bind( + provider->support()->SetScheduleOverlayPlaneCallback(base::Bind( &MockOverlayScheduler::Schedule, base::Unretained(&overlay_scheduler))); FakeOutputSurfaceClient output_surface_client; std::unique_ptr<OutputSurface> output_surface( - FakeOutputSurface::Create3d(context_provider)); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( new TestSharedBitmapManager()); @@ -1859,10 +1872,13 @@ class GLRendererPartialSwapTest : public GLRendererTest { auto gl_owned = base::MakeUnique<PartialSwapMockGLES2Interface>(); auto* gl = gl_owned.get(); + auto provider = TestContextProvider::Create(std::move(gl_owned)); + provider->BindToCurrentThread(); + FakeOutputSurfaceClient output_surface_client; std::unique_ptr<FakeOutputSurface> output_surface( - FakeOutputSurface::Create3d(std::move(gl_owned))); - CHECK(output_surface->BindToClient(&output_surface_client)); + FakeOutputSurface::Create3d(std::move(provider))); + output_surface->BindToClient(&output_surface_client); std::unique_ptr<ResourceProvider> resource_provider = FakeResourceProvider::Create(output_surface->context_provider(), @@ -1940,6 +1956,7 @@ class GLRendererWithMockContextTest : public ::testing::Test { context_support_ptr_ = context_support.get(); auto context_provider = TestContextProvider::Create( TestWebGraphicsContext3D::Create(), std::move(context_support)); + context_provider->BindToCurrentThread(); output_surface_ = FakeOutputSurface::Create3d(std::move(context_provider)); output_surface_->BindToClient(&output_surface_client_); resource_provider_ = FakeResourceProvider::Create( diff --git a/chromium/cc/output/managed_memory_policy.cc b/chromium/cc/output/managed_memory_policy.cc index 0dc7def60e1..ed3f4a86509 100644 --- a/chromium/cc/output/managed_memory_policy.cc +++ b/chromium/cc/output/managed_memory_policy.cc @@ -7,8 +7,6 @@ #include <stddef.h> #include "base/logging.h" -#include "cc/proto/gpu_conversions.h" -#include "cc/proto/managed_memory_policy.pb.h" namespace cc { @@ -45,21 +43,6 @@ bool ManagedMemoryPolicy::operator!=(const ManagedMemoryPolicy& other) const { return !(*this == other); } -void ManagedMemoryPolicy::ToProtobuf(proto::ManagedMemoryPolicy* proto) const { - proto->set_bytes_limit_when_visible(bytes_limit_when_visible); - proto->set_priority_cutoff_when_visible( - MemoryAllocationPriorityCutoffToProto(priority_cutoff_when_visible)); - proto->set_num_resources_limit(num_resources_limit); -} - -void ManagedMemoryPolicy::FromProtobuf( - const proto::ManagedMemoryPolicy& proto) { - bytes_limit_when_visible = proto.bytes_limit_when_visible(); - priority_cutoff_when_visible = MemoryAllocationPriorityCutoffFromProto( - proto.priority_cutoff_when_visible()); - num_resources_limit = proto.num_resources_limit(); -} - // static TileMemoryLimitPolicy ManagedMemoryPolicy::PriorityCutoffToTileMemoryLimitPolicy( diff --git a/chromium/cc/output/managed_memory_policy.h b/chromium/cc/output/managed_memory_policy.h index 54fa271d0bf..953e6ec1da8 100644 --- a/chromium/cc/output/managed_memory_policy.h +++ b/chromium/cc/output/managed_memory_policy.h @@ -30,9 +30,6 @@ struct CC_EXPORT ManagedMemoryPolicy { bool operator==(const ManagedMemoryPolicy&) const; bool operator!=(const ManagedMemoryPolicy&) const; - void ToProtobuf(proto::ManagedMemoryPolicy* proto) const; - void FromProtobuf(const proto::ManagedMemoryPolicy& proto); - size_t bytes_limit_when_visible; gpu::MemoryAllocation::PriorityCutoff priority_cutoff_when_visible; size_t num_resources_limit; diff --git a/chromium/cc/output/managed_memory_policy_unittest.cc b/chromium/cc/output/managed_memory_policy_unittest.cc deleted file mode 100644 index de2ecfd52e6..00000000000 --- a/chromium/cc/output/managed_memory_policy_unittest.cc +++ /dev/null @@ -1,43 +0,0 @@ -// Copyright 2015 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/output/managed_memory_policy.h" - -#include <stddef.h> - -#include "cc/proto/managed_memory_policy.pb.h" -#include "cc/proto/memory_allocation.pb.h" -#include "gpu/command_buffer/common/gpu_memory_allocation.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -void VerifySerializeAndDeserialize( - size_t bytes_limit_when_visible, - gpu::MemoryAllocation::PriorityCutoff priority_cutoff_when_visible, - size_t num_resources_limit) { - ManagedMemoryPolicy policy1(bytes_limit_when_visible, - gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY, - num_resources_limit); - proto::ManagedMemoryPolicy proto; - policy1.ToProtobuf(&proto); - ManagedMemoryPolicy policy2(1); - policy2.FromProtobuf(proto); - EXPECT_EQ(policy1, policy2); -} - -TEST(ManagedMemoryPolicyTest, SerializeDeserialize) { - VerifySerializeAndDeserialize( - 42, gpu::MemoryAllocation::CUTOFF_ALLOW_REQUIRED_ONLY, 24); - VerifySerializeAndDeserialize(0, gpu::MemoryAllocation::CUTOFF_ALLOW_NOTHING, - 1); - VerifySerializeAndDeserialize( - 1, gpu::MemoryAllocation::CUTOFF_ALLOW_NICE_TO_HAVE, 0); - VerifySerializeAndDeserialize( - 1024, gpu::MemoryAllocation::CUTOFF_ALLOW_EVERYTHING, 4096); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/output/output_surface.cc b/chromium/cc/output/output_surface.cc index 1a81af3e854..9c86c08a80b 100644 --- a/chromium/cc/output/output_surface.cc +++ b/chromium/cc/output/output_surface.cc @@ -9,233 +9,33 @@ #include "base/bind.h" #include "base/location.h" #include "base/macros.h" -#include "base/single_thread_task_runner.h" #include "base/threading/thread_task_runner_handle.h" -#include "base/trace_event/memory_dump_manager.h" #include "base/trace_event/trace_event.h" -#include "cc/output/managed_memory_policy.h" #include "cc/output/output_surface_client.h" #include "cc/output/output_surface_frame.h" #include "gpu/GLES2/gl2extchromium.h" #include "gpu/command_buffer/client/context_support.h" #include "gpu/command_buffer/client/gles2_interface.h" -#include "third_party/skia/include/core/SkTraceMemoryDump.h" -#include "third_party/skia/include/gpu/GrContext.h" -#include "ui/gfx/geometry/rect.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gl/trace_util.h" - -class SkDiscardableMemory; namespace cc { -namespace { - -// Constants used by SkiaGpuTraceMemoryDump to identify different memory types. -const char* kGLTextureBackingType = "gl_texture"; -const char* kGLBufferBackingType = "gl_buffer"; -const char* kGLRenderbufferBackingType = "gl_renderbuffer"; - -// Derives from SkTraceMemoryDump and implements graphics specific memory -// backing functionality. -class SkiaGpuTraceMemoryDump : public SkTraceMemoryDump { - public: - // This should never outlive the provided ProcessMemoryDump, as it should - // always be scoped to a single OnMemoryDump funciton call. - explicit SkiaGpuTraceMemoryDump(base::trace_event::ProcessMemoryDump* pmd, - uint64_t share_group_tracing_guid) - : pmd_(pmd), share_group_tracing_guid_(share_group_tracing_guid) {} - - // Overridden from SkTraceMemoryDump: - void dumpNumericValue(const char* dump_name, - const char* value_name, - const char* units, - uint64_t value) override { - auto* dump = GetOrCreateAllocatorDump(dump_name); - dump->AddScalar(value_name, units, value); - } - - void setMemoryBacking(const char* dump_name, - const char* backing_type, - const char* backing_object_id) override { - const uint64_t tracing_process_id = - base::trace_event::MemoryDumpManager::GetInstance() - ->GetTracingProcessId(); - - // For uniformity, skia provides this value as a string. Convert back to a - // uint32_t. - uint32_t gl_id = - std::strtoul(backing_object_id, nullptr /* str_end */, 10 /* base */); - - // Populated in if statements below. - base::trace_event::MemoryAllocatorDumpGuid guid; - - if (strcmp(backing_type, kGLTextureBackingType) == 0) { - guid = gl::GetGLTextureClientGUIDForTracing(share_group_tracing_guid_, - gl_id); - } else if (strcmp(backing_type, kGLBufferBackingType) == 0) { - guid = gl::GetGLBufferGUIDForTracing(tracing_process_id, gl_id); - } else if (strcmp(backing_type, kGLRenderbufferBackingType) == 0) { - guid = gl::GetGLRenderbufferGUIDForTracing(tracing_process_id, gl_id); - } - - if (!guid.empty()) { - pmd_->CreateSharedGlobalAllocatorDump(guid); - - auto* dump = GetOrCreateAllocatorDump(dump_name); - - const int kImportance = 2; - pmd_->AddOwnershipEdge(dump->guid(), guid, kImportance); - } - } - - void setDiscardableMemoryBacking( - const char* dump_name, - const SkDiscardableMemory& discardable_memory_object) override { - // We don't use this class for dumping discardable memory. - NOTREACHED(); - } - - LevelOfDetail getRequestedDetails() const override { - // TODO(ssid): Use MemoryDumpArgs to create light dumps when requested - // (crbug.com/499731). - return kObjectsBreakdowns_LevelOfDetail; - } - - private: - // Helper to create allocator dumps. - base::trace_event::MemoryAllocatorDump* GetOrCreateAllocatorDump( - const char* dump_name) { - auto* dump = pmd_->GetAllocatorDump(dump_name); - if (!dump) - dump = pmd_->CreateAllocatorDump(dump_name); - return dump; - } - - base::trace_event::ProcessMemoryDump* pmd_; - uint64_t share_group_tracing_guid_; - - DISALLOW_COPY_AND_ASSIGN(SkiaGpuTraceMemoryDump); -}; - -} // namespace - OutputSurface::OutputSurface(scoped_refptr<ContextProvider> context_provider) - : context_provider_(std::move(context_provider)), weak_ptr_factory_(this) { + : context_provider_(std::move(context_provider)) { DCHECK(context_provider_); - thread_checker_.DetachFromThread(); } OutputSurface::OutputSurface( std::unique_ptr<SoftwareOutputDevice> software_device) - : software_device_(std::move(software_device)), weak_ptr_factory_(this) { + : software_device_(std::move(software_device)) { DCHECK(software_device_); - thread_checker_.DetachFromThread(); } OutputSurface::OutputSurface( scoped_refptr<VulkanContextProvider> vulkan_context_provider) - : vulkan_context_provider_(vulkan_context_provider), - weak_ptr_factory_(this) { + : vulkan_context_provider_(std::move(vulkan_context_provider)) { DCHECK(vulkan_context_provider_); - thread_checker_.DetachFromThread(); -} - -OutputSurface::~OutputSurface() { - // Is destroyed on the thread it is bound to. - DCHECK(thread_checker_.CalledOnValidThread()); - - if (!client_) - return; - - // Unregister any dump provider. Safe to call (no-op) if we have not yet - // registered. - if (base::ThreadTaskRunnerHandle::IsSet()) { - base::trace_event::MemoryDumpManager::GetInstance()->UnregisterDumpProvider( - this); - } - - if (context_provider_) { - context_provider_->SetLostContextCallback( - ContextProvider::LostContextCallback()); - } -} - -bool OutputSurface::BindToClient(OutputSurfaceClient* client) { - DCHECK(thread_checker_.CalledOnValidThread()); - DCHECK(client); - DCHECK(!client_); - client_ = client; - - if (context_provider_) { - if (!context_provider_->BindToCurrentThread()) - return false; - - context_provider_->SetLostContextCallback(base::Bind( - &OutputSurface::DidLoseOutputSurface, base::Unretained(this))); - } - - // In certain cases, ThreadTaskRunnerHandle isn't set (Android Webview). - // Don't register a dump provider in these cases. - // TODO(ericrk): Get this working in Android Webview. crbug.com/517156 - if (base::ThreadTaskRunnerHandle::IsSet()) { - // Now that we are on the context thread, register a dump provider with this - // thread's task runner. This will overwrite any previous dump provider - // registered. - base::trace_event::MemoryDumpManager::GetInstance()->RegisterDumpProvider( - this, "OutputSurface", base::ThreadTaskRunnerHandle::Get()); - } - return true; } -void OutputSurface::Reshape(const gfx::Size& size, - float scale_factor, - const gfx::ColorSpace& color_space, - bool has_alpha) { - device_color_space_ = color_space; - if (size == surface_size_ && scale_factor == device_scale_factor_ && - has_alpha == has_alpha_) - return; - - surface_size_ = size; - device_scale_factor_ = scale_factor; - has_alpha_ = has_alpha; - if (context_provider_.get()) { - context_provider_->ContextGL()->ResizeCHROMIUM(size.width(), size.height(), - scale_factor, has_alpha); - } - if (software_device_) - software_device_->Resize(size, scale_factor); -} - -void OutputSurface::PostSwapBuffersComplete() { - base::ThreadTaskRunnerHandle::Get()->PostTask( - FROM_HERE, base::Bind(&OutputSurface::OnSwapBuffersComplete, - weak_ptr_factory_.GetWeakPtr())); -} - -// We don't post tasks bound to the client directly since they might run -// after the OutputSurface has been destroyed. -void OutputSurface::OnSwapBuffersComplete() { - client_->DidSwapBuffersComplete(); -} - -bool OutputSurface::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) { - if (auto* context_provider = this->context_provider()) { - // No need to lock, main context provider is not shared. - if (auto* gr_context = context_provider->GrContext()) { - SkiaGpuTraceMemoryDump trace_memory_dump( - pmd, context_provider->ContextSupport()->ShareGroupTracingGUID()); - gr_context->dumpMemoryStatistics(&trace_memory_dump); - } - } - return true; -} - -void OutputSurface::DidLoseOutputSurface() { - TRACE_EVENT0("cc", "OutputSurface::DidLoseOutputSurface"); - client_->DidLoseOutputSurface(); -} +OutputSurface::~OutputSurface() = default; } // namespace cc diff --git a/chromium/cc/output/output_surface.h b/chromium/cc/output/output_surface.h index 9a3d8ce6802..e5199e6d6cc 100644 --- a/chromium/cc/output/output_surface.h +++ b/chromium/cc/output/output_surface.h @@ -10,9 +10,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" #include "base/threading/thread_checker.h" -#include "base/trace_event/memory_dump_provider.h" #include "cc/base/cc_export.h" #include "cc/output/context_provider.h" #include "cc/output/overlay_candidate_validator.h" @@ -22,31 +20,20 @@ #include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/color_space.h" -namespace ui { -class LatencyInfo; -} - namespace gfx { class ColorSpace; -class Rect; class Size; -class Transform; } namespace cc { -struct ManagedMemoryPolicy; class OutputSurfaceClient; class OutputSurfaceFrame; -// Represents the output surface for a compositor. The compositor owns -// and manages its destruction. Its lifetime is: -// 1. Created on the main thread by the LayerTreeHost through its client. -// 2. Passed to the compositor thread and bound to a client via BindToClient. -// From here on, it will only be used on the compositor thread. -// 3. If the 3D context is lost, then the compositor will delete the output -// surface (on the compositor thread) and go back to step 1. -class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { +// This class represents a platform-independent API for presenting +// buffers to display via GPU or software compositing. Implementations +// can provide platform-specific behaviour. +class CC_EXPORT OutputSurface { public: struct Capabilities { Capabilities() = default; @@ -67,16 +54,7 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { explicit OutputSurface( scoped_refptr<VulkanContextProvider> vulkan_context_provider); - ~OutputSurface() override; - - // Called by the compositor on the compositor thread. This is a place where - // thread-specific data for the output surface can be initialized, since from - // this point to when DetachFromClient() is called the output surface will - // only be used on the compositor thread. - // The caller should call DetachFromClient() on the same thread before - // destroying the OutputSurface, even if this fails. And BindToClient should - // not be called twice for a given OutputSurface. - virtual bool BindToClient(OutputSurfaceClient* client); + virtual ~OutputSurface(); const Capabilities& capabilities() const { return capabilities_; } @@ -92,6 +70,8 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { return software_device_.get(); } + virtual void BindToClient(OutputSurfaceClient* client) = 0; + virtual void EnsureBackbuffer() = 0; virtual void DiscardBackbuffer() = 0; @@ -99,10 +79,6 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { // OutputSurfaces. virtual void BindFramebuffer() = 0; - const gfx::ColorSpace& device_color_space() const { - return device_color_space_; - } - // Get the class capable of informing cc of hardware overlay capability. virtual OverlayCandidateValidator* GetOverlayCandidateValidator() const = 0; @@ -116,9 +92,9 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { virtual bool SurfaceIsSuspendForRecycle() const = 0; virtual void Reshape(const gfx::Size& size, - float scale_factor, + float device_scale_factor, const gfx::ColorSpace& color_space, - bool alpha); + bool has_alpha) = 0; virtual bool HasExternalStencilTest() const = 0; virtual void ApplyExternalStencil() = 0; @@ -127,41 +103,18 @@ class CC_EXPORT OutputSurface : public base::trace_event::MemoryDumpProvider { // when the framebuffer is bound via BindFramebuffer(). virtual uint32_t GetFramebufferCopyTextureFormat() = 0; - // The implementation may destroy or steal the contents of the CompositorFrame - // passed in (though it will not take ownership of the CompositorFrame - // itself). For successful swaps, the implementation must call - // OutputSurfaceClient::DidSwapBuffersComplete() eventually. + // Swaps the current backbuffer to the screen. For successful swaps, the + // implementation must call OutputSurfaceClient::DidReceiveSwapBuffersAck() + // after returning from this method in order to unblock the next frame. virtual void SwapBuffers(OutputSurfaceFrame frame) = 0; - // base::trace_event::MemoryDumpProvider implementation. - bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, - base::trace_event::ProcessMemoryDump* pmd) override; - protected: - void PostSwapBuffersComplete(); - - // Used internally for the context provider to inform the client about loss, - // and can be overridden to change behaviour instead of informing the client. - virtual void DidLoseOutputSurface(); - - OutputSurfaceClient* client_ = nullptr; - struct OutputSurface::Capabilities capabilities_; scoped_refptr<ContextProvider> context_provider_; scoped_refptr<VulkanContextProvider> vulkan_context_provider_; std::unique_ptr<SoftwareOutputDevice> software_device_; - gfx::Size surface_size_; - float device_scale_factor_ = -1; - gfx::ColorSpace device_color_space_; - bool has_alpha_ = true; - gfx::ColorSpace color_space_; - base::ThreadChecker thread_checker_; private: - void OnSwapBuffersComplete(); - - base::WeakPtrFactory<OutputSurface> weak_ptr_factory_; - DISALLOW_COPY_AND_ASSIGN(OutputSurface); }; diff --git a/chromium/cc/output/output_surface_client.h b/chromium/cc/output/output_surface_client.h index cd91919e6c4..7f8cadef43b 100644 --- a/chromium/cc/output/output_surface_client.h +++ b/chromium/cc/output/output_surface_client.h @@ -14,62 +14,21 @@ #include "gpu/command_buffer/common/texture_in_use_response.h" #include "ui/gfx/geometry/rect.h" -namespace gfx { -class Transform; -} - namespace cc { -class BeginFrameSource; -struct ManagedMemoryPolicy; - class CC_EXPORT OutputSurfaceClient { public: - // ============== DISPLAY COMPOSITOR ONLY ======================= + // A notification that the swap of the backbuffer to the hardware is complete + // and is now visible to the user. + virtual void DidReceiveSwapBuffersAck() = 0; - // From surfaceless/ozone browser compositor output surface. + // For surfaceless/ozone implementations to create damage for the next frame. virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0; + // For overlays. virtual void DidReceiveTextureInUseResponses( const gpu::TextureInUseResponses& responses) = 0; - // ============== LAYER TREE COMPOSITOR ONLY ==================== - - // Pass the begin frame source for the client to observe. Client does not own - // the BeginFrameSource. OutputSurface should call this once after binding to - // the client and then call again with a null while detaching. - virtual void SetBeginFrameSource(BeginFrameSource* source) = 0; - virtual void ReclaimResources(const ReturnedResourceArray& resources) = 0; - // For WebView. - virtual void SetExternalTilePriorityConstraints( - const gfx::Rect& viewport_rect, - const gfx::Transform& transform) = 0; - // If set, |callback| will be called subsequent to each new tree activation, - // regardless of the compositor visibility or damage. |callback| must remain - // valid for the lifetime of the OutputSurfaceClient or until unregisted -- - // use SetTreeActivationCallback(base::Closure()) to unregister it. - virtual void SetTreeActivationCallback(const base::Closure& callback) = 0; - // This allows the output surface to ask its client for a draw. - virtual void OnDraw(const gfx::Transform& transform, - const gfx::Rect& viewport, - bool resourceless_software_draw) = 0; - // For SynchronousCompositor (WebView) to set how much memory the compositor - // can use without changing visibility. - virtual void SetMemoryPolicy(const ManagedMemoryPolicy& policy) = 0; - - // ============== BOTH TYPES OF COMPOSITOR ====================== - - // For LayerTreeHostImpl, this is more of a OnSwapBuffersAck from the display - // compositor that it received and will use the frame, unblocking it from - // producing more frames. - // For the display compositor this is literally a notification that the swap - // to the hardware is complete. - virtual void DidSwapBuffersComplete() = 0; - - // Needs thought, if LTHI has only context providers, it needs to register a - // lost callback, so we need to support multiple callbacks. - virtual void DidLoseOutputSurface() = 0; - protected: virtual ~OutputSurfaceClient() {} }; diff --git a/chromium/cc/output/output_surface_unittest.cc b/chromium/cc/output/output_surface_unittest.cc deleted file mode 100644 index f589a25ff26..00000000000 --- a/chromium/cc/output/output_surface_unittest.cc +++ /dev/null @@ -1,118 +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. - -#include "cc/output/output_surface.h" - -#include <utility> - -#include "base/memory/ptr_util.h" -#include "cc/output/output_surface_frame.h" -#include "cc/output/software_output_device.h" -#include "cc/test/fake_output_surface_client.h" -#include "cc/test/test_context_provider.h" -#include "cc/test/test_web_graphics_context_3d.h" -#include "gpu/GLES2/gl2extchromium.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -class TestOutputSurface : public OutputSurface { - public: - explicit TestOutputSurface( - scoped_refptr<TestContextProvider> context_provider) - : OutputSurface(std::move(context_provider)) {} - - explicit TestOutputSurface( - std::unique_ptr<SoftwareOutputDevice> software_device) - : OutputSurface(std::move(software_device)) {} - - void EnsureBackbuffer() override {} - void DiscardBackbuffer() override {} - void BindFramebuffer() override {} - void SwapBuffers(OutputSurfaceFrame frame) override { - client_->DidSwapBuffersComplete(); - } - uint32_t GetFramebufferCopyTextureFormat() override { - // TestContextProvider has no real framebuffer, just use RGB. - return GL_RGB; - } - OverlayCandidateValidator* GetOverlayCandidateValidator() const override { - return nullptr; - } - bool IsDisplayedAsOverlayPlane() const override { return false; } - unsigned GetOverlayTextureId() const override { return 0; } - bool SurfaceIsSuspendForRecycle() const override { return false; } - bool HasExternalStencilTest() const override { return false; } - void ApplyExternalStencil() override {} - - void OnSwapBuffersCompleteForTesting() { client_->DidSwapBuffersComplete(); } - - protected: -}; - -class TestSoftwareOutputDevice : public SoftwareOutputDevice { - public: - TestSoftwareOutputDevice(); - ~TestSoftwareOutputDevice() override; - - // Overriden from cc:SoftwareOutputDevice - void DiscardBackbuffer() override; - void EnsureBackbuffer() override; - - int discard_backbuffer_count() { return discard_backbuffer_count_; } - int ensure_backbuffer_count() { return ensure_backbuffer_count_; } - - private: - int discard_backbuffer_count_; - int ensure_backbuffer_count_; -}; - -TestSoftwareOutputDevice::TestSoftwareOutputDevice() - : discard_backbuffer_count_(0), ensure_backbuffer_count_(0) {} - -TestSoftwareOutputDevice::~TestSoftwareOutputDevice() {} - -void TestSoftwareOutputDevice::DiscardBackbuffer() { - SoftwareOutputDevice::DiscardBackbuffer(); - discard_backbuffer_count_++; -} - -void TestSoftwareOutputDevice::EnsureBackbuffer() { - SoftwareOutputDevice::EnsureBackbuffer(); - ensure_backbuffer_count_++; -} - -TEST(OutputSurfaceTest, ContextLossInformsClient) { - scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(); - TestOutputSurface output_surface(provider); - - FakeOutputSurfaceClient client; - EXPECT_TRUE(output_surface.BindToClient(&client)); - - // Verify DidLoseOutputSurface callback is hooked up correctly. - EXPECT_FALSE(client.did_lose_output_surface_called()); - output_surface.context_provider()->ContextGL()->LoseContextCHROMIUM( - GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); - output_surface.context_provider()->ContextGL()->Flush(); - EXPECT_TRUE(client.did_lose_output_surface_called()); -} - -// TODO(danakj): Add a test for worker context failure as well when -// OutputSurface creates/binds it. -TEST(OutputSurfaceTest, ContextLossFailsBind) { - scoped_refptr<TestContextProvider> context_provider = - TestContextProvider::Create(); - - // Lose the context so BindToClient fails. - context_provider->UnboundTestContext3d()->set_context_lost(true); - - TestOutputSurface output_surface(context_provider); - - FakeOutputSurfaceClient client; - EXPECT_FALSE(output_surface.BindToClient(&client)); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/output/overlay_unittest.cc b/chromium/cc/output/overlay_unittest.cc index 5dcb2744a5f..c15b5e4ad85 100644 --- a/chromium/cc/output/overlay_unittest.cc +++ b/chromium/cc/output/overlay_unittest.cc @@ -149,22 +149,25 @@ class OverlayOutputSurface : public OutputSurface { explicit OverlayOutputSurface( scoped_refptr<TestContextProvider> context_provider) : OutputSurface(std::move(context_provider)) { - surface_size_ = kDisplaySize; - device_scale_factor_ = 1; is_displayed_as_overlay_plane_ = true; } // OutputSurface implementation. + void BindToClient(OutputSurfaceClient* client) override {} void EnsureBackbuffer() override {} void DiscardBackbuffer() override {} void BindFramebuffer() override { bind_framebuffer_count_ += 1; } + void Reshape(const gfx::Size& size, + float device_scale_factor, + const gfx::ColorSpace& color_space, + bool has_alpha) override {} + void SwapBuffers(OutputSurfaceFrame frame) override {} uint32_t GetFramebufferCopyTextureFormat() override { // TestContextProvider has no real framebuffer, just use RGB. return GL_RGB; } - void SwapBuffers(OutputSurfaceFrame frame) override {} bool HasExternalStencilTest() const override { return false; } void ApplyExternalStencil() override {} OverlayCandidateValidator* GetOverlayCandidateValidator() const override { @@ -174,15 +177,10 @@ class OverlayOutputSurface : public OutputSurface { return is_displayed_as_overlay_plane_; } unsigned GetOverlayTextureId() const override { return 10000; } - void set_is_displayed_as_overlay_plane(bool value) { - is_displayed_as_overlay_plane_ = value; - } bool SurfaceIsSuspendForRecycle() const override { return false; } - void OnSwapBuffersComplete() { client_->DidSwapBuffersComplete(); } - - void SetScaleFactor(float scale_factor) { - device_scale_factor_ = scale_factor; + void set_is_displayed_as_overlay_plane(bool value) { + is_displayed_as_overlay_plane_ = value; } void SetOverlayCandidateValidator(OverlayCandidateValidator* validator) { @@ -350,8 +348,9 @@ class OverlayTest : public testing::Test { protected: void SetUp() override { provider_ = TestContextProvider::Create(); + provider_->BindToCurrentThread(); output_surface_.reset(new OverlayOutputSurface(provider_)); - EXPECT_TRUE(output_surface_->BindToClient(&client_)); + output_surface_->BindToClient(&client_); output_surface_->SetOverlayCandidateValidator( new OverlayCandidateValidatorType); @@ -388,9 +387,10 @@ TEST(OverlayTest, NoOverlaysByDefault) { TEST(OverlayTest, OverlaysProcessorHasStrategy) { scoped_refptr<TestContextProvider> provider = TestContextProvider::Create(); + provider->BindToCurrentThread(); OverlayOutputSurface output_surface(provider); FakeOutputSurfaceClient client; - EXPECT_TRUE(output_surface.BindToClient(&client)); + output_surface.BindToClient(&client); output_surface.SetOverlayCandidateValidator(new SingleOverlayValidator); std::unique_ptr<SharedBitmapManager> shared_bitmap_manager( @@ -1309,8 +1309,9 @@ class GLRendererWithOverlaysTest : public testing::Test { protected: GLRendererWithOverlaysTest() { provider_ = TestContextProvider::Create(); + provider_->BindToCurrentThread(); output_surface_.reset(new OverlayOutputSurface(provider_)); - CHECK(output_surface_->BindToClient(&output_surface_client_)); + output_surface_->BindToClient(&output_surface_client_); resource_provider_ = FakeResourceProvider::Create(provider_.get(), nullptr); provider_->support()->SetScheduleOverlayPlaneCallback(base::Bind( @@ -1332,14 +1333,12 @@ class GLRendererWithOverlaysTest : public testing::Test { } void SwapBuffers() { renderer_->SwapBuffers(std::vector<ui::LatencyInfo>()); - output_surface_->OnSwapBuffersComplete(); renderer_->SwapBuffersComplete(); } void SwapBuffersWithoutComplete() { renderer_->SwapBuffers(std::vector<ui::LatencyInfo>()); } void SwapBuffersComplete() { - output_surface_->OnSwapBuffersComplete(); renderer_->SwapBuffersComplete(); } void ReturnResourceInUseQuery(ResourceId id) { diff --git a/chromium/cc/output/renderer_pixeltest.cc b/chromium/cc/output/renderer_pixeltest.cc index c62ae058d00..c799d62a8cf 100644 --- a/chromium/cc/output/renderer_pixeltest.cc +++ b/chromium/cc/output/renderer_pixeltest.cc @@ -285,6 +285,35 @@ void CreateTestYUVVideoDrawQuad_FromVideoFrame( bits_per_channel); } +void CreateTestY16TextureDrawQuad_FromVideoFrame( + const SharedQuadState* shared_state, + scoped_refptr<media::VideoFrame> video_frame, + const gfx::RectF& tex_coord_rect, + RenderPass* render_pass, + VideoResourceUpdater* video_resource_updater, + const gfx::Rect& rect, + const gfx::Rect& visible_rect, + ResourceProvider* resource_provider) { + VideoFrameExternalResources resources = + video_resource_updater->CreateExternalResourcesFromVideoFrame( + video_frame); + + EXPECT_EQ(VideoFrameExternalResources::RGBA_RESOURCE, resources.type); + EXPECT_EQ(1u, resources.mailboxes.size()); + EXPECT_EQ(1u, resources.release_callbacks.size()); + + ResourceId y_resource = resource_provider->CreateResourceFromTextureMailbox( + resources.mailboxes[0], + SingleReleaseCallbackImpl::Create(resources.release_callbacks[0])); + + TextureDrawQuad* quad = + render_pass->CreateAndAppendDrawQuad<TextureDrawQuad>(); + float vertex_opacity[4] = {1.0f, 1.0f, 1.0f, 1.0f}; + quad->SetNew(shared_state, rect, gfx::Rect(), rect, y_resource, false, + tex_coord_rect.origin(), tex_coord_rect.bottom_right(), + SK_ColorBLACK, vertex_opacity, false, false, false); +} + // Upshift video frame to 10 bit. scoped_refptr<media::VideoFrame> CreateHighbitVideoFrame( media::VideoFrame* video_frame) { @@ -539,6 +568,61 @@ void CreateTestYUVVideoDrawQuad_NV12(const SharedQuadState* shared_state, color_space, video_color_space, 0.0f, 1.0f, 8); } +void CreateTestY16TextureDrawQuad_TwoColor( + const SharedQuadState* shared_state, + const gfx::RectF& tex_coord_rect, + uint8_t g_foreground, + uint8_t g_background, + RenderPass* render_pass, + VideoResourceUpdater* video_resource_updater, + const gfx::Rect& rect, + const gfx::Rect& visible_rect, + const gfx::Rect& foreground_rect, + ResourceProvider* resource_provider) { + std::unique_ptr<unsigned char, base::AlignedFreeDeleter> memory( + static_cast<unsigned char*>( + base::AlignedAlloc(rect.size().GetArea() * 2, + media::VideoFrame::kFrameAddressAlignment))); + scoped_refptr<media::VideoFrame> video_frame = + media::VideoFrame::WrapExternalData( + media::PIXEL_FORMAT_Y16, rect.size(), visible_rect, + visible_rect.size(), memory.get(), rect.size().GetArea() * 2, + base::TimeDelta()); + DCHECK_EQ(video_frame->rows(0) % 2, 0); + DCHECK_EQ(video_frame->stride(0) % 2, 0); + + for (int j = 0; j < video_frame->rows(0); ++j) { + uint8_t* row = video_frame->data(0) + j * video_frame->stride(0); + if (j < foreground_rect.y() || j >= foreground_rect.bottom()) { + for (int i = 0; i < video_frame->stride(0) / 2; ++i) { + *row++ = i & 0xFF; // Fill R with anything. It is not rendered. + *row++ = g_background; + } + } else { + for (int i = 0; + i < std::min(video_frame->stride(0) / 2, foreground_rect.x()); ++i) { + *row++ = i & 0xFF; + *row++ = g_background; + } + for (int i = foreground_rect.x(); + i < std::min(video_frame->stride(0) / 2, foreground_rect.right()); + ++i) { + *row++ = i & 0xFF; + *row++ = g_foreground; + } + for (int i = foreground_rect.right(); i < video_frame->stride(0) / 2; + ++i) { + *row++ = i & 0xFF; + *row++ = g_background; + } + } + } + + CreateTestY16TextureDrawQuad_FromVideoFrame( + shared_state, video_frame, tex_coord_rect, render_pass, + video_resource_updater, rect, visible_rect, resource_provider); +} + typedef ::testing::Types<GLRenderer, SoftwareRenderer, GLRendererWithExpandedViewport, @@ -711,19 +795,6 @@ TYPED_TEST(RendererPixelTest, PremultipliedTextureWithBackground) { FuzzyPixelOffByOneComparator(true))); } -template <typename QuadType> -static const base::FilePath::CharType* IntersectingQuadImage() { - return FILE_PATH_LITERAL("intersecting_blue_green_squares.png"); -} -template <> -const base::FilePath::CharType* IntersectingQuadImage<SolidColorDrawQuad>() { - return FILE_PATH_LITERAL("intersecting_blue_green.png"); -} -template <> -const base::FilePath::CharType* IntersectingQuadImage<YUVVideoDrawQuad>() { - return FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png"); -} - template <typename TypeParam> class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> { protected: @@ -763,8 +834,8 @@ class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> { back_quad_state_->sorting_context_id = 1; back_quad_state_->clip_rect = quad_rect_; } - template <typename T> - void AppendBackgroundAndRunTest(const PixelComparator& comparator) { + void AppendBackgroundAndRunTest(const PixelComparator& comparator, + const base::FilePath::CharType* ref_file) { SharedQuadState* background_quad_state = CreateTestSharedQuadState( gfx::Transform(), viewport_rect_, render_pass_.get()); SolidColorDrawQuad* background_quad = @@ -772,9 +843,8 @@ class IntersectingQuadPixelTest : public RendererPixelTest<TypeParam> { background_quad->SetNew(background_quad_state, viewport_rect_, viewport_rect_, SK_ColorWHITE, false); pass_list_.push_back(std::move(render_pass_)); - const base::FilePath::CharType* fileName = IntersectingQuadImage<T>(); EXPECT_TRUE( - this->RunPixelTest(&pass_list_, base::FilePath(fileName), comparator)); + this->RunPixelTest(&pass_list_, base::FilePath(ref_file), comparator)); } template <typename T> T* CreateAndAppendDrawQuad() { @@ -834,8 +904,9 @@ TYPED_TEST(IntersectingQuadPixelTest, SolidColorQuads) { quad2->SetNew(this->back_quad_state_, this->quad_rect_, this->quad_rect_, SK_ColorGREEN, false); SCOPED_TRACE("IntersectingSolidColorQuads"); - this->template AppendBackgroundAndRunTest<SolidColorDrawQuad>( - FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); + this->AppendBackgroundAndRunTest( + FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f), + FILE_PATH_LITERAL("intersecting_blue_green.png")); } template <typename TypeParam> @@ -867,8 +938,9 @@ TYPED_TEST(IntersectingQuadPixelTest, TexturedQuads) { this->render_pass_.get()); SCOPED_TRACE("IntersectingTexturedQuads"); - this->template AppendBackgroundAndRunTest<TextureDrawQuad>( - FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); + this->AppendBackgroundAndRunTest( + FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f), + FILE_PATH_LITERAL("intersecting_blue_green_squares.png")); } TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) { @@ -917,8 +989,9 @@ TYPED_TEST(IntersectingQuadSoftwareTest, PictureQuads) { this->quad_rect_.size(), false, RGBA_8888, this->quad_rect_, 1.f, green_raster_source); SCOPED_TRACE("IntersectingPictureQuadsPass"); - this->template AppendBackgroundAndRunTest<PictureDrawQuad>( - FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); + this->AppendBackgroundAndRunTest( + FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f), + FILE_PATH_LITERAL("intersecting_blue_green_squares.png")); } TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) { @@ -953,8 +1026,9 @@ TYPED_TEST(IntersectingQuadPixelTest, RenderPassQuads) { this->pass_list_.push_back(std::move(child_pass1)); this->pass_list_.push_back(std::move(child_pass2)); SCOPED_TRACE("IntersectingRenderQuadsPass"); - this->template AppendBackgroundAndRunTest<RenderPassDrawQuad>( - FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f)); + this->AppendBackgroundAndRunTest( + FuzzyPixelComparator(false, 2.f, 0.f, 256.f, 256, 0.f), + FILE_PATH_LITERAL("intersecting_blue_green_squares.png")); } TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) { @@ -980,8 +1054,35 @@ TYPED_TEST(IntersectingQuadGLPixelTest, YUVVideoQuads) { this->resource_provider_.get()); SCOPED_TRACE("IntersectingVideoQuads"); - this->template AppendBackgroundAndRunTest<YUVVideoDrawQuad>( - FuzzyPixelOffByOneComparator(false)); + this->AppendBackgroundAndRunTest( + FuzzyPixelOffByOneComparator(false), + FILE_PATH_LITERAL("intersecting_blue_green_squares_video.png")); +} + +TYPED_TEST(IntersectingQuadGLPixelTest, Y16VideoQuads) { + this->SetupQuadStateAndRenderPass(); + gfx::Rect inner_rect( + ((this->quad_rect_.x() + (this->quad_rect_.width() / 4)) & ~0xF), + ((this->quad_rect_.y() + (this->quad_rect_.height() / 4)) & ~0xF), + (this->quad_rect_.width() / 2) & ~0xF, + (this->quad_rect_.height() / 2) & ~0xF); + + CreateTestY16TextureDrawQuad_TwoColor( + this->front_quad_state_, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 18, 0, + this->render_pass_.get(), this->video_resource_updater_.get(), + this->quad_rect_, this->quad_rect_, inner_rect, + this->resource_provider_.get()); + + CreateTestY16TextureDrawQuad_TwoColor( + this->back_quad_state_, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 0, 182, + this->render_pass_.get(), this->video_resource_updater2_.get(), + this->quad_rect_, this->quad_rect_, inner_rect, + this->resource_provider_.get()); + + SCOPED_TRACE("IntersectingVideoQuads"); + this->AppendBackgroundAndRunTest( + FuzzyPixelOffByOneComparator(false), + FILE_PATH_LITERAL("intersecting_light_dark_squares_video.png")); } // TODO(skaslev): The software renderer does not support non-premultplied alpha. @@ -1345,6 +1446,30 @@ TEST_F(VideoGLRendererPixelTest, FullyTransparentYUVARect) { ExactPixelComparator(true))); } +TEST_F(VideoGLRendererPixelTest, TwoColorY16Rect) { + gfx::Rect rect(this->device_viewport_size_); + + RenderPassId id(1, 1); + std::unique_ptr<RenderPass> pass = CreateTestRootRenderPass(id, rect); + + SharedQuadState* shared_state = + CreateTestSharedQuadState(gfx::Transform(), rect, pass.get()); + + gfx::Rect upper_rect(rect.x(), rect.y(), rect.width(), rect.height() / 2); + CreateTestY16TextureDrawQuad_TwoColor( + shared_state, gfx::RectF(0.0f, 0.0f, 1.0f, 1.0f), 68, 123, pass.get(), + video_resource_updater_.get(), rect, rect, upper_rect, + resource_provider_.get()); + + RenderPassList pass_list; + pass_list.push_back(std::move(pass)); + + EXPECT_TRUE(this->RunPixelTest( + &pass_list, + base::FilePath(FILE_PATH_LITERAL("blue_yellow_filter_chain.png")), + FuzzyPixelOffByOneComparator(true))); +} + TYPED_TEST(RendererPixelTest, FastPassColorFilterAlpha) { gfx::Rect viewport_rect(this->device_viewport_size_); diff --git a/chromium/cc/output/renderer_settings.cc b/chromium/cc/output/renderer_settings.cc index 308926c8070..c4125954ec5 100644 --- a/chromium/cc/output/renderer_settings.cc +++ b/chromium/cc/output/renderer_settings.cc @@ -7,7 +7,6 @@ #include <limits> #include "base/logging.h" -#include "cc/proto/renderer_settings.pb.h" #include "cc/resources/platform_color.h" namespace cc { @@ -33,61 +32,6 @@ RendererSettings::RendererSettings(const RendererSettings& other) = default; RendererSettings::~RendererSettings() { } -void RendererSettings::ToProtobuf(proto::RendererSettings* proto) const { - proto->set_allow_antialiasing(allow_antialiasing); - proto->set_force_antialiasing(force_antialiasing); - proto->set_force_blending_with_shaders(force_blending_with_shaders); - proto->set_partial_swap_enabled(partial_swap_enabled); - proto->set_finish_rendering_on_resize(finish_rendering_on_resize); - proto->set_should_clear_root_render_pass(should_clear_root_render_pass); - proto->set_disable_display_vsync(disable_display_vsync); - proto->set_release_overlay_resources_after_gpu_query( - release_overlay_resources_after_gpu_query); - proto->set_refresh_rate(refresh_rate); - proto->set_highp_threshold_min(highp_threshold_min); - proto->set_texture_id_allocation_chunk_size(texture_id_allocation_chunk_size); - proto->set_use_gpu_memory_buffer_resources(use_gpu_memory_buffer_resources); - proto->set_preferred_tile_format(preferred_tile_format); - - for (const auto& target : buffer_to_texture_target_map) { - auto* proto_target = proto->add_buffer_to_texture_target(); - proto_target->set_buffer_usage(static_cast<uint32_t>(target.first.first)); - proto_target->set_buffer_format(static_cast<uint32_t>(target.first.second)); - proto_target->set_texture_target(target.second); - } -} - -void RendererSettings::FromProtobuf(const proto::RendererSettings& proto) { - allow_antialiasing = proto.allow_antialiasing(); - force_antialiasing = proto.force_antialiasing(); - force_blending_with_shaders = proto.force_blending_with_shaders(); - partial_swap_enabled = proto.partial_swap_enabled(); - finish_rendering_on_resize = proto.finish_rendering_on_resize(); - should_clear_root_render_pass = proto.should_clear_root_render_pass(); - disable_display_vsync = proto.disable_display_vsync(); - release_overlay_resources_after_gpu_query = - proto.release_overlay_resources_after_gpu_query(); - refresh_rate = proto.refresh_rate(); - highp_threshold_min = proto.highp_threshold_min(); - texture_id_allocation_chunk_size = proto.texture_id_allocation_chunk_size(); - use_gpu_memory_buffer_resources = proto.use_gpu_memory_buffer_resources(); - - DCHECK_LE(proto.preferred_tile_format(), - static_cast<uint32_t>(RESOURCE_FORMAT_MAX)); - preferred_tile_format = - static_cast<ResourceFormat>(proto.preferred_tile_format()); - - // |buffer_to_texture_target_map| may contain existing values, so clear first. - buffer_to_texture_target_map.clear(); - for (const auto& proto_target : proto.buffer_to_texture_target()) { - buffer_to_texture_target_map.insert(BufferToTextureTargetMap::value_type( - BufferToTextureTargetKey( - static_cast<gfx::BufferUsage>(proto_target.buffer_usage()), - static_cast<gfx::BufferFormat>(proto_target.buffer_format())), - proto_target.texture_target())); - } -} - bool RendererSettings::operator==(const RendererSettings& other) const { return allow_antialiasing == other.allow_antialiasing && force_antialiasing == other.force_antialiasing && diff --git a/chromium/cc/output/renderer_settings.h b/chromium/cc/output/renderer_settings.h index 16e8be9f384..eb157a39245 100644 --- a/chromium/cc/output/renderer_settings.h +++ b/chromium/cc/output/renderer_settings.h @@ -13,10 +13,6 @@ namespace cc { -namespace proto { -class RendererSettings; -} // namespace proto - class CC_EXPORT RendererSettings { public: RendererSettings(); @@ -40,9 +36,6 @@ class CC_EXPORT RendererSettings { ResourceFormat preferred_tile_format; BufferToTextureTargetMap buffer_to_texture_target_map; - void ToProtobuf(proto::RendererSettings* proto) const; - void FromProtobuf(const proto::RendererSettings& proto); - bool operator==(const RendererSettings& other) const; }; diff --git a/chromium/cc/output/renderer_settings_unittest.cc b/chromium/cc/output/renderer_settings_unittest.cc deleted file mode 100644 index cfcbdccce39..00000000000 --- a/chromium/cc/output/renderer_settings_unittest.cc +++ /dev/null @@ -1,78 +0,0 @@ -// Copyright 2015 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/output/renderer_settings.h" - -#include "cc/proto/renderer_settings.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -void VerifySerializeAndDeserializeProto(const RendererSettings& settings1) { - proto::RendererSettings proto; - settings1.ToProtobuf(&proto); - RendererSettings settings2; - settings2.FromProtobuf(proto); - EXPECT_EQ(settings1, settings2); -} - -TEST(RendererSettingsTest, AllFieldsFlipped) { - RendererSettings settings; - settings.allow_antialiasing = false; - settings.force_antialiasing = true; - settings.force_blending_with_shaders = true; - settings.partial_swap_enabled = true; - settings.finish_rendering_on_resize = true; - settings.should_clear_root_render_pass = false; - settings.disable_display_vsync = true; - settings.release_overlay_resources_after_gpu_query = true; - settings.refresh_rate = 6.0; - settings.highp_threshold_min = 1; - settings.texture_id_allocation_chunk_size = 46; - settings.use_gpu_memory_buffer_resources = true; - settings.preferred_tile_format = RGBA_4444; - settings.buffer_to_texture_target_map.insert( - BufferToTextureTargetMap::value_type( - BufferToTextureTargetKey(gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferFormat::R_8), - 54)); - settings.buffer_to_texture_target_map.insert( - BufferToTextureTargetMap::value_type( - BufferToTextureTargetKey(gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferFormat::BGRA_8888), - 55)); - VerifySerializeAndDeserializeProto(settings); -} - -TEST(RendererSettingsTest, ArbitraryFieldValues) { - RendererSettings settings; - settings.allow_antialiasing = false; - settings.force_antialiasing = true; - settings.force_blending_with_shaders = false; - settings.partial_swap_enabled = true; - settings.finish_rendering_on_resize = false; - settings.should_clear_root_render_pass = false; - settings.disable_display_vsync = true; - settings.release_overlay_resources_after_gpu_query = true; - settings.refresh_rate = 999.0; - settings.highp_threshold_min = 1; - settings.texture_id_allocation_chunk_size = 12; - settings.use_gpu_memory_buffer_resources = true; - settings.preferred_tile_format = RGBA_4444; - settings.buffer_to_texture_target_map.insert( - BufferToTextureTargetMap::value_type( - BufferToTextureTargetKey(gfx::BufferUsage::SCANOUT, - gfx::BufferFormat::UYVY_422), - 10)); - settings.buffer_to_texture_target_map.insert( - BufferToTextureTargetMap::value_type( - BufferToTextureTargetKey(gfx::BufferUsage::GPU_READ_CPU_READ_WRITE, - gfx::BufferFormat::RGBA_8888), - 19)); - VerifySerializeAndDeserializeProto(settings); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/output/shader.cc b/chromium/cc/output/shader.cc index b5d163862d1..4b23bd97a46 100644 --- a/chromium/cc/output/shader.cc +++ b/chromium/cc/output/shader.cc @@ -2140,7 +2140,7 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, // Select layer float layer = min(floor(pos.x), size - 2.0); // Compress the yz coordinates so they stay within - // [0.5 .. 31.5] / 32 (assuming a LUT size of 32^3) + // [0.5 .. 31.5] / 17 (assuming a LUT size of 17^3) pos.yz = (pos.yz + vec2(0.5)) / size; pos.z = (pos.z + layer) / size; return mix(texture2D(sampler, pos.yz), @@ -2150,7 +2150,7 @@ std::string FragmentShaderYUVVideo::GetShaderString(TexCoordPrecision precision, vec3 yuv2rgb(vec3 yuv) { yuv = (yuv - vec3(resource_offset)) * resource_multiplier; - return LUT(lut_texture, yuv, 32.0).xyz; + return LUT(lut_texture, yuv, 17.0).xyz; } }); } else { diff --git a/chromium/cc/output/software_output_device.cc b/chromium/cc/output/software_output_device.cc index 449fa3075cb..04a426a12ea 100644 --- a/chromium/cc/output/software_output_device.cc +++ b/chromium/cc/output/software_output_device.cc @@ -10,15 +10,11 @@ namespace cc { -SoftwareOutputDevice::SoftwareOutputDevice() : scale_factor_(1.f) { -} - -SoftwareOutputDevice::~SoftwareOutputDevice() {} +SoftwareOutputDevice::SoftwareOutputDevice() = default; +SoftwareOutputDevice::~SoftwareOutputDevice() = default; void SoftwareOutputDevice::Resize(const gfx::Size& viewport_pixel_size, float scale_factor) { - scale_factor_ = scale_factor; - if (viewport_pixel_size_ == viewport_pixel_size) return; diff --git a/chromium/cc/output/software_output_device.h b/chromium/cc/output/software_output_device.h index 109fc90f387..f4c766c532f 100644 --- a/chromium/cc/output/software_output_device.h +++ b/chromium/cc/output/software_output_device.h @@ -14,7 +14,6 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/geometry/vector2d.h" -class SkBitmap; class SkCanvas; namespace gfx { @@ -58,7 +57,6 @@ class CC_EXPORT SoftwareOutputDevice { protected: gfx::Size viewport_pixel_size_; - float scale_factor_; gfx::Rect damage_rect_; sk_sp<SkSurface> surface_; std::unique_ptr<gfx::VSyncProvider> vsync_provider_; diff --git a/chromium/cc/output/software_renderer.cc b/chromium/cc/output/software_renderer.cc index 44a575998f2..4a4d89097ff 100644 --- a/chromium/cc/output/software_renderer.cc +++ b/chromium/cc/output/software_renderer.cc @@ -82,7 +82,7 @@ void SoftwareRenderer::FinishDrawingFrame(DrawingFrame* frame) { void SoftwareRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { DCHECK(visible_); - TRACE_EVENT0("cc,benchmark", "SoftwareRenderer::SwapBuffers"); + TRACE_EVENT0("cc", "SoftwareRenderer::SwapBuffers"); OutputSurfaceFrame output_frame; output_frame.latency_info = std::move(latency_info); output_surface_->SwapBuffers(std::move(output_frame)); @@ -152,12 +152,7 @@ void SoftwareRenderer::SetClipRect(const gfx::Rect& rect) { void SoftwareRenderer::ClearCanvas(SkColor color) { if (!current_canvas_) return; - // SkCanvas::clear doesn't respect the current clipping region - // so we SkCanvas::drawColor instead if scissoring is active. - if (is_scissor_enabled_) - current_canvas_->drawColor(color, SkXfermode::kSrc_Mode); - else - current_canvas_->clear(color); + current_canvas_->clear(color); } void SoftwareRenderer::ClearFramebuffer(DrawingFrame* frame) { @@ -244,9 +239,10 @@ void SoftwareRenderer::DoDrawQuad(DrawingFrame* frame, if (quad->ShouldDrawWithBlending() || quad->shared_quad_state->blend_mode != SkXfermode::kSrcOver_Mode) { current_paint_.setAlpha(quad->shared_quad_state->opacity * 255); - current_paint_.setXfermodeMode(quad->shared_quad_state->blend_mode); + current_paint_.setBlendMode( + static_cast<SkBlendMode>(quad->shared_quad_state->blend_mode)); } else { - current_paint_.setXfermodeMode(SkXfermode::kSrc_Mode); + current_paint_.setBlendMode(SkBlendMode::kSrc); } if (draw_region) { @@ -361,11 +357,13 @@ void SoftwareRenderer::DrawPictureQuad(const DrawingFrame* frame, disable_image_filtering); quad->raster_source->PlaybackToCanvas( &filtered_canvas, quad->content_rect, quad->content_rect, - quad->contents_scale, playback_settings); + gfx::SizeF(quad->contents_scale, quad->contents_scale), + playback_settings); } else { quad->raster_source->PlaybackToCanvas( current_canvas_, quad->content_rect, quad->content_rect, - quad->contents_scale, playback_settings); + gfx::SizeF(quad->contents_scale, quad->contents_scale), + playback_settings); } } diff --git a/chromium/cc/output/software_renderer_unittest.cc b/chromium/cc/output/software_renderer_unittest.cc index 9c417de3bbf..578d107b1aa 100644 --- a/chromium/cc/output/software_renderer_unittest.cc +++ b/chromium/cc/output/software_renderer_unittest.cc @@ -38,7 +38,7 @@ class SoftwareRendererTest : public testing::Test { std::unique_ptr<SoftwareOutputDevice> software_output_device) { output_surface_ = FakeOutputSurface::CreateSoftware(std::move(software_output_device)); - CHECK(output_surface_->BindToClient(&output_surface_client_)); + output_surface_->BindToClient(&output_surface_client_); shared_bitmap_manager_.reset(new TestSharedBitmapManager()); resource_provider_ = diff --git a/chromium/cc/output/vulkan_renderer.cc b/chromium/cc/output/vulkan_renderer.cc index 5caa02ee100..79ccf3b2e6b 100644 --- a/chromium/cc/output/vulkan_renderer.cc +++ b/chromium/cc/output/vulkan_renderer.cc @@ -3,18 +3,16 @@ // found in the LICENSE file. #include "cc/output/vulkan_renderer.h" +#include "cc/output/output_surface_frame.h" namespace cc { VulkanRenderer::~VulkanRenderer() {} -void VulkanRenderer::SwapBuffers(const CompositorFrameMetadata& metadata) { - CompositorFrame* compositor_frame = nullptr; - output_surface_->SwapBuffers(compositor_frame); -} - -void VulkanRenderer::ReceiveSwapBuffersAck(const CompositorFrameAck& ack) { - NOTIMPLEMENTED(); +void VulkanRenderer::SwapBuffers(std::vector<ui::LatencyInfo> latency_info) { + OutputSurfaceFrame output_frame; + output_frame.latency_info = std::move(latency_info); + output_surface_->SwapBuffers(std::move(output_frame)); } VulkanRenderer::VulkanRenderer(const RendererSettings* settings, @@ -80,18 +78,15 @@ void VulkanRenderer::EnsureScissorTestDisabled() { NOTIMPLEMENTED(); } -void VulkanRenderer::DiscardBackbuffer() { - NOTIMPLEMENTED(); -} - -void VulkanRenderer::EnsureBackbuffer() { - NOTIMPLEMENTED(); -} - void VulkanRenderer::CopyCurrentRenderPassToBitmap( DrawingFrame* frame, std::unique_ptr<CopyOutputRequest> request) { NOTIMPLEMENTED(); } +bool VulkanRenderer::CanPartialSwap() { + NOTIMPLEMENTED(); + return false; +} + } // namespace cc diff --git a/chromium/cc/output/vulkan_renderer.h b/chromium/cc/output/vulkan_renderer.h index 513e4757c12..45b34a847be 100644 --- a/chromium/cc/output/vulkan_renderer.h +++ b/chromium/cc/output/vulkan_renderer.h @@ -7,6 +7,7 @@ #include "cc/base/cc_export.h" #include "cc/output/direct_renderer.h" +#include "ui/events/latency_info.h" namespace cc { @@ -22,8 +23,7 @@ class CC_EXPORT VulkanRenderer : public DirectRenderer { ~VulkanRenderer() override; // Implementation of public DirectRenderer functions. - void SwapBuffers(const CompositorFrameMetadata& metadata) override; - void ReceiveSwapBuffersAck(const CompositorFrameAck& ack) override; + void SwapBuffers(std::vector<ui::LatencyInfo> latency_info) override; protected: // Implementations of protected Renderer functions. @@ -46,11 +46,10 @@ class CC_EXPORT VulkanRenderer : public DirectRenderer { bool FlippedFramebuffer(const DrawingFrame* frame) const override; void EnsureScissorTestEnabled() override; void EnsureScissorTestDisabled() override; - void DiscardBackbuffer() override; - void EnsureBackbuffer() override; void CopyCurrentRenderPassToBitmap( DrawingFrame* frame, std::unique_ptr<CopyOutputRequest> request) override; + bool CanPartialSwap() override; private: DISALLOW_COPY_AND_ASSIGN(VulkanRenderer); diff --git a/chromium/cc/playback/compositing_display_item.cc b/chromium/cc/playback/compositing_display_item.cc index 521bcd15dfb..125526a10ab 100644 --- a/chromium/cc/playback/compositing_display_item.cc +++ b/chromium/cc/playback/compositing_display_item.cc @@ -99,7 +99,7 @@ void CompositingDisplayItem::Raster( SkCanvas* canvas, SkPicture::AbortCallback* callback) const { SkPaint paint; - paint.setXfermodeMode(xfermode_); + paint.setBlendMode(static_cast<SkBlendMode>(xfermode_)); paint.setAlpha(alpha_); paint.setColorFilter(color_filter_); const SkRect* bounds = has_bounds_ ? &bounds_ : nullptr; diff --git a/chromium/cc/playback/discardable_image_map.cc b/chromium/cc/playback/discardable_image_map.cc index 822d49b6e4c..7082e4a0cb5 100644 --- a/chromium/cc/playback/discardable_image_map.cc +++ b/chromium/cc/playback/discardable_image_map.cc @@ -205,12 +205,12 @@ void DiscardableImageMap::EndGeneratingMetadata() { void DiscardableImageMap::GetDiscardableImagesInRect( const gfx::Rect& rect, - float raster_scale, + const gfx::SizeF& raster_scales, std::vector<DrawImage>* images) const { std::vector<size_t> indices; images_rtree_.Search(rect, &indices); for (size_t index : indices) - images->push_back(all_images_[index].first.ApplyScale(raster_scale)); + images->push_back(all_images_[index].first.ApplyScale(raster_scales)); } DiscardableImageMap::ScopedMetadataGenerator::ScopedMetadataGenerator( diff --git a/chromium/cc/playback/discardable_image_map.h b/chromium/cc/playback/discardable_image_map.h index 2d1b69f048b..adae8624807 100644 --- a/chromium/cc/playback/discardable_image_map.h +++ b/chromium/cc/playback/discardable_image_map.h @@ -44,7 +44,7 @@ class CC_EXPORT DiscardableImageMap { bool empty() const { return all_images_.empty(); } void GetDiscardableImagesInRect(const gfx::Rect& rect, - float raster_scale, + const gfx::SizeF& raster_scales, std::vector<DrawImage>* images) const; private: diff --git a/chromium/cc/playback/discardable_image_map_unittest.cc b/chromium/cc/playback/discardable_image_map_unittest.cc index 1b880e6a9b7..1dfdb3a1b5f 100644 --- a/chromium/cc/playback/discardable_image_map_unittest.cc +++ b/chromium/cc/playback/discardable_image_map_unittest.cc @@ -40,7 +40,8 @@ class DiscardableImageMapTest : public testing::Test { const DiscardableImageMap& image_map, const gfx::Rect& rect) { std::vector<DrawImage> draw_images; - image_map.GetDiscardableImagesInRect(rect, 1.f, &draw_images); + image_map.GetDiscardableImagesInRect(rect, gfx::SizeF(1.f, 1.f), + &draw_images); std::vector<size_t> indices; image_map.images_rtree_.Search(rect, &indices); diff --git a/chromium/cc/playback/display_item_list.cc b/chromium/cc/playback/display_item_list.cc index 52bddee6110..068cb00999b 100644 --- a/chromium/cc/playback/display_item_list.cc +++ b/chromium/cc/playback/display_item_list.cc @@ -266,9 +266,9 @@ void DisplayItemList::GenerateDiscardableImagesMetadata() { void DisplayItemList::GetDiscardableImagesInRect( const gfx::Rect& rect, - float raster_scale, + const gfx::SizeF& raster_scales, std::vector<DrawImage>* images) { - image_map_.GetDiscardableImagesInRect(rect, raster_scale, images); + image_map_.GetDiscardableImagesInRect(rect, raster_scales, images); } } // namespace cc diff --git a/chromium/cc/playback/display_item_list.h b/chromium/cc/playback/display_item_list.h index fcc936f17ed..9280f124ca8 100644 --- a/chromium/cc/playback/display_item_list.h +++ b/chromium/cc/playback/display_item_list.h @@ -25,12 +25,10 @@ #include "ui/gfx/geometry/rect_conversions.h" class SkCanvas; -class SkPictureRecorder; namespace cc { class ClientPictureCache; class DisplayItem; -class DrawingDisplayItem; namespace proto { class DisplayItemList; @@ -155,7 +153,7 @@ class CC_EXPORT DisplayItemList void GenerateDiscardableImagesMetadata(); void GetDiscardableImagesInRect(const gfx::Rect& rect, - float raster_scale, + const gfx::SizeF& raster_scales, std::vector<DrawImage>* images); void SetRetainVisualRectsForTesting(bool retain) { diff --git a/chromium/cc/playback/draw_image.h b/chromium/cc/playback/draw_image.h index 6323a636f64..3b45781da59 100644 --- a/chromium/cc/playback/draw_image.h +++ b/chromium/cc/playback/draw_image.h @@ -11,6 +11,7 @@ #include "third_party/skia/include/core/SkMatrix.h" #include "third_party/skia/include/core/SkRect.h" #include "third_party/skia/include/core/SkRefCnt.h" +#include "ui/gfx/geometry/size_f.h" namespace cc { @@ -33,13 +34,9 @@ class CC_EXPORT DrawImage { bool matrix_is_decomposable() const { return matrix_is_decomposable_; } const SkMatrix& matrix() const { return matrix_; } - DrawImage ApplyScale(float scale) const { - return ApplyScale(SkSize::Make(scale, scale)); - } - - DrawImage ApplyScale(const SkSize& scale) const { + DrawImage ApplyScale(const gfx::SizeF& scales) const { SkMatrix scaled_matrix = matrix_; - scaled_matrix.postScale(scale.width(), scale.height()); + scaled_matrix.preScale(scales.width(), scales.height()); return DrawImage(image_, src_rect_, filter_quality_, scaled_matrix); } diff --git a/chromium/cc/playback/filter_display_item.cc b/chromium/cc/playback/filter_display_item.cc index e369e06e31e..212d6e43570 100644 --- a/chromium/cc/playback/filter_display_item.cc +++ b/chromium/cc/playback/filter_display_item.cc @@ -15,7 +15,6 @@ #include "third_party/skia/include/core/SkImageFilter.h" #include "third_party/skia/include/core/SkPaint.h" #include "third_party/skia/include/core/SkRefCnt.h" -#include "third_party/skia/include/core/SkXfermode.h" #include "ui/gfx/skia_util.h" namespace cc { @@ -68,7 +67,7 @@ void FilterDisplayItem::Raster(SkCanvas* canvas, boundaries.offset(-origin_.x(), -origin_.y()); SkPaint paint; - paint.setXfermodeMode(SkXfermode::kSrcOver_Mode); + paint.setBlendMode(SkBlendMode::kSrcOver); paint.setImageFilter(std::move(image_filter)); canvas->saveLayer(&boundaries, &paint); diff --git a/chromium/cc/playback/raster_source.cc b/chromium/cc/playback/raster_source.cc index 0dc9c6c520c..2a05bf2399b 100644 --- a/chromium/cc/playback/raster_source.cc +++ b/chromium/cc/playback/raster_source.cc @@ -40,7 +40,6 @@ RasterSource::RasterSource(const RecordingSource* other, bool can_use_lcd_text) clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), slow_down_raster_scale_factor_for_debug_( other->slow_down_raster_scale_factor_for_debug_), - should_attempt_to_use_distance_field_text_(false), image_decode_controller_(nullptr) {} RasterSource::RasterSource(const RasterSource* other, bool can_use_lcd_text) @@ -56,8 +55,6 @@ RasterSource::RasterSource(const RasterSource* other, bool can_use_lcd_text) clear_canvas_with_debug_color_(other->clear_canvas_with_debug_color_), slow_down_raster_scale_factor_for_debug_( other->slow_down_raster_scale_factor_for_debug_), - should_attempt_to_use_distance_field_text_( - other->should_attempt_to_use_distance_field_text_), image_decode_controller_(other->image_decode_controller_) { } @@ -67,7 +64,7 @@ RasterSource::~RasterSource() { void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, - float contents_scale, + const gfx::SizeF& raster_scales, const PlaybackSettings& settings) const { SkIRect raster_bounds = gfx::RectToSkIRect(canvas_bitmap_rect); if (!canvas_playback_rect.IsEmpty() && @@ -79,7 +76,7 @@ void RasterSource::PlaybackToCanvas(SkCanvas* raster_canvas, raster_canvas->save(); raster_canvas->translate(-canvas_bitmap_rect.x(), -canvas_bitmap_rect.y()); raster_canvas->clipRect(SkRect::MakeFromIRect(raster_bounds)); - raster_canvas->scale(contents_scale, contents_scale); + raster_canvas->scale(raster_scales.width(), raster_scales.height()); PlaybackToCanvas(raster_canvas, settings); raster_canvas->restore(); } @@ -220,12 +217,12 @@ size_t RasterSource::GetPictureMemoryUsage() const { } bool RasterSource::PerformSolidColorAnalysis(const gfx::Rect& content_rect, - float contents_scale, + const gfx::SizeF& raster_scales, SkColor* color) const { TRACE_EVENT0("cc", "RasterSource::PerformSolidColorAnalysis"); - gfx::Rect layer_rect = - gfx::ScaleToEnclosingRect(content_rect, 1.0f / contents_scale); + gfx::Rect layer_rect = gfx::ScaleToEnclosingRect( + content_rect, 1.f / raster_scales.width(), 1.f / raster_scales.height()); layer_rect.Intersect(gfx::Rect(size_)); skia::AnalysisCanvas canvas(layer_rect.width(), layer_rect.height()); @@ -236,10 +233,10 @@ bool RasterSource::PerformSolidColorAnalysis(const gfx::Rect& content_rect, void RasterSource::GetDiscardableImagesInRect( const gfx::Rect& layer_rect, - float raster_scale, + const gfx::SizeF& raster_scales, std::vector<DrawImage>* images) const { DCHECK_EQ(0u, images->size()); - display_list_->GetDiscardableImagesInRect(layer_rect, raster_scale, images); + display_list_->GetDiscardableImagesInRect(layer_rect, raster_scales, images); } bool RasterSource::CoversRect(const gfx::Rect& layer_rect) const { @@ -271,14 +268,6 @@ gfx::Rect RasterSource::RecordedViewport() const { return recorded_viewport_; } -void RasterSource::SetShouldAttemptToUseDistanceFieldText() { - should_attempt_to_use_distance_field_text_ = true; -} - -bool RasterSource::ShouldAttemptToUseDistanceFieldText() const { - return should_attempt_to_use_distance_field_text_; -} - void RasterSource::AsValueInto(base::trace_event::TracedValue* array) const { if (display_list_.get()) TracedValue::AppendIDRef(display_list_.get(), array); diff --git a/chromium/cc/playback/raster_source.h b/chromium/cc/playback/raster_source.h index e4da161c538..709b310e19f 100644 --- a/chromium/cc/playback/raster_source.h +++ b/chromium/cc/playback/raster_source.h @@ -47,7 +47,7 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> { void PlaybackToCanvas(SkCanvas* canvas, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, - float contents_scale, + const gfx::SizeF& raster_scales, const PlaybackSettings& settings) const; // Raster this RasterSource into the given canvas. Canvas states such as @@ -65,7 +65,7 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> { // Returns whether the given rect at given scale is of solid color in // this raster source, as well as the solid color value. bool PerformSolidColorAnalysis(const gfx::Rect& content_rect, - float contents_scale, + const gfx::SizeF& raster_scales, SkColor* color) const; // Returns true iff the whole raster source is of solid color. @@ -82,7 +82,7 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> { // rect in layer space. The returned draw images' matrices are modified as if // they were being using during raster at scale |raster_scale|. void GetDiscardableImagesInRect(const gfx::Rect& layer_rect, - float raster_scale, + const gfx::SizeF& raster_scales, std::vector<DrawImage>* images) const; // Return true iff this raster source can raster the given rect in layer @@ -95,14 +95,6 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> { // Valid rectangle in which everything is recorded and can be rastered from. virtual gfx::Rect RecordedViewport() const; - // Informs the raster source that it should attempt to use distance field text - // during rasterization. - virtual void SetShouldAttemptToUseDistanceFieldText(); - - // Return true iff this raster source would benefit from using distance - // field text. - virtual bool ShouldAttemptToUseDistanceFieldText() const; - // Tracing functionality. virtual void DidBeginTracing(); virtual void AsValueInto(base::trace_event::TracedValue* array) const; @@ -153,9 +145,6 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> { const gfx::Size size_; const bool clear_canvas_with_debug_color_; const int slow_down_raster_scale_factor_for_debug_; - // TODO(enne/vmiura): this has a read/write race between raster and compositor - // threads with multi-threaded Ganesh. Make this const or remove it. - bool should_attempt_to_use_distance_field_text_; // In practice, this is only set once before raster begins, so it's ok with // respect to threading. diff --git a/chromium/cc/playback/raster_source_unittest.cc b/chromium/cc/playback/raster_source_unittest.cc index 717d2408825..0dc74f8334a 100644 --- a/chromium/cc/playback/raster_source_unittest.cc +++ b/chromium/cc/playback/raster_source_unittest.cc @@ -48,7 +48,8 @@ TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) { for (int y = 0; y <= 300; y += 100) { for (int x = 0; x <= 300; x += 100) { gfx::Rect rect(x, y, 100, 100); - is_solid_color = raster->PerformSolidColorAnalysis(rect, 1.0, &color); + is_solid_color = + raster->PerformSolidColorAnalysis(rect, gfx::SizeF(1.f, 1.f), &color); EXPECT_TRUE(is_solid_color) << rect.ToString(); EXPECT_EQ(solid_color, color) << rect.ToString(); } @@ -62,32 +63,32 @@ TEST(RasterSourceTest, AnalyzeIsSolidUnscaled) { RasterSource::CreateFromRecordingSource(recording_source.get(), false); color = SK_ColorTRANSPARENT; - is_solid_color = - raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 100, 100), 1.0, &color); + is_solid_color = raster->PerformSolidColorAnalysis( + gfx::Rect(0, 0, 100, 100), gfx::SizeF(1.f, 1.f), &color); EXPECT_FALSE(is_solid_color); color = SK_ColorTRANSPARENT; is_solid_color = raster->PerformSolidColorAnalysis( - gfx::Rect(100, 0, 100, 100), 1.0, &color); + gfx::Rect(100, 0, 100, 100), gfx::SizeF(1.f, 1.f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(solid_color, color); // Boundaries should be clipped. color = SK_ColorTRANSPARENT; is_solid_color = raster->PerformSolidColorAnalysis( - gfx::Rect(350, 0, 100, 100), 1.0, &color); + gfx::Rect(350, 0, 100, 100), gfx::SizeF(1.f, 1.f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(solid_color, color); color = SK_ColorTRANSPARENT; is_solid_color = raster->PerformSolidColorAnalysis( - gfx::Rect(0, 350, 100, 100), 1.0, &color); + gfx::Rect(0, 350, 100, 100), gfx::SizeF(1.f, 1.f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(solid_color, color); color = SK_ColorTRANSPARENT; is_solid_color = raster->PerformSolidColorAnalysis( - gfx::Rect(350, 350, 100, 100), 1.0, &color); + gfx::Rect(350, 350, 100, 100), gfx::SizeF(1.f, 1.f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(solid_color, color); } @@ -119,7 +120,8 @@ TEST(RasterSourceTest, AnalyzeIsSolidScaled) { for (int y = 0; y <= 30; y += 10) { for (int x = 0; x <= 30; x += 10) { gfx::Rect rect(x, y, 10, 10); - is_solid_color = raster->PerformSolidColorAnalysis(rect, 0.1f, &color); + is_solid_color = raster->PerformSolidColorAnalysis( + rect, gfx::SizeF(0.1f, 0.1f), &color); EXPECT_TRUE(is_solid_color) << rect.ToString(); EXPECT_EQ(color, solid_color) << rect.ToString(); } @@ -133,32 +135,32 @@ TEST(RasterSourceTest, AnalyzeIsSolidScaled) { RasterSource::CreateFromRecordingSource(recording_source.get(), false); color = SK_ColorTRANSPARENT; - is_solid_color = - raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 10, 10), 0.1f, &color); + is_solid_color = raster->PerformSolidColorAnalysis( + gfx::Rect(0, 0, 10, 10), gfx::SizeF(0.1f, 0.1f), &color); EXPECT_FALSE(is_solid_color); color = SK_ColorTRANSPARENT; - is_solid_color = - raster->PerformSolidColorAnalysis(gfx::Rect(10, 0, 10, 10), 0.1f, &color); + is_solid_color = raster->PerformSolidColorAnalysis( + gfx::Rect(10, 0, 10, 10), gfx::SizeF(0.1f, 0.1f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(color, solid_color); // Boundaries should be clipped. color = SK_ColorTRANSPARENT; - is_solid_color = - raster->PerformSolidColorAnalysis(gfx::Rect(35, 0, 10, 10), 0.1f, &color); + is_solid_color = raster->PerformSolidColorAnalysis( + gfx::Rect(35, 0, 10, 10), gfx::SizeF(0.1f, 0.1f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(color, solid_color); color = SK_ColorTRANSPARENT; - is_solid_color = - raster->PerformSolidColorAnalysis(gfx::Rect(0, 35, 10, 10), 0.1f, &color); + is_solid_color = raster->PerformSolidColorAnalysis( + gfx::Rect(0, 35, 10, 10), gfx::SizeF(0.1f, 0.1f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(color, solid_color); color = SK_ColorTRANSPARENT; - is_solid_color = raster->PerformSolidColorAnalysis(gfx::Rect(35, 35, 10, 10), - 0.1f, &color); + is_solid_color = raster->PerformSolidColorAnalysis( + gfx::Rect(35, 35, 10, 10), gfx::SizeF(0.1f, 0.1f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(color, solid_color); } @@ -174,8 +176,8 @@ TEST(RasterSourceTest, AnalyzeIsSolidEmpty) { RasterSource::CreateFromRecordingSource(recording_source.get(), false); SkColor color = SK_ColorTRANSPARENT; - bool is_solid_color = - raster->PerformSolidColorAnalysis(gfx::Rect(0, 0, 400, 400), 1.f, &color); + bool is_solid_color = raster->PerformSolidColorAnalysis( + gfx::Rect(0, 0, 400, 400), gfx::SizeF(1.f, 1.f), &color); EXPECT_TRUE(is_solid_color); EXPECT_EQ(color, SkColorSetARGB(0, 0, 0, 0)); @@ -211,29 +213,31 @@ TEST(RasterSourceTest, PixelRefIteratorDiscardableRefsOneTile) { // Tile sized iterators. These should find only one pixel ref. { std::vector<DrawImage> images; - raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, &images); + raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_EQ(discardable_image[0][0], images[0].image()); } // Shifted tile sized iterators. These should find only one pixel ref. { std::vector<DrawImage> images; - raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), 1.f, - &images); + raster->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_EQ(discardable_image[1][1], images[0].image()); } // Ensure there's no discardable pixel refs in the empty cell { std::vector<DrawImage> images; - raster->GetDiscardableImagesInRect(gfx::Rect(0, 256, 256, 256), 1.f, - &images); + raster->GetDiscardableImagesInRect(gfx::Rect(0, 256, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(0u, images.size()); } // Layer sized iterators. These should find three pixel ref. { std::vector<DrawImage> images; - raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), 1.f, &images); + raster->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(3u, images.size()); EXPECT_EQ(discardable_image[0][0], images[0].image()); EXPECT_EQ(discardable_image[0][1], images[1].image()); @@ -287,7 +291,7 @@ TEST(RasterSourceTest, RasterFullContents) { canvas.clear(SK_ColorTRANSPARENT); raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, - contents_scale, + gfx::SizeF(contents_scale, contents_scale), RasterSource::PlaybackSettings()); SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -339,7 +343,8 @@ TEST(RasterSourceTest, RasterPartialContents) { gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale, RasterSource::PlaybackSettings()); + gfx::SizeF(contents_scale, contents_scale), + RasterSource::PlaybackSettings()); { SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -370,7 +375,8 @@ TEST(RasterSourceTest, RasterPartialContents) { // that touches the edge pixels of the recording. playback_rect.Inset(1, 2, 0, 1); raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale, RasterSource::PlaybackSettings()); + gfx::SizeF(contents_scale, contents_scale), + RasterSource::PlaybackSettings()); SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); int num_black = 0; @@ -434,7 +440,8 @@ TEST(RasterSourceTest, RasterPartialClear) { gfx::Rect raster_full_rect(content_bounds); gfx::Rect playback_rect(content_bounds); raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale, RasterSource::PlaybackSettings()); + gfx::SizeF(contents_scale, contents_scale), + RasterSource::PlaybackSettings()); { SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -473,7 +480,8 @@ TEST(RasterSourceTest, RasterPartialClear) { playback_rect = gfx::Rect(gfx::ScaleToCeiledSize(partial_bounds, contents_scale)); raster->PlaybackToCanvas(&canvas, raster_full_rect, playback_rect, - contents_scale, RasterSource::PlaybackSettings()); + gfx::SizeF(contents_scale, contents_scale), + RasterSource::PlaybackSettings()); // Test that the whole playback_rect was cleared and repainted with new alpha. SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -512,7 +520,8 @@ TEST(RasterSourceTest, RasterContentsTransparent) { bitmap.allocN32Pixels(canvas_rect.width(), canvas_rect.height()); SkCanvas canvas(bitmap); - raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, contents_scale, + raster->PlaybackToCanvas(&canvas, canvas_rect, canvas_rect, + gfx::SizeF(contents_scale, contents_scale), RasterSource::PlaybackSettings()); SkColor* pixels = reinterpret_cast<SkColor*>(bitmap.getPixels()); @@ -586,7 +595,7 @@ TEST(RasterSourceTest, ImageHijackCanvasRespectsSharedCanvasTransform) { settings.playback_to_shared_canvas = true; settings.use_image_hijack_canvas = true; raster_source->PlaybackToCanvas(&canvas, gfx::Rect(size), gfx::Rect(size), - 1.f, settings); + gfx::SizeF(1.f, 1.f), settings); EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(0, 0)); EXPECT_EQ(SK_ColorGREEN, bitmap.getColor(49, 0)); diff --git a/chromium/cc/playback/recording_source.cc b/chromium/cc/playback/recording_source.cc index d5ad6ffe8ce..f1f4d3780cf 100644 --- a/chromium/cc/playback/recording_source.cc +++ b/chromium/cc/playback/recording_source.cc @@ -14,7 +14,6 @@ #include "cc/playback/display_item_list.h" #include "cc/playback/raster_source.h" #include "cc/proto/gfx_conversions.h" -#include "cc/proto/recording_source.pb.h" #include "skia/ext/analysis_canvas.h" namespace { @@ -40,40 +39,6 @@ RecordingSource::RecordingSource() RecordingSource::~RecordingSource() {} -void RecordingSource::ToProtobuf(proto::RecordingSource* proto) const { - SizeToProto(size_, proto->mutable_size()); - proto->set_slow_down_raster_scale_factor_for_debug( - slow_down_raster_scale_factor_for_debug_); - proto->set_generate_discardable_images_metadata( - generate_discardable_images_metadata_); - proto->set_requires_clear(requires_clear_); - proto->set_is_solid_color(is_solid_color_); - proto->set_clear_canvas_with_debug_color(clear_canvas_with_debug_color_); - proto->set_solid_color(static_cast<uint64_t>(solid_color_)); - proto->set_background_color(static_cast<uint64_t>(background_color_)); -} - -void RecordingSource::FromProtobuf( - const proto::RecordingSource& proto, - const scoped_refptr<DisplayItemList>& display_list, - const gfx::Rect& recorded_viewport) { - size_ = ProtoToSize(proto.size()); - slow_down_raster_scale_factor_for_debug_ = - proto.slow_down_raster_scale_factor_for_debug(); - generate_discardable_images_metadata_ = - proto.generate_discardable_images_metadata(); - requires_clear_ = proto.requires_clear(); - is_solid_color_ = proto.is_solid_color(); - clear_canvas_with_debug_color_ = proto.clear_canvas_with_debug_color(); - solid_color_ = static_cast<SkColor>(proto.solid_color()); - background_color_ = static_cast<SkColor>(proto.background_color()); - - display_list_ = display_list; - recorded_viewport_ = recorded_viewport; - if (display_list_) - FinishDisplayItemListUpdate(); -} - void RecordingSource::UpdateInvalidationForNewViewport( const gfx::Rect& old_recorded_viewport, const gfx::Rect& new_recorded_viewport, diff --git a/chromium/cc/playback/recording_source.h b/chromium/cc/playback/recording_source.h index d0c36e598c1..802aaf65bd0 100644 --- a/chromium/cc/playback/recording_source.h +++ b/chromium/cc/playback/recording_source.h @@ -19,12 +19,6 @@ namespace cc { -namespace proto { -class RecordingSource; -} // namespace proto - -class ClientPictureCache; -class ContentLayerClient; class DisplayItemList; class RasterSource; class Region; @@ -44,11 +38,6 @@ class CC_EXPORT RecordingSource { RecordingSource(); virtual ~RecordingSource(); - void ToProtobuf(proto::RecordingSource* proto) const; - void FromProtobuf(const proto::RecordingSource& proto, - const scoped_refptr<DisplayItemList>& display_list, - const gfx::Rect& recorded_viewport); - bool UpdateAndExpandInvalidation(Region* invalidation, const gfx::Size& layer_size, const gfx::Rect& new_recorded_viewport); @@ -68,6 +57,7 @@ class CC_EXPORT RecordingSource { bool can_use_lcd_text) const; const DisplayItemList* GetDisplayItemList(); + gfx::Rect recorded_viewport() const { return recorded_viewport_; } protected: gfx::Rect recorded_viewport_; diff --git a/chromium/cc/playback/recording_source_unittest.cc b/chromium/cc/playback/recording_source_unittest.cc index 26594ffe70b..32c7ba9de3d 100644 --- a/chromium/cc/playback/recording_source_unittest.cc +++ b/chromium/cc/playback/recording_source_unittest.cc @@ -7,7 +7,6 @@ #include "base/memory/ptr_util.h" #include "cc/base/region.h" #include "cc/playback/raster_source.h" -#include "cc/proto/recording_source.pb.h" #include "cc/test/fake_client_picture_cache.h" #include "cc/test/fake_content_layer_client.h" #include "cc/test/fake_engine_picture_cache.h" @@ -36,65 +35,6 @@ scoped_refptr<RasterSource> CreateRasterSource( can_use_lcd_text); } -void ValidateRecordingSourceSerialization(FakeRecordingSource* source) { - proto::RecordingSource proto; - source->ToProtobuf(&proto); - - FakeRecordingSource new_source; - new_source.FromProtobuf(proto, nullptr, gfx::Rect()); - - EXPECT_TRUE(source->EqualsTo(new_source)); -} - -TEST(RecordingSourceTest, TestNullDisplayListSerialization) { - gfx::Rect recorded_viewport(0, 0, 256, 256); - - std::unique_ptr<FakeRecordingSource> recording_source = - CreateRecordingSource(recorded_viewport); - recording_source->SetDisplayListUsesCachedPicture(false); - recording_source->SetGenerateDiscardableImagesMetadata(true); - recording_source->Rerecord(); - recording_source->SetEmptyBounds(); - - ValidateRecordingSourceSerialization(recording_source.get()); -} - -TEST(RecordingSourceTest, TestEmptySerializationDeserialization) { - gfx::Rect recorded_viewport(0, 0, 256, 256); - - std::unique_ptr<FakeRecordingSource> recording_source = - CreateRecordingSource(recorded_viewport); - recording_source->SetDisplayListUsesCachedPicture(false); - recording_source->SetGenerateDiscardableImagesMetadata(true); - recording_source->Rerecord(); - - ValidateRecordingSourceSerialization(recording_source.get()); -} - -TEST(RecordingSourceTest, TestPopulatedSerializationDeserialization) { - gfx::Rect recorded_viewport(0, 0, 256, 256); - - std::unique_ptr<FakeRecordingSource> recording_source = - CreateRecordingSource(recorded_viewport); - recording_source->SetDisplayListUsesCachedPicture(false); - - SkPaint simple_paint; - simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34)); - recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 256, 256), - simple_paint); - recording_source->add_draw_rect_with_paint(gfx::Rect(128, 128, 512, 512), - simple_paint); - recording_source->add_draw_rect_with_paint(gfx::Rect(512, 0, 256, 256), - simple_paint); - recording_source->add_draw_rect_with_paint(gfx::Rect(0, 512, 256, 256), - simple_paint); - - recording_source->SetGenerateDiscardableImagesMetadata(true); - recording_source->Rerecord(); - - ValidateRecordingSourceSerialization(recording_source.get()); -} - TEST(RecordingSourceTest, DiscardableImagesWithTransform) { gfx::Rect recorded_viewport(256, 256); @@ -138,8 +78,8 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { // Tile sized iterators. These should find only one pixel ref. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(2u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[0][0]); EXPECT_TRUE(images[1].image() == discardable_image[1][1]); @@ -149,7 +89,7 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { { std::vector<DrawImage> images; raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 140, 128, 128), - 1.f, &images); + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } @@ -157,8 +97,8 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { // The rotated bitmap would still be in the top right tile. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } @@ -166,8 +106,8 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { // Layer sized iterators. These should find all pixel refs. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(3u, images.size()); // Top left tile with bitmap[0][0] and bitmap[1][1]. EXPECT_TRUE(images[0].image() == discardable_image[0][0]); @@ -176,13 +116,15 @@ TEST(RecordingSourceTest, DiscardableImagesWithTransform) { } // Verify different raster scales - for (float scale = 1.f; scale <= 5.f; scale += 0.5f) { - std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(130, 0, 128, 128), - scale, &images); - EXPECT_EQ(1u, images.size()); - EXPECT_FLOAT_EQ(scale, images[0].scale().width()); - EXPECT_FLOAT_EQ(scale, images[0].scale().height()); + for (float x_scale = 1.f; x_scale <= 5.f; x_scale += 0.5f) { + for (float y_scale = 1.f; y_scale <= 5.f; y_scale += 0.5f) { + std::vector<DrawImage> images; + raster_source->GetDiscardableImagesInRect( + gfx::Rect(130, 0, 128, 128), gfx::SizeF(x_scale, y_scale), &images); + EXPECT_EQ(1u, images.size()); + EXPECT_FLOAT_EQ(x_scale, images[0].scale().width()); + EXPECT_FLOAT_EQ(y_scale, images[0].scale().height()); + } } } @@ -201,7 +143,8 @@ TEST(RecordingSourceTest, NoGatherImageEmptyImages) { // get images. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(recorded_viewport, 1.f, &images); + raster_source->GetDiscardableImagesInRect(recorded_viewport, + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } } @@ -220,22 +163,22 @@ TEST(RecordingSourceTest, EmptyImages) { // Tile sized iterators. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } // Shifted tile sized iterators. { std::vector<DrawImage> images; raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 140, 128, 128), - 1.f, &images); + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } // Layer sized iterators. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } } @@ -275,22 +218,22 @@ TEST(RecordingSourceTest, NoDiscardableImages) { // Tile sized iterators. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } // Shifted tile sized iterators. { std::vector<DrawImage> images; raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 140, 128, 128), - 1.f, &images); + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } // Layer sized iterators. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } } @@ -325,8 +268,8 @@ TEST(RecordingSourceTest, DiscardableImages) { // Tile sized iterators. These should find only one image. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 128, 128), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[0][0]); } @@ -335,7 +278,7 @@ TEST(RecordingSourceTest, DiscardableImages) { { std::vector<DrawImage> images; raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 140, 128, 128), - 1.f, &images); + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } @@ -343,16 +286,16 @@ TEST(RecordingSourceTest, DiscardableImages) { // Ensure there's no discardable images in the empty cell { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 0, 128, 128), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(140, 0, 128, 128), + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } // Layer sized iterators. These should find all 3 images. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(3u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[0][0]); EXPECT_TRUE(images[1].image() == discardable_image[1][0]); @@ -398,8 +341,8 @@ TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) { // Tile sized iterators. These should find only one image. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[0][0]); } @@ -407,22 +350,22 @@ TEST(RecordingSourceTest, DiscardableImagesBaseNonDiscardable) { { std::vector<DrawImage> images; raster_source->GetDiscardableImagesInRect(gfx::Rect(260, 260, 256, 256), - 1.f, &images); + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(1u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[1][1]); } // Ensure there's no discardable images in the empty cell { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 256, 256, 256), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 256, 256, 256), + gfx::SizeF(1.f, 1.f), &images); EXPECT_TRUE(images.empty()); } // Layer sized iterators. These should find three images. { std::vector<DrawImage> images; - raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), 1.f, - &images); + raster_source->GetDiscardableImagesInRect(gfx::Rect(0, 0, 512, 512), + gfx::SizeF(1.f, 1.f), &images); EXPECT_EQ(3u, images.size()); EXPECT_TRUE(images[0].image() == discardable_image[0][0]); EXPECT_TRUE(images[1].image() == discardable_image[0][1]); diff --git a/chromium/cc/proto/BUILD.gn b/chromium/cc/proto/BUILD.gn index cfbcd31904b..d94c4cbc299 100644 --- a/chromium/cc/proto/BUILD.gn +++ b/chromium/cc/proto/BUILD.gn @@ -29,38 +29,27 @@ proto_library("proto_internal") { sources = [ # TODO(dtrainor): Move protos to their correct packages once it's possible # to include protos from other directories/targets (crbug.com/542423). - "begin_main_frame_and_commit_state.proto", - "commit_earlyout_reason.proto", + "client_state_update.proto", "compositor_message.proto", - "compositor_message_to_impl.proto", - "compositor_message_to_main.proto", "display_item.proto", - "element_id.proto", "layer.proto", "layer_position_constraint.proto", "layer_selection_bound.proto", "layer_sticky_position_constraint.proto", "layer_tree.proto", - "layer_tree_debug_state.proto", "layer_tree_host.proto", - "managed_memory_policy.proto", - "memory_allocation.proto", "point.proto", "point3f.proto", "pointf.proto", - "property_tree.proto", - "recording_source.proto", "rect.proto", "rectf.proto", "region.proto", - "renderer_settings.proto", "scroll_offset.proto", "size.proto", "sizef.proto", "skregion.proto", "skrrect.proto", "skxfermode.proto", - "synced_property.proto", "transform.proto", "vector2d.proto", "vector2df.proto", diff --git a/chromium/cc/proto/begin_main_frame_and_commit_state.proto b/chromium/cc/proto/begin_main_frame_and_commit_state.proto deleted file mode 100644 index c90bb6a6590..00000000000 --- a/chromium/cc/proto/begin_main_frame_and_commit_state.proto +++ /dev/null @@ -1,50 +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. - -syntax = "proto2"; - -import "vector2d.proto"; -import "vector2df.proto"; - -option optimize_for = LITE_RUNTIME; - -package cc.proto; - -message ScrollUpdateInfo { - optional int64 layer_id = 1; - optional Vector2d scroll_delta = 2; -} - -message ScrollAndScaleSet { - repeated ScrollUpdateInfo scrolls = 1; - optional float page_scale_delta = 2; - optional Vector2dF elastic_overscroll_delta = 3; - optional float top_controls_delta = 4; - - // TODO(khushalsagar): Do we need to send swap promises? - // See crbug/576999. -} - -message BeginFrameArgs { - enum BeginFrameArgsType { - INVALID = 1; - NORMAL = 2; - MISSED = 3; - BEGIN_FRAME_ARGS_TYPE_MAX = 100; - } - - optional int64 frame_time = 1; - optional int64 deadline = 2; - optional int64 interval = 3; - optional BeginFrameArgsType type = 4; - optional bool on_critical_path = 5; -} - -message BeginMainFrameAndCommitState { - optional int64 begin_frame_id = 1; - optional BeginFrameArgs begin_frame_args = 2; - optional ScrollAndScaleSet scroll_info = 3; - optional int64 memory_allocation_limit_bytes = 4; - optional bool evicted_ui_resources = 5; -} diff --git a/chromium/cc/proto/cc_conversions.h b/chromium/cc/proto/cc_conversions.h index 78c697b8896..6d74018e506 100644 --- a/chromium/cc/proto/cc_conversions.h +++ b/chromium/cc/proto/cc_conversions.h @@ -8,6 +8,7 @@ #include "cc/base/cc_export.h" #include "cc/input/scrollbar.h" #include "cc/proto/layer.pb.h" +#include "cc/trees/clip_node.h" namespace cc { class Region; diff --git a/chromium/cc/proto/commit_earlyout_reason.proto b/chromium/cc/proto/client_state_update.proto index 092fbd34b43..c1ae4908ff7 100644 --- a/chromium/cc/proto/commit_earlyout_reason.proto +++ b/chromium/cc/proto/client_state_update.proto @@ -6,15 +6,16 @@ syntax = "proto2"; option optimize_for = LITE_RUNTIME; -package cc.proto; +import "vector2df.proto"; -message CommitEarlyOutReason { - enum Reason { - ABORTED_COMPOSITOR_FRAME_SINK_LOST = 1; - ABORTED_NOT_VISIBLE = 2; - ABORTED_DEFERRED_COMMIT = 3; - FINISHED_NO_UPDATES = 4; - } +package cc.proto; - optional Reason reason = 1; +message ScrollUpdate { + optional int32 layer_id = 1; + optional Vector2dF scroll_delta = 2; } + +message ClientStateUpdate { + repeated ScrollUpdate scroll_updates = 1; + optional float page_scale_delta = 2; +}
\ No newline at end of file diff --git a/chromium/cc/proto/compositor_message.proto b/chromium/cc/proto/compositor_message.proto index 0697a18611d..93dc438a38a 100644 --- a/chromium/cc/proto/compositor_message.proto +++ b/chromium/cc/proto/compositor_message.proto @@ -6,8 +6,7 @@ syntax = "proto2"; option optimize_for = LITE_RUNTIME; -import "compositor_message_to_impl.proto"; -import "compositor_message_to_main.proto"; +import "client_state_update.proto"; import "layer_tree_host.proto"; package cc.proto; @@ -21,7 +20,21 @@ message CompositorMessage { // Frame Update. optional LayerTreeHost layer_tree_host = 3; - // One of these is set based on where the message is going to. - optional CompositorMessageToMain to_main = 1; - optional CompositorMessageToImpl to_impl = 2; + // Client -> Engine + // Sent from the client to the engine when a frame update was processed + // on the client. + optional bool frame_ack = 4; + + // Client -> Engine + // Reports any changes made to the main thread state on the compositor thread + // on the client. + optional ClientStateUpdate client_state_update = 5; + + // Engine -> Client + // Acknowledges the application of the client state update to the associated + // state on the engine. + // If the application of the update resulted in any additional changes to the + // state on the engine, the ack will always be bundled with the resulting + // frame update. + optional bool client_state_update_ack = 6; } diff --git a/chromium/cc/proto/compositor_message_to_impl.proto b/chromium/cc/proto/compositor_message_to_impl.proto deleted file mode 100644 index 63b8387fbe0..00000000000 --- a/chromium/cc/proto/compositor_message_to_impl.proto +++ /dev/null @@ -1,106 +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. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -import "commit_earlyout_reason.proto"; -import "layer_tree_host.proto"; -import "rect.proto"; - -package cc.proto; - -// Control messages sent to the impl side of the compositor (client) from the -// main side of the compositor (server). -// Note: Unless specified in a comment, all fields in a message are required, -// even if listed as optional. - -// Commit Flow: The commit flow defines the protocol for data exchange between -// the client and the server. The commit flow is characterized by -// the following messages. -// -// 1) The commit will always be started by the client. The server -// may request a commit from the client by sending a -// CompositorMessageToImpl of type SET_NEEDS_COMMIT. Note that -// if the server needs to push any updates to the client, this -// message will only be sent once, and the client must respond -// with CompositorMessageToMain of type BEGIN_MAIN_FRAME to -// start the commit. -// The client can spontaneously initiate a commit when it needs -// to request new data from the server by sending the -// BEGIN_MAIN_FRAME message. -// -// 2) On receiving BEGIN_MAIN_FRAME message, the server can respond -// with either CompositorMessageToImpl of type START_COMMIT, if -// it needs to push an update to the client, or of type -// BEGIN_MAIN_FRAME_ABORTED if the commit was aborted. - -message CompositorMessageToImpl { - enum Type { - // The enum values which are unknown get mapped to the default value, which - // is zero. This can happen with when the protocol version skewing is - // different on the client and server. - // Ignore the messages with type UNKNOWN. - // see crbug/559338. - UNKNOWN = 0; - - // Sent to the client to request a commit. The client will respond with - // CompositorMessageToMain of type BEGIN_MAIN_FRAME. - SET_NEEDS_COMMIT = 4; - - // Informs the client to start/stop commit requests. The message can be sent - // any time to the client. - SET_DEFER_COMMITS = 5; - - // Sent in response to a CompositorMessageToMain of type BEGIN_MAIN_FRAME - // from the client, with the updated state of the LayerTreeHost. - START_COMMIT = 6; - - // Sent in response to a CompositorMessageToMain of type BEGIN_MAIN_FRAME - // from the client, if the commit was aborted. - BEGIN_MAIN_FRAME_ABORTED = 7; - - // Sent when a redraw is requested for the given damaged rect. - SET_NEEDS_REDRAW = 8; - } - - optional Type message_type = 1; - - // Only one of the following fields will be set per CompositorMessageToImpl. - - // Set for message Type::SET_DEFER_COMMITS. - optional SetDeferCommits defer_commits_message = 3; - - // Set for message Type::START_COMMIT. - optional StartCommit start_commit_message = 4; - - // Set for message Type::BEGIN_MAIN_FRAME_ABORTED. - optional BeginMainFrameAborted begin_main_frame_aborted_message = 5; - - // Set for message Type::SET_NEEDS_REDRAW. - optional SetNeedsRedraw set_needs_redraw_message = 6; -} - -message SetDeferCommits { - // If set to true, the client will defer sending any BEGIN_MAIN_FRAME messages - // to start a commit. The server must send a message with defer_commits set to - // false to allow the client to start commits. - // Note: If a pending commit request from the server was throttled if the - // client was defering commits, it will be honoured after the server informs - // the client to start commits. - optional bool defer_commits = 1; -} - -message StartCommit { - optional LayerTreeHost layer_tree_host = 1; -} - -message BeginMainFrameAborted { - optional CommitEarlyOutReason reason = 1; -} - -message SetNeedsRedraw { - optional Rect damaged_rect = 1; -}
\ No newline at end of file diff --git a/chromium/cc/proto/compositor_message_to_main.proto b/chromium/cc/proto/compositor_message_to_main.proto deleted file mode 100644 index b0d41660a9c..00000000000 --- a/chromium/cc/proto/compositor_message_to_main.proto +++ /dev/null @@ -1,39 +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. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -import "begin_main_frame_and_commit_state.proto"; - -package cc.proto; - -// Control messages sent to the main side of the compositor(server) from the -// impl side of the compositor(client). -// TODO(khushalsagar): Are any more messages required? (See crbug.com/584078) -message CompositorMessageToMain { - enum Type { - // The enum values which are unknown get mapped to the default value, which - // is zero. This can happen with when the protocol version is different on - // the client and server. - // Ignore the messages with type UNKNOWN. - UNKNOWN = 0; - - // Sent by the client to start the commit process. See - // compositor_message_to_impl.proto for details. - BEGIN_MAIN_FRAME = 1; - } - - optional Type message_type = 1; - - // Only one of the following fields will be set per CompositorMessageToMain. - - // Set for message Type::BEGIN_MAIN_FRAME. - optional BeginMainFrame begin_main_frame_message = 2; -} - -message BeginMainFrame { - optional BeginMainFrameAndCommitState begin_main_frame_state = 1; -} diff --git a/chromium/cc/proto/element_id.proto b/chromium/cc/proto/element_id.proto deleted file mode 100644 index 9e5cedd80a5..00000000000 --- a/chromium/cc/proto/element_id.proto +++ /dev/null @@ -1,18 +0,0 @@ -// Copyright 2015 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. - -syntax = "proto2"; - -option optimize_for = LITE_RUNTIME; - -package cc.proto; - -// The message declared in this file corresponds to the class declared in -// cc/animation/element_id.h - -// NEXT ID: 3 -message ElementId { - required int64 primary_id = 1; - required int64 secondary_id = 2; -} diff --git a/chromium/cc/proto/gpu_conversions.cc b/chromium/cc/proto/gpu_conversions.cc deleted file mode 100644 index 8454aed0ffc..00000000000 --- a/chromium/cc/proto/gpu_conversions.cc +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright 2015 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/proto/gpu_conversions.h" - -#include "base/logging.h" -#include "cc/proto/memory_allocation.pb.h" -#include "gpu/command_buffer/common/gpu_memory_allocation.h" - -namespace cc { - -proto::MemoryAllocation::PriorityCutoff MemoryAllocationPriorityCutoffToProto( - const gpu::MemoryAllocation::PriorityCutoff& priority_cutoff) { - switch (priority_cutoff) { - case gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_NOTHING: - return proto::MemoryAllocation_PriorityCutoff_ALLOW_NOTHING; - case gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_REQUIRED_ONLY: - return proto::MemoryAllocation_PriorityCutoff_ALLOW_REQUIRED_ONLY; - case gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_NICE_TO_HAVE: - return proto::MemoryAllocation_PriorityCutoff_ALLOW_NICE_TO_HAVE; - case gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_EVERYTHING: - return proto::MemoryAllocation_PriorityCutoff_ALLOW_EVERYTHING; - } - return proto::MemoryAllocation_PriorityCutoff_UNKNOWN; -} - -gpu::MemoryAllocation::PriorityCutoff MemoryAllocationPriorityCutoffFromProto( - const proto::MemoryAllocation::PriorityCutoff& priority_cutoff) { - switch (priority_cutoff) { - case proto::MemoryAllocation_PriorityCutoff_ALLOW_NOTHING: - return gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_NOTHING; - case proto::MemoryAllocation_PriorityCutoff_ALLOW_REQUIRED_ONLY: - return gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_REQUIRED_ONLY; - case proto::MemoryAllocation_PriorityCutoff_ALLOW_NICE_TO_HAVE: - return gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_NICE_TO_HAVE; - case proto::MemoryAllocation_PriorityCutoff_ALLOW_EVERYTHING: - return gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_EVERYTHING; - case proto::MemoryAllocation_PriorityCutoff_UNKNOWN: - NOTREACHED() << "Received MemoryAllocation::PriorityCutoff_UNKNOWN"; - return gpu::MemoryAllocation::PriorityCutoff::CUTOFF_LAST; - } - return gpu::MemoryAllocation::PriorityCutoff::CUTOFF_ALLOW_NOTHING; -} - -} // namespace cc diff --git a/chromium/cc/proto/gpu_conversions.h b/chromium/cc/proto/gpu_conversions.h deleted file mode 100644 index 1a748791418..00000000000 --- a/chromium/cc/proto/gpu_conversions.h +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2015 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_PROTO_GPU_CONVERSIONS_H_ -#define CC_PROTO_GPU_CONVERSIONS_H_ - -#include "cc/base/cc_export.h" -#include "cc/proto/memory_allocation.pb.h" -#include "gpu/command_buffer/common/gpu_memory_allocation.h" - -namespace cc { - -// TODO(dtrainor): Move these to a class and make them static -// (crbug.com/548432). -CC_EXPORT proto::MemoryAllocation::PriorityCutoff -MemoryAllocationPriorityCutoffToProto( - const gpu::MemoryAllocation::PriorityCutoff& priority_cutoff); -CC_EXPORT gpu::MemoryAllocation::PriorityCutoff -MemoryAllocationPriorityCutoffFromProto( - const proto::MemoryAllocation::PriorityCutoff& proto); - -} // namespace cc - -#endif // CC_PROTO_GPU_CONVERSIONS_H_ diff --git a/chromium/cc/proto/gpu_conversions_unittest.cc b/chromium/cc/proto/gpu_conversions_unittest.cc deleted file mode 100644 index 7ed770b326f..00000000000 --- a/chromium/cc/proto/gpu_conversions_unittest.cc +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2015 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/proto/gpu_conversions.h" - -#include <stddef.h> - -#include "cc/proto/memory_allocation.pb.h" -#include "gpu/command_buffer/common/gpu_memory_allocation.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -TEST(GpuProtoConversionTest, - SerializeDeserializeMemoryAllocationPriorityCutoff) { - for (size_t i = 0; i < gpu::MemoryAllocation::PriorityCutoff::CUTOFF_LAST; - ++i) { - gpu::MemoryAllocation::PriorityCutoff priority_cutoff = - static_cast<gpu::MemoryAllocation::PriorityCutoff>(i); - EXPECT_EQ(priority_cutoff, - MemoryAllocationPriorityCutoffFromProto( - MemoryAllocationPriorityCutoffToProto(priority_cutoff))); - } -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/proto/layer.proto b/chromium/cc/proto/layer.proto index b4b6035575b..5e111daf613 100644 --- a/chromium/cc/proto/layer.proto +++ b/chromium/cc/proto/layer.proto @@ -9,9 +9,8 @@ import "layer_position_constraint.proto"; import "layer_sticky_position_constraint.proto"; import "point3f.proto"; import "pointf.proto"; -import "recording_source.proto"; -import "region.proto"; import "rect.proto"; +import "region.proto"; import "scroll_offset.proto"; import "size.proto"; import "skxfermode.proto"; @@ -30,9 +29,12 @@ message LayerNode { UNKNOWN = 0; LAYER = 1; PICTURE_LAYER = 2; - HEADS_UP_DISPLAY_LAYER = 3; SOLID_COLOR_SCROLLBAR_LAYER = 4; + // Layer Types for testing only. + FAKE_PICTURE_LAYER = 5; + PUSH_PROPERTIES_COUNTING_LAYER = 6; + // TODO(nyquist): Add the rest of the necessary LayerTypes. }; @@ -44,6 +46,9 @@ message LayerNode { // A List of all the children of the current LayerNode. repeated LayerNode children = 4; optional LayerNode mask_layer = 5; + + // Set for SolidColorScrollbarLayers. + optional SolidColorScrollbarLayerProperties solid_scrollbar = 6; } // A container for a list of dirty layers. @@ -65,12 +70,11 @@ message LayerProperties { // TODO(dtrainor): use a 'oneof' union when it's supported in Chromium. See // crbug.com/570371. optional PictureLayerProperties picture = 6; - optional SolidColorScrollbarLayerProperties solid_scrollbar = 7; } // NEXT ID: 59 message BaseLayerProperties { - // The following fields mirror the data stored in Layer::Inputs ---------- + // The following fields mirror the data stored in Layer::Inputs. optional Rect update_rect = 46; optional Size bounds = 3; optional bool masks_to_bounds = 14; @@ -117,43 +121,12 @@ message BaseLayerProperties { // TODO(nyquist): Add support for FilterOperation. See crbug.com/541321. // repeated FilterOperation filters = 12; // repeated FilterOperation background_filters = 13; - - // ----------------------------------------------------------------------- - - // TODO(khushalsagar): Remove these when crbug.com/648442 - optional uint32 safe_opaque_background_color = 53; - optional int64 transform_free_index = 4; - optional int64 effect_tree_index = 5; - optional int64 clip_tree_index = 6; - optional int64 scroll_tree_index = 50; - optional Vector2dF offset_to_transform_parent = 7; - optional bool draws_content = 9; - optional bool may_contain_video = 55; - optional bool subtree_property_changed = 47; - optional bool have_scroll_event_handlers = 17; - optional bool should_flatten_transform_from_property_tree = 29; - optional int32 num_layer_or_descendants_with_copy_request = 30; - optional SkXfermode.Mode draw_blend_mode = 31; - optional bool use_local_transform_for_backface_visibility = 51; - optional bool should_check_backface_visibility = 52; - optional bool transform_is_invertible = 34; - optional int32 num_descendants_that_draw_content = 36; - repeated int32 scroll_children_ids = 41; - repeated int32 clip_children_ids = 43; - - // TODO(nyquist): Figure out what to do with LayerAnimationController. - // optional LayerAnimationController layer_animation_controller = ???; } message PictureLayerProperties { - optional RecordingSource recording_source = 1; - optional Region invalidation = 2; - optional Rect last_updated_visible_layer_rect = 3; - optional bool is_mask = 4; + // The following fields mirror the data stored in + // PictureLayer::PictureLayerInputs. optional bool nearest_neighbor = 5; - - optional int64 update_source_frame_number = 6; - optional Rect recorded_viewport = 7; optional DisplayItemList display_list = 8; } diff --git a/chromium/cc/proto/layer_sticky_position_constraint.proto b/chromium/cc/proto/layer_sticky_position_constraint.proto index 97d8fea1cc9..fe9f962aff2 100644 --- a/chromium/cc/proto/layer_sticky_position_constraint.proto +++ b/chromium/cc/proto/layer_sticky_position_constraint.proto @@ -4,6 +4,7 @@ syntax = "proto2"; +import "point.proto"; import "rect.proto"; import "transform.proto"; @@ -23,6 +24,7 @@ message LayerStickyPositionConstraint { optional float top_offset = 8; optional float bottom_offset = 9; + optional Point parent_relative_sticky_box_offset = 12; optional Rect scroll_container_relative_sticky_box_rect = 10; optional Rect scroll_container_relative_containing_block_rect = 11; }; diff --git a/chromium/cc/proto/layer_tree.proto b/chromium/cc/proto/layer_tree.proto index f6dbd858cfe..9836f0441e5 100644 --- a/chromium/cc/proto/layer_tree.proto +++ b/chromium/cc/proto/layer_tree.proto @@ -8,21 +8,19 @@ package cc.proto; import "layer.proto"; import "layer_selection_bound.proto"; -import "property_tree.proto"; import "size.proto"; import "vector2df.proto"; option optimize_for = LITE_RUNTIME; message LayerTree { - // LayerTree::Inputs ---------------------------------------- optional LayerNode root_layer = 27; optional int32 overscroll_elasticity_layer_id = 3; optional int32 page_scale_layer_id = 4; optional int32 inner_viewport_scroll_layer_id = 5; optional int32 outer_viewport_scroll_layer_id = 6; - // Top Controls ignored. They are not supported. + // Browser Controls ignored. They are not supported. optional float device_scale_factor = 13; optional float painted_device_scale_factor = 14; @@ -43,15 +41,4 @@ message LayerTree { optional uint32 touch_start_or_move_event_listener_properties = 24; optional uint32 wheel_event_listener_properties = 25; optional uint32 touch_end_or_cancel_event_listener_properties = 26; - - // ------------------------------------------------------------ - - // TODO(khushalsagar): Remove these when crbug.com/648442 - repeated int32 layers_that_should_push_properties = 1; - optional bool in_paint_layer_contents = 2; - optional bool needs_full_tree_sync = 7; - optional bool needs_meta_info_recomputation = 8; - optional int32 hud_layer_id = 9; - optional PropertyTrees property_trees = 30; - optional Vector2dF elastic_overscroll = 31; } diff --git a/chromium/cc/proto/layer_tree_debug_state.proto b/chromium/cc/proto/layer_tree_debug_state.proto deleted file mode 100644 index 0255d1b6e60..00000000000 --- a/chromium/cc/proto/layer_tree_debug_state.proto +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2015 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. - -syntax = "proto2"; - -package cc.proto; - -option optimize_for = LITE_RUNTIME; - -message LayerTreeDebugState { - optional bool show_fps_counter = 1; - optional bool show_debug_borders = 2; - - optional bool show_paint_rects = 3; - optional bool show_property_changed_rects = 4; - optional bool show_surface_damage_rects = 5; - optional bool show_screen_space_rects = 6; - optional bool show_touch_event_handler_rects = 8; - optional bool show_wheel_event_handler_rects = 9; - optional bool show_scroll_event_handler_rects = 10; - optional bool show_non_fast_scrollable_rects = 11; - optional bool show_layer_animation_bounds_rects = 12; - - optional int32 slow_down_raster_scale_factor = 13; - optional bool rasterize_only_visible_content = 14; - optional bool show_picture_borders = 15; - - optional bool record_rendering_stats = 16; -} diff --git a/chromium/cc/proto/layer_tree_host.proto b/chromium/cc/proto/layer_tree_host.proto index 876f5625799..dabfba39986 100644 --- a/chromium/cc/proto/layer_tree_host.proto +++ b/chromium/cc/proto/layer_tree_host.proto @@ -7,7 +7,6 @@ syntax = "proto2"; import "display_item.proto"; import "layer.proto"; import "layer_tree.proto"; -import "layer_tree_debug_state.proto"; package cc.proto; @@ -29,15 +28,4 @@ message LayerTreeHost { optional LayerTree layer_tree = 36; optional LayerUpdate layer_updates = 28; optional SkPictures pictures = 38; - - // TODO(khushalsagar): Remove these when crbug.com/648442. - optional int32 source_frame_number = 3; - optional int32 meta_information_sequence_number = 4; - optional LayerTreeDebugState debug_state = 8; - optional bool has_gpu_rasterization_trigger = 19; - optional bool content_is_suitable_for_gpu_rasterization = 20; - optional int32 id = 23; - optional bool next_commit_forces_redraw = 24; - optional uint32 surface_client_id = 31; - optional uint32 next_surface_sequence = 32; } diff --git a/chromium/cc/proto/managed_memory_policy.proto b/chromium/cc/proto/managed_memory_policy.proto deleted file mode 100644 index 9f42a6a65f6..00000000000 --- a/chromium/cc/proto/managed_memory_policy.proto +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright 2015 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. - -syntax = "proto2"; - -import "memory_allocation.proto"; - -package cc.proto; - -option optimize_for = LITE_RUNTIME; - -message ManagedMemoryPolicy { - optional uint32 bytes_limit_when_visible = 1; - optional MemoryAllocation.PriorityCutoff priority_cutoff_when_visible = 2; - optional uint32 num_resources_limit = 3; -} diff --git a/chromium/cc/proto/memory_allocation.proto b/chromium/cc/proto/memory_allocation.proto deleted file mode 100644 index 436461d6044..00000000000 --- a/chromium/cc/proto/memory_allocation.proto +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2015 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. - -syntax = "proto2"; - -package cc.proto; - -option optimize_for = LITE_RUNTIME; - -message MemoryAllocation { - enum PriorityCutoff { - UNKNOWN = 0; - ALLOW_NOTHING = 1; - ALLOW_REQUIRED_ONLY = 2; - ALLOW_NICE_TO_HAVE = 3; - ALLOW_EVERYTHING = 4; - } -} diff --git a/chromium/cc/proto/property_tree.proto b/chromium/cc/proto/property_tree.proto deleted file mode 100644 index bcb50b41ab7..00000000000 --- a/chromium/cc/proto/property_tree.proto +++ /dev/null @@ -1,237 +0,0 @@ -// Copyright 2015 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. - -syntax = "proto2"; - -import "element_id.proto"; -import "layer_sticky_position_constraint.proto"; -import "rectf.proto"; -import "scroll_offset.proto"; -import "size.proto"; -import "skxfermode.proto"; -import "synced_property.proto"; -import "transform.proto"; -import "vector2df.proto"; - -option optimize_for = LITE_RUNTIME; - -package cc.proto; - -// The messages declared in this file correspond to the classes declared in -// cc/trees/property_tree.h - -// Proto for struct TransformNodeData. -// NEXT ID: 43 -message TranformNodeData { - optional Transform pre_local = 1; - optional Transform local = 2; - optional Transform post_local = 3; - optional Transform to_parent = 4; - - optional int64 source_node_id = 11; - optional bool needs_local_transform_update = 12; - optional bool node_and_ancestors_are_animated_or_invertible = 41; - optional bool is_invertible = 13; - optional bool ancestors_are_invertible = 14; - optional bool has_potential_animation = 15; - optional bool is_currently_animating = 42; - optional bool to_screen_is_potentially_animated = 16; - optional bool has_only_translation_animations = 17; - optional bool flattens_inherited_transform = 19; - optional bool node_and_ancestors_are_flat = 20; - optional bool node_and_ancestors_have_only_integer_translation = 21; - optional bool scrolls = 22; - optional bool needs_surface_contents_scale = 23; - optional bool affected_by_inner_viewport_bounds_delta_x = 24; - optional bool affected_by_inner_viewport_bounds_delta_y = 25; - optional bool affected_by_outer_viewport_bounds_delta_x = 26; - optional bool affected_by_outer_viewport_bounds_delta_y = 27; - optional bool in_subtree_of_page_scale_layer = 28; - optional bool transform_changed = 40; - optional float post_local_scale_factor = 29; - - optional Vector2dF surface_contents_scale = 34; - optional ScrollOffset scroll_offset = 35; - optional Vector2dF scroll_snap = 36; - optional Vector2dF source_offset = 37; - optional Vector2dF source_to_parent = 38; - optional int64 sorting_context_id = 39; -} - -// Proto for TransformCachedNodeData -message TransformCachedNodeData { - optional Transform from_target = 1; - optional Transform to_target = 2; - optional Transform from_screen = 3; - optional Transform to_screen = 4; - optional int64 target_id = 5; - optional int64 content_target_id = 6; -} - -// Proto for StickyPositionNodeData -message StickyPositionNodeData { - optional int64 scroll_ancestor = 1; - optional LayerStickyPositionConstraint constraints = 2; - optional Vector2dF main_thread_offset = 3; -} - -// Proto for struct ClipNodeData. -// NEXT ID: 13 -message ClipNodeData { - optional RectF clip = 1; - optional RectF combined_clip_in_target_space = 2; - optional RectF clip_in_target_space = 3; - - optional int64 transform_id = 4; - optional int64 target_transform_id = 5; - optional int64 target_effect_id = 12; - optional bool applies_local_clip = 6; - optional bool layer_clipping_uses_only_local_clip = 7; - optional bool target_is_clipped = 8; - optional bool layers_are_clipped = 9; - optional bool layers_are_clipped_when_surfaces_disabled = 10; - optional bool resets_clip = 11; -} - -// Proto for struct EffectNodeData. -// NEXT ID: 27 -message EffectNodeData { - optional float opacity = 1; - optional float screen_space_opacity = 2; - optional SkXfermode.Mode blend_mode = 25; - optional Size unscaled_mask_target_size = 26; - optional bool has_render_surface = 3; - optional bool has_copy_request = 4; - optional bool hidden_by_backface_visibility = 14; - optional bool double_sided = 13; - optional bool is_drawn = 6; - optional bool subtree_hidden = 15; - optional bool has_potential_filter_animation = 21; - optional bool has_potential_opacity_animation = 7; - optional bool is_currently_animating_filter = 22; - optional bool is_currently_animating_opacity = 16; - optional bool effect_changed = 11; - optional int64 num_copy_requests_in_subtree = 8; - optional int64 transform_id = 9; - optional int64 clip_id = 10; - optional int64 target_id = 12; - optional int64 mask_layer_id = 17; - optional Vector2dF surface_contents_scale = 20; - // TODO(nyquist): Add support for FilterOperation. See crbug.com/541321. - // repeated FilterOperation filters = 23; - // repeated FilterOperation background_filters = 24; -} - -// Proto for struct ScrollNodeData -// NEXT ID: 16 -message ScrollNodeData { - optional bool scrollable = 1; - optional int32 main_thread_scrolling_reasons = 2; - optional bool contains_non_fast_scrollable_region = 3; - optional Size scroll_clip_layer_bounds = 4; - optional Size bounds = 5; - optional bool max_scroll_offset_affected_by_page_scale = 6; - optional bool is_inner_viewport_scroll_layer = 7; - optional bool is_outer_viewport_scroll_layer = 8; - optional Vector2dF offset_to_transform_parent = 9; - optional bool should_flatten = 10; - optional bool user_scrollable_horizontal = 13; - optional bool user_scrollable_vertical = 14; - optional ElementId element_id = 15; - optional int64 transform_id = 11; -} - -// This defines the proto used for all types of struct TreeNode. -message TreeNode { - // The following fields are the base TreeNode properties. This list - // corresponds to the data members from struct TreeNode. - optional int64 id = 1; - optional int64 parent_id = 2; - optional int64 owner_id = 3; - - // The following fields correspond to the possible values for TreeNode::data. - // Only one of these fields should be set, based on the type of property tree - // this node belongs to. - optional TranformNodeData transform_node_data = 1000; - optional ClipNodeData clip_node_data = 1001; - optional EffectNodeData effect_node_data = 1002; - optional ScrollNodeData scroll_node_data = 1003; -} - -// This defines the proto used for all property trees. PropertyType denotes the -// type of this tree. -message PropertyTree { - enum PropertyType { - Transform = 1; - Clip = 2; - Effect = 3; - Scroll = 4; - } - - // The following fields are the base PropertyTree properties. This list - // corresponds to the data members from class PropertyTree. - optional PropertyType property_type = 1; - repeated TreeNode nodes = 2; - optional bool needs_update = 3; - - // The following fields denote the data members for each subclass of - // PropertyTree. Only one of these fields should be set, depending on the type - // of this property tree. - optional TransformTreeData transform_tree_data = 1000; - optional ScrollTreeData scroll_tree_data = 1001; - optional EffectTreeData effect_tree_data = 1002; -} - -message ScrollOffsetMapEntry { - required int64 layer_id = 1; - optional SyncedProperty scroll_offset = 2; -} - -// Proto for data members of class ScrollTree -message ScrollTreeData { - optional int64 currently_scrolling_node_id = 1; - repeated ScrollOffsetMapEntry layer_id_to_scroll_offset_map = 2; -} - -// Proto for data members of class TransformTree. -message TransformTreeData { - optional bool source_to_parent_updates_allowed = 1; - optional float page_scale_factor = 2; - optional float device_scale_factor = 3; - optional float device_transform_scale_factor = 4; - repeated int64 nodes_affected_by_inner_viewport_bounds_delta = 7 - [packed = true]; - repeated int64 nodes_affected_by_outer_viewport_bounds_delta = 8 - [packed = true]; - repeated TransformCachedNodeData cached_data = 9; - repeated StickyPositionNodeData sticky_position_data = 10; -} - -// Proto for data members of class EffectTree. -message EffectTreeData { - repeated int64 mask_layer_ids = 1 [packed = true]; -} - -// Proto for class PropertyTrees. -// NEXT ID: 17 -message PropertyTrees { - optional PropertyTree transform_tree = 1; - optional PropertyTree effect_tree = 2; - optional PropertyTree clip_tree = 3; - optional PropertyTree scroll_tree = 7; - - optional bool needs_rebuild = 4; - optional bool non_root_surfaces_enabled = 5; - optional bool changed = 11; - optional bool full_tree_damaged = 12; - optional int64 sequence_number = 6; - optional bool is_main_thread = 13; - optional bool is_active = 14; - optional bool verify_transform_tree_calculations = 16; - - optional Vector2dF inner_viewport_container_bounds_delta = 8; - optional Vector2dF outer_viewport_container_bounds_delta = 9; - optional Vector2dF inner_viewport_scroll_bounds_delta = 10; - repeated int64 always_use_active_tree_opacity_effect_ids = 15 [packed = true]; -} diff --git a/chromium/cc/proto/recording_source.proto b/chromium/cc/proto/recording_source.proto deleted file mode 100644 index a4954f6cb56..00000000000 --- a/chromium/cc/proto/recording_source.proto +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright 2015 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. - -syntax = "proto2"; - -import "size.proto"; - -option optimize_for = LITE_RUNTIME; - -package cc.proto; - -// A serialized representation of the RecordingSource class. -message RecordingSource { - optional Size size = 1; - optional int64 slow_down_raster_scale_factor_for_debug = 2; - optional bool generate_discardable_images_metadata = 3; - optional bool requires_clear = 4; - optional bool is_solid_color = 5; - optional bool clear_canvas_with_debug_color = 6; - optional uint64 solid_color = 7; - optional uint64 background_color = 8; -} diff --git a/chromium/cc/proto/region.proto b/chromium/cc/proto/region.proto index a4d235be3c5..0524e921ada 100644 --- a/chromium/cc/proto/region.proto +++ b/chromium/cc/proto/region.proto @@ -12,4 +12,4 @@ package cc.proto; message Region { repeated Rect rects = 1; -} +}
\ No newline at end of file diff --git a/chromium/cc/proto/renderer_settings.proto b/chromium/cc/proto/renderer_settings.proto deleted file mode 100644 index 4809c3ed99a..00000000000 --- a/chromium/cc/proto/renderer_settings.proto +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2015 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. - -syntax = "proto2"; - -package cc.proto; - -option optimize_for = LITE_RUNTIME; - -message BufferToTextureTarget { - optional uint32 buffer_usage = 1; - optional uint32 buffer_format = 2; - optional uint32 texture_target = 3; -}; - -message RendererSettings { - optional bool allow_antialiasing = 1; - optional bool force_antialiasing = 2; - optional bool force_blending_with_shaders = 3; - optional bool partial_swap_enabled = 4; - optional bool finish_rendering_on_resize = 5; - optional bool should_clear_root_render_pass = 6; - optional bool disable_display_vsync = 7; - optional bool release_overlay_resources_after_gpu_query = 8; - optional double refresh_rate = 9; - optional uint32 highp_threshold_min = 10; - optional uint32 texture_id_allocation_chunk_size = 11; - optional bool use_gpu_memory_buffer_resources = 12; - optional uint32 preferred_tile_format = 13; - repeated BufferToTextureTarget buffer_to_texture_target = 14; -} diff --git a/chromium/cc/proto/synced_property.proto b/chromium/cc/proto/synced_property.proto deleted file mode 100644 index 5b8658f3411..00000000000 --- a/chromium/cc/proto/synced_property.proto +++ /dev/null @@ -1,29 +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. - -syntax = "proto2"; - -import "scroll_offset.proto"; - -option optimize_for = LITE_RUNTIME; - -package cc.proto; - -// Since plumbing SyncedScrollOffset is only used by PropertyTree, and can only -// travel from main thread to impl thread one way, the From/To protobuf function -// for SyncedProperty only needs to care the current base, because main thread -// does not have pending/active tree or scroll offset deltas. -message ScrollOffsetGroup { - optional ScrollOffset pending_base = 1; - optional ScrollOffset pending_delta = 2; - optional ScrollOffset active_base = 3; - optional ScrollOffset active_delta = 4; - optional ScrollOffset sent_delta = 5; -} - -message SyncedProperty { - optional bool clobber_active_value = 1; - - optional ScrollOffsetGroup scroll_offset_group = 1001; -} diff --git a/chromium/cc/proto/synced_property_conversions.cc b/chromium/cc/proto/synced_property_conversions.cc deleted file mode 100644 index 09c8be26777..00000000000 --- a/chromium/cc/proto/synced_property_conversions.cc +++ /dev/null @@ -1,26 +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/proto/synced_property_conversions.h" - -#include "cc/proto/gfx_conversions.h" -#include "cc/proto/synced_property.pb.h" - -namespace cc { - -void SyncedScrollOffsetToProto(const SyncedScrollOffset& synced_scroll_offset, - proto::SyncedProperty* proto) { - proto::ScrollOffsetGroup* data = proto->mutable_scroll_offset_group(); - ScrollOffsetToProto(synced_scroll_offset.PendingBase(), - data->mutable_pending_base()); -} - -void ProtoToSyncedScrollOffset(const proto::SyncedProperty& proto, - SyncedScrollOffset* synced_scroll_offset) { - const proto::ScrollOffsetGroup& data = proto.scroll_offset_group(); - synced_scroll_offset->PushFromMainThread( - ProtoToScrollOffset(data.pending_base())); -} - -} // namespace cc diff --git a/chromium/cc/proto/synced_property_conversions.h b/chromium/cc/proto/synced_property_conversions.h deleted file mode 100644 index 7f3c62308ea..00000000000 --- a/chromium/cc/proto/synced_property_conversions.h +++ /dev/null @@ -1,26 +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_PROTO_SYNCED_PROPERTY_CONVERSIONS_H_ -#define CC_PROTO_SYNCED_PROPERTY_CONVERSIONS_H_ - -#include "cc/base/cc_export.h" -#include "cc/trees/property_tree.h" - -namespace cc { - -namespace proto { -class SyncedProperty; -} // namespace proto - -CC_EXPORT void SyncedScrollOffsetToProto( - const SyncedScrollOffset& synced_scroll_offset, - proto::SyncedProperty* proto); -CC_EXPORT void ProtoToSyncedScrollOffset( - const proto::SyncedProperty& proto, - SyncedScrollOffset* synced_scroll_offset); - -} // namespace cc - -#endif // CC_PROTO_SYNCED_PROPERTY_CONVERSIONS_H_ diff --git a/chromium/cc/proto/synced_property_conversions_unittest.cc b/chromium/cc/proto/synced_property_conversions_unittest.cc deleted file mode 100644 index bf2a4fde42a..00000000000 --- a/chromium/cc/proto/synced_property_conversions_unittest.cc +++ /dev/null @@ -1,30 +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/proto/synced_property_conversions.h" - -#include "cc/proto/synced_property.pb.h" -#include "cc/trees/property_tree.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -TEST(SyncedPropertyConversionTest, SerializeDeserializeSyncedScrollOffset) { - scoped_refptr<SyncedScrollOffset> synced_scroll_offset = - new SyncedScrollOffset(); - synced_scroll_offset->PushFromMainThread(gfx::ScrollOffset(1, 2)); - proto::SyncedProperty proto; - scoped_refptr<SyncedScrollOffset> serialized_synced_scroll_offset = - new SyncedScrollOffset(); - SyncedScrollOffsetToProto(*synced_scroll_offset.get(), &proto); - ProtoToSyncedScrollOffset(proto, serialized_synced_scroll_offset.get()); - EXPECT_EQ(synced_scroll_offset.get()->PendingBase(), - serialized_synced_scroll_offset.get()->PendingBase()); - EXPECT_EQ(synced_scroll_offset.get()->PendingBase(), - serialized_synced_scroll_offset.get()->PendingBase()); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/quads/draw_polygon.cc b/chromium/cc/quads/draw_polygon.cc index 86cb8731942..59ecbef0edb 100644 --- a/chromium/cc/quads/draw_polygon.cc +++ b/chromium/cc/quads/draw_polygon.cc @@ -237,10 +237,6 @@ void DrawPolygon::SplitPolygon(std::unique_ptr<DrawPolygon> polygon, return; } - // There should be at most two points that are considered to be on the thick - // plane. If this is not the case, then the polygon is not convex. - DCHECK_LE(num_points - pos_count - neg_count, 2u); - // Handle splitting case. size_t front_begin; size_t back_begin; diff --git a/chromium/cc/quads/draw_polygon.h b/chromium/cc/quads/draw_polygon.h index 2dc642cde31..8c89e599334 100644 --- a/chromium/cc/quads/draw_polygon.h +++ b/chromium/cc/quads/draw_polygon.h @@ -56,7 +56,10 @@ class CC_EXPORT DrawPolygon { bool is_split() const { return is_split_; } std::unique_ptr<DrawPolygon> CreateCopy(); + // These are helper functions for testing. void RecomputeNormalForTesting(); + friend bool IsPlanarForTesting(const DrawPolygon& p); + friend bool IsConvexForTesting(const DrawPolygon& p); private: void ApplyTransform(const gfx::Transform& transform); diff --git a/chromium/cc/quads/draw_polygon_unittest.cc b/chromium/cc/quads/draw_polygon_unittest.cc index fcdff70ff07..847a25dcedb 100644 --- a/chromium/cc/quads/draw_polygon_unittest.cc +++ b/chromium/cc/quads/draw_polygon_unittest.cc @@ -26,6 +26,45 @@ void DrawPolygon::RecomputeNormalForTesting() { } #endif +static int sign(float v) { + static const float epsilon = 0.00001f; + + if (v > epsilon) + return 1; + if (v < -epsilon) + return -1; + return 0; +} + +bool IsPlanarForTesting(const DrawPolygon& p) { + static const float epsilon = 0.00001f; + for (size_t i = 1; i < p.points_.size(); i++) { + if (gfx::DotProduct(p.points_[i] - p.points_[0], p.normal_) > epsilon) + return false; + } + return true; +} + +bool IsConvexForTesting(const DrawPolygon& p) { + if (p.points_.size() < 3) + return true; + + gfx::Vector3dF prev = + p.points_[p.points_.size() - 1] - p.points_[p.points_.size() - 2]; + gfx::Vector3dF next = p.points_[0] - p.points_[p.points_.size() - 1]; + int ccw = sign(gfx::DotProduct(CrossProduct(prev, next), p.normal_)); + for (size_t i = 1; i < p.points_.size(); i++) { + prev = next; + next = p.points_[i] - p.points_[i - 1]; + int next_sign = sign(gfx::DotProduct(CrossProduct(prev, next), p.normal_)); + if (ccw == 0) + ccw = next_sign; + if (next_sign != 0 && next_sign != ccw) + return false; + } + return true; +} + namespace { #define CREATE_NEW_DRAW_POLYGON(name, points_vector, normal, polygon_id) \ @@ -320,6 +359,44 @@ TEST(DrawPolygonSplitTest, BarelyTouchingNoSplit) { EXPECT_NE(back, nullptr); } +// One quad intersects a pent with an occluded side. +TEST(DrawPolygonSplitTest, SlimClip) { + std::vector<gfx::Point3F> vertices_a; + vertices_a.push_back(gfx::Point3F(0.0f, 10.0f, 0.0f)); + vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); + vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); + vertices_a.push_back(gfx::Point3F(10.0f, 10.0f, 0.0f)); + std::vector<gfx::Point3F> vertices_b; + vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, 5.000f)); + vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.001f)); + vertices_b.push_back(gfx::Point3F(1.0f, 1.0f, 0.000f)); + vertices_b.push_back(gfx::Point3F(1.002f, 1.002f, -0.005f)); + vertices_b.push_back(gfx::Point3F(9.0f, 9.0f, -4.000f)); + + CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a, + gfx::Vector3dF(0.0f, 0.0f, 1.0f), 0); + CREATE_NEW_DRAW_POLYGON_PTR( + polygon_b, vertices_b, + gfx::Vector3dF(sqrt(2) / 2, -sqrt(2) / 2, 0.000000), 1); + + // These are well formed, convex polygons. + EXPECT_TRUE(IsPlanarForTesting(*(polygon_a.get()))); + EXPECT_TRUE(IsConvexForTesting(*(polygon_a.get()))); + EXPECT_TRUE(IsPlanarForTesting(*(polygon_b.get()))); + EXPECT_TRUE(IsConvexForTesting(*(polygon_b.get()))); + + std::unique_ptr<DrawPolygon> front_polygon; + std::unique_ptr<DrawPolygon> back_polygon; + bool is_coplanar; + + polygon_a->SplitPolygon(std::move(polygon_b), &front_polygon, &back_polygon, + &is_coplanar); + + EXPECT_FALSE(is_coplanar); + EXPECT_TRUE(front_polygon != nullptr); + EXPECT_TRUE(back_polygon != nullptr); +} + // One quad intersects another and becomes two pieces. TEST(DrawPolygonSplitTest, BasicSplit) { std::vector<gfx::Point3F> vertices_a; @@ -409,6 +486,60 @@ TEST(DrawPolygonSplitTest, AngledSplit) { ValidatePointsWithinDeltaOf(*(back_polygon.get()), test_points_b, 1e-6f); } +// In this test we cut the corner of a quad so that it creates a triangle and +// a pentagon as a result, and then cut the pentagon. +TEST(DrawPolygonSplitTest, DoubleSplit) { + std::vector<gfx::Point3F> vertices_a; + vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 0.0f)); + vertices_a.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); + vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 10.0f)); + vertices_a.push_back(gfx::Point3F(10.0f, 0.0f, 0.0f)); + std::vector<gfx::Point3F> vertices_b; + vertices_b.push_back(gfx::Point3F(2.0f, 5.0f, 1.0f)); + vertices_b.push_back(gfx::Point3F(2.0f, -5.0f, 1.0f)); + vertices_b.push_back(gfx::Point3F(-1.0f, -5.0f, -2.0f)); + vertices_b.push_back(gfx::Point3F(-1.0f, 5.0f, -2.0f)); + + CREATE_NEW_DRAW_POLYGON_PTR(polygon_a, vertices_a, + gfx::Vector3dF(0.0f, 1.0f, 0.0f), 0); + CREATE_NEW_DRAW_POLYGON_PTR(polygon_b, vertices_b, + gfx::Vector3dF(sqrt(2) / 2, 0.0f, -sqrt(2) / 2), + 1); + + std::unique_ptr<DrawPolygon> front_polygon; + std::unique_ptr<DrawPolygon> back_polygon; + bool is_coplanar; + + polygon_b->SplitPolygon(std::move(polygon_a), &front_polygon, &back_polygon, + &is_coplanar); + EXPECT_FALSE(is_coplanar); + EXPECT_TRUE(front_polygon != nullptr); + EXPECT_TRUE(back_polygon != nullptr); + + EXPECT_EQ(3u, front_polygon->points().size()); + EXPECT_EQ(5u, back_polygon->points().size()); + + std::vector<gfx::Point3F> vertices_c; + vertices_c.push_back(gfx::Point3F(0.0f, 0.0f, 10.0f)); + vertices_c.push_back(gfx::Point3F(1.0f, -0.05f, 0.0f)); + vertices_c.push_back(gfx::Point3F(10.0f, 0.05f, 9.0f)); + + CREATE_NEW_DRAW_POLYGON_PTR(polygon_c, vertices_c, + gfx::Vector3dF(0.0055f, -0.999f, 0.0055f), 0); + + std::unique_ptr<DrawPolygon> second_front_polygon; + std::unique_ptr<DrawPolygon> second_back_polygon; + + polygon_c->SplitPolygon(std::move(back_polygon), &second_front_polygon, + &second_back_polygon, &is_coplanar); + EXPECT_FALSE(is_coplanar); + EXPECT_TRUE(second_front_polygon != nullptr); + EXPECT_TRUE(second_back_polygon != nullptr); + + EXPECT_EQ(3u, second_front_polygon->points().size()); + EXPECT_EQ(3u, second_back_polygon->points().size()); +} + TEST(DrawPolygonTransformTest, TransformNormal) { std::vector<gfx::Point3F> vertices_a; vertices_a.push_back(gfx::Point3F(1.0f, 0.0f, 1.0f)); diff --git a/chromium/cc/quads/draw_quad.h b/chromium/cc/quads/draw_quad.h index 854980d2f0a..4a72e994106 100644 --- a/chromium/cc/quads/draw_quad.h +++ b/chromium/cc/quads/draw_quad.h @@ -16,8 +16,6 @@ namespace base { namespace trace_event { class TracedValue; } -class Value; -class DictionaryValue; } namespace cc { diff --git a/chromium/cc/quads/draw_quad_unittest.cc b/chromium/cc/quads/draw_quad_unittest.cc index e91fb073714..6ff69a76b04 100644 --- a/chromium/cc/quads/draw_quad_unittest.cc +++ b/chromium/cc/quads/draw_quad_unittest.cc @@ -524,7 +524,8 @@ TEST(DrawQuadTest, CopyStreamVideoDrawQuad) { TEST(DrawQuadTest, CopySurfaceDrawQuad) { gfx::Rect visible_rect(40, 50, 30, 20); - SurfaceId surface_id(kArbitraryFrameSinkId, LocalFrameId(1234, 0)); + SurfaceId surface_id(kArbitraryFrameSinkId, + LocalFrameId(1234, base::UnguessableToken::Create())); CREATE_SHARED_STATE(); CREATE_QUAD_2_NEW(SurfaceDrawQuad, visible_rect, surface_id); @@ -813,7 +814,8 @@ TEST_F(DrawQuadIteratorTest, StreamVideoDrawQuad) { TEST_F(DrawQuadIteratorTest, SurfaceDrawQuad) { gfx::Rect visible_rect(40, 50, 30, 20); - SurfaceId surface_id(kArbitraryFrameSinkId, LocalFrameId(4321, 0)); + SurfaceId surface_id(kArbitraryFrameSinkId, + LocalFrameId(4321, base::UnguessableToken::Create())); CREATE_SHARED_STATE(); CREATE_QUAD_2_NEW(SurfaceDrawQuad, visible_rect, surface_id); diff --git a/chromium/cc/quads/render_pass.h b/chromium/cc/quads/render_pass.h index a82e9d86662..7859ac323ae 100644 --- a/chromium/cc/quads/render_pass.h +++ b/chromium/cc/quads/render_pass.h @@ -28,7 +28,6 @@ namespace base { namespace trace_event { class TracedValue; } -class Value; } namespace cc { diff --git a/chromium/cc/quads/shared_quad_state.h b/chromium/cc/quads/shared_quad_state.h index 75f603fe6a6..35ad110935a 100644 --- a/chromium/cc/quads/shared_quad_state.h +++ b/chromium/cc/quads/shared_quad_state.h @@ -16,7 +16,6 @@ namespace base { namespace trace_event { class TracedValue; } -class Value; } namespace cc { diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc index 7ed1334f69c..f0a7126190a 100644 --- a/chromium/cc/raster/bitmap_raster_buffer_provider.cc +++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc @@ -40,7 +40,7 @@ class RasterBufferImpl : public RasterBuffer { const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) override { TRACE_EVENT0("cc", "BitmapRasterBuffer::Playback"); gfx::Rect playback_rect = raster_full_rect; @@ -53,7 +53,7 @@ class RasterBufferImpl : public RasterBuffer { size_t stride = 0u; RasterBufferProvider::PlaybackToMemory( lock_.sk_bitmap().getPixels(), resource_->format(), resource_->size(), - stride, raster_source, raster_full_rect, playback_rect, scale, + stride, raster_source, raster_full_rect, playback_rect, scales, lock_.sk_color_space(), playback_settings); } diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc index 85a77c201b3..343ebd0b4f8 100644 --- a/chromium/cc/raster/gpu_raster_buffer_provider.cc +++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc @@ -32,7 +32,7 @@ static sk_sp<SkPicture> PlaybackToPicture( const gfx::Size& resource_size, const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) { // GPU raster doesn't do low res tiles, so should always include images. DCHECK(!playback_settings.skip_images); @@ -74,7 +74,7 @@ static sk_sp<SkPicture> PlaybackToPicture( RasterSource::PlaybackSettings settings = playback_settings; settings.use_image_hijack_canvas = false; raster_source->PlaybackToCanvas(canvas.get(), raster_full_rect, playback_rect, - scale, settings); + scales, settings); canvas->restore(); return recorder.finishRecordingAsPicture(); } @@ -146,13 +146,13 @@ void GpuRasterBufferProvider::RasterBufferImpl::Playback( const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) { TRACE_EVENT0("cc", "GpuRasterBuffer::Playback"); client_->PlaybackOnWorkerThread(&lock_, sync_token_, resource_has_previous_content_, raster_source, raster_full_rect, raster_dirty_rect, - new_content_id, scale, playback_settings); + new_content_id, scales, playback_settings); } GpuRasterBufferProvider::GpuRasterBufferProvider( @@ -244,7 +244,7 @@ void GpuRasterBufferProvider::PlaybackOnWorkerThread( const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) { ContextProvider::ScopedContextLock scoped_context(worker_context_provider_); gpu::gles2::GLES2Interface* gl = scoped_context.ContextGL(); @@ -261,15 +261,10 @@ void GpuRasterBufferProvider::PlaybackOnWorkerThread( sk_sp<SkPicture> picture = PlaybackToPicture( raster_source, resource_has_previous_content, resource_lock->size(), - raster_full_rect, raster_dirty_rect, scale, playback_settings); - - // Turn on distance fields for layers that have ever animated. - bool use_distance_field_text = - use_distance_field_text_ || - raster_source->ShouldAttemptToUseDistanceFieldText(); + raster_full_rect, raster_dirty_rect, scales, playback_settings); RasterizePicture(picture.get(), worker_context_provider_, resource_lock, - async_worker_context_enabled_, use_distance_field_text, + async_worker_context_enabled_, use_distance_field_text_, raster_source->CanUseLCDText(), msaa_sample_count_, raster_source->image_decode_controller(), playback_settings.use_image_hijack_canvas); diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.h b/chromium/cc/raster/gpu_raster_buffer_provider.h index 0df055b2d55..7c674d37f9d 100644 --- a/chromium/cc/raster/gpu_raster_buffer_provider.h +++ b/chromium/cc/raster/gpu_raster_buffer_provider.h @@ -45,7 +45,7 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider { const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings); private: @@ -64,7 +64,7 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider { const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) override; void set_sync_token(const gpu::SyncToken& sync_token) { diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc index 08a2cc4221a..3d3a44ca8e7 100644 --- a/chromium/cc/raster/one_copy_raster_buffer_provider.cc +++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc @@ -55,12 +55,12 @@ void OneCopyRasterBufferProvider::RasterBufferImpl::Playback( const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) { TRACE_EVENT0("cc", "OneCopyRasterBuffer::Playback"); client_->PlaybackAndCopyOnWorkerThread( resource_, &lock_, sync_token_, raster_source, raster_full_rect, - raster_dirty_rect, scale, playback_settings, previous_content_id_, + raster_dirty_rect, scales, playback_settings, previous_content_id_, new_content_id); } @@ -173,7 +173,7 @@ void OneCopyRasterBufferProvider::PlaybackAndCopyOnWorkerThread( const RasterSource* raster_source, const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings, uint64_t previous_content_id, uint64_t new_content_id) { @@ -193,7 +193,7 @@ void OneCopyRasterBufferProvider::PlaybackAndCopyOnWorkerThread( staging_pool_.AcquireStagingBuffer(resource, previous_content_id); PlaybackToStagingBuffer(staging_buffer.get(), resource, raster_source, - raster_full_rect, raster_dirty_rect, scale, + raster_full_rect, raster_dirty_rect, scales, resource_lock->sk_color_space(), playback_settings, previous_content_id, new_content_id); @@ -209,7 +209,7 @@ void OneCopyRasterBufferProvider::PlaybackToStagingBuffer( const RasterSource* raster_source, const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, - float scale, + const gfx::SizeF& scales, sk_sp<SkColorSpace> dst_color_space, const RasterSource::PlaybackSettings& playback_settings, uint64_t previous_content_id, @@ -260,7 +260,7 @@ void OneCopyRasterBufferProvider::PlaybackToStagingBuffer( RasterBufferProvider::PlaybackToMemory( buffer->memory(0), resource->format(), staging_buffer->size, buffer->stride(0), raster_source, raster_full_rect, playback_rect, - scale, dst_color_space, playback_settings); + scales, dst_color_space, playback_settings); buffer->Unmap(); staging_buffer->content_id = new_content_id; } diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.h b/chromium/cc/raster/one_copy_raster_buffer_provider.h index b32a101f5fb..513c393fd5b 100644 --- a/chromium/cc/raster/one_copy_raster_buffer_provider.h +++ b/chromium/cc/raster/one_copy_raster_buffer_provider.h @@ -17,7 +17,6 @@ namespace cc { struct StagingBuffer; class StagingBufferPool; -class ResourcePool; class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider { public: @@ -52,7 +51,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider { const RasterSource* raster_source, const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings, uint64_t previous_content_id, uint64_t new_content_id); @@ -73,7 +72,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider { const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) override; void set_sync_token(const gpu::SyncToken& sync_token) { @@ -97,7 +96,7 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider { const RasterSource* raster_source, const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, - float scale, + const gfx::SizeF& scales, sk_sp<SkColorSpace> dst_color_space, const RasterSource::PlaybackSettings& playback_settings, uint64_t previous_content_id, diff --git a/chromium/cc/raster/raster_buffer.h b/chromium/cc/raster/raster_buffer.h index 04972f9d73e..688053b2b1f 100644 --- a/chromium/cc/raster/raster_buffer.h +++ b/chromium/cc/raster/raster_buffer.h @@ -23,7 +23,7 @@ class CC_EXPORT RasterBuffer { const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) = 0; }; diff --git a/chromium/cc/raster/raster_buffer_provider.cc b/chromium/cc/raster/raster_buffer_provider.cc index d34fe6e0a52..587a39ba0b1 100644 --- a/chromium/cc/raster/raster_buffer_provider.cc +++ b/chromium/cc/raster/raster_buffer_provider.cc @@ -51,10 +51,10 @@ void RasterBufferProvider::PlaybackToMemory( const RasterSource* raster_source, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, - float scale, + const gfx::SizeF& scales, sk_sp<SkColorSpace> dst_color_space, const RasterSource::PlaybackSettings& playback_settings) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "RasterBufferProvider::PlaybackToMemory"); DCHECK(IsSupportedPlaybackToMemoryFormat(format)) << format; @@ -80,7 +80,7 @@ void RasterBufferProvider::PlaybackToMemory( sk_sp<SkSurface> surface = SkSurface::MakeRasterDirect(info, memory, stride, &surface_props); raster_source->PlaybackToCanvas(surface->getCanvas(), canvas_bitmap_rect, - canvas_playback_rect, scale, + canvas_playback_rect, scales, playback_settings); return; } @@ -90,7 +90,7 @@ void RasterBufferProvider::PlaybackToMemory( // TODO(reveman): Improve partial raster support by reducing the size of // playback rect passed to PlaybackToCanvas. crbug.com/519070 raster_source->PlaybackToCanvas(surface->getCanvas(), canvas_bitmap_rect, - canvas_bitmap_rect, scale, + canvas_bitmap_rect, scales, playback_settings); if (format == ETC1) { diff --git a/chromium/cc/raster/raster_buffer_provider.h b/chromium/cc/raster/raster_buffer_provider.h index 5f2d0bd0491..8c3b6447367 100644 --- a/chromium/cc/raster/raster_buffer_provider.h +++ b/chromium/cc/raster/raster_buffer_provider.h @@ -15,10 +15,6 @@ #include "ui/gfx/geometry/rect.h" #include "ui/gfx/geometry/size.h" -namespace base { -class SequencedTaskRunner; -} - namespace cc { class Resource; @@ -41,7 +37,7 @@ class CC_EXPORT RasterBufferProvider { const RasterSource* raster_source, const gfx::Rect& canvas_bitmap_rect, const gfx::Rect& canvas_playback_rect, - float scale, + const gfx::SizeF& scales, sk_sp<SkColorSpace> color_space, const RasterSource::PlaybackSettings& playback_settings); diff --git a/chromium/cc/raster/raster_buffer_provider_unittest.cc b/chromium/cc/raster/raster_buffer_provider_unittest.cc index 3b8668d85ff..a88674e9864 100644 --- a/chromium/cc/raster/raster_buffer_provider_unittest.cc +++ b/chromium/cc/raster/raster_buffer_provider_unittest.cc @@ -82,7 +82,8 @@ class TestRasterTaskImpl : public TileTask { uint64_t new_content_id = 0; raster_buffer_->Playback(raster_source_.get(), gfx::Rect(1, 1), - gfx::Rect(1, 1), new_content_id, 1.f, settings); + gfx::Rect(1, 1), new_content_id, + gfx::SizeF(1.f, 1.f), settings); } // Overridden from TileTask: diff --git a/chromium/cc/raster/single_thread_task_graph_runner.cc b/chromium/cc/raster/single_thread_task_graph_runner.cc index fdabe85d35a..1bc184225a3 100644 --- a/chromium/cc/raster/single_thread_task_graph_runner.cc +++ b/chromium/cc/raster/single_thread_task_graph_runner.cc @@ -46,9 +46,9 @@ void SingleThreadTaskGraphRunner::Shutdown() { thread_->Join(); } -NamespaceToken SingleThreadTaskGraphRunner::GetNamespaceToken() { +NamespaceToken SingleThreadTaskGraphRunner::GenerateNamespaceToken() { base::AutoLock lock(lock_); - return work_queue_.GetNamespaceToken(); + return work_queue_.GenerateNamespaceToken(); } void SingleThreadTaskGraphRunner::ScheduleTasks(NamespaceToken token, diff --git a/chromium/cc/raster/single_thread_task_graph_runner.h b/chromium/cc/raster/single_thread_task_graph_runner.h index a8609cb25c0..923c78983f2 100644 --- a/chromium/cc/raster/single_thread_task_graph_runner.h +++ b/chromium/cc/raster/single_thread_task_graph_runner.h @@ -27,7 +27,7 @@ class CC_EXPORT SingleThreadTaskGraphRunner ~SingleThreadTaskGraphRunner() override; // Overridden from TaskGraphRunner: - NamespaceToken GetNamespaceToken() override; + NamespaceToken GenerateNamespaceToken() override; void ScheduleTasks(NamespaceToken token, TaskGraph* graph) override; void WaitForTasksToFinishRunning(NamespaceToken token) override; void CollectCompletedTasks(NamespaceToken token, diff --git a/chromium/cc/raster/staging_buffer_pool.cc b/chromium/cc/raster/staging_buffer_pool.cc index 0e2a88a14a7..ef78e4d317e 100644 --- a/chromium/cc/raster/staging_buffer_pool.cc +++ b/chromium/cc/raster/staging_buffer_pool.cc @@ -17,6 +17,10 @@ #include "gpu/command_buffer/client/gles2_interface.h" #include "ui/gfx/gpu_memory_buffer_tracing.h" +using base::trace_event::MemoryAllocatorDump; +using base::trace_event::MemoryAllocatorDumpGuid; +using base::trace_event::MemoryDumpLevelOfDetail; + namespace cc { namespace { @@ -96,23 +100,21 @@ void StagingBuffer::OnMemoryDump(base::trace_event::ProcessMemoryDump* pmd, gfx::GpuMemoryBufferId buffer_id = gpu_memory_buffer->GetId(); std::string buffer_dump_name = base::StringPrintf("cc/one_copy/staging_memory/buffer_%d", buffer_id.id); - base::trace_event::MemoryAllocatorDump* buffer_dump = - pmd->CreateAllocatorDump(buffer_dump_name); + MemoryAllocatorDump* buffer_dump = pmd->CreateAllocatorDump(buffer_dump_name); uint64_t buffer_size_in_bytes = ResourceUtil::UncheckedSizeInBytes<uint64_t>(size, format); - buffer_dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, - base::trace_event::MemoryAllocatorDump::kUnitsBytes, + buffer_dump->AddScalar(MemoryAllocatorDump::kNameSize, + MemoryAllocatorDump::kUnitsBytes, buffer_size_in_bytes); - buffer_dump->AddScalar("free_size", - base::trace_event::MemoryAllocatorDump::kUnitsBytes, + buffer_dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, in_free_list ? buffer_size_in_bytes : 0); // Emit an ownership edge towards a global allocator dump node. const uint64_t tracing_process_id = base::trace_event::MemoryDumpManager::GetInstance() ->GetTracingProcessId(); - base::trace_event::MemoryAllocatorDumpGuid shared_buffer_guid = + MemoryAllocatorDumpGuid shared_buffer_guid = gfx::GetGpuMemoryBufferGUIDForTracing(tracing_process_id, buffer_id); pmd->CreateSharedGlobalAllocatorDump(shared_buffer_guid); @@ -187,16 +189,23 @@ bool StagingBufferPool::OnMemoryDump( base::trace_event::ProcessMemoryDump* pmd) { base::AutoLock lock(lock_); - for (const auto* buffer : buffers_) { - auto in_free_buffers = - std::find_if(free_buffers_.begin(), free_buffers_.end(), - [buffer](const std::unique_ptr<StagingBuffer>& b) { - return b.get() == buffer; - }); - buffer->OnMemoryDump(pmd, buffer->format, - in_free_buffers != free_buffers_.end()); + if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { + std::string dump_name("cc/one_copy/staging_memory"); + MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name); + dump->AddScalar(MemoryAllocatorDump::kNameSize, + MemoryAllocatorDump::kUnitsBytes, + staging_buffer_usage_in_bytes_); + } else { + for (const auto* buffer : buffers_) { + auto in_free_buffers = + std::find_if(free_buffers_.begin(), free_buffers_.end(), + [buffer](const std::unique_ptr<StagingBuffer>& b) { + return b.get() == buffer; + }); + buffer->OnMemoryDump(pmd, buffer->format, + in_free_buffers != free_buffers_.end()); + } } - return true; } diff --git a/chromium/cc/raster/staging_buffer_pool.h b/chromium/cc/raster/staging_buffer_pool.h index 7ac3ef1af01..528d0315448 100644 --- a/chromium/cc/raster/staging_buffer_pool.h +++ b/chromium/cc/raster/staging_buffer_pool.h @@ -29,8 +29,6 @@ class GLES2Interface; namespace cc { class Resource; -class RasterSource; -class ResourcePool; struct StagingBuffer { StagingBuffer(const gfx::Size& size, ResourceFormat format); diff --git a/chromium/cc/raster/synchronous_task_graph_runner.cc b/chromium/cc/raster/synchronous_task_graph_runner.cc index fe9f5f8e1a7..f9c0a65b24e 100644 --- a/chromium/cc/raster/synchronous_task_graph_runner.cc +++ b/chromium/cc/raster/synchronous_task_graph_runner.cc @@ -21,8 +21,8 @@ SynchronousTaskGraphRunner::~SynchronousTaskGraphRunner() { DCHECK(!work_queue_.HasReadyToRunTasks()); } -NamespaceToken SynchronousTaskGraphRunner::GetNamespaceToken() { - return work_queue_.GetNamespaceToken(); +NamespaceToken SynchronousTaskGraphRunner::GenerateNamespaceToken() { + return work_queue_.GenerateNamespaceToken(); } void SynchronousTaskGraphRunner::ScheduleTasks(NamespaceToken token, diff --git a/chromium/cc/raster/synchronous_task_graph_runner.h b/chromium/cc/raster/synchronous_task_graph_runner.h index 720c435cdff..2cb65ce4cea 100644 --- a/chromium/cc/raster/synchronous_task_graph_runner.h +++ b/chromium/cc/raster/synchronous_task_graph_runner.h @@ -18,7 +18,7 @@ class CC_EXPORT SynchronousTaskGraphRunner : public TaskGraphRunner { ~SynchronousTaskGraphRunner() override; // Overridden from TaskGraphRunner: - NamespaceToken GetNamespaceToken() override; + NamespaceToken GenerateNamespaceToken() override; void ScheduleTasks(NamespaceToken token, TaskGraph* graph) override; void WaitForTasksToFinishRunning(NamespaceToken token) override; void CollectCompletedTasks(NamespaceToken token, diff --git a/chromium/cc/raster/task_graph_runner.h b/chromium/cc/raster/task_graph_runner.h index 112124797ca..d5e0d90f786 100644 --- a/chromium/cc/raster/task_graph_runner.h +++ b/chromium/cc/raster/task_graph_runner.h @@ -73,7 +73,7 @@ class CC_EXPORT TaskGraphRunner { // Returns a unique token that can be used to pass a task graph to // ScheduleTasks(). Valid tokens are always nonzero. - virtual NamespaceToken GetNamespaceToken() = 0; + virtual NamespaceToken GenerateNamespaceToken() = 0; // Schedule running of tasks in |graph|. Tasks previously scheduled but no // longer needed will be canceled unless already running. Canceled tasks are diff --git a/chromium/cc/raster/task_graph_runner_perftest.cc b/chromium/cc/raster/task_graph_runner_perftest.cc index 5dcbdc031b6..a4b2af2a479 100644 --- a/chromium/cc/raster/task_graph_runner_perftest.cc +++ b/chromium/cc/raster/task_graph_runner_perftest.cc @@ -51,7 +51,7 @@ class TaskGraphRunnerPerfTest : public testing::Test { // Overridden from testing::Test: void SetUp() override { task_graph_runner_ = base::WrapUnique(new SynchronousTaskGraphRunner); - namespace_token_ = task_graph_runner_->GetNamespaceToken(); + namespace_token_ = task_graph_runner_->GenerateNamespaceToken(); } void TearDown() override { task_graph_runner_ = nullptr; } diff --git a/chromium/cc/raster/task_graph_work_queue.cc b/chromium/cc/raster/task_graph_work_queue.cc index 9d599fe781b..702b82d021a 100644 --- a/chromium/cc/raster/task_graph_work_queue.cc +++ b/chromium/cc/raster/task_graph_work_queue.cc @@ -125,7 +125,7 @@ TaskGraphWorkQueue::PrioritizedTask::PrioritizedTask(PrioritizedTask&& other) = default; TaskGraphWorkQueue::PrioritizedTask::~PrioritizedTask() = default; -NamespaceToken TaskGraphWorkQueue::GetNamespaceToken() { +NamespaceToken TaskGraphWorkQueue::GenerateNamespaceToken() { NamespaceToken token(next_namespace_id_++); DCHECK(namespaces_.find(token) == namespaces_.end()); return token; diff --git a/chromium/cc/raster/task_graph_work_queue.h b/chromium/cc/raster/task_graph_work_queue.h index 1596f35ef83..4842a575270 100644 --- a/chromium/cc/raster/task_graph_work_queue.h +++ b/chromium/cc/raster/task_graph_work_queue.h @@ -79,9 +79,9 @@ class CC_EXPORT TaskGraphWorkQueue { TaskGraphWorkQueue(); virtual ~TaskGraphWorkQueue(); - // Gets a NamespaceToken which is guaranteed to be unique within this + // Generates a NamespaceToken which is guaranteed to be unique within this // TaskGraphWorkQueue. - NamespaceToken GetNamespaceToken(); + NamespaceToken GenerateNamespaceToken(); // Updates a TaskNamespace with a new TaskGraph to run. This cancels any // previous tasks in the graph being replaced. diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc index b94c1fb69e6..d201acde265 100644 --- a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc +++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc @@ -34,7 +34,7 @@ class RasterBufferImpl : public RasterBuffer { const gfx::Rect& raster_full_rect, const gfx::Rect& raster_dirty_rect, uint64_t new_content_id, - float scale, + const gfx::SizeF& scales, const RasterSource::PlaybackSettings& playback_settings) override { TRACE_EVENT0("cc", "ZeroCopyRasterBuffer::Playback"); gfx::GpuMemoryBuffer* buffer = lock_.GetGpuMemoryBuffer(); @@ -52,7 +52,7 @@ class RasterBufferImpl : public RasterBuffer { RasterBufferProvider::PlaybackToMemory( buffer->memory(0), resource_->format(), resource_->size(), buffer->stride(0), raster_source, raster_full_rect, raster_full_rect, - scale, lock_.sk_color_space(), playback_settings); + scales, lock_.sk_color_space(), playback_settings); buffer->Unmap(); } diff --git a/chromium/cc/resources/resource.h b/chromium/cc/resources/resource.h index 20756423e07..7fd361f503d 100644 --- a/chromium/cc/resources/resource.h +++ b/chromium/cc/resources/resource.h @@ -24,7 +24,7 @@ class CC_EXPORT Resource { : id_(id), size_(size), format_(format), color_space_(color_space) {} ResourceId id() const { return id_; } - gfx::Size size() const { return size_; } + const gfx::Size& size() const { return size_; } ResourceFormat format() const { return format_; } const gfx::ColorSpace& color_space() const { return color_space_; } diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc index da33b11a96f..3fc3993aea2 100644 --- a/chromium/cc/resources/resource_pool.cc +++ b/chromium/cc/resources/resource_pool.cc @@ -20,6 +20,9 @@ #include "cc/resources/resource_util.h" #include "cc/resources/scoped_resource.h" +using base::trace_event::MemoryAllocatorDump; +using base::trace_event::MemoryDumpLevelOfDetail; + namespace cc { base::TimeDelta ResourcePool::kDefaultExpirationDelay = base::TimeDelta::FromSeconds(1); @@ -37,21 +40,16 @@ void ResourcePool::PoolResource::OnMemoryDump( std::string dump_name = base::StringPrintf("cc/tile_memory/provider_%d/resource_%d", resource_provider->tracing_id(), id()); - base::trace_event::MemoryAllocatorDump* dump = - pmd->CreateAllocatorDump(dump_name); - + MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name); pmd->AddSuballocation(dump->guid(), parent_node); uint64_t total_bytes = ResourceUtil::UncheckedSizeInBytesAligned<size_t>(size(), format()); - dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, - base::trace_event::MemoryAllocatorDump::kUnitsBytes, - total_bytes); + dump->AddScalar(MemoryAllocatorDump::kNameSize, + MemoryAllocatorDump::kUnitsBytes, total_bytes); if (is_free) { - dump->AddScalar("free_size", - base::trace_event::MemoryAllocatorDump::kUnitsBytes, - total_bytes); + dump->AddScalar("free_size", MemoryAllocatorDump::kUnitsBytes, total_bytes); } } @@ -447,14 +445,23 @@ base::TimeTicks ResourcePool::GetUsageTimeForLRUResource() const { bool ResourcePool::OnMemoryDump(const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) { - for (const auto& resource : unused_resources_) { - resource->OnMemoryDump(pmd, resource_provider_, true /* is_free */); - } - for (const auto& resource : busy_resources_) { - resource->OnMemoryDump(pmd, resource_provider_, false /* is_free */); - } - for (const auto& entry : in_use_resources_) { - entry.second->OnMemoryDump(pmd, resource_provider_, false /* is_free */); + if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { + std::string dump_name = base::StringPrintf( + "cc/tile_memory/provider_%d", resource_provider_->tracing_id()); + MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name); + dump->AddScalar(MemoryAllocatorDump::kNameSize, + MemoryAllocatorDump::kUnitsBytes, + total_memory_usage_bytes_); + } else { + for (const auto& resource : unused_resources_) { + resource->OnMemoryDump(pmd, resource_provider_, true /* is_free */); + } + for (const auto& resource : busy_resources_) { + resource->OnMemoryDump(pmd, resource_provider_, false /* is_free */); + } + for (const auto& entry : in_use_resources_) { + entry.second->OnMemoryDump(pmd, resource_provider_, false /* is_free */); + } } return true; } diff --git a/chromium/cc/resources/resource_pool.h b/chromium/cc/resources/resource_pool.h index a1bd9d696cb..c87d0453c40 100644 --- a/chromium/cc/resources/resource_pool.h +++ b/chromium/cc/resources/resource_pool.h @@ -71,8 +71,8 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider, void SetResourceUsageLimits(size_t max_memory_usage_bytes, size_t max_resource_count); - void ReduceResourceUsage(); + bool ResourceUsageTooHigh(); // Must be called regularly to move resources from the busy pool to the unused // pool. @@ -104,8 +104,6 @@ class CC_EXPORT ResourcePool : public base::trace_event::MemoryDumpProvider, bool use_gpu_memory_buffers, const base::TimeDelta& expiration_delay); - bool ResourceUsageTooHigh(); - private: FRIEND_TEST_ALL_PREFIXES(ResourcePoolTest, ReuseResource); class PoolResource : public ScopedResource { diff --git a/chromium/cc/resources/resource_provider.cc b/chromium/cc/resources/resource_provider.cc index 42eda06e3e5..18cabee1cab 100644 --- a/chromium/cc/resources/resource_provider.cc +++ b/chromium/cc/resources/resource_provider.cc @@ -1227,7 +1227,6 @@ ResourceProvider::ScopedReadLockSkImage::ScopedReadLockSkImage( texture_info.fID = resource->gl_id; texture_info.fTarget = resource->target; GrBackendTextureDesc desc; - desc.fFlags = kRenderTarget_GrBackendTextureFlag; desc.fWidth = resource->size.width(); desc.fHeight = resource->size.height(); desc.fConfig = ToGrPixelConfig(resource->format); diff --git a/chromium/cc/resources/resource_provider.h b/chromium/cc/resources/resource_provider.h index afabed7b8d8..458bd8da9ac 100644 --- a/chromium/cc/resources/resource_provider.h +++ b/chromium/cc/resources/resource_provider.h @@ -42,9 +42,6 @@ #include "ui/gfx/geometry/size.h" #include "ui/gfx/gpu_memory_buffer.h" -class GrContext; -class GrSurface; - namespace gpu { class GpuMemoryBufferManager; namespace gles { @@ -52,11 +49,6 @@ class GLES2Interface; } } -namespace gfx { -class Rect; -class Vector2d; -} - namespace cc { class BlockingTaskRunner; class IdAllocator; diff --git a/chromium/cc/resources/scoped_ui_resource.h b/chromium/cc/resources/scoped_ui_resource.h index 14db076b1e7..a0fb5d6df29 100644 --- a/chromium/cc/resources/scoped_ui_resource.h +++ b/chromium/cc/resources/scoped_ui_resource.h @@ -32,6 +32,9 @@ class CC_EXPORT ScopedUIResource : public UIResourceClient { UIResourceBitmap GetBitmap(UIResourceId uid, bool resource_lost) override; UIResourceId id() { return id_; } + // Returns the memory usage of the bitmap. + size_t EstimateMemoryUsage() const { return bitmap_.EstimateMemoryUsage(); } + protected: ScopedUIResource(UIResourceManager* ui_resource_manager, const UIResourceBitmap& bitmap); diff --git a/chromium/cc/resources/ui_resource_bitmap.h b/chromium/cc/resources/ui_resource_bitmap.h index 23492182b35..fab6bc8d4b4 100644 --- a/chromium/cc/resources/ui_resource_bitmap.h +++ b/chromium/cc/resources/ui_resource_bitmap.h @@ -20,8 +20,6 @@ class SkBitmap; namespace cc { -class ETC1PixelRef; - // A bitmap class that contains a ref-counted reference to a SkPixelRef that // holds the content of the bitmap (cannot use SkBitmap because of ETC1). // Thread-safety (by ways of SkPixelRef) ensures that both main and impl threads @@ -51,6 +49,11 @@ class CC_EXPORT UIResourceBitmap { UIResourceBitmap(const UIResourceBitmap& other); ~UIResourceBitmap(); + // Returns the memory usage of the bitmap. + size_t EstimateMemoryUsage() const { + return pixel_ref_ ? pixel_ref_->rowBytes() * size_.height() : 0; + } + private: friend class AutoLockUIResourceBitmap; diff --git a/chromium/cc/resources/video_resource_updater.cc b/chromium/cc/resources/video_resource_updater.cc index b54be5579f0..2ea3f4691ea 100644 --- a/chromium/cc/resources/video_resource_updater.cc +++ b/chromium/cc/resources/video_resource_updater.cc @@ -61,6 +61,7 @@ VideoFrameExternalResources::ResourceType ResourceTypeForVideoFrame( case media::PIXEL_FORMAT_NV12: switch (video_frame->mailbox_holder(0).texture_target) { case GL_TEXTURE_EXTERNAL_OES: + case GL_TEXTURE_2D: return VideoFrameExternalResources::YUV_RESOURCE; case GL_TEXTURE_RECTANGLE_ARB: return VideoFrameExternalResources::RGB_RESOURCE; @@ -295,17 +296,87 @@ static gfx::Size SoftwarePlaneDimension(media::VideoFrame* input_frame, return gfx::Size(plane_width, plane_height); } -void VideoResourceUpdater::MakeHalfFloats(const uint16_t* src, - int bits_per_channel, - size_t num, - uint16_t* dst) { - // Source and dest stride can be zero since we're only copying - // one row at a time. - int stride = 0; - // Maximum value used in |src|. - int max_value = (1 << bits_per_channel) - 1; - int rows = 1; - libyuv::HalfFloatPlane(src, stride, dst, stride, 1.0f / max_value, num, rows); +namespace { +// By OR-ing with 0x3800, 10-bit numbers become half-floats in the +// range [0.5..1) and 9-bit numbers get the range [0.5..0.75). +// +// Half-floats are evaluated as: +// float value = pow(2.0, exponent - 25) * (0x400 + fraction); +// +// In our case the exponent is 14 (since we or with 0x3800) and +// pow(2.0, 14-25) * 0x400 evaluates to 0.5 (our offset) and +// pow(2.0, 14-25) * fraction is [0..0.49951171875] for 10-bit and +// [0..0.24951171875] for 9-bit. +// +// https://en.wikipedia.org/wiki/Half-precision_floating-point_format +class HalfFloatMaker_xor : public VideoResourceUpdater::HalfFloatMaker { + public: + explicit HalfFloatMaker_xor(int bits_per_channel) + : bits_per_channel_(bits_per_channel) {} + float Offset() const override { return 0.5; } + float Multiplier() const override { + int max_input_value = (1 << bits_per_channel_) - 1; + // 2 << 11 = 2048 would be 1.0 with our exponent. + return 2048.0 / max_input_value; + } + void MakeHalfFloats(const uint16_t* src, size_t num, uint16_t* dst) override { + // Micro-benchmarking indicates that the compiler does + // a good enough job of optimizing this loop that trying + // to manually operate on one uint64 at a time is not + // actually helpful. + // Note to future optimizers: Benchmark your optimizations! + for (size_t i = 0; i < num; i++) + dst[i] = src[i] | 0x3800; + } + + private: + int bits_per_channel_; +}; + +class HalfFloatMaker_libyuv : public VideoResourceUpdater::HalfFloatMaker { + public: + explicit HalfFloatMaker_libyuv(int bits_per_channel) { + int max_value = (1 << bits_per_channel) - 1; + // For less than 15 bits, we can give libyuv a multiplier of + // 1.0, which is faster on some platforms. If bits is 16 or larger, + // a multiplier of 1.0 would cause overflows. However, a multiplier + // of 1/max_value would cause subnormal floats, which perform + // very poorly on some platforms. + if (bits_per_channel <= 15) { + libyuv_multiplier_ = 1.0f; + } else { + // This multiplier makes sure that we avoid subnormal values. + libyuv_multiplier_ = 1.0f / 4096.0f; + } + resource_multiplier_ = 1.0f / libyuv_multiplier_ / max_value; + } + float Offset() const override { return 0.0f; } + float Multiplier() const override { return resource_multiplier_; } + void MakeHalfFloats(const uint16_t* src, size_t num, uint16_t* dst) override { + // Source and dest stride can be zero since we're only copying + // one row at a time. + int stride = 0; + int rows = 1; + libyuv::HalfFloatPlane(src, stride, dst, stride, libyuv_multiplier_, num, + rows); + } + + private: + float libyuv_multiplier_; + float resource_multiplier_; +}; + +} // namespace + +std::unique_ptr<VideoResourceUpdater::HalfFloatMaker> +VideoResourceUpdater::NewHalfFloatMaker(int bits_per_channel) { + if (bits_per_channel < 11) { + return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( + new HalfFloatMaker_xor(bits_per_channel)); + } else { + return std::unique_ptr<VideoResourceUpdater::HalfFloatMaker>( + new HalfFloatMaker_libyuv(bits_per_channel)); + } } VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( @@ -357,19 +428,22 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( break; } - // TODO(dshwang): support PIXEL_FORMAT_Y16. crbug.com/624436 - DCHECK_NE(bits_per_channel, 16); - - // Only YUV software video frames are supported. - if (!media::IsYuvPlanar(input_frame_format)) { - NOTREACHED() << media::VideoPixelFormatToString(input_frame_format); - return VideoFrameExternalResources(); - } + // Only YUV and Y16 software video frames are supported. + DCHECK(media::IsYuvPlanar(input_frame_format) || + input_frame_format == media::PIXEL_FORMAT_Y16); const bool software_compositor = context_provider_ == NULL; - ResourceFormat output_resource_format = - resource_provider_->YuvResourceFormat(bits_per_channel); + ResourceFormat output_resource_format; + if (input_frame_format == media::PIXEL_FORMAT_Y16) { + // Unable to display directly as yuv planes so convert it to RGBA for + // compositing. + output_resource_format = RGBA_8888; + } else { + // Can be composited directly from yuv planes. + output_resource_format = + resource_provider_->YuvResourceFormat(bits_per_channel); + } // If GPU compositing is enabled, but the output resource format // returned by the resource provider is RGBA_8888, then a GPU driver @@ -483,6 +557,14 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( return external_resources; } + std::unique_ptr<HalfFloatMaker> half_float_maker; + if (resource_provider_->YuvResourceFormat(bits_per_channel) == + LUMINANCE_F16) { + half_float_maker = NewHalfFloatMaker(bits_per_channel); + external_resources.offset = half_float_maker->Offset(); + external_resources.multiplier = half_float_maker->Multiplier(); + } + for (size_t i = 0; i < plane_resources.size(); ++i) { PlaneResource& plane_resource = *plane_resources[i]; // Update each plane's resource id with its content. @@ -537,17 +619,7 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( &upload_pixels_[upload_image_stride * row]); const uint16_t* src = reinterpret_cast<uint16_t*>( video_frame->data(i) + (video_stride_bytes * row)); - if (bits_per_channel <= 10) { - // Micro-benchmarking indicates that the compiler does - // a good enough job of optimizing this loop that trying - // to manually operate on one uint64 at a time is not - // actually helpful. - // Note to future optimizers: Benchmark your optimizations! - for (size_t i = 0; i < bytes_per_row / 2; i++) - dst[i] = src[i] | 0x3800; - } else { - MakeHalfFloats(src, bits_per_channel, bytes_per_row / 2, dst); - } + half_float_maker->MakeHalfFloats(src, bytes_per_row / 2, dst); } else if (shift != 0) { // We have more-than-8-bit input which we need to shift // down to fit it into an 8-bit texture. @@ -573,36 +645,6 @@ VideoFrameExternalResources VideoResourceUpdater::CreateForSoftwarePlanes( plane_resource.SetUniqueId(video_frame->unique_id(), i); } - if (plane_resource.resource_format() == LUMINANCE_F16) { - // If the input data was 9 or 10 bit, and we output to half-floats, - // then we used the OR path above, which means that we need to - // adjust the resource offset and multiplier accordingly. If the - // input data uses more than 10 bits, it will already be normalized - // to 0.0..1.0, so there is no need to do anything. - if (bits_per_channel <= 10) { - // By OR-ing with 0x3800, 10-bit numbers become half-floats in the - // range [0.5..1) and 9-bit numbers get the range [0.5..0.75). - // - // Half-floats are evaluated as: - // float value = pow(2.0, exponent - 25) * (0x400 + fraction); - // - // In our case the exponent is 14 (since we or with 0x3800) and - // pow(2.0, 14-25) * 0x400 evaluates to 0.5 (our offset) and - // pow(2.0, 14-25) * fraction is [0..0.49951171875] for 10-bit and - // [0..0.24951171875] for 9-bit. - // - // https://en.wikipedia.org/wiki/Half-precision_floating-point_format - // - // PLEASE NOTE: - // All planes are assumed to use the same multiplier/offset. - external_resources.offset = 0.5f; - // Max value from input data. - int max_input_value = (1 << bits_per_channel) - 1; - // 2 << 11 = 2048 would be 1.0 with our exponent. - external_resources.multiplier = 2048.0 / max_input_value; - } - } - // VideoResourceUpdater shares a context with the compositor so a // sync token is not required. TextureMailbox mailbox(plane_resource.mailbox(), gpu::SyncToken(), diff --git a/chromium/cc/resources/video_resource_updater.h b/chromium/cc/resources/video_resource_updater.h index a42784c9b99..b9b5b95c026 100644 --- a/chromium/cc/resources/video_resource_updater.h +++ b/chromium/cc/resources/video_resource_updater.h @@ -80,14 +80,28 @@ class CC_EXPORT VideoResourceUpdater VideoFrameExternalResources CreateExternalResourcesFromVideoFrame( scoped_refptr<media::VideoFrame> video_frame); - // Convert an array of short integers into an array of half-floats. - // |src| is an array of integers in range 0 .. 2^{bits_per_channel} - 1 - // |num| is number of entries in input and output array. - // The numbers stored in |dst| will be half floats in range 0.0..1.0 - static void MakeHalfFloats(const uint16_t* src, - int bits_per_channel, - size_t num, - uint16_t* dst); + // Base class for converting short integers to half-floats. + // TODO(hubbe): Move this to media/. + class HalfFloatMaker { + public: + // Convert an array of short integers into an array of half-floats. + // |src| is an array of integers in range 0 .. 2^{bits_per_channel} - 1 + // |num| is number of entries in input and output array. + // The numbers stored in |dst| will be half floats in range 0.0..1.0 + virtual void MakeHalfFloats(const uint16_t* src, + size_t num, + uint16_t* dst) = 0; + // The half-floats made needs by this class will be in the range + // [Offset() .. Offset() + 1.0/Multiplier]. So if you want results + // in the 0-1 range, you need to do: + // (half_float - Offset()) * Multiplier() + // to each returned value. + virtual float Offset() const = 0; + virtual float Multiplier() const = 0; + }; + + static std::unique_ptr<HalfFloatMaker> NewHalfFloatMaker( + int bits_per_channel); private: class PlaneResource { diff --git a/chromium/cc/resources/video_resource_updater_unittest.cc b/chromium/cc/resources/video_resource_updater_unittest.cc index 9b9dcfccf9a..dce047cd523 100644 --- a/chromium/cc/resources/video_resource_updater_unittest.cc +++ b/chromium/cc/resources/video_resource_updater_unittest.cc @@ -536,27 +536,35 @@ double FromHalfFloat(uint16_t half_float) { } // namespace TEST_F(VideoResourceUpdaterTest, MakeHalfFloatTest) { - unsigned short integers[1 << 12]; - unsigned short half_floats[1 << 12]; - for (int bits = 9; bits <= 12; bits++) { + unsigned short integers[1 << 16]; + unsigned short half_floats[1 << 16]; + for (int bits = 9; bits <= 16; bits++) { + std::unique_ptr<VideoResourceUpdater::HalfFloatMaker> half_float_maker; + half_float_maker = VideoResourceUpdater::NewHalfFloatMaker(bits); int num_values = 1 << bits; for (int i = 0; i < num_values; i++) integers[i] = i; - VideoResourceUpdater::MakeHalfFloats(integers, bits, num_values, - half_floats); - + half_float_maker->MakeHalfFloats(integers, num_values, half_floats); // Multiplier to converting integers to 0.0..1.0 range. double multiplier = 1.0 / (num_values - 1); for (int i = 0; i < num_values; i++) { + // This value is in range 0..1 + float value = integers[i] * multiplier; + // Reverse the effect of offset and multiplier to get the expected + // output value from the half-float converter. + float expected_value = + value / half_float_maker->Multiplier() + half_float_maker->Offset(); + EXPECT_EQ(integers[i], i); + // We expect the result to be within +/- one least-significant bit. // Within the range we care about, half-floats values and // their representation both sort in the same order, so we // can just add one to get the next bigger half-float. float expected_precision = FromHalfFloat(half_floats[i] + 1) - FromHalfFloat(half_floats[i]); - EXPECT_NEAR(FromHalfFloat(half_floats[i]), integers[i] * multiplier, + EXPECT_NEAR(FromHalfFloat(half_floats[i]), expected_value, expected_precision) << "i = " << i << " bits = " << bits; } diff --git a/chromium/cc/scheduler/commit_earlyout_reason.cc b/chromium/cc/scheduler/commit_earlyout_reason.cc deleted file mode 100644 index dc151c2bf1b..00000000000 --- a/chromium/cc/scheduler/commit_earlyout_reason.cc +++ /dev/null @@ -1,47 +0,0 @@ -// 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. - -#include "cc/scheduler/commit_earlyout_reason.h" - -#include "cc/proto/commit_earlyout_reason.pb.h" - -namespace cc { - -CommitEarlyOutReason CommitEarlyOutReasonFromProtobuf( - const proto::CommitEarlyOutReason& proto) { - switch (proto.reason()) { - case proto::CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST: - return CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST; - case proto::CommitEarlyOutReason::ABORTED_NOT_VISIBLE: - return CommitEarlyOutReason::ABORTED_NOT_VISIBLE; - case proto::CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT: - return CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT; - case proto::CommitEarlyOutReason::FINISHED_NO_UPDATES: - return CommitEarlyOutReason::FINISHED_NO_UPDATES; - } - NOTREACHED(); - return CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST; -} - -void CommitEarlyOutReasonToProtobuf(CommitEarlyOutReason reason, - proto::CommitEarlyOutReason* proto) { - switch (reason) { - case CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST: - proto->set_reason( - proto::CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST); - return; - case CommitEarlyOutReason::ABORTED_NOT_VISIBLE: - proto->set_reason(proto::CommitEarlyOutReason::ABORTED_NOT_VISIBLE); - return; - case CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT: - proto->set_reason(proto::CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT); - return; - case CommitEarlyOutReason::FINISHED_NO_UPDATES: - proto->set_reason(proto::CommitEarlyOutReason::FINISHED_NO_UPDATES); - return; - } - NOTREACHED(); -} - -} // namespace cc diff --git a/chromium/cc/scheduler/commit_earlyout_reason.h b/chromium/cc/scheduler/commit_earlyout_reason.h index 172288cf217..ff1566d9697 100644 --- a/chromium/cc/scheduler/commit_earlyout_reason.h +++ b/chromium/cc/scheduler/commit_earlyout_reason.h @@ -10,10 +10,6 @@ namespace cc { -namespace proto { -class CommitEarlyOutReason; -} - enum class CommitEarlyOutReason { ABORTED_COMPOSITOR_FRAME_SINK_LOST, ABORTED_NOT_VISIBLE, @@ -21,14 +17,6 @@ enum class CommitEarlyOutReason { FINISHED_NO_UPDATES, }; -// Please update the To/From Protobuf methods for any updates made to -// CommitEarlyOutReason enum. -CC_EXPORT CommitEarlyOutReason -CommitEarlyOutReasonFromProtobuf(const proto::CommitEarlyOutReason& proto); -CC_EXPORT void CommitEarlyOutReasonToProtobuf( - CommitEarlyOutReason reason, - proto::CommitEarlyOutReason* proto); - inline const char* CommitEarlyOutReasonToString(CommitEarlyOutReason reason) { switch (reason) { case CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST: diff --git a/chromium/cc/scheduler/commit_earlyout_reason_unittest.cc b/chromium/cc/scheduler/commit_earlyout_reason_unittest.cc deleted file mode 100644 index 1972a3bbebb..00000000000 --- a/chromium/cc/scheduler/commit_earlyout_reason_unittest.cc +++ /dev/null @@ -1,39 +0,0 @@ -// 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. - -#include "cc/scheduler/commit_earlyout_reason.h" - -#include "cc/proto/commit_earlyout_reason.pb.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -CommitEarlyOutReason SerializeAndDeserializeReason( - CommitEarlyOutReason reason) { - proto::CommitEarlyOutReason proto; - CommitEarlyOutReasonToProtobuf(reason, &proto); - return CommitEarlyOutReasonFromProtobuf(proto); -} - -TEST(CommitEarlyOutReasonUnittest, SerializeCommitEarlyOutReason) { - EXPECT_EQ(CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST, - SerializeAndDeserializeReason( - CommitEarlyOutReason::ABORTED_COMPOSITOR_FRAME_SINK_LOST)); - - EXPECT_EQ( - CommitEarlyOutReason::ABORTED_NOT_VISIBLE, - SerializeAndDeserializeReason(CommitEarlyOutReason::ABORTED_NOT_VISIBLE)); - - EXPECT_EQ(CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT, - SerializeAndDeserializeReason( - CommitEarlyOutReason::ABORTED_DEFERRED_COMMIT)); - - EXPECT_EQ( - CommitEarlyOutReason::FINISHED_NO_UPDATES, - SerializeAndDeserializeReason(CommitEarlyOutReason::FINISHED_NO_UPDATES)); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/scheduler/compositor_timing_history.cc b/chromium/cc/scheduler/compositor_timing_history.cc index db07ffd834e..eee7dd06b00 100644 --- a/chromium/cc/scheduler/compositor_timing_history.cc +++ b/chromium/cc/scheduler/compositor_timing_history.cc @@ -36,8 +36,8 @@ class CompositorTimingHistory::UMAReporter { virtual void AddPrepareTilesDuration(base::TimeDelta duration) = 0; virtual void AddActivateDuration(base::TimeDelta duration) = 0; virtual void AddDrawDuration(base::TimeDelta duration) = 0; - virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0; - virtual void AddSwapAckWasFast(bool was_fast) = 0; + virtual void AddSubmitToAckLatency(base::TimeDelta duration) = 0; + virtual void AddSubmitAckWasFast(bool was_fast) = 0; // Synchronization measurements virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0; @@ -59,7 +59,7 @@ const double kPrepareTilesEstimationPercentile = 90.0; const double kActivateEstimationPercentile = 90.0; const double kDrawEstimationPercentile = 90.0; -constexpr base::TimeDelta kSwapAckWatchdogTimeout = +constexpr base::TimeDelta kSubmitAckWatchdogTimeout = base::TimeDelta::FromSeconds(8); const int kUmaDurationMinMicros = 1; @@ -190,12 +190,12 @@ class RendererUMAReporter : public CompositorTimingHistory::UMAReporter { duration); } - void AddSwapToAckLatency(base::TimeDelta duration) override { + void AddSubmitToAckLatency(base::TimeDelta duration) override { UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.SwapToAckLatency", duration); } - void AddSwapAckWasFast(bool was_fast) override { + void AddSubmitAckWasFast(bool was_fast) override { UMA_HISTOGRAM_BOOLEAN("Scheduling.Renderer.SwapAckWasFast", was_fast); } @@ -267,12 +267,12 @@ class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter { duration); } - void AddSwapToAckLatency(base::TimeDelta duration) override { + void AddSubmitToAckLatency(base::TimeDelta duration) override { UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.SwapToAckLatency", duration); } - void AddSwapAckWasFast(bool was_fast) override { + void AddSubmitAckWasFast(bool was_fast) override { UMA_HISTOGRAM_BOOLEAN("Scheduling.Browser.SwapAckWasFast", was_fast); } @@ -300,8 +300,8 @@ class NullUMAReporter : public CompositorTimingHistory::UMAReporter { void AddPrepareTilesDuration(base::TimeDelta duration) override {} void AddActivateDuration(base::TimeDelta duration) override {} void AddDrawDuration(base::TimeDelta duration) override {} - void AddSwapToAckLatency(base::TimeDelta duration) override {} - void AddSwapAckWasFast(bool was_fast) override {} + void AddSubmitToAckLatency(base::TimeDelta duration) override {} + void AddSubmitAckWasFast(bool was_fast) override {} void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {} }; @@ -328,7 +328,7 @@ CompositorTimingHistory::CompositorTimingHistory( activate_duration_history_(kDurationHistorySize), draw_duration_history_(kDurationHistorySize), begin_main_frame_on_critical_path_(false), - swap_ack_watchdog_enabled_(false), + submit_ack_watchdog_enabled_(false), uma_reporter_(CreateUMAReporter(uma_category)), rendering_stats_instrumentation_(rendering_stats_instrumentation) {} @@ -455,9 +455,9 @@ base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const { void CompositorTimingHistory::DidCreateAndInitializeCompositorFrameSink() { // After we get a new output surface, we won't get a spurious - // swap ack from the old output surface. - swap_start_time_ = base::TimeTicks(); - swap_ack_watchdog_enabled_ = false; + // CompositorFrameAck from the old output surface. + submit_start_time_ = base::TimeTicks(); + submit_ack_watchdog_enabled_ = false; } void CompositorTimingHistory::WillBeginImplFrame( @@ -473,12 +473,12 @@ void CompositorTimingHistory::WillBeginImplFrame( SetBeginMainFrameCommittingContinuously(false); } - if (swap_ack_watchdog_enabled_) { - base::TimeDelta swap_not_acked_time_ = Now() - swap_start_time_; - if (swap_not_acked_time_ >= kSwapAckWatchdogTimeout) { - uma_reporter_->AddSwapAckWasFast(false); - // Only record this UMA once per swap. - swap_ack_watchdog_enabled_ = false; + if (submit_ack_watchdog_enabled_) { + base::TimeDelta submit_not_acked_time_ = Now() - submit_start_time_; + if (submit_not_acked_time_ >= kSubmitAckWatchdogTimeout) { + uma_reporter_->AddSubmitAckWasFast(false); + // Only record this UMA once per submitted CompositorFrame. + submit_ack_watchdog_enabled_ = false; } } @@ -718,22 +718,22 @@ void CompositorTimingHistory::DidDraw(bool used_new_active_tree, draw_start_time_ = base::TimeTicks(); } -void CompositorTimingHistory::DidSwapBuffers() { - DCHECK_EQ(base::TimeTicks(), swap_start_time_); - swap_start_time_ = Now(); - swap_ack_watchdog_enabled_ = true; +void CompositorTimingHistory::DidSubmitCompositorFrame() { + DCHECK_EQ(base::TimeTicks(), submit_start_time_); + submit_start_time_ = Now(); + submit_ack_watchdog_enabled_ = true; } -void CompositorTimingHistory::DidSwapBuffersComplete() { - DCHECK_NE(base::TimeTicks(), swap_start_time_); - base::TimeDelta swap_to_ack_duration = Now() - swap_start_time_; - uma_reporter_->AddSwapToAckLatency(swap_to_ack_duration); - if (swap_ack_watchdog_enabled_) { - bool was_fast = swap_to_ack_duration < kSwapAckWatchdogTimeout; - uma_reporter_->AddSwapAckWasFast(was_fast); - swap_ack_watchdog_enabled_ = false; +void CompositorTimingHistory::DidReceiveCompositorFrameAck() { + DCHECK_NE(base::TimeTicks(), submit_start_time_); + base::TimeDelta submit_to_ack_duration = Now() - submit_start_time_; + uma_reporter_->AddSubmitToAckLatency(submit_to_ack_duration); + if (submit_ack_watchdog_enabled_) { + bool was_fast = submit_to_ack_duration < kSubmitAckWatchdogTimeout; + uma_reporter_->AddSubmitAckWasFast(was_fast); + submit_ack_watchdog_enabled_ = false; } - swap_start_time_ = base::TimeTicks(); + submit_start_time_ = base::TimeTicks(); } } // namespace cc diff --git a/chromium/cc/scheduler/compositor_timing_history.h b/chromium/cc/scheduler/compositor_timing_history.h index c66eea41ac9..fb2fd816744 100644 --- a/chromium/cc/scheduler/compositor_timing_history.h +++ b/chromium/cc/scheduler/compositor_timing_history.h @@ -71,8 +71,8 @@ class CC_EXPORT CompositorTimingHistory { void DidDraw(bool used_new_active_tree, bool main_thread_missed_last_deadline, base::TimeTicks impl_frame_time); - void DidSwapBuffers(); - void DidSwapBuffersComplete(); + void DidSubmitCompositorFrame(); + void DidReceiveCompositorFrameAck(); protected: void DidBeginMainFrame(); @@ -115,10 +115,10 @@ class CC_EXPORT CompositorTimingHistory { base::TimeTicks activate_start_time_; base::TimeTicks active_tree_main_frame_time_; base::TimeTicks draw_start_time_; - base::TimeTicks swap_start_time_; + base::TimeTicks submit_start_time_; // Watchdog timers. - bool swap_ack_watchdog_enabled_; + bool submit_ack_watchdog_enabled_; std::unique_ptr<UMAReporter> uma_reporter_; RenderingStatsInstrumentation* rendering_stats_instrumentation_; diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc index df57ddd64a1..14d5e69e6a0 100644 --- a/chromium/cc/scheduler/scheduler.cc +++ b/chromium/cc/scheduler/scheduler.cc @@ -46,13 +46,12 @@ Scheduler::Scheduler( state_machine_(settings), inside_process_scheduled_actions_(false), inside_action_(SchedulerStateMachine::ACTION_NONE), + stopped_(false), weak_factory_(this) { TRACE_EVENT1("cc", "Scheduler::Scheduler", "settings", settings_.AsValue()); DCHECK(client_); DCHECK(!state_machine_.BeginFrameNeeded()); - begin_retro_frame_closure_ = - base::Bind(&Scheduler::BeginRetroFrame, weak_factory_.GetWeakPtr()); begin_impl_frame_deadline_closure_ = base::Bind( &Scheduler::OnBeginImplFrameDeadline, weak_factory_.GetWeakPtr()); @@ -63,6 +62,10 @@ Scheduler::~Scheduler() { SetBeginFrameSource(nullptr); } +void Scheduler::Stop() { + stopped_ = true; +} + base::TimeTicks Scheduler::Now() const { base::TimeTicks now = base::TimeTicks::Now(); TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.now"), @@ -126,21 +129,21 @@ void Scheduler::SetNeedsPrepareTiles() { ProcessScheduledActions(); } -void Scheduler::DidSwapBuffers() { - compositor_timing_history_->DidSwapBuffers(); - state_machine_.DidSwapBuffers(); +void Scheduler::DidSubmitCompositorFrame() { + compositor_timing_history_->DidSubmitCompositorFrame(); + state_machine_.DidSubmitCompositorFrame(); // There is no need to call ProcessScheduledActions here because - // swapping should not trigger any new actions. + // submitting a CompositorFrame should not trigger any new actions. if (!inside_process_scheduled_actions_) { DCHECK_EQ(state_machine_.NextAction(), SchedulerStateMachine::ACTION_NONE); } } -void Scheduler::DidSwapBuffersComplete() { - DCHECK_GT(state_machine_.pending_swaps(), 0) << AsValue()->ToString(); - compositor_timing_history_->DidSwapBuffersComplete(); - state_machine_.DidSwapBuffersComplete(); +void Scheduler::DidReceiveCompositorFrameAck() { + DCHECK_GT(state_machine_.pending_submit_frames(), 0) << AsValue()->ToString(); + compositor_timing_history_->DidReceiveCompositorFrameAck(); + state_machine_.DidReceiveCompositorFrameAck(); ProcessScheduledActions(); } @@ -181,8 +184,6 @@ void Scheduler::DidPrepareTiles() { void Scheduler::DidLoseCompositorFrameSink() { TRACE_EVENT0("cc", "Scheduler::DidLoseCompositorFrameSink"); - begin_retro_frame_args_.clear(); - begin_retro_frame_task_.Cancel(); state_machine_.DidLoseCompositorFrameSink(); UpdateCompositorTimingHistoryRecordingEnabled(); ProcessScheduledActions(); @@ -219,29 +220,26 @@ void Scheduler::BeginImplFrameNotExpectedSoon() { } void Scheduler::SetupNextBeginFrameIfNeeded() { - // Never call SetNeedsBeginFrames if the frame source already has the right - // value. - if (observing_begin_frame_source_ != state_machine_.BeginFrameNeeded()) { - if (state_machine_.BeginFrameNeeded()) { - // Call AddObserver as soon as possible. - observing_begin_frame_source_ = true; - if (begin_frame_source_) - begin_frame_source_->AddObserver(this); - devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, - true); - } else if (state_machine_.begin_impl_frame_state() == - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { - // Call RemoveObserver in between frames only. - observing_begin_frame_source_ = false; - if (begin_frame_source_) - begin_frame_source_->RemoveObserver(this); - BeginImplFrameNotExpectedSoon(); - devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, - false); - } + if (state_machine_.begin_impl_frame_state() != + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) { + return; } - PostBeginRetroFrameIfNeeded(); + bool needs_begin_frames = state_machine_.BeginFrameNeeded(); + if (needs_begin_frames && !observing_begin_frame_source_) { + observing_begin_frame_source_ = true; + if (begin_frame_source_) + begin_frame_source_->AddObserver(this); + devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, true); + } else if (!needs_begin_frames && observing_begin_frame_source_) { + observing_begin_frame_source_ = false; + if (begin_frame_source_) + begin_frame_source_->RemoveObserver(this); + missed_begin_frame_task_.Cancel(); + BeginImplFrameNotExpectedSoon(); + devtools_instrumentation::NeedsBeginFrameChanged(layer_tree_host_id_, + false); + } } void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { @@ -260,6 +258,12 @@ void Scheduler::OnBeginFrameSourcePausedChanged(bool paused) { bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { TRACE_EVENT1("cc,benchmark", "Scheduler::BeginFrame", "args", args.AsValue()); + if (!state_machine_.BeginFrameNeeded()) { + TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrameDropped", + TRACE_EVENT_SCOPE_THREAD); + return false; + } + // Trace this begin frame time through the Chrome stack TRACE_EVENT_FLOW_BEGIN0( TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "BeginFrameArgs", @@ -270,31 +274,18 @@ bool Scheduler::OnBeginFrameDerivedImpl(const BeginFrameArgs& args) { return true; } - // We have just called SetNeedsBeginFrame(true) and the BeginFrameSource has - // sent us the last BeginFrame we have missed. As we might not be able to - // actually make rendering for this call, handle it like a "retro frame". - // TODO(brainderson): Add a test for this functionality ASAP! - if (args.type == BeginFrameArgs::MISSED) { - begin_retro_frame_args_.push_back(args); - PostBeginRetroFrameIfNeeded(); + if (inside_process_scheduled_actions_) { + // The BFS can send a missed begin frame inside AddObserver. We can't handle + // a begin frame inside ProcessScheduledActions so post a task. + DCHECK_EQ(args.type, BeginFrameArgs::MISSED); + DCHECK(missed_begin_frame_task_.IsCancelled()); + missed_begin_frame_task_.Reset(base::Bind( + &Scheduler::BeginImplFrameWithDeadline, base::Unretained(this), args)); + task_runner_->PostTask(FROM_HERE, missed_begin_frame_task_.callback()); return true; } - bool should_defer_begin_frame = - !begin_retro_frame_args_.empty() || - !begin_retro_frame_task_.IsCancelled() || - !observing_begin_frame_source_ || - (state_machine_.begin_impl_frame_state() != - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); - - if (should_defer_begin_frame) { - begin_retro_frame_args_.push_back(args); - TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginFrame deferred", - TRACE_EVENT_SCOPE_THREAD); - // Queuing the frame counts as "using it", so we need to return true. - } else { - BeginImplFrameWithDeadline(args); - } + BeginImplFrameWithDeadline(args); return true; } @@ -318,87 +309,47 @@ void Scheduler::OnDrawForCompositorFrameSink(bool resourceless_software_draw) { state_machine_.SetResourcelessSoftwareDraw(false); } -// BeginRetroFrame is called for BeginFrames that we've deferred because -// the scheduler was in the middle of processing a previous BeginFrame. -void Scheduler::BeginRetroFrame() { - TRACE_EVENT0("cc,benchmark", "Scheduler::BeginRetroFrame"); - DCHECK(!settings_.using_synchronous_renderer_compositor); - DCHECK(!begin_retro_frame_args_.empty()); - DCHECK(!begin_retro_frame_task_.IsCancelled()); - DCHECK_EQ(state_machine_.begin_impl_frame_state(), - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); - - begin_retro_frame_task_.Cancel(); +void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { + // The storage for |args| is owned by the missed begin frame task. Therefore + // save |args| before cancelling the task either here or in the deadline. + BeginFrameArgs adjusted_args = args; + // Cancel the missed begin frame task in case the BFS sends a begin frame + // before the missed frame task runs. + missed_begin_frame_task_.Cancel(); - // Discard expired BeginRetroFrames - // Today, we should always end up with at most one un-expired BeginRetroFrame - // because deadlines will not be greater than the next frame time. We don't - // DCHECK though because some systems don't always have monotonic timestamps. - // TODO(brianderson): In the future, long deadlines could result in us not - // draining the queue if we don't catch up. If we consistently can't catch - // up, our fallback should be to lower our frame rate. base::TimeTicks now = Now(); - while (!begin_retro_frame_args_.empty()) { - const BeginFrameArgs& args = begin_retro_frame_args_.front(); - base::TimeTicks expiration_time = args.deadline; - if (now <= expiration_time) - break; - TRACE_EVENT_INSTANT2( - "cc", "Scheduler::BeginRetroFrame discarding", TRACE_EVENT_SCOPE_THREAD, - "expiration_time - now", (expiration_time - now).InMillisecondsF(), - "BeginFrameArgs", begin_retro_frame_args_.front().AsValue()); - begin_retro_frame_args_.pop_front(); - if (begin_frame_source_) - begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); + // Discard missed begin frames if they are too late. + if (adjusted_args.type == BeginFrameArgs::MISSED && + now > adjusted_args.deadline) { + begin_frame_source_->DidFinishFrame(this, 0); + return; } - if (begin_retro_frame_args_.empty()) { - TRACE_EVENT_INSTANT0("cc", "Scheduler::BeginRetroFrames all expired", - TRACE_EVENT_SCOPE_THREAD); - } else { - BeginFrameArgs front = begin_retro_frame_args_.front(); - begin_retro_frame_args_.pop_front(); - BeginImplFrameWithDeadline(front); + // Run the previous deadline if any. + if (state_machine_.begin_impl_frame_state() == + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_BEGIN_FRAME) { + OnBeginImplFrameDeadline(); + // We may not need begin frames any longer. + if (!observing_begin_frame_source_) { + begin_frame_source_->DidFinishFrame(this, 0); + return; + } } -} - -// There could be a race between the posted BeginRetroFrame and a new -// BeginFrame arriving via the normal mechanism. Scheduler::BeginFrame -// will check if there is a pending BeginRetroFrame to ensure we handle -// BeginFrames in FIFO order. -void Scheduler::PostBeginRetroFrameIfNeeded() { - TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), - "Scheduler::PostBeginRetroFrameIfNeeded", "state", AsValue()); - if (!observing_begin_frame_source_) - return; - - if (begin_retro_frame_args_.empty() || !begin_retro_frame_task_.IsCancelled()) - return; - - // begin_retro_frame_args_ should always be empty for the - // synchronous compositor. - DCHECK(!settings_.using_synchronous_renderer_compositor); - - if (state_machine_.begin_impl_frame_state() != - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE) - return; - - begin_retro_frame_task_.Reset(begin_retro_frame_closure_); - - task_runner_->PostTask(FROM_HERE, begin_retro_frame_task_.callback()); -} + DCHECK_EQ(state_machine_.begin_impl_frame_state(), + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); -void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { bool main_thread_is_in_high_latency_mode = state_machine_.main_thread_missed_last_deadline(); TRACE_EVENT2("cc,benchmark", "Scheduler::BeginImplFrame", "args", - args.AsValue(), "main_thread_missed_last_deadline", + adjusted_args.AsValue(), "main_thread_missed_last_deadline", main_thread_is_in_high_latency_mode); TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"), "MainThreadLatency", main_thread_is_in_high_latency_mode); - BeginFrameArgs adjusted_args = args; + DCHECK_EQ(state_machine_.begin_impl_frame_state(), + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); + adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); adjusted_args.deadline -= kDeadlineFudgeFactor; @@ -413,7 +364,7 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); state_machine_.SetCriticalBeginMainFrameToActivateIsFast( - bmf_to_activate_estimate_critical < args.interval); + bmf_to_activate_estimate_critical < adjusted_args.interval); // Update the BeginMainFrame args now that we know whether the main // thread will be on the critical path or not. @@ -430,7 +381,7 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { bool can_activate_before_deadline = CanBeginMainFrameAndActivateBeforeDeadline(adjusted_args, - bmf_to_activate_estimate); + bmf_to_activate_estimate, now); if (ShouldRecoverMainLatency(adjusted_args, can_activate_before_deadline)) { TRACE_EVENT_INSTANT0("cc", "SkipBeginMainFrameToReduceLatency", @@ -441,7 +392,7 @@ void Scheduler::BeginImplFrameWithDeadline(const BeginFrameArgs& args) { TRACE_EVENT_INSTANT0("cc", "SkipBeginImplFrameToReduceLatency", TRACE_EVENT_SCOPE_THREAD); if (begin_frame_source_) - begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); + begin_frame_source_->DidFinishFrame(this, 0); return; } @@ -470,7 +421,7 @@ void Scheduler::FinishImplFrame() { client_->DidFinishImplFrame(); if (begin_frame_source_) - begin_frame_source_->DidFinishFrame(this, begin_retro_frame_args_.size()); + begin_frame_source_->DidFinishFrame(this, 0); begin_impl_frame_tracker_.Finish(); } @@ -576,28 +527,28 @@ void Scheduler::OnBeginImplFrameDeadline() { FinishImplFrame(); } -void Scheduler::DrawAndSwapIfPossible() { +void Scheduler::DrawIfPossible() { bool drawing_with_new_active_tree = state_machine_.active_tree_needs_first_draw(); bool main_thread_missed_last_deadline = state_machine_.main_thread_missed_last_deadline(); compositor_timing_history_->WillDraw(); state_machine_.WillDraw(); - DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible(); + DrawResult result = client_->ScheduledActionDrawIfPossible(); state_machine_.DidDraw(result); compositor_timing_history_->DidDraw( drawing_with_new_active_tree, main_thread_missed_last_deadline, begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time); } -void Scheduler::DrawAndSwapForced() { +void Scheduler::DrawForced() { bool drawing_with_new_active_tree = state_machine_.active_tree_needs_first_draw(); bool main_thread_missed_last_deadline = state_machine_.main_thread_missed_last_deadline(); compositor_timing_history_->WillDraw(); state_machine_.WillDraw(); - DrawResult result = client_->ScheduledActionDrawAndSwapForced(); + DrawResult result = client_->ScheduledActionDrawForced(); state_machine_.DidDraw(result); compositor_timing_history_->DidDraw( drawing_with_new_active_tree, main_thread_missed_last_deadline, @@ -612,6 +563,10 @@ void Scheduler::SetDeferCommits(bool defer_commits) { } void Scheduler::ProcessScheduledActions() { + // Do not perform actions during compositor shutdown. + if (stopped_) + return; + // We do not allow ProcessScheduledActions to be recursive. // The top-level call will iteratively execute the next action for us anyway. if (inside_process_scheduled_actions_) @@ -649,16 +604,16 @@ void Scheduler::ProcessScheduledActions() { client_->ScheduledActionActivateSyncTree(); compositor_timing_history_->DidActivate(); break; - case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: - DrawAndSwapIfPossible(); + case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: + DrawIfPossible(); break; - case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: - DrawAndSwapForced(); + case SchedulerStateMachine::ACTION_DRAW_FORCED: + DrawForced(); break; - case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: { + case SchedulerStateMachine::ACTION_DRAW_ABORT: { // No action is actually performed, but this allows the state machine to // drain the pipeline without actually drawing. - state_machine_.AbortDrawAndSwap(); + state_machine_.AbortDraw(); compositor_timing_history_->DrawAborted(); break; } @@ -695,12 +650,10 @@ Scheduler::AsValue() const { state->BeginDictionary("scheduler_state"); state->SetBoolean("observing_begin_frame_source", observing_begin_frame_source_); - state->SetInteger("begin_retro_frame_args", - static_cast<int>(begin_retro_frame_args_.size())); - state->SetBoolean("begin_retro_frame_task", - !begin_retro_frame_task_.IsCancelled()); state->SetBoolean("begin_impl_frame_deadline_task", !begin_impl_frame_deadline_task_.IsCancelled()); + state->SetBoolean("missed_begin_frame_task", + !missed_begin_frame_task_.IsCancelled()); state->SetString("inside_action", SchedulerStateMachine::ActionToString(inside_action_)); @@ -762,7 +715,7 @@ bool Scheduler::ShouldRecoverImplLatency( // If we are swap throttled at the BeginFrame, that means the impl thread is // very likely in a high latency mode. - bool impl_thread_is_likely_high_latency = state_machine_.SwapThrottled(); + bool impl_thread_is_likely_high_latency = state_machine_.IsDrawThrottled(); if (!impl_thread_is_likely_high_latency) return false; @@ -788,11 +741,11 @@ bool Scheduler::ShouldRecoverImplLatency( bool Scheduler::CanBeginMainFrameAndActivateBeforeDeadline( const BeginFrameArgs& args, - base::TimeDelta bmf_to_activate_estimate) const { + base::TimeDelta bmf_to_activate_estimate, + base::TimeTicks now) const { // Check if the main thread computation and commit can be finished before the // impl thread's deadline. - base::TimeTicks estimated_draw_time = - args.frame_time + bmf_to_activate_estimate; + base::TimeTicks estimated_draw_time = now + bmf_to_activate_estimate; return estimated_draw_time < args.deadline; } diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h index 57470da922e..afc2247ec02 100644 --- a/chromium/cc/scheduler/scheduler.h +++ b/chromium/cc/scheduler/scheduler.h @@ -38,8 +38,8 @@ class SchedulerClient { virtual void WillBeginImplFrame(const BeginFrameArgs& args) = 0; virtual void ScheduledActionSendBeginMainFrame( const BeginFrameArgs& args) = 0; - virtual DrawResult ScheduledActionDrawAndSwapIfPossible() = 0; - virtual DrawResult ScheduledActionDrawAndSwapForced() = 0; + virtual DrawResult ScheduledActionDrawIfPossible() = 0; + virtual DrawResult ScheduledActionDrawForced() = 0; virtual void ScheduledActionCommit() = 0; virtual void ScheduledActionActivateSyncTree() = 0; virtual void ScheduledActionBeginCompositorFrameSinkCreation() = 0; @@ -61,6 +61,10 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase { std::unique_ptr<CompositorTimingHistory> compositor_timing_history); ~Scheduler() override; + // This is needed so that the scheduler doesn't perform spurious actions while + // the compositor is being torn down. + void Stop(); + // BeginFrameObserverBase void OnBeginFrameSourcePausedChanged(bool paused) override; bool OnBeginFrameDerivedImpl(const BeginFrameArgs& args) override; @@ -85,8 +89,12 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase { void SetNeedsPrepareTiles(); - void DidSwapBuffers(); - void DidSwapBuffersComplete(); + // Drawing should result in submitting a CompositorFrame to the + // CompositorFrameSink and then calling this. + void DidSubmitCompositorFrame(); + // The CompositorFrameSink acks when it is ready for a new frame which + // should result in this getting called to unblock the next draw. + void DidReceiveCompositorFrameAck(); void SetTreePrioritiesAndScrollState(TreePriority tree_priority, ScrollHandlerState scroll_handler_state); @@ -150,29 +158,28 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase { std::unique_ptr<CompositorTimingHistory> compositor_timing_history_; - std::deque<BeginFrameArgs> begin_retro_frame_args_; SchedulerStateMachine::BeginImplFrameDeadlineMode begin_impl_frame_deadline_mode_; BeginFrameTracker begin_impl_frame_tracker_; BeginFrameArgs begin_main_frame_args_; - base::Closure begin_retro_frame_closure_; base::Closure begin_impl_frame_deadline_closure_; - base::CancelableClosure begin_retro_frame_task_; base::CancelableClosure begin_impl_frame_deadline_task_; + base::CancelableClosure missed_begin_frame_task_; SchedulerStateMachine state_machine_; bool inside_process_scheduled_actions_; SchedulerStateMachine::Action inside_action_; + bool stopped_; + private: void ScheduleBeginImplFrameDeadline(); void ScheduleBeginImplFrameDeadlineIfNeeded(); void BeginImplFrameNotExpectedSoon(); void SetupNextBeginFrameIfNeeded(); - void PostBeginRetroFrameIfNeeded(); - void DrawAndSwapIfPossible(); - void DrawAndSwapForced(); + void DrawIfPossible(); + void DrawForced(); void ProcessScheduledActions(); void UpdateCompositorTimingHistoryRecordingEnabled(); bool ShouldRecoverMainLatency(const BeginFrameArgs& args, @@ -181,10 +188,10 @@ class CC_EXPORT Scheduler : public BeginFrameObserverBase { bool can_activate_before_deadline) const; bool CanBeginMainFrameAndActivateBeforeDeadline( const BeginFrameArgs& args, - base::TimeDelta bmf_to_activate_estimate) const; + base::TimeDelta bmf_to_activate_estimate, + base::TimeTicks now) const; void AdvanceCommitStateIfPossible(); bool IsBeginMainFrameSentOrStarted() const; - void BeginRetroFrame(); void BeginImplFrameWithDeadline(const BeginFrameArgs& args); void BeginImplFrameSynchronous(const BeginFrameArgs& args); void BeginImplFrame(const BeginFrameArgs& args); diff --git a/chromium/cc/scheduler/scheduler_settings.cc b/chromium/cc/scheduler/scheduler_settings.cc index 5e66d5c9322..0a95df8548a 100644 --- a/chromium/cc/scheduler/scheduler_settings.cc +++ b/chromium/cc/scheduler/scheduler_settings.cc @@ -18,8 +18,8 @@ std::unique_ptr<base::trace_event::ConvertableToTraceFormat> SchedulerSettings::AsValue() const { std::unique_ptr<base::trace_event::TracedValue> state( new base::trace_event::TracedValue()); - state->SetBoolean("main_frame_while_swap_throttled_enabled", - main_frame_while_swap_throttled_enabled); + state->SetBoolean("main_frame_while_submit_frame_throttled_enabled", + main_frame_while_submit_frame_throttled_enabled); state->SetBoolean("main_frame_before_activation_enabled", main_frame_before_activation_enabled); state->SetBoolean("commit_to_active_tree", commit_to_active_tree); diff --git a/chromium/cc/scheduler/scheduler_settings.h b/chromium/cc/scheduler/scheduler_settings.h index f59f52ef397..00941a0ea8e 100644 --- a/chromium/cc/scheduler/scheduler_settings.h +++ b/chromium/cc/scheduler/scheduler_settings.h @@ -27,7 +27,7 @@ class CC_EXPORT SchedulerSettings { ~SchedulerSettings(); bool use_external_begin_frame_source = false; - bool main_frame_while_swap_throttled_enabled = false; + bool main_frame_while_submit_frame_throttled_enabled = false; bool main_frame_before_activation_enabled = false; bool commit_to_active_tree = false; bool timeout_and_draw_when_animation_checkerboards = true; diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc index 80d45ed2336..4a9a2e09919 100644 --- a/chromium/cc/scheduler/scheduler_state_machine.cc +++ b/chromium/cc/scheduler/scheduler_state_machine.cc @@ -15,7 +15,7 @@ namespace cc { namespace { // Surfaces and CompositorTimingHistory don't support more than 1 pending swap. -const int kMaxPendingSwaps = 1; +const int kMaxPendingSubmitFrames = 1; } // namespace SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) @@ -26,7 +26,7 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) forced_redraw_state_(FORCED_REDRAW_STATE_IDLE), commit_count_(0), current_frame_number_(0), - last_frame_number_swap_performed_(-1), + last_frame_number_submit_performed_(-1), last_frame_number_draw_performed_(-1), last_frame_number_begin_main_frame_sent_(-1), last_frame_number_invalidate_compositor_frame_sink_performed_(-1), @@ -35,8 +35,8 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) invalidate_compositor_frame_sink_funnel_(false), prepare_tiles_funnel_(0), consecutive_checkerboard_animations_(0), - pending_swaps_(0), - swaps_with_current_compositor_frame_sink_(0), + pending_submit_frames_(0), + submit_frames_with_current_compositor_frame_sink_(0), needs_redraw_(false), needs_prepare_tiles_(false), needs_begin_main_frame_(false), @@ -60,7 +60,7 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings) last_commit_had_no_updates_(false), wait_for_ready_to_draw_(false), did_draw_in_last_frame_(false), - did_swap_in_last_frame_(false) {} + did_submit_in_last_frame_(false) {} const char* SchedulerStateMachine::CompositorFrameSinkStateToString( CompositorFrameSinkState state) { @@ -123,10 +123,6 @@ const char* SchedulerStateMachine::BeginMainFrameStateToString( return "BEGIN_MAIN_FRAME_STATE_STARTED"; case BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT: return "BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT"; - case BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION: - return "BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION"; - case BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW: - return "BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW"; } NOTREACHED(); return "???"; @@ -169,12 +165,12 @@ const char* SchedulerStateMachine::ActionToString(Action action) { return "ACTION_COMMIT"; case ACTION_ACTIVATE_SYNC_TREE: return "ACTION_ACTIVATE_SYNC_TREE"; - case ACTION_DRAW_AND_SWAP_IF_POSSIBLE: - return "ACTION_DRAW_AND_SWAP_IF_POSSIBLE"; - case ACTION_DRAW_AND_SWAP_FORCED: - return "ACTION_DRAW_AND_SWAP_FORCED"; - case ACTION_DRAW_AND_SWAP_ABORT: - return "ACTION_DRAW_AND_SWAP_ABORT"; + case ACTION_DRAW_IF_POSSIBLE: + return "ACTION_DRAW_IF_POSSIBLE"; + case ACTION_DRAW_FORCED: + return "ACTION_DRAW_FORCED"; + case ACTION_DRAW_ABORT: + return "ACTION_DRAW_ABORT"; case ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION: return "ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION"; case ACTION_PREPARE_TILES: @@ -212,8 +208,8 @@ void SchedulerStateMachine::AsValueInto( state->BeginDictionary("minor_state"); state->SetInteger("commit_count", commit_count_); state->SetInteger("current_frame_number", current_frame_number_); - state->SetInteger("last_frame_number_swap_performed", - last_frame_number_swap_performed_); + state->SetInteger("last_frame_number_submit_performed", + last_frame_number_submit_performed_); state->SetInteger("last_frame_number_draw_performed", last_frame_number_draw_performed_); state->SetInteger("last_frame_number_begin_main_frame_sent", @@ -226,9 +222,9 @@ void SchedulerStateMachine::AsValueInto( invalidate_compositor_frame_sink_funnel_); state->SetInteger("consecutive_checkerboard_animations", consecutive_checkerboard_animations_); - state->SetInteger("pending_swaps_", pending_swaps_); - state->SetInteger("swaps_with_current_compositor_frame_sink", - swaps_with_current_compositor_frame_sink_); + state->SetInteger("pending_submit_frames_", pending_submit_frames_); + state->SetInteger("submit_frames_with_current_compositor_frame_sink", + submit_frames_with_current_compositor_frame_sink_); state->SetBoolean("needs_redraw", needs_redraw_); state->SetBoolean("needs_prepare_tiles", needs_prepare_tiles_); state->SetBoolean("needs_begin_main_frame", needs_begin_main_frame_); @@ -258,7 +254,7 @@ void SchedulerStateMachine::AsValueInto( state->SetBoolean("defer_commits", defer_commits_); state->SetBoolean("last_commit_had_no_updates", last_commit_had_no_updates_); state->SetBoolean("did_draw_in_last_frame", did_draw_in_last_frame_); - state->SetBoolean("did_swap_in_last_frame", did_swap_in_last_frame_); + state->SetBoolean("did_submit_in_last_frame", did_submit_in_last_frame_); state->EndDictionary(); } @@ -358,8 +354,8 @@ bool SchedulerStateMachine::ShouldDraw() const { if (compositor_frame_sink_state_ != COMPOSITOR_FRAME_SINK_ACTIVE) return false; - // Do not queue too many swaps. - if (SwapThrottled()) + // Do not queue too many draws. + if (IsDrawThrottled()) return false; // Except for the cases above, do not draw outside of the BeginImplFrame @@ -367,6 +363,17 @@ bool SchedulerStateMachine::ShouldDraw() const { if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) return false; + // Wait for active tree to be rasterized before drawing in browser compositor. + if (wait_for_ready_to_draw_) { + DCHECK(settings_.commit_to_active_tree); + return false; + } + + // Browser compositor commit steals any resources submitted in draw. Therefore + // drawing while a commit is pending is wasteful. + if (settings_.commit_to_active_tree && CommitPending()) + return false; + // Only handle forced redraws due to timeouts on the regular deadline. if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) return true; @@ -429,6 +436,16 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE) return false; + // MFBA is disabled and we are waiting for previous activation. + if (!settings_.main_frame_before_activation_enabled && has_pending_tree_) + return false; + + // We are waiting for previous frame to be drawn, submitted and acked. + if (settings_.commit_to_active_tree && + (active_tree_needs_first_draw_ || IsDrawThrottled())) { + return false; + } + // Don't send BeginMainFrame early if we are prioritizing the active tree // because of ImplLatencyTakesPriority. if (ImplLatencyTakesPriority() && @@ -456,15 +473,16 @@ bool SchedulerStateMachine::ShouldSendBeginMainFrame() const { if (!HasInitializedCompositorFrameSink()) return false; - if (!settings_.main_frame_while_swap_throttled_enabled) { - // SwapAck throttle the BeginMainFrames unless we just swapped to - // potentially improve impl-thread latency over main-thread throughput. + if (!settings_.main_frame_while_submit_frame_throttled_enabled) { + // Throttle the BeginMainFrames on CompositorFrameAck unless we just + // submitted a frame to potentially improve impl-thread latency over + // main-thread throughput. // TODO(brianderson): Remove this restriction to improve throughput or // make it conditional on ImplLatencyTakesPriority. - bool just_swapped_in_deadline = + bool just_submitted_in_deadline = begin_impl_frame_state_ == BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE && - did_swap_in_last_frame_; - if (SwapThrottled() && !just_swapped_in_deadline) + did_submit_in_last_frame_; + if (IsDrawThrottled() && !just_submitted_in_deadline) return false; } @@ -484,10 +502,13 @@ bool SchedulerStateMachine::ShouldCommit() const { return false; } - // If we only have an active tree, it is incorrect to replace it - // before we've drawn it. + // If we only have an active tree, it is incorrect to replace it before we've + // drawn it. DCHECK(!settings_.commit_to_active_tree || !active_tree_needs_first_draw_); + // In browser compositor commit reclaims any resources submitted during draw. + DCHECK(!settings_.commit_to_active_tree || !IsDrawThrottled()); + return true; } @@ -532,11 +553,11 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const { return ACTION_COMMIT; if (ShouldDraw()) { if (PendingDrawsShouldBeAborted()) - return ACTION_DRAW_AND_SWAP_ABORT; + return ACTION_DRAW_ABORT; else if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) - return ACTION_DRAW_AND_SWAP_FORCED; + return ACTION_DRAW_FORCED; else - return ACTION_DRAW_AND_SWAP_IF_POSSIBLE; + return ACTION_DRAW_IF_POSSIBLE; } if (ShouldPrepareTiles()) return ACTION_PREPARE_TILES; @@ -566,12 +587,7 @@ void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { commit_has_no_updates)); commit_count_++; last_commit_had_no_updates_ = commit_has_no_updates; - - if (commit_has_no_updates || settings_.main_frame_before_activation_enabled) { - begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; - } else { - begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION; - } + begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; if (!commit_has_no_updates) { // Pending tree only exists if commit had updates. @@ -597,13 +613,6 @@ void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) { } void SchedulerStateMachine::WillActivate() { - if (begin_main_frame_state_ == - BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION) { - begin_main_frame_state_ = settings_.commit_to_active_tree - ? BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW - : BEGIN_MAIN_FRAME_STATE_IDLE; - } - if (compositor_frame_sink_state_ == COMPOSITOR_FRAME_SINK_WAITING_FOR_FIRST_ACTIVATION) compositor_frame_sink_state_ = COMPOSITOR_FRAME_SINK_ACTIVE; @@ -636,9 +645,6 @@ void SchedulerStateMachine::WillDrawInternal() { if (forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; - - if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW) - begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_IDLE; } void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) { @@ -654,7 +660,7 @@ void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) { forced_redraw_state_ = FORCED_REDRAW_STATE_IDLE; break; case DRAW_ABORTED_CHECKERBOARD_ANIMATIONS: - DCHECK(!did_swap_in_last_frame_); + DCHECK(!did_submit_in_last_frame_); needs_begin_main_frame_ = true; needs_redraw_ = true; consecutive_checkerboard_animations_++; @@ -669,7 +675,7 @@ void SchedulerStateMachine::DidDrawInternal(DrawResult draw_result) { } break; case DRAW_ABORTED_MISSING_HIGH_RES_CONTENT: - DCHECK(!did_swap_in_last_frame_); + DCHECK(!did_submit_in_last_frame_); // It's not clear whether this missing content is because of missing // pictures (which requires a commit) or because of memory pressure // removing textures (which might not). To be safe, request a commit @@ -688,7 +694,7 @@ void SchedulerStateMachine::DidDraw(DrawResult draw_result) { DidDrawInternal(draw_result); } -void SchedulerStateMachine::AbortDrawAndSwap() { +void SchedulerStateMachine::AbortDraw() { // Pretend like the draw was successful. // Note: We may abort at any time and cannot DCHECK that // we haven't drawn in or swapped in the last frame here. @@ -803,11 +809,10 @@ bool SchedulerStateMachine::ProactiveBeginFrameWanted() const { if (needs_prepare_tiles_) return true; - // If we just tried to DrawAndSwap, it's likely that we are going to produce - // another frame soon. This helps avoid negative glitches in our - // SetNeedsBeginFrame requests, which may propagate to the BeginImplFrame - // provider and get sampled at an inopportune time, delaying the next - // BeginImplFrame. + // If we just tried to draw, it's likely that we are going to produce another + // frame soon. This helps avoid negative glitches in our SetNeedsBeginFrame + // requests, which may propagate to the BeginImplFrame provider and get + // sampled at an inopportune time, delaying the next BeginImplFrame. if (did_draw_in_last_frame_) return true; @@ -825,7 +830,7 @@ void SchedulerStateMachine::OnBeginImplFrame() { last_commit_had_no_updates_ = false; did_draw_in_last_frame_ = false; - did_swap_in_last_frame_ = false; + did_submit_in_last_frame_ = false; needs_one_begin_impl_frame_ = false; // Clear funnels for any actions we perform during the frame. @@ -871,12 +876,12 @@ SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const { if (settings_.using_synchronous_renderer_compositor) { // No deadline for synchronous compositor. return BEGIN_IMPL_FRAME_DEADLINE_MODE_NONE; - } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { - return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; } else if (wait_for_ready_to_draw_) { - // When we are waiting for ready to draw signal, we do not wait to post a - // deadline yet. + // In browser compositor, wait for active tree to be rasterized. + DCHECK(settings_.commit_to_active_tree); return BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED_ON_READY_TO_DRAW; + } else if (ShouldTriggerBeginImplFrameDeadlineImmediately()) { + return BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE; } else if (needs_redraw_) { // We have an animation or fast input path on the impl thread that wants // to draw, so don't wait too long for a new active tree. @@ -894,13 +899,9 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() if (PendingActivationsShouldBeForced() && !has_pending_tree_) return true; - // Do not trigger deadline immediately if we're waiting for READY_TO_DRAW - // unless it's one of the forced cases. - if (wait_for_ready_to_draw_) - return false; - - // SwapAck throttle the deadline since we wont draw and swap anyway. - if (SwapThrottled()) + // Throttle the deadline on CompositorFrameAck since we wont draw and submit + // anyway. + if (IsDrawThrottled()) return false; if (active_tree_needs_first_draw_) @@ -914,8 +915,7 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() // don't have a pending tree -- otherwise we should give it a chance to // activate. // TODO(skyostil): Revisit this when we have more accurate deadline estimates. - if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_IDLE && - !has_pending_tree_) + if (!CommitPending() && !has_pending_tree_) return true; // Prioritize impl-thread draws in ImplLatencyTakesPriority mode. @@ -925,8 +925,8 @@ bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately() return false; } -bool SchedulerStateMachine::SwapThrottled() const { - return pending_swaps_ >= kMaxPendingSwaps; +bool SchedulerStateMachine::IsDrawThrottled() const { + return pending_submit_frames_ >= kMaxPendingSubmitFrames; } void SchedulerStateMachine::SetVisible(bool visible) { @@ -975,22 +975,22 @@ void SchedulerStateMachine::SetNeedsPrepareTiles() { needs_prepare_tiles_ = true; } } -void SchedulerStateMachine::DidSwapBuffers() { - TRACE_EVENT_ASYNC_BEGIN1("cc", "Scheduler:pending_swaps", this, - "pending_frames", pending_swaps_); - DCHECK_LT(pending_swaps_, kMaxPendingSwaps); +void SchedulerStateMachine::DidSubmitCompositorFrame() { + TRACE_EVENT_ASYNC_BEGIN1("cc", "Scheduler:pending_submit_frames", this, + "pending_frames", pending_submit_frames_); + DCHECK_LT(pending_submit_frames_, kMaxPendingSubmitFrames); - pending_swaps_++; - swaps_with_current_compositor_frame_sink_++; + pending_submit_frames_++; + submit_frames_with_current_compositor_frame_sink_++; - did_swap_in_last_frame_ = true; - last_frame_number_swap_performed_ = current_frame_number_; + did_submit_in_last_frame_ = true; + last_frame_number_submit_performed_ = current_frame_number_; } -void SchedulerStateMachine::DidSwapBuffersComplete() { - TRACE_EVENT_ASYNC_END1("cc", "Scheduler:pending_swaps", this, - "pending_frames", pending_swaps_); - pending_swaps_--; +void SchedulerStateMachine::DidReceiveCompositorFrameAck() { + TRACE_EVENT_ASYNC_END1("cc", "Scheduler:pending_submit_frames", this, + "pending_frames", pending_submit_frames_); + pending_submit_frames_--; } void SchedulerStateMachine::SetTreePrioritiesAndScrollState( @@ -1032,9 +1032,8 @@ void SchedulerStateMachine::NotifyReadyToCommit() { DCHECK_EQ(begin_main_frame_state_, BEGIN_MAIN_FRAME_STATE_STARTED) << AsValue()->ToString(); begin_main_frame_state_ = BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT; - // In commit_to_active_tree mode, commit should happen right after - // BeginFrame, meaning when this function is called, next action should be - // commit. + // In commit_to_active_tree mode, commit should happen right after BeginFrame, + // meaning when this function is called, next action should be commit. if (settings_.commit_to_active_tree) DCHECK(ShouldCommit()); } @@ -1094,8 +1093,8 @@ void SchedulerStateMachine::DidCreateAndInitializeCompositorFrameSink() { needs_begin_main_frame_ = true; } did_create_and_initialize_first_compositor_frame_sink_ = true; - pending_swaps_ = 0; - swaps_with_current_compositor_frame_sink_ = 0; + pending_submit_frames_ = 0; + submit_frames_with_current_compositor_frame_sink_ = 0; main_thread_missed_last_deadline_ = false; } diff --git a/chromium/cc/scheduler/scheduler_state_machine.h b/chromium/cc/scheduler/scheduler_state_machine.h index 6fd86a66e2f..b04bd9b85a3 100644 --- a/chromium/cc/scheduler/scheduler_state_machine.h +++ b/chromium/cc/scheduler/scheduler_state_machine.h @@ -21,7 +21,6 @@ namespace trace_event { class ConvertableToTraceFormat; class TracedValue; } -class Value; } namespace cc { @@ -82,8 +81,6 @@ class CC_EXPORT SchedulerStateMachine { BEGIN_MAIN_FRAME_STATE_SENT, BEGIN_MAIN_FRAME_STATE_STARTED, BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT, - BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION, - BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW, }; static const char* BeginMainFrameStateToString(BeginMainFrameState state); @@ -118,9 +115,9 @@ class CC_EXPORT SchedulerStateMachine { ACTION_SEND_BEGIN_MAIN_FRAME, ACTION_COMMIT, ACTION_ACTIVATE_SYNC_TREE, - ACTION_DRAW_AND_SWAP_IF_POSSIBLE, - ACTION_DRAW_AND_SWAP_FORCED, - ACTION_DRAW_AND_SWAP_ABORT, + ACTION_DRAW_IF_POSSIBLE, + ACTION_DRAW_FORCED, + ACTION_DRAW_ABORT, ACTION_BEGIN_COMPOSITOR_FRAME_SINK_CREATION, ACTION_PREPARE_TILES, ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK, @@ -141,7 +138,7 @@ class CC_EXPORT SchedulerStateMachine { void DidDraw(DrawResult draw_result); - void AbortDrawAndSwap(); + void AbortDraw(); // Indicates whether the impl thread needs a BeginImplFrame callback in order // to make progress. @@ -156,6 +153,9 @@ class CC_EXPORT SchedulerStateMachine { // TODO(sunnyps): Rename OnBeginImplFrameDeadline to OnDraw or similar. void OnBeginImplFrameDeadline(); void OnBeginImplFrameIdle(); + + int current_frame_number() const { return current_frame_number_; } + BeginImplFrameState begin_impl_frame_state() const { return begin_impl_frame_state_; } @@ -167,7 +167,7 @@ class CC_EXPORT SchedulerStateMachine { return main_thread_missed_last_deadline_; } - bool SwapThrottled() const; + bool IsDrawThrottled() const; // Indicates whether the LayerTreeHostImpl is visible. void SetVisible(bool visible); @@ -187,19 +187,16 @@ class CC_EXPORT SchedulerStateMachine { // PrepareTiles will occur shortly (even if no redraw is required). void SetNeedsPrepareTiles(); - // If the scheduler attempted to draw and swap, this provides feedback - // regarding whether or not the swap actually occured. We might skip the - // swap when there is not damage, for example. - void DidSwapBuffers(); - - // Indicates whether a redraw is required because we are currently rendering - // with a low resolution or checkerboarded tile. - void SetSwapUsedIncompleteTile(bool used_incomplete_tile); + // If the scheduler attempted to draw, this provides feedback regarding + // whether or not a CompositorFrame was actually submitted. We might skip the + // submitting anything when there is not damage, for example. + void DidSubmitCompositorFrame(); - // Notification from the CompositorFrameSink that a swap has been consumed. - void DidSwapBuffersComplete(); + // Notification from the CompositorFrameSink that a submitted frame has been + // consumed and it is ready for the next one. + void DidReceiveCompositorFrameAck(); - int pending_swaps() const { return pending_swaps_; } + int pending_submit_frames() const { return pending_submit_frames_; } // Indicates whether to prioritize impl thread latency (i.e., animation // smoothness) over new content activation. @@ -304,7 +301,7 @@ class CC_EXPORT SchedulerStateMachine { // These are used for tracing only. int commit_count_; int current_frame_number_; - int last_frame_number_swap_performed_; + int last_frame_number_submit_performed_; int last_frame_number_draw_performed_; int last_frame_number_begin_main_frame_sent_; int last_frame_number_invalidate_compositor_frame_sink_performed_; @@ -321,9 +318,8 @@ class CC_EXPORT SchedulerStateMachine { int prepare_tiles_funnel_; int consecutive_checkerboard_animations_; - int max_pending_swaps_; - int pending_swaps_; - int swaps_with_current_compositor_frame_sink_; + int pending_submit_frames_; + int submit_frames_with_current_compositor_frame_sink_; bool needs_redraw_; bool needs_prepare_tiles_; bool needs_begin_main_frame_; @@ -346,7 +342,7 @@ class CC_EXPORT SchedulerStateMachine { bool last_commit_had_no_updates_; bool wait_for_ready_to_draw_; bool did_draw_in_last_frame_; - bool did_swap_in_last_frame_; + bool did_submit_in_last_frame_; private: DISALLOW_COPY_AND_ASSIGN(SchedulerStateMachine); diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc index e0f21f9444f..93e2cc26faa 100644 --- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc +++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc @@ -16,7 +16,7 @@ // Value of: actual() Actual: 7 // Expected: expected() Which is: 0 // With: -// Value of: actual() Actual: "ACTION_DRAW_AND_SWAP" +// Value of: actual() Actual: "ACTION_DRAW" // Expected: expected() Which is: "ACTION_NONE" #define EXPECT_ENUM_EQ(enum_tostring, expected, actual) \ EXPECT_STREQ(SchedulerStateMachine::enum_tostring(expected), \ @@ -35,18 +35,18 @@ EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction()) \ << state.AsValue()->ToString() -#define EXPECT_ACTION_UPDATE_STATE(action) \ - EXPECT_ACTION(action); \ - if (action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE || \ - action == SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED) { \ - EXPECT_IMPL_FRAME_STATE( \ - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); \ - } \ - PerformAction(&state, action); \ - if (action == SchedulerStateMachine::ACTION_NONE) { \ - if (state.begin_impl_frame_state() == \ - SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \ - state.OnBeginImplFrameIdle(); \ +#define EXPECT_ACTION_UPDATE_STATE(action) \ + EXPECT_ACTION(action); \ + if (action == SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE || \ + action == SchedulerStateMachine::ACTION_DRAW_FORCED) { \ + EXPECT_IMPL_FRAME_STATE( \ + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE); \ + } \ + PerformAction(&state, action); \ + if (action == SchedulerStateMachine::ACTION_NONE) { \ + if (state.begin_impl_frame_state() == \ + SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE) \ + state.OnBeginImplFrameIdle(); \ } #define SET_UP_STATE(state) \ @@ -72,9 +72,7 @@ const SchedulerStateMachine::BeginMainFrameState begin_main_frame_states[] = { SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE, SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT, SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_STARTED, - SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT, - SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION, - SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW}; + SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT}; // Exposes the protected state fields of the SchedulerStateMachine for testing class StateMachine : public SchedulerStateMachine { @@ -179,15 +177,15 @@ void PerformAction(StateMachine* sm, SchedulerStateMachine::Action action) { return; } - case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED: - case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE: { + case SchedulerStateMachine::ACTION_DRAW_FORCED: + case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: { sm->WillDraw(); sm->DidDraw(sm->draw_result_for_test()); return; } - case SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT: { - sm->AbortDrawAndSwap(); + case SchedulerStateMachine::ACTION_DRAW_ABORT: { + sm->AbortDraw(); return; } @@ -405,10 +403,9 @@ TEST(SchedulerStateMachineTest, MainFrameBeforeActivationEnabled) { EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE); } @@ -430,8 +427,7 @@ TEST(SchedulerStateMachineTest, // Failing a draw triggers request for a new BeginMainFrame. state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE( SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -446,8 +442,7 @@ TEST(SchedulerStateMachineTest, EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameIdle(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -470,8 +465,7 @@ TEST(SchedulerStateMachineTest, FailedDrawForMissingHighResNeedsCommit) { // request for a new BeginMainFrame. state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_MISSING_HIGH_RES_CONTENT); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE( SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -503,9 +497,8 @@ TEST(SchedulerStateMachineTest, FailedDrawForMissingHighResNeedsCommit) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_SUCCESS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameIdle(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -531,8 +524,7 @@ TEST(SchedulerStateMachineTest, state.SetNeedsRedraw(true); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); EXPECT_TRUE(state.BeginFrameNeeded()); EXPECT_TRUE(state.RedrawPending()); @@ -559,11 +551,10 @@ TEST(SchedulerStateMachineTest, EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_SUCCESS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_FORCED); - state.DidSwapBuffers(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_FORCED); + state.DidSubmitCompositorFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.DidSwapBuffersComplete(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } @@ -587,8 +578,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { // Then initiate a draw. state.SetNeedsRedraw(true); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); // Fail the draw enough times to force a redraw. for (int i = 0; i < draw_limit; ++i) { @@ -597,8 +587,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameIdle(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -619,8 +608,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawsDoNotRestartForcedDraw) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameIdle(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -643,8 +631,7 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) { state.OnBeginImplFrameDeadline(); EXPECT_TRUE(state.RedrawPending()); state.SetDrawResultForTest(DRAW_ABORTED_CHECKERBOARD_ANIMATIONS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); // Failing the draw for animation checkerboards makes us require a commit. EXPECT_ACTION_UPDATE_STATE( @@ -661,10 +648,9 @@ TEST(SchedulerStateMachineTest, TestFailedDrawIsRetriedInNextBeginImplFrame) { // the impl thread. state.OnBeginImplFrameDeadline(); state.SetDrawResultForTest(DRAW_SUCCESS); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } @@ -680,10 +666,9 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // Before the next BeginImplFrame, set needs redraw again. @@ -696,13 +681,12 @@ TEST(SchedulerStateMachineTest, TestDoestDrawTwiceInSameFrame) { state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - // We just swapped, so we should proactively request another BeginImplFrame. + // We just submitted, so we should proactively request another BeginImplFrame. EXPECT_TRUE(state.BeginFrameNeeded()); } @@ -733,12 +717,12 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { state.SetVisible(visible); // Case 1: needs_begin_main_frame=false - EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, + EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); // Case 2: needs_begin_main_frame=true state.SetNeedsBeginMainFrame(); - EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, + EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()) << state.AsValue()->ToString(); } @@ -765,7 +749,7 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) { SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT) { expected_action = SchedulerStateMachine::ACTION_COMMIT; } else { - expected_action = SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE; + expected_action = SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE; } // Case 1: needs_begin_main_frame=false. @@ -801,12 +785,12 @@ TEST(SchedulerStateMachineTest, TestNoBeginMainFrameStatesRedrawWhenInvisible) { } // Case 1: needs_begin_main_frame=false. - EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, + EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); // Case 2: needs_begin_main_frame=true. state.SetNeedsBeginMainFrame(); - EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, + EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()) << state.AsValue()->ToString(); } @@ -835,7 +819,7 @@ TEST(SchedulerStateMachineTest, TestCanRedraw_StopsDraw) { state.OnBeginImplFrame(); state.SetCanDraw(false); - EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE, + EXPECT_NE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE, state.NextAction()); } } @@ -856,7 +840,7 @@ TEST(SchedulerStateMachineTest, state.SetNeedsRedraw(true); state.SetCanDraw(false); state.OnBeginImplFrame(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_ABORT); EXPECT_ACTION_UPDATE_STATE( SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -866,7 +850,7 @@ TEST(SchedulerStateMachineTest, state.NotifyReadyToActivate(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_ABORT); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } @@ -925,10 +909,9 @@ TEST(SchedulerStateMachineTest, TestSetNeedsBeginMainFrameIsNotLost) { state.OnBeginImplFrameDeadline(); EXPECT_TRUE(state.active_tree_needs_first_draw()); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } @@ -968,10 +951,9 @@ TEST(SchedulerStateMachineTest, TestFullCycle) { // At BeginImplFrame deadline, draw. state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); // Should be synchronized, no draw needed, no action needed. EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -1114,60 +1096,53 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) { state.NotifyReadyToCommit(); EXPECT_MAIN_FRAME_STATE( SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT); - // Commit. EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + // Commit always calls NotifyReadyToActivate in this mode. + state.NotifyReadyToActivate(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - // Now commit should wait for activation. - EXPECT_MAIN_FRAME_STATE( - SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION); - - // No activation yet, so this commit is not drawn yet. Force to draw this - // frame, and still block BeginMainFrame. - state.SetNeedsRedraw(true); - state.SetNeedsBeginMainFrame(); + // No draw because we haven't received NotifyReadyToDraw yet. state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_TRUE(state.active_tree_needs_first_draw()); + EXPECT_TRUE(state.needs_redraw()); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - // Cannot BeginMainFrame yet since last commit is not yet activated and drawn. + // Can't BeginMainFrame yet since last commit hasn't been drawn yet. + state.SetNeedsBeginMainFrame(); state.OnBeginImplFrame(); - EXPECT_MAIN_FRAME_STATE( - SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_ACTIVATION); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - // Now activate sync tree. - state.NotifyReadyToActivate(); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - EXPECT_TRUE(state.active_tree_needs_first_draw()); - EXPECT_TRUE(state.needs_redraw()); - EXPECT_MAIN_FRAME_STATE( - SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_WAITING_FOR_DRAW); - - // Swap throttled. Do not draw. - state.DidSwapBuffers(); + // Now call ready to draw which will allow the draw to happen and + // BeginMainFrame to be sent. + state.NotifyReadyToDraw(); state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + // Submit throttled from this point. + state.DidSubmitCompositorFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.DidSwapBuffersComplete(); - // Haven't draw since last commit, do not begin new main frame. + // Can't BeginMainFrame yet since we're submit-frame throttled. state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - // At BeginImplFrame deadline, draw. This draws unblocks BeginMainFrame. - state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); - - // Now will be able to start main frame. - EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_IDLE); - EXPECT_FALSE(state.needs_redraw()); + // CompositorFrameAck unblocks BeginMainFrame. + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE( SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); + state.NotifyBeginMainFrameStarted(); + state.NotifyReadyToCommit(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); + state.NotifyReadyToActivate(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); + + // Draw the newly activated tree. + state.NotifyReadyToDraw(); + state.OnBeginImplFrameDeadline(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { @@ -1208,10 +1183,9 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) { // At BeginImplFrame deadline, draw. state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); // Should be synchronized, no draw needed, no action needed. EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); @@ -1493,8 +1467,7 @@ TEST(SchedulerStateMachineTest, state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); EXPECT_FALSE(state.RedrawPending()); @@ -1510,12 +1483,11 @@ TEST(SchedulerStateMachineTest, state.OnBeginImplFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); state.SetCanDraw(false); EXPECT_ACTION(SchedulerStateMachine::ACTION_NONE); state.SetCanDraw(true); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // Once the context is recreated, whether we draw should be based on @@ -1537,11 +1509,11 @@ TEST(SchedulerStateMachineTest, EXPECT_TRUE(state.needs_redraw()); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); state.SetCanDraw(false); - EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_ABORT); state.SetCanDraw(true); - EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); + EXPECT_ACTION(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); } TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { @@ -1559,10 +1531,9 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // Cause a lost context while the BeginMainFrame is in flight. @@ -1582,7 +1553,7 @@ TEST(SchedulerStateMachineTest, TestContextLostWhileCommitInProgress) { // We will abort the draw when the CompositorFrameSink is lost if we are // waiting for the first draw to unblock the main thread. EXPECT_TRUE(state.active_tree_needs_first_draw()); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_ABORT); // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); @@ -1617,10 +1588,9 @@ TEST(SchedulerStateMachineTest, SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // Cause a lost context while the BeginMainFrame is in flight. @@ -1640,7 +1610,7 @@ TEST(SchedulerStateMachineTest, EXPECT_TRUE(state.active_tree_needs_first_draw()); // Because the CompositorFrameSink is missing, we expect the draw to abort. - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_ABORT); // Expect to begin context recreation only in BEGIN_IMPL_FRAME_STATE_IDLE EXPECT_IMPL_FRAME_STATE(SchedulerStateMachine::BEGIN_IMPL_FRAME_STATE_IDLE); @@ -1675,10 +1645,9 @@ TEST(SchedulerStateMachineTest, EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); - state.DidSwapBuffersComplete(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } @@ -1722,7 +1691,7 @@ TEST(SchedulerStateMachineTest, EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); EXPECT_TRUE(state.PendingDrawsShouldBeAborted()); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_ABORT); } TEST(SchedulerStateMachineTest, TestNoBeginFrameNeededWhenInvisible) { @@ -1786,7 +1755,7 @@ TEST(SchedulerStateMachineTest, TestFinishCommitWhenCommitInProgress) { EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); EXPECT_TRUE(state.active_tree_needs_first_draw()); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_ABORT); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } @@ -1812,7 +1781,7 @@ TEST(SchedulerStateMachineTest, EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE); EXPECT_TRUE(state.active_tree_needs_first_draw()); - EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_AND_SWAP_ABORT); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_ABORT); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); } @@ -1965,9 +1934,8 @@ void FinishPreviousCommitAndDrawWithoutExitingDeadline( EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately()); state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); } TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) { @@ -1994,11 +1962,10 @@ TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) { // Trigger the deadline. state.OnBeginImplFrameDeadline(); - EXPECT_ACTION_UPDATE_STATE( - SchedulerStateMachine::ACTION_DRAW_AND_SWAP_IF_POSSIBLE); - state.DidSwapBuffers(); + EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE); + state.DidSubmitCompositorFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.DidSwapBuffersComplete(); + state.DidReceiveCompositorFrameAck(); // Request a new commit and finish the previous one. state.SetNeedsBeginMainFrame(); @@ -2006,15 +1973,15 @@ TEST(SchedulerStateMachineTest, TestImplLatencyTakesPriority) { EXPECT_ACTION_UPDATE_STATE( SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - state.DidSwapBuffersComplete(); + state.DidReceiveCompositorFrameAck(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); // Finish the previous commit and draw it. FinishPreviousCommitAndDrawWithoutExitingDeadline(&state); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); - // Verify we do not send another BeginMainFrame if was are swap throttled - // and did not just swap. + // Verify we do not send another BeginMainFrame if was are submit-frame + // throttled and did not just submit one. state.SetNeedsBeginMainFrame(); EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE); state.OnBeginImplFrame(); diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc index 6c4e316a234..ace12c64bdc 100644 --- a/chromium/cc/scheduler/scheduler_unittest.cc +++ b/chromium/cc/scheduler/scheduler_unittest.cc @@ -57,7 +57,7 @@ class FakeSchedulerClient : public SchedulerClient, public: FakeSchedulerClient() : inside_begin_impl_frame_(false), - automatic_swap_ack_(true), + automatic_ack_(true), scheduler_(nullptr) { Reset(); } @@ -105,8 +105,8 @@ class FakeSchedulerClient : public SchedulerClient, void SetSwapWillHappenIfDrawHappens(bool swap_will_happen_if_draw_happens) { swap_will_happen_if_draw_happens_ = swap_will_happen_if_draw_happens; } - void SetAutomaticSwapAck(bool automatic_swap_ack) { - automatic_swap_ack_ = automatic_swap_ack; + void SetAutomaticSubmitCompositorFrameAck(bool automatic_ack) { + automatic_ack_ = automatic_ack; } // SchedulerClient implementation. void WillBeginImplFrame(const BeginFrameArgs& args) override { @@ -132,23 +132,23 @@ class FakeSchedulerClient : public SchedulerClient, return last_begin_main_frame_args_; } - DrawResult ScheduledActionDrawAndSwapIfPossible() override { - PushAction("ScheduledActionDrawAndSwapIfPossible"); + DrawResult ScheduledActionDrawIfPossible() override { + PushAction("ScheduledActionDrawIfPossible"); num_draws_++; DrawResult result = draw_will_happen_ ? DRAW_SUCCESS : DRAW_ABORTED_CHECKERBOARD_ANIMATIONS; bool swap_will_happen = draw_will_happen_ && swap_will_happen_if_draw_happens_; if (swap_will_happen) { - scheduler_->DidSwapBuffers(); + scheduler_->DidSubmitCompositorFrame(); - if (automatic_swap_ack_) - scheduler_->DidSwapBuffersComplete(); + if (automatic_ack_) + scheduler_->DidReceiveCompositorFrameAck(); } return result; } - DrawResult ScheduledActionDrawAndSwapForced() override { - PushAction("ScheduledActionDrawAndSwapForced"); + DrawResult ScheduledActionDrawForced() override { + PushAction("ScheduledActionDrawForced"); return DRAW_SUCCESS; } void ScheduledActionCommit() override { @@ -182,6 +182,16 @@ class FakeSchedulerClient : public SchedulerClient, base::Unretained(this), state); } + bool IsCurrentFrame(int last_frame_number) const { + return scheduler_->current_frame_number() == last_frame_number; + } + + base::Callback<bool(void)> FrameHasNotAdvancedCallback() { + return base::Bind(&FakeSchedulerClient::IsCurrentFrame, + base::Unretained(this), + scheduler_->current_frame_number()); + } + void PushAction(const char* description) { actions_.push_back(description); states_.push_back(scheduler_->AsValue()); @@ -205,7 +215,7 @@ class FakeSchedulerClient : public SchedulerClient, bool will_begin_impl_frame_requests_one_begin_impl_frame_; bool draw_will_happen_; bool swap_will_happen_if_draw_happens_; - bool automatic_swap_ack_; + bool automatic_ack_; int num_draws_; BeginFrameArgs last_begin_main_frame_args_; base::TimeTicks posted_begin_impl_frame_deadline_; @@ -377,11 +387,6 @@ class SchedulerTest : public testing::Test { void AdvanceFrame() { TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"), "FakeSchedulerClient::AdvanceFrame"); - // Consume any previous deadline first, if no deadline is currently - // pending, InsideBeginImplFrame will return false straight away and we - // will run no tasks. - task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); // Send the next BeginFrame message if using an external source, otherwise // it will be already in the task queue. @@ -389,13 +394,8 @@ class SchedulerTest : public testing::Test { fake_external_begin_frame_source_.get()) { EXPECT_TRUE(scheduler_->begin_frames_expected()); SendNextBeginFrame(); - } - - if (!scheduler_->settings().using_synchronous_renderer_compositor) { - // Then run tasks until new deadline is scheduled. - EXPECT_TRUE( - task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(false))); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); + } else { + task_runner_->RunTasksWhile(client_->FrameHasNotAdvancedCallback()); } } @@ -415,11 +415,12 @@ class SchedulerTest : public testing::Test { return fake_external_begin_frame_source_.get(); } + void AdvanceAndMissOneFrame(); void CheckMainFrameSkippedAfterLateCommit(bool expect_send_begin_main_frame); - void ImplFrameSkippedAfterLateSwapAck(bool swap_ack_before_deadline); - void ImplFrameNotSkippedAfterLateSwapAck(); + void ImplFrameSkippedAfterLateAck(bool receive_ack_before_deadline); + void ImplFrameNotSkippedAfterLateAck(); void BeginFramesNotFromClient(BeginFrameSourceType bfs_type); - void BeginFramesNotFromClient_SwapThrottled(BeginFrameSourceType bfs_type); + void BeginFramesNotFromClient_IsDrawThrottled(BeginFrameSourceType bfs_type); bool BeginMainFrameOnCriticalPath(TreePriority tree_priority, ScrollHandlerState scroll_handler_state, base::TimeDelta durations); @@ -448,6 +449,21 @@ TEST_F(SchedulerTest, InitializeCompositorFrameSinkDoesNotBeginImplFrame) { EXPECT_NO_ACTION(client_); } +TEST_F(SchedulerTest, Stop) { + SetUpScheduler(EXTERNAL_BFS); + + scheduler_->SetNeedsBeginMainFrame(); + EXPECT_SINGLE_ACTION("AddObserver(this)", client_); + client_->Reset(); + + // No scheduled actions are performed after Stop. WillBeginImplFrame is only + // a notification and not an action performed by the scheduler. + scheduler_->Stop(); + EXPECT_SCOPED(AdvanceFrame()); + EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); + client_->Reset(); +} + TEST_F(SchedulerTest, VideoNeedsBeginFrames) { SetUpScheduler(EXTERNAL_BFS); @@ -522,7 +538,7 @@ TEST_F(SchedulerTest, RequestCommit) { // BeginImplFrame deadline should draw. task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); EXPECT_TRUE(scheduler_->begin_frames_expected()); client_->Reset(); @@ -587,7 +603,7 @@ TEST_F(SchedulerTest, DeferCommitWithRedraw) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); EXPECT_TRUE(scheduler_->begin_frames_expected()); @@ -632,7 +648,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); // Because we just swapped, the Scheduler should also request the next @@ -659,7 +675,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) { EXPECT_TRUE(client_->IsInsideBeginImplFrame()); client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); EXPECT_TRUE(scheduler_->begin_frames_expected()); client_->Reset(); @@ -679,15 +695,15 @@ class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { void SetRequestRedrawsInsideDraw(bool enable) { request_redraws_ = enable; } - DrawResult ScheduledActionDrawAndSwapIfPossible() override { + DrawResult ScheduledActionDrawIfPossible() override { // Only SetNeedsRedraw the first time this is called if (request_redraws_) { scheduler_->SetNeedsRedraw(); } - return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); + return FakeSchedulerClient::ScheduledActionDrawIfPossible(); } - DrawResult ScheduledActionDrawAndSwapForced() override { + DrawResult ScheduledActionDrawForced() override { NOTREACHED(); return DRAW_SUCCESS; } @@ -698,7 +714,7 @@ class SchedulerClientThatsetNeedsDrawInsideDraw : public FakeSchedulerClient { // Tests for two different situations: // 1. the scheduler dropping SetNeedsRedraw requests that happen inside -// a ScheduledActionDrawAndSwap +// a ScheduledActionDraw // 2. the scheduler drawing twice inside a single tick TEST_F(SchedulerTest, RequestRedrawInsideDraw) { SchedulerClientThatsetNeedsDrawInsideDraw* client = @@ -785,16 +801,16 @@ class SchedulerClientThatSetNeedsBeginMainFrameInsideDraw SchedulerClientThatSetNeedsBeginMainFrameInsideDraw() : set_needs_commit_on_next_draw_(false) {} - DrawResult ScheduledActionDrawAndSwapIfPossible() override { + DrawResult ScheduledActionDrawIfPossible() override { // Only SetNeedsBeginMainFrame the first time this is called if (set_needs_commit_on_next_draw_) { scheduler_->SetNeedsBeginMainFrame(); set_needs_commit_on_next_draw_ = false; } - return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); + return FakeSchedulerClient::ScheduledActionDrawIfPossible(); } - DrawResult ScheduledActionDrawAndSwapForced() override { + DrawResult ScheduledActionDrawForced() override { NOTREACHED(); return DRAW_SUCCESS; } @@ -808,7 +824,7 @@ class SchedulerClientThatSetNeedsBeginMainFrameInsideDraw }; // Tests for the scheduler infinite-looping on SetNeedsBeginMainFrame requests -// that happen inside a ScheduledActionDrawAndSwap +// that happen inside a ScheduledActionDraw TEST_F(SchedulerTest, RequestCommitInsideDraw) { SchedulerClientThatSetNeedsBeginMainFrameInsideDraw* client = new SchedulerClientThatSetNeedsBeginMainFrameInsideDraw; @@ -922,9 +938,9 @@ TEST_F(SchedulerTest, NoSwapWhenDrawFails) { class SchedulerClientNeedsPrepareTilesInDraw : public FakeSchedulerClient { public: - DrawResult ScheduledActionDrawAndSwapIfPossible() override { + DrawResult ScheduledActionDrawIfPossible() override { scheduler_->SetNeedsPrepareTiles(); - return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); + return FakeSchedulerClient::ScheduledActionDrawIfPossible(); } }; @@ -944,7 +960,7 @@ TEST_F(SchedulerTest, PrepareTiles) { EXPECT_TRUE(client->needs_begin_frames()); EXPECT_EQ(0, client->num_draws()); EXPECT_FALSE(client->HasAction("ScheduledActionPrepareTiles")); - EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_FALSE(client->HasAction("ScheduledActionDrawIfPossible")); // We have no immediate actions to perform, so the BeginImplFrame should post // the deadline task. @@ -957,9 +973,9 @@ TEST_F(SchedulerTest, PrepareTiles) { client->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client->num_draws()); - EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client->HasAction("ScheduledActionDrawIfPossible")); EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles")); - EXPECT_LT(client->ActionIndex("ScheduledActionDrawAndSwapIfPossible"), + EXPECT_LT(client->ActionIndex("ScheduledActionDrawIfPossible"), client->ActionIndex("ScheduledActionPrepareTiles")); EXPECT_FALSE(scheduler_->RedrawPending()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); @@ -986,9 +1002,9 @@ TEST_F(SchedulerTest, PrepareTiles) { client->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client->num_draws()); - EXPECT_TRUE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client->HasAction("ScheduledActionDrawIfPossible")); EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles")); - EXPECT_LT(client->ActionIndex("ScheduledActionDrawAndSwapIfPossible"), + EXPECT_LT(client->ActionIndex("ScheduledActionDrawIfPossible"), client->ActionIndex("ScheduledActionPrepareTiles")); EXPECT_FALSE(scheduler_->RedrawPending()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); @@ -1023,7 +1039,7 @@ TEST_F(SchedulerTest, PrepareTiles) { client->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(0, client->num_draws()); - EXPECT_FALSE(client->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_FALSE(client->HasAction("ScheduledActionDrawIfPossible")); EXPECT_TRUE(client->HasAction("ScheduledActionPrepareTiles")); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); } @@ -1050,7 +1066,7 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client_->num_draws()); - EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible")); EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles")); EXPECT_FALSE(scheduler_->RedrawPending()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); @@ -1067,9 +1083,9 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client_->num_draws()); - EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible")); EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles")); - EXPECT_LT(client_->ActionIndex("ScheduledActionDrawAndSwapIfPossible"), + EXPECT_LT(client_->ActionIndex("ScheduledActionDrawIfPossible"), client_->ActionIndex("ScheduledActionPrepareTiles")); EXPECT_FALSE(scheduler_->RedrawPending()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); @@ -1091,7 +1107,7 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client_->num_draws()); - EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible")); EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles")); EXPECT_FALSE(scheduler_->RedrawPending()); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); @@ -1115,7 +1131,7 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client_->num_draws()); - EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible")); EXPECT_FALSE(client_->HasAction("ScheduledActionPrepareTiles")); EXPECT_FALSE(scheduler_->RedrawPending()); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); @@ -1131,9 +1147,9 @@ TEST_F(SchedulerTest, PrepareTilesOncePerFrame) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client_->num_draws()); - EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible")); EXPECT_TRUE(client_->HasAction("ScheduledActionPrepareTiles")); - EXPECT_LT(client_->ActionIndex("ScheduledActionDrawAndSwapIfPossible"), + EXPECT_LT(client_->ActionIndex("ScheduledActionDrawIfPossible"), client_->ActionIndex("ScheduledActionPrepareTiles")); EXPECT_FALSE(scheduler_->RedrawPending()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); @@ -1168,7 +1184,7 @@ TEST_F(SchedulerTest, PrepareTilesFunnelResetOnVisibilityChange) { client_->Reset(); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2); EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2); } @@ -1221,7 +1237,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. EXPECT_EQ(1, client_->num_draws()); - EXPECT_TRUE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_TRUE(client_->HasAction("ScheduledActionDrawIfPossible")); } TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostCompositorFrameSink) { @@ -1267,8 +1283,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostCompositorFrameSink) { EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); } -void SchedulerTest::CheckMainFrameSkippedAfterLateCommit( - bool expect_send_begin_main_frame) { +void SchedulerTest::AdvanceAndMissOneFrame() { // Impl thread hits deadline before commit finishes. scheduler_->SetNeedsBeginMainFrame(); EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); @@ -1285,8 +1300,13 @@ void SchedulerTest::CheckMainFrameSkippedAfterLateCommit( EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5); EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); - client_->Reset(); +} + +void SchedulerTest::CheckMainFrameSkippedAfterLateCommit( + bool expect_send_begin_main_frame) { + AdvanceAndMissOneFrame(); + scheduler_->SetNeedsBeginMainFrame(); EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); EXPECT_SCOPED(AdvanceFrame()); @@ -1299,6 +1319,33 @@ void SchedulerTest::CheckMainFrameSkippedAfterLateCommit( client_->HasAction("ScheduledActionSendBeginMainFrame")); } +TEST_F(SchedulerTest, MainFrameNotSkippedAfterLateBeginFrame) { + // If a begin frame is delivered extremely late (because the browser has + // some contention), make sure that the main frame is not skipped even + // if it can activate before the deadline. + SetUpScheduler(EXTERNAL_BFS); + fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); + + AdvanceAndMissOneFrame(); + EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); + scheduler_->SetNeedsBeginMainFrame(); + + // Advance frame and create a begin frame. + now_src_->Advance(BeginFrameArgs::DefaultInterval()); + BeginFrameArgs args = + CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); + + // Deliver this begin frame super late. + now_src_->Advance(BeginFrameArgs::DefaultInterval() * 100); + fake_external_begin_frame_source_->TestOnBeginFrame(args); + + task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); + EXPECT_EQ(true, scheduler_->MainThreadMissedLastDeadline()); + EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); + EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); +} + TEST_F(SchedulerTest, MainFrameSkippedAfterLateCommit) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); @@ -1481,10 +1528,10 @@ TEST_F(SchedulerTest, MainFrameNotSkippedAfterCanDrawChanges) { EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); } -void SchedulerTest::ImplFrameSkippedAfterLateSwapAck( - bool swap_ack_before_deadline) { +void SchedulerTest::ImplFrameSkippedAfterLateAck( + bool receive_ack_before_deadline) { // To get into a high latency state, this test disables automatic swap acks. - client_->SetAutomaticSwapAck(false); + client_->SetAutomaticSubmitCompositorFrameAck(false); // Draw and swap for first BeginFrame client_->Reset(); @@ -1504,12 +1551,12 @@ void SchedulerTest::ImplFrameSkippedAfterLateSwapAck( task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); // Verify we skip every other frame if the swap ack consistently // comes back late. for (int i = 0; i < 10; i++) { - // Not calling scheduler_->DidSwapBuffersComplete() until after next + // Not calling scheduler_->DidReceiveCompositorFrameAck() until after next // BeginImplFrame puts the impl thread in high latency mode. client_->Reset(); scheduler_->SetNeedsBeginMainFrame(); @@ -1524,14 +1571,14 @@ void SchedulerTest::ImplFrameSkippedAfterLateSwapAck( // Verify that we do not perform any actions after we are no longer // swap throttled. client_->Reset(); - if (swap_ack_before_deadline) { + if (receive_ack_before_deadline) { // It shouldn't matter if the swap ack comes back before the deadline... - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); } else { // ... or after the deadline. task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); } EXPECT_NO_ACTION(client_); @@ -1550,41 +1597,40 @@ void SchedulerTest::ImplFrameSkippedAfterLateSwapAck( task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); } } TEST_F(SchedulerTest, - ImplFrameSkippedAfterLateSwapAck_FastEstimates_SwapAckThenDeadline) { + ImplFrameSkippedAfterLateAck_FastEstimates_SubmitAckThenDeadline) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); - bool swap_ack_before_deadline = true; - EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline)); + bool receive_ack_before_deadline = true; + EXPECT_SCOPED(ImplFrameSkippedAfterLateAck(receive_ack_before_deadline)); } TEST_F(SchedulerTest, - ImplFrameSkippedAfterLateSwapAck_FastEstimates_DeadlineThenSwapAck) { + ImplFrameSkippedAfterLateAck_FastEstimates_DeadlineThenSubmitAck) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); - bool swap_ack_before_deadline = false; - EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline)); + bool receive_ack_before_deadline = false; + EXPECT_SCOPED(ImplFrameSkippedAfterLateAck(receive_ack_before_deadline)); } TEST_F(SchedulerTest, - ImplFrameSkippedAfterLateSwapAck_LongMainFrameQueueDurationNotCritical) { + ImplFrameSkippedAfterLateAck_LongMainFrameQueueDurationNotCritical) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); fake_compositor_timing_history_ ->SetBeginMainFrameQueueDurationNotCriticalEstimate(kSlowDuration); - bool swap_ack_before_deadline = false; - EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline)); + bool receive_ack_before_deadline = false; + EXPECT_SCOPED(ImplFrameSkippedAfterLateAck(receive_ack_before_deadline)); } -TEST_F(SchedulerTest, - ImplFrameSkippedAfterLateSwapAck_ImplLatencyTakesPriority) { +TEST_F(SchedulerTest, ImplFrameSkippedAfterLateAck_ImplLatencyTakesPriority) { SetUpScheduler(EXTERNAL_BFS); // Even if every estimate related to the main thread is slow, we should @@ -1596,17 +1642,17 @@ TEST_F(SchedulerTest, fake_compositor_timing_history_->SetAllEstimatesTo(kSlowDuration); fake_compositor_timing_history_->SetDrawDurationEstimate(kFastDuration); - bool swap_ack_before_deadline = false; - EXPECT_SCOPED(ImplFrameSkippedAfterLateSwapAck(swap_ack_before_deadline)); + bool receive_ack_before_deadline = false; + EXPECT_SCOPED(ImplFrameSkippedAfterLateAck(receive_ack_before_deadline)); } TEST_F(SchedulerTest, - ImplFrameSkippedAfterLateSwapAck_OnlyImplSideUpdatesExpected) { + ImplFrameSkippedAfterLateAck_OnlyImplSideUpdatesExpected) { // This tests that we recover impl thread latency when there are no commits. SetUpScheduler(EXTERNAL_BFS); // To get into a high latency state, this test disables automatic swap acks. - client_->SetAutomaticSwapAck(false); + client_->SetAutomaticSubmitCompositorFrameAck(false); // Even if every estimate related to the main thread is slow, we should // still expect to recover impl thread latency if there are no commits from @@ -1625,12 +1671,12 @@ TEST_F(SchedulerTest, client_->Reset(); EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); // Verify we skip every other frame if the swap ack consistently // comes back late. for (int i = 0; i < 10; i++) { - // Not calling scheduler_->DidSwapBuffersComplete() until after next + // Not calling scheduler_->DidReceiveCompositorFrameAck() until after next // BeginImplFrame puts the impl thread in high latency mode. client_->Reset(); scheduler_->SetNeedsRedraw(); @@ -1644,7 +1690,7 @@ TEST_F(SchedulerTest, // Verify that we do not perform any actions after we are no longer // swap throttled. client_->Reset(); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); EXPECT_NO_ACTION(client_); // Verify that we start the next BeginImplFrame and continue normally @@ -1659,13 +1705,13 @@ TEST_F(SchedulerTest, EXPECT_TRUE(client_->IsInsideBeginImplFrame()); task_runner().RunUntilTime(now_src_->NowTicks()); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); } } -void SchedulerTest::ImplFrameNotSkippedAfterLateSwapAck() { +void SchedulerTest::ImplFrameNotSkippedAfterLateAck() { // To get into a high latency state, this test disables automatic swap acks. - client_->SetAutomaticSwapAck(false); + client_->SetAutomaticSubmitCompositorFrameAck(false); // Draw and swap for first BeginFrame client_->Reset(); @@ -1684,12 +1730,13 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateSwapAck() { task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_ACTION("ScheduledActionCommit", client_, 0, 3); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 3); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); // Verify impl thread consistently operates in high latency mode // without skipping any frames. for (int i = 0; i < 10; i++) { - // Not calling scheduler_->DidSwapBuffersComplete() until after next frame + // Not calling scheduler_->DidReceiveCompositorFrameAck() until after next + // frame // puts the impl thread in high latency mode. client_->Reset(); scheduler_->SetNeedsBeginMainFrame(); @@ -1700,7 +1747,7 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateSwapAck() { EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); client_->Reset(); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); scheduler_->NotifyReadyToCommit(); scheduler_->NotifyReadyToActivate(); @@ -1710,57 +1757,53 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateSwapAck() { EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 0, 4); EXPECT_ACTION("ScheduledActionCommit", client_, 1, 4); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 2, 4); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 4); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 3, 4); } } -TEST_F( - SchedulerTest, - ImplFrameNotSkippedAfterLateSwapAck_MainFrameQueueDurationCriticalTooLong) { +TEST_F(SchedulerTest, + ImplFrameNotSkippedAfterLateAck_MainFrameQueueDurationCriticalTooLong) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); fake_compositor_timing_history_ ->SetBeginMainFrameQueueDurationCriticalEstimate(kSlowDuration); fake_compositor_timing_history_ ->SetBeginMainFrameQueueDurationNotCriticalEstimate(kSlowDuration); - EXPECT_SCOPED(ImplFrameNotSkippedAfterLateSwapAck()); + EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck()); } -TEST_F(SchedulerTest, - ImplFrameNotSkippedAfterLateSwapAck_CommitEstimateTooLong) { +TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_CommitEstimateTooLong) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); fake_compositor_timing_history_ ->SetBeginMainFrameStartToCommitDurationEstimate(kSlowDuration); - EXPECT_SCOPED(ImplFrameNotSkippedAfterLateSwapAck()); + EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck()); } TEST_F(SchedulerTest, - ImplFrameNotSkippedAfterLateSwapAck_ReadyToActivateEstimateTooLong) { + ImplFrameNotSkippedAfterLateAck_ReadyToActivateEstimateTooLong) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); fake_compositor_timing_history_->SetCommitToReadyToActivateDurationEstimate( kSlowDuration); - EXPECT_SCOPED(ImplFrameNotSkippedAfterLateSwapAck()); + EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck()); } -TEST_F(SchedulerTest, - ImplFrameNotSkippedAfterLateSwapAck_ActivateEstimateTooLong) { +TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_ActivateEstimateTooLong) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); fake_compositor_timing_history_->SetActivateDurationEstimate(kSlowDuration); - EXPECT_SCOPED(ImplFrameNotSkippedAfterLateSwapAck()); + EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck()); } -TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateSwapAck_DrawEstimateTooLong) { +TEST_F(SchedulerTest, ImplFrameNotSkippedAfterLateAck_DrawEstimateTooLong) { SetUpScheduler(EXTERNAL_BFS); fake_compositor_timing_history_->SetAllEstimatesTo(kFastDuration); fake_compositor_timing_history_->SetDrawDurationEstimate(kSlowDuration); - EXPECT_SCOPED(ImplFrameNotSkippedAfterLateSwapAck()); + EXPECT_SCOPED(ImplFrameNotSkippedAfterLateAck()); } -TEST_F(SchedulerTest, - MainFrameThenImplFrameSkippedAfterLateCommitAndLateSwapAck) { +TEST_F(SchedulerTest, MainFrameThenImplFrameSkippedAfterLateCommitAndLateAck) { // Set up client with custom estimates. // This test starts off with expensive estimates to prevent latency recovery // initially, then lowers the estimates to enable it once both the main @@ -1769,7 +1812,7 @@ TEST_F(SchedulerTest, fake_compositor_timing_history_->SetAllEstimatesTo(kSlowDuration); // To get into a high latency state, this test disables automatic swap acks. - client_->SetAutomaticSwapAck(false); + client_->SetAutomaticSubmitCompositorFrameAck(false); // Impl thread hits deadline before commit finishes to make // MainThreadMissedLastDeadline true @@ -1804,11 +1847,12 @@ TEST_F(SchedulerTest, EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5); EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 5); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 5); EXPECT_ACTION("ScheduledActionCommit", client_, 3, 5); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 4, 5); - // Don't call scheduler_->DidSwapBuffersComplete() until after next frame + // Don't call scheduler_->DidReceiveCompositorFrameAck() until after next + // frame // to put the impl thread in a high latency mode. client_->Reset(); scheduler_->SetNeedsBeginMainFrame(); @@ -1821,7 +1865,7 @@ TEST_F(SchedulerTest, // Note: BeginMainFrame and swap are skipped here because of // swap ack backpressure, not because of latency recovery. EXPECT_FALSE(client_->HasAction("ScheduledActionSendBeginMainFrame")); - EXPECT_FALSE(client_->HasAction("ScheduledActionDrawAndSwapIfPossible")); + EXPECT_FALSE(client_->HasAction("ScheduledActionDrawIfPossible")); EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); // Lower estimates so that the scheduler will attempt latency recovery. @@ -1835,15 +1879,15 @@ TEST_F(SchedulerTest, client_->Reset(); // Previous commit request is still outstanding. EXPECT_TRUE(scheduler_->NeedsBeginMainFrame()); - EXPECT_TRUE(scheduler_->SwapThrottled()); + EXPECT_TRUE(scheduler_->IsDrawThrottled()); SendNextBeginFrame(); EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline()); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 1, 2); // Verify we skip the BeginImplFrame second. client_->Reset(); @@ -1853,7 +1897,7 @@ TEST_F(SchedulerTest, SendNextBeginFrame(); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); EXPECT_NO_ACTION(client_); @@ -1870,14 +1914,14 @@ TEST_F(SchedulerTest, scheduler_->NotifyReadyToActivate(); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline()); EXPECT_ACTION("WillBeginImplFrame", client_, 0, 5); EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5); EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 5); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 4, 5); } TEST_F( @@ -1886,12 +1930,12 @@ TEST_F( // NPAPI plugins on Windows block the Browser UI thread on the Renderer main // thread. This prevents the scheduler from receiving any pending swap acks. - scheduler_settings_.main_frame_while_swap_throttled_enabled = true; + scheduler_settings_.main_frame_while_submit_frame_throttled_enabled = true; SetUpScheduler(EXTERNAL_BFS); // Disables automatic swap acks so this test can force swap ack throttling // to simulate a blocked Browser ui thread. - client_->SetAutomaticSwapAck(false); + client_->SetAutomaticSubmitCompositorFrameAck(false); // Get a new active tree in main-thread high latency mode and put us // in a swap throttled state. @@ -1911,7 +1955,7 @@ TEST_F( EXPECT_ACTION("AddObserver(this)", client_, 0, 6); EXPECT_ACTION("WillBeginImplFrame", client_, 1, 6); EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 6); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 6); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 3, 6); EXPECT_ACTION("ScheduledActionCommit", client_, 4, 6); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 5, 6); @@ -1949,13 +1993,13 @@ TEST_F( // Since we are simulating a long commit, set up a client with draw duration // estimates that prevent skipping main frames to get to low latency mode. - scheduler_settings_.main_frame_while_swap_throttled_enabled = true; + scheduler_settings_.main_frame_while_submit_frame_throttled_enabled = true; scheduler_settings_.main_frame_before_activation_enabled = true; SetUpScheduler(EXTERNAL_BFS); // Disables automatic swap acks so this test can force swap ack throttling // to simulate a blocked Browser ui thread. - client_->SetAutomaticSwapAck(false); + client_->SetAutomaticSubmitCompositorFrameAck(false); // Start a new commit in main-thread high latency mode and hold off on // activation. @@ -1968,14 +2012,14 @@ TEST_F( EXPECT_TRUE(client_->IsInsideBeginImplFrame()); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); scheduler_->NotifyReadyToCommit(); EXPECT_FALSE(scheduler_->CommitPending()); EXPECT_ACTION("AddObserver(this)", client_, 0, 5); EXPECT_ACTION("WillBeginImplFrame", client_, 1, 5); EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 2, 5); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 3, 5); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 3, 5); EXPECT_ACTION("ScheduledActionCommit", client_, 4, 5); // Start another commit while we still have an active tree. @@ -1988,11 +2032,11 @@ TEST_F( EXPECT_TRUE(client_->IsInsideBeginImplFrame()); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); EXPECT_ACTION("WillBeginImplFrame", client_, 0, 3); EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 3); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 2, 3); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 2, 3); // Can't commit yet because there's still a pending tree. client_->Reset(); @@ -2007,236 +2051,6 @@ TEST_F( EXPECT_ACTION("ScheduledActionCommit", client_, 1, 2); } -TEST_F(SchedulerTest, BeginRetroFrame) { - SetUpScheduler(EXTERNAL_BFS); - - // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - client_->Reset(); - - // Create a BeginFrame with a long deadline to avoid race conditions. - // This is the first BeginFrame, which will be handled immediately. - BeginFrameArgs args = - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); - args.deadline += base::TimeDelta::FromHours(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - client_->Reset(); - - // Queue BeginFrames while we are still handling the previous BeginFrame. - args.frame_time += base::TimeDelta::FromSeconds(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - args.frame_time += base::TimeDelta::FromSeconds(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - - // If we don't swap on the deadline, we wait for the next BeginImplFrame. - task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_NO_ACTION(client_); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - client_->Reset(); - - // NotifyReadyToCommit should trigger the commit. - scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); - scheduler_->NotifyReadyToCommit(); - EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - client_->Reset(); - - // NotifyReadyToActivate should trigger the activation. - scheduler_->NotifyReadyToActivate(); - EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - client_->Reset(); - - // BeginImplFrame should prepare the draw. - task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - client_->Reset(); - - // BeginImplFrame deadline should draw. - task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - client_->Reset(); - - // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) - // to avoid excessive toggles. - task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. - EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - client_->Reset(); - - task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("RemoveObserver(this)", client_, 0, 2); - EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 1, 2); - client_->Reset(); -} - -TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) { - SetUpScheduler(EXTERNAL_BFS); - - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - - client_->Reset(); - EXPECT_SCOPED(AdvanceFrame()); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - - client_->Reset(); - scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); - - client_->Reset(); - BeginFrameArgs retro_frame_args = SendNextBeginFrame(); - // This BeginFrame is queued up as a retro frame. - EXPECT_NO_ACTION(client_); - // The previous deadline is still pending. - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - - client_->Reset(); - // This main frame activating should schedule the (previous) deadline to - // trigger immediately. - scheduler_->NotifyReadyToCommit(); - scheduler_->NotifyReadyToActivate(); - EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2); - EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2); - - client_->Reset(); - // The deadline task should trigger causing a draw. - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); - - // Keep animating. - client_->Reset(); - scheduler_->SetNeedsOneBeginImplFrame(); - scheduler_->SetNeedsRedraw(); - EXPECT_NO_ACTION(client_); - - // Let's advance to the retro frame's deadline. - now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks()); - - // The retro frame hasn't expired yet. - task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false)); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - - // This is an immediate deadline case. - client_->Reset(); - task_runner().RunPendingTasks(); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); -} - -TEST_F(SchedulerTest, RetroFrameExpiresOnTime) { - SetUpScheduler(EXTERNAL_BFS); - - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - - client_->Reset(); - EXPECT_SCOPED(AdvanceFrame()); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - - client_->Reset(); - scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); - - client_->Reset(); - BeginFrameArgs retro_frame_args = SendNextBeginFrame(); - // This BeginFrame is queued up as a retro frame. - EXPECT_NO_ACTION(client_); - // The previous deadline is still pending. - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - - client_->Reset(); - // This main frame activating should schedule the (previous) deadline to - // trigger immediately. - scheduler_->NotifyReadyToCommit(); - scheduler_->NotifyReadyToActivate(); - EXPECT_ACTION("ScheduledActionCommit", client_, 0, 2); - EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 1, 2); - - client_->Reset(); - // The deadline task should trigger causing a draw. - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); - - // Keep animating. - client_->Reset(); - scheduler_->SetNeedsOneBeginImplFrame(); - scheduler_->SetNeedsRedraw(); - EXPECT_NO_ACTION(client_); - - // Let's advance sufficiently past the retro frame's deadline. - now_src()->Advance(retro_frame_args.deadline - now_src()->NowTicks() + - base::TimeDelta::FromMicroseconds(1)); - - // The retro frame should've expired. - EXPECT_NO_ACTION(client_); -} - -TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) { - SetUpScheduler(EXTERNAL_BFS); - - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - - BeginFrameArgs missed_frame_args = - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); - missed_frame_args.type = BeginFrameArgs::MISSED; - - // Advance to the deadline. - now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks()); - - // Missed frame is handled because it's on time. - client_->Reset(); - fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); - EXPECT_TRUE( - task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false))); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); -} - -TEST_F(SchedulerTest, MissedFrameExpiresOnTime) { - SetUpScheduler(EXTERNAL_BFS); - - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - - BeginFrameArgs missed_frame_args = - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); - missed_frame_args.type = BeginFrameArgs::MISSED; - - // Advance sufficiently past the deadline. - now_src()->Advance(missed_frame_args.deadline - now_src()->NowTicks() + - base::TimeDelta::FromMicroseconds(1)); - - // Missed frame is dropped because it's too late. - client_->Reset(); - fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args); - EXPECT_FALSE( - task_runner().RunTasksWhile(client_->InsideBeginImplFrame(false))); - EXPECT_NO_ACTION(client_); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); -} - void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) { SetUpScheduler(bfs_type); @@ -2246,18 +2060,17 @@ void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) { EXPECT_NO_ACTION(client_); client_->Reset(); - // When the client-driven BeginFrame are disabled, the scheduler posts it's - // own BeginFrame tasks. - task_runner().RunPendingTasks(); // Run posted BeginFrame. + EXPECT_SCOPED(AdvanceFrame()); EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); EXPECT_TRUE(client_->IsInsideBeginImplFrame()); client_->Reset(); - // If we don't swap on the deadline, we wait for the next BeginFrame. - task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_NO_ACTION(client_); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); + // Can't run the deadline task because it can race with begin frame for the + // SyntheticBFS case. + EXPECT_SCOPED(AdvanceFrame()); + EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); + EXPECT_TRUE(client_->IsInsideBeginImplFrame()); client_->Reset(); // NotifyReadyToCommit should trigger the commit. @@ -2271,23 +2084,11 @@ void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) { EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); client_->Reset(); - // BeginImplFrame should prepare the draw. - task_runner().RunPendingTasks(); // Run posted BeginFrame. - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - client_->Reset(); - - // BeginImplFrame deadline should draw. - task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - client_->Reset(); - - // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) - // to avoid excessive toggles. - task_runner().RunPendingTasks(); // Run posted BeginFrame. - EXPECT_SINGLE_ACTION("WillBeginImplFrame", client_); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); + // BeginImplFrame deadline should draw. The following BeginImplFrame deadline + // should SetNeedsBeginFrame(false) to avoid excessive toggles. + EXPECT_SCOPED(AdvanceFrame()); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2); + EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2); client_->Reset(); // Make sure SetNeedsBeginFrame isn't called on the client @@ -2305,7 +2106,7 @@ TEST_F(SchedulerTest, UnthrottledBeginFrames) { BeginFramesNotFromClient(UNTHROTTLED_BFS); } -void SchedulerTest::BeginFramesNotFromClient_SwapThrottled( +void SchedulerTest::BeginFramesNotFromClient_IsDrawThrottled( BeginFrameSourceType bfs_type) { SetUpScheduler(bfs_type); @@ -2313,7 +2114,7 @@ void SchedulerTest::BeginFramesNotFromClient_SwapThrottled( fake_compositor_timing_history_->SetDrawDurationEstimate(base::TimeDelta()); // To test swap ack throttling, this test disables automatic swap acks. - client_->SetAutomaticSwapAck(false); + client_->SetAutomaticSubmitCompositorFrameAck(false); // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. client_->Reset(); @@ -2342,7 +2143,7 @@ void SchedulerTest::BeginFramesNotFromClient_SwapThrottled( // Swapping will put us into a swap throttled state. // Run posted deadline. task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -2375,7 +2176,7 @@ void SchedulerTest::BeginFramesNotFromClient_SwapThrottled( client_->Reset(); // Take us out of a swap throttled state. - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveCompositorFrameAck(); EXPECT_SINGLE_ACTION("ScheduledActionSendBeginMainFrame", client_); EXPECT_TRUE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -2393,12 +2194,12 @@ void SchedulerTest::BeginFramesNotFromClient_SwapThrottled( client_->Reset(); } -TEST_F(SchedulerTest, SyntheticBeginFrames_SwapThrottled) { - BeginFramesNotFromClient_SwapThrottled(THROTTLED_BFS); +TEST_F(SchedulerTest, SyntheticBeginFrames_IsDrawThrottled) { + BeginFramesNotFromClient_IsDrawThrottled(THROTTLED_BFS); } -TEST_F(SchedulerTest, UnthrottledBeginFrames_SwapThrottled) { - BeginFramesNotFromClient_SwapThrottled(UNTHROTTLED_BFS); +TEST_F(SchedulerTest, UnthrottledBeginFrames_IsDrawThrottled) { + BeginFramesNotFromClient_IsDrawThrottled(UNTHROTTLED_BFS); } TEST_F(SchedulerTest, @@ -2555,140 +2356,6 @@ TEST_F(SchedulerTest, DidLoseCompositorFrameSinkAfterSetNeedsPrepareTiles) { EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 3, 4); } -TEST_F(SchedulerTest, DidLoseCompositorFrameSinkAfterBeginRetroFramePosted) { - SetUpScheduler(EXTERNAL_BFS); - - // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - - // Create a BeginFrame with a long deadline to avoid race conditions. - // This is the first BeginFrame, which will be handled immediately. - client_->Reset(); - BeginFrameArgs args = - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); - args.deadline += base::TimeDelta::FromHours(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - // Queue BeginFrames while we are still handling the previous BeginFrame. - args.frame_time += base::TimeDelta::FromSeconds(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - args.frame_time += base::TimeDelta::FromSeconds(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - - // If we don't swap on the deadline, we wait for the next BeginImplFrame. - client_->Reset(); - task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_NO_ACTION(client_); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - // NotifyReadyToCommit should trigger the commit. - client_->Reset(); - scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); - scheduler_->NotifyReadyToCommit(); - EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - // NotifyReadyToActivate should trigger the activation. - client_->Reset(); - scheduler_->NotifyReadyToActivate(); - EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - client_->Reset(); - EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); - scheduler_->DidLoseCompositorFrameSink(); - EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0, - 3); - EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); - EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); - EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); - - // Posted BeginRetroFrame is aborted. - client_->Reset(); - task_runner().RunPendingTasks(); - EXPECT_NO_ACTION(client_); -} - -TEST_F(SchedulerTest, DidLoseCompositorFrameSinkDuringBeginRetroFrameRunning) { - SetUpScheduler(EXTERNAL_BFS); - - // SetNeedsBeginMainFrame should begin the frame on the next BeginImplFrame. - scheduler_->SetNeedsBeginMainFrame(); - EXPECT_SINGLE_ACTION("AddObserver(this)", client_); - - // Create a BeginFrame with a long deadline to avoid race conditions. - // This is the first BeginFrame, which will be handled immediately. - client_->Reset(); - BeginFrameArgs args = - CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src()); - args.deadline += base::TimeDelta::FromHours(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2); - EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - // Queue BeginFrames while we are still handling the previous BeginFrame. - args.frame_time += base::TimeDelta::FromSeconds(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - args.frame_time += base::TimeDelta::FromSeconds(1); - fake_external_begin_frame_source()->TestOnBeginFrame(args); - - // If we don't swap on the deadline, we wait for the next BeginImplFrame. - client_->Reset(); - task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_NO_ACTION(client_); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - // NotifyReadyToCommit should trigger the commit. - client_->Reset(); - scheduler_->NotifyBeginMainFrameStarted(base::TimeTicks()); - scheduler_->NotifyReadyToCommit(); - EXPECT_SINGLE_ACTION("ScheduledActionCommit", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - // NotifyReadyToActivate should trigger the activation. - client_->Reset(); - scheduler_->NotifyReadyToActivate(); - EXPECT_SINGLE_ACTION("ScheduledActionActivateSyncTree", client_); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - // BeginImplFrame should prepare the draw. - client_->Reset(); - task_runner().RunPendingTasks(); // Run posted BeginRetroFrame. - EXPECT_ACTION("WillBeginImplFrame", client_, 0, 1); - EXPECT_TRUE(client_->IsInsideBeginImplFrame()); - EXPECT_TRUE(scheduler_->begin_frames_expected()); - - client_->Reset(); - EXPECT_FALSE(scheduler_->IsBeginRetroFrameArgsEmpty()); - scheduler_->DidLoseCompositorFrameSink(); - EXPECT_NO_ACTION(client_); - EXPECT_TRUE(scheduler_->IsBeginRetroFrameArgsEmpty()); - - // BeginImplFrame deadline should abort drawing. - client_->Reset(); - task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_ACTION("ScheduledActionBeginCompositorFrameSinkCreation", client_, 0, - 3); - EXPECT_ACTION("RemoveObserver(this)", client_, 1, 3); - EXPECT_ACTION("SendBeginMainFrameNotExpectedSoon", client_, 2, 3); - EXPECT_FALSE(client_->IsInsideBeginImplFrame()); - EXPECT_FALSE(scheduler_->begin_frames_expected()); - - // No more BeginRetroFrame because BeginRetroFrame queue is cleared. - client_->Reset(); - task_runner().RunPendingTasks(); - EXPECT_NO_ACTION(client_); -} - TEST_F(SchedulerTest, DidLoseCompositorFrameSinkWithDelayBasedBeginFrameSource) { SetUpScheduler(THROTTLED_BFS); @@ -2756,7 +2423,7 @@ TEST_F(SchedulerTest, DidLoseCompositorFrameSinkWhenIdle) { client_->Reset(); task_runner().RunTasksWhile(client_->InsideBeginImplFrame(true)); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); // Idle time between BeginFrames. client_->Reset(); @@ -2838,7 +2505,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottled) { EXPECT_TRUE(scheduler_->begin_frames_expected()); client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); scheduler_->SetNeedsRedraw(); // Switch to an unthrottled frame source. @@ -2853,7 +2520,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottled) { // If we don't swap on the deadline, we wait for the next BeginFrame. task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); } @@ -2880,14 +2547,14 @@ TEST_F(SchedulerTest, SwitchFrameSourceToUnthrottledBeforeDeadline) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2); // Unthrottled frame source will immediately begin a new frame. EXPECT_ACTION("WillBeginImplFrame", client_, 1, 2); scheduler_->SetNeedsRedraw(); client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); } @@ -2907,7 +2574,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) { client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -2927,7 +2594,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceToThrottled) { EXPECT_TRUE(scheduler_->begin_frames_expected()); client_->Reset(); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); } TEST_F(SchedulerTest, SwitchFrameSourceToNullInsideDeadline) { @@ -2948,7 +2615,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceToNullInsideDeadline) { EXPECT_TRUE(client_->IsInsideBeginImplFrame()); task_runner().RunPendingTasks(); // Run posted deadline. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); EXPECT_FALSE(scheduler_->begin_frames_expected()); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -2977,7 +2644,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceToNullInsideDeadline) { client_->Reset(); task_runner().RunPendingTasks(); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); } // This test maskes sure that switching a frame source when not observing @@ -3054,7 +2721,7 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon) { EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 5); EXPECT_ACTION("ScheduledActionCommit", client_, 2, 5); EXPECT_ACTION("ScheduledActionActivateSyncTree", client_, 3, 5); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 4, 5); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 4, 5); client_->Reset(); // The following BeginImplFrame deadline should SetNeedsBeginFrame(false) @@ -3094,7 +2761,7 @@ TEST_F(SchedulerTest, SynchronousCompositorAnimation) { scheduler_->SetNeedsRedraw(); bool resourceless_software_draw = false; scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -3112,7 +2779,7 @@ TEST_F(SchedulerTest, SynchronousCompositorAnimation) { // Android onDraw. scheduler_->SetNeedsRedraw(); scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -3133,7 +2800,7 @@ TEST_F(SchedulerTest, SynchronousCompositorOnDrawDuringIdle) { bool resourceless_software_draw = false; scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); EXPECT_ACTION("AddObserver(this)", client_, 0, 2); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 1, 2); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 1, 2); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -3226,7 +2893,7 @@ TEST_F(SchedulerTest, SynchronousCompositorCommit) { scheduler_->SetNeedsRedraw(); bool resourceless_software_draw = false; scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); @@ -3289,9 +2956,9 @@ class SchedulerClientSetNeedsPrepareTilesOnDraw : public FakeSchedulerClient { SchedulerClientSetNeedsPrepareTilesOnDraw() : FakeSchedulerClient() {} protected: - DrawResult ScheduledActionDrawAndSwapIfPossible() override { + DrawResult ScheduledActionDrawIfPossible() override { scheduler_->SetNeedsPrepareTiles(); - return FakeSchedulerClient::ScheduledActionDrawAndSwapIfPossible(); + return FakeSchedulerClient::ScheduledActionDrawIfPossible(); } }; @@ -3316,7 +2983,7 @@ TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) { scheduler_->SetNeedsRedraw(); bool resourceless_software_draw = false; scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2); EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); @@ -3325,7 +2992,7 @@ TEST_F(SchedulerTest, SynchronousCompositorPrepareTilesOnDraw) { // Android onDraw. scheduler_->SetNeedsRedraw(); scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 2); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 2); EXPECT_ACTION("ScheduledActionPrepareTiles", client_, 1, 2); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); @@ -3359,7 +3026,7 @@ TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) { scheduler_->SetNeedsRedraw(); bool resourceless_software_draw = false; scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); client_->Reset(); @@ -3387,7 +3054,7 @@ TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) { // Android onDraw. scheduler_->SetNeedsRedraw(); scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); - EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); + EXPECT_SINGLE_ACTION("ScheduledActionDrawIfPossible", client_); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); EXPECT_FALSE(scheduler_->PrepareTilesPending()); client_->Reset(); @@ -3408,7 +3075,7 @@ TEST_F(SchedulerTest, SynchronousCompositorResourcelessOnDrawWhenInvisible) { bool resourceless_software_draw = true; scheduler_->OnDrawForCompositorFrameSink(resourceless_software_draw); // SynchronousCompositor has to draw regardless of visibility. - EXPECT_ACTION("ScheduledActionDrawAndSwapIfPossible", client_, 0, 1); + EXPECT_ACTION("ScheduledActionDrawIfPossible", client_, 0, 1); EXPECT_FALSE(client_->IsInsideBeginImplFrame()); client_->Reset(); } diff --git a/chromium/cc/surfaces/direct_compositor_frame_sink.cc b/chromium/cc/surfaces/direct_compositor_frame_sink.cc index fe40b4d66f0..27e2aed52cf 100644 --- a/chromium/cc/surfaces/direct_compositor_frame_sink.cc +++ b/chromium/cc/surfaces/direct_compositor_frame_sink.cc @@ -20,9 +20,13 @@ DirectCompositorFrameSink::DirectCompositorFrameSink( SurfaceManager* surface_manager, Display* display, scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider) + scoped_refptr<ContextProvider> worker_context_provider, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + SharedBitmapManager* shared_bitmap_manager) : CompositorFrameSink(std::move(context_provider), - std::move(worker_context_provider)), + std::move(worker_context_provider), + gpu_memory_buffer_manager, + shared_bitmap_manager), frame_sink_id_(frame_sink_id), surface_manager_(surface_manager), display_(display), @@ -51,55 +55,52 @@ DirectCompositorFrameSink::DirectCompositorFrameSink( DirectCompositorFrameSink::~DirectCompositorFrameSink() { DCHECK(thread_checker_.CalledOnValidThread()); - if (HasClient()) - DetachFromClient(); } bool DirectCompositorFrameSink::BindToClient( CompositorFrameSinkClient* client) { DCHECK(thread_checker_.CalledOnValidThread()); - surface_manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); - if (!CompositorFrameSink::BindToClient(client)) return false; + surface_manager_->RegisterSurfaceFactoryClient(frame_sink_id_, this); + // We want the Display's output surface to hear about lost context, and since // this shares a context with it, we should not be listening for lost context // callbacks on the context here. - if (context_provider()) - context_provider()->SetLostContextCallback(base::Closure()); + if (auto* cp = context_provider()) + cp->SetLostContextCallback(base::Closure()); // Avoid initializing GL context here, as this should be sharing the // Display's context. - display_->Initialize(this, surface_manager_, frame_sink_id_); + display_->Initialize(this, surface_manager_); return true; } void DirectCompositorFrameSink::DetachFromClient() { - DCHECK(HasClient()); // Unregister the SurfaceFactoryClient here instead of the dtor so that only // one client is alive for this namespace at any given time. surface_manager_->UnregisterSurfaceFactoryClient(frame_sink_id_); - if (!delegated_local_frame_id_.is_null()) + if (delegated_local_frame_id_.is_valid()) factory_.Destroy(delegated_local_frame_id_); CompositorFrameSink::DetachFromClient(); } -void DirectCompositorFrameSink::SwapBuffers(CompositorFrame frame) { +void DirectCompositorFrameSink::SubmitCompositorFrame(CompositorFrame frame) { gfx::Size frame_size = frame.delegated_frame_data->render_pass_list.back()->output_rect.size(); if (frame_size.IsEmpty() || frame_size != last_swap_frame_size_) { - if (!delegated_local_frame_id_.is_null()) { + if (delegated_local_frame_id_.is_valid()) { factory_.Destroy(delegated_local_frame_id_); } delegated_local_frame_id_ = surface_id_allocator_.GenerateId(); factory_.Create(delegated_local_frame_id_); last_swap_frame_size_ = frame_size; } - display_->SetSurfaceId(SurfaceId(frame_sink_id_, delegated_local_frame_id_), - frame.metadata.device_scale_factor); + display_->SetLocalFrameId(delegated_local_frame_id_, + frame.metadata.device_scale_factor); factory_.SubmitCompositorFrame( delegated_local_frame_id_, std::move(frame), @@ -108,7 +109,7 @@ void DirectCompositorFrameSink::SwapBuffers(CompositorFrame frame) { } void DirectCompositorFrameSink::ForceReclaimResources() { - if (!delegated_local_frame_id_.is_null()) { + if (delegated_local_frame_id_.is_valid()) { factory_.SubmitCompositorFrame(delegated_local_frame_id_, CompositorFrame(), SurfaceFactory::DrawCallback()); } @@ -144,9 +145,7 @@ void DirectCompositorFrameSink::DisplayDidDrawAndSwap() { } void DirectCompositorFrameSink::DidDrawCallback() { - // TODO(danakj): Why the lost check? - if (!is_lost_) - client_->DidSwapBuffersComplete(); + client_->DidReceiveCompositorFrameAck(); } } // namespace cc diff --git a/chromium/cc/surfaces/direct_compositor_frame_sink.h b/chromium/cc/surfaces/direct_compositor_frame_sink.h index 16a29c1ec44..86210dabab4 100644 --- a/chromium/cc/surfaces/direct_compositor_frame_sink.h +++ b/chromium/cc/surfaces/direct_compositor_frame_sink.h @@ -33,7 +33,9 @@ class CC_SURFACES_EXPORT DirectCompositorFrameSink SurfaceManager* surface_manager, Display* display, scoped_refptr<ContextProvider> context_provider, - scoped_refptr<ContextProvider> worker_context_provider); + scoped_refptr<ContextProvider> worker_context_provider, + gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, + SharedBitmapManager* shared_bitmap_manager); DirectCompositorFrameSink( const FrameSinkId& frame_sink_id, SurfaceManager* surface_manager, @@ -44,7 +46,7 @@ class CC_SURFACES_EXPORT DirectCompositorFrameSink // CompositorFrameSink implementation. bool BindToClient(CompositorFrameSinkClient* client) override; void DetachFromClient() override; - void SwapBuffers(CompositorFrame frame) override; + void SubmitCompositorFrame(CompositorFrame frame) override; void ForceReclaimResources() override; // SurfaceFactoryClient implementation. diff --git a/chromium/cc/surfaces/direct_compositor_frame_sink_unittest.cc b/chromium/cc/surfaces/direct_compositor_frame_sink_unittest.cc index 4291539c1ec..c9d7417a90c 100644 --- a/chromium/cc/surfaces/direct_compositor_frame_sink_unittest.cc +++ b/chromium/cc/surfaces/direct_compositor_frame_sink_unittest.cc @@ -52,12 +52,13 @@ class DirectCompositorFrameSinkTest : public testing::Test { display_.reset(new Display( &bitmap_manager_, &gpu_memory_buffer_manager_, RendererSettings(), - std::move(begin_frame_source), std::move(display_output_surface), - std::move(scheduler), + kArbitraryFrameSinkId, std::move(begin_frame_source), + std::move(display_output_surface), std::move(scheduler), base::MakeUnique<TextureMailboxDeleter>(task_runner_.get()))); compositor_frame_sink_.reset(new DirectCompositorFrameSink( kArbitraryFrameSinkId, &surface_manager_, display_.get(), - context_provider_, nullptr)); + context_provider_, nullptr, &gpu_memory_buffer_manager_, + &bitmap_manager_)); compositor_frame_sink_->BindToClient(&compositor_frame_sink_client_); display_->Resize(display_size_); @@ -67,7 +68,9 @@ class DirectCompositorFrameSinkTest : public testing::Test { compositor_frame_sink_client_.did_lose_compositor_frame_sink_called()); } - ~DirectCompositorFrameSinkTest() override {} + ~DirectCompositorFrameSinkTest() override { + compositor_frame_sink_->DetachFromClient(); + } void SwapBuffersWithDamage(const gfx::Rect& damage_rect) { std::unique_ptr<RenderPass> render_pass(RenderPass::Create()); @@ -80,7 +83,7 @@ class DirectCompositorFrameSinkTest : public testing::Test { CompositorFrame frame; frame.delegated_frame_data = std::move(frame_data); - compositor_frame_sink_->SwapBuffers(std::move(frame)); + compositor_frame_sink_->SubmitCompositorFrame(std::move(frame)); } void SetUp() override { diff --git a/chromium/cc/surfaces/display.cc b/chromium/cc/surfaces/display.cc index 89d6bd4087c..cc904a07420 100644 --- a/chromium/cc/surfaces/display.cc +++ b/chromium/cc/surfaces/display.cc @@ -33,6 +33,7 @@ namespace cc { Display::Display(SharedBitmapManager* bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& settings, + const FrameSinkId& frame_sink_id, std::unique_ptr<BeginFrameSource> begin_frame_source, std::unique_ptr<OutputSurface> output_surface, std::unique_ptr<DisplayScheduler> scheduler, @@ -40,12 +41,14 @@ Display::Display(SharedBitmapManager* bitmap_manager, : bitmap_manager_(bitmap_manager), gpu_memory_buffer_manager_(gpu_memory_buffer_manager), settings_(settings), + frame_sink_id_(frame_sink_id), begin_frame_source_(std::move(begin_frame_source)), output_surface_(std::move(output_surface)), scheduler_(std::move(scheduler)), texture_mailbox_deleter_(std::move(texture_mailbox_deleter)) { DCHECK(output_surface_); DCHECK_EQ(!scheduler_, !begin_frame_source_); + DCHECK(frame_sink_id_.is_valid()); if (scheduler_) scheduler_->SetClient(this); } @@ -53,6 +56,8 @@ Display::Display(SharedBitmapManager* bitmap_manager, Display::~Display() { // Only do this if Initialize() happened. if (client_) { + if (auto* context = output_surface_->context_provider()) + context->SetLostContextCallback(base::Closure()); if (begin_frame_source_) surface_manager_->UnregisterBeginFrameSource(begin_frame_source_.get()); surface_manager_->RemoveObserver(this); @@ -67,13 +72,11 @@ Display::~Display() { } void Display::Initialize(DisplayClient* client, - SurfaceManager* surface_manager, - const FrameSinkId& frame_sink_id) { + SurfaceManager* surface_manager) { DCHECK(client); DCHECK(surface_manager); client_ = client; surface_manager_ = surface_manager; - frame_sink_id_ = frame_sink_id; surface_manager_->AddObserver(this); @@ -84,25 +87,35 @@ void Display::Initialize(DisplayClient* client, frame_sink_id_); } - bool ok = output_surface_->BindToClient(this); - // The context given to the Display's OutputSurface should already be - // initialized, so Bind can not fail. - DCHECK(ok); + output_surface_->BindToClient(this); InitializeRenderer(); + + if (auto* context = output_surface_->context_provider()) { + // This depends on assumptions that Display::Initialize will happen + // on the same callstack as the ContextProvider being created/initialized + // or else it could miss a callback before setting this. + context->SetLostContextCallback(base::Bind( + &Display::DidLoseContextProvider, + // Unretained is safe since the callback is unset in this class' + // destructor and is never posted. + base::Unretained(this))); + } } -void Display::SetSurfaceId(const SurfaceId& id, float device_scale_factor) { - DCHECK(id.frame_sink_id() == frame_sink_id_); - if (current_surface_id_ == id && device_scale_factor_ == device_scale_factor) +void Display::SetLocalFrameId(const LocalFrameId& id, + float device_scale_factor) { + if (current_surface_id_.local_frame_id() == id && + device_scale_factor_ == device_scale_factor) { return; + } TRACE_EVENT0("cc", "Display::SetSurfaceId"); - current_surface_id_ = id; + current_surface_id_ = SurfaceId(frame_sink_id_, id); device_scale_factor_ = device_scale_factor; UpdateRootSurfaceResourcesLocked(); if (scheduler_) - scheduler_->SetNewRootSurface(id); + scheduler_->SetNewRootSurface(current_surface_id_); } void Display::SetVisible(bool visible) { @@ -116,7 +129,7 @@ void Display::SetVisible(bool visible) { if (!visible) { // Damage tracker needs a full reset as renderer resources are dropped when // not visible. - if (aggregator_ && !current_surface_id_.is_null()) + if (aggregator_ && current_surface_id_.is_valid()) aggregator_->SetFullDamageForSurface(current_surface_id_); } } @@ -154,7 +167,7 @@ void Display::SetOutputIsSecure(bool secure) { if (aggregator_) { aggregator_->set_output_is_secure(secure); // Force a redraw. - if (!current_surface_id_.is_null()) + if (current_surface_id_.is_valid()) aggregator_->SetFullDamageForSurface(current_surface_id_); } } @@ -202,14 +215,6 @@ void Display::InitializeRenderer() { aggregator_->set_output_is_secure(output_is_secure_); } -void Display::DidLoseOutputSurface() { - if (scheduler_) - scheduler_->OutputSurfaceLost(); - // WARNING: The client may delete the Display in this method call. Do not - // make any additional references to members after this call. - client_->DisplayOutputSurfaceLost(); -} - void Display::UpdateRootSurfaceResourcesLocked() { Surface* surface = surface_manager_->GetSurfaceForId(current_surface_id_); bool root_surface_resources_locked = @@ -218,10 +223,18 @@ void Display::UpdateRootSurfaceResourcesLocked() { scheduler_->SetRootSurfaceResourcesLocked(root_surface_resources_locked); } +void Display::DidLoseContextProvider() { + if (scheduler_) + scheduler_->OutputSurfaceLost(); + // WARNING: The client may delete the Display in this method call. Do not + // make any additional references to members after this call. + client_->DisplayOutputSurfaceLost(); +} + bool Display::DrawAndSwap() { TRACE_EVENT0("cc", "Display::DrawAndSwap"); - if (current_surface_id_.is_null()) { + if (!current_surface_id_.is_valid()) { TRACE_EVENT_INSTANT0("cc", "No root surface.", TRACE_EVENT_SCOPE_THREAD); return false; } @@ -330,7 +343,7 @@ bool Display::DrawAndSwap() { frame.metadata.latency_info.end()); if (scheduler_) { scheduler_->DidSwapBuffers(); - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveSwapBuffersAck(); } } @@ -338,9 +351,9 @@ bool Display::DrawAndSwap() { return true; } -void Display::DidSwapBuffersComplete() { +void Display::DidReceiveSwapBuffersAck() { if (scheduler_) - scheduler_->DidSwapBuffersComplete(); + scheduler_->DidReceiveSwapBuffersAck(); if (renderer_) renderer_->SwapBuffersComplete(); } @@ -351,43 +364,12 @@ void Display::DidReceiveTextureInUseResponses( renderer_->DidReceiveTextureInUseResponses(responses); } -void Display::SetBeginFrameSource(BeginFrameSource* source) { - // The BeginFrameSource is set from the constructor, it doesn't come - // from the OutputSurface for the Display. - NOTREACHED(); -} - -void Display::SetMemoryPolicy(const ManagedMemoryPolicy& policy) { - // This is only for LayerTreeHostImpl. - NOTREACHED(); -} - -void Display::OnDraw(const gfx::Transform& transform, - const gfx::Rect& viewport, - bool resourceless_software_draw) { - NOTREACHED(); -} - void Display::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { aggregator_->SetFullDamageForSurface(current_surface_id_); if (scheduler_) scheduler_->SurfaceDamaged(current_surface_id_); } -void Display::ReclaimResources(const ReturnedResourceArray& resources) { - NOTREACHED(); -} - -void Display::SetExternalTilePriorityConstraints( - const gfx::Rect& viewport_rect, - const gfx::Transform& transform) { - NOTREACHED(); -} - -void Display::SetTreeActivationCallback(const base::Closure& callback) { - NOTREACHED(); -} - void Display::OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) { if (aggregator_ && aggregator_->previous_contained_surfaces().count(surface_id)) { @@ -412,6 +394,10 @@ void Display::OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) { UpdateRootSurfaceResourcesLocked(); } +void Display::OnSurfaceCreated(const SurfaceId& surface_id, + const gfx::Size& frame, + float device_scale_factor) {} + const SurfaceId& Display::CurrentSurfaceId() { return current_surface_id_; } diff --git a/chromium/cc/surfaces/display.h b/chromium/cc/surfaces/display.h index abc3e73e092..a91ae09938d 100644 --- a/chromium/cc/surfaces/display.h +++ b/chromium/cc/surfaces/display.h @@ -40,10 +40,7 @@ class RendererSettings; class ResourceProvider; class SharedBitmapManager; class SoftwareRenderer; -class Surface; class SurfaceAggregator; -class SurfaceIdAllocator; -class SurfaceFactory; class TextureMailboxDeleter; // A Display produces a surface that can be used to draw to a physical display @@ -51,13 +48,14 @@ class TextureMailboxDeleter; // surface IDs used to draw into the display and deciding when to draw. class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, public OutputSurfaceClient, - public SurfaceDamageObserver { + public SurfaceObserver { public: // The |begin_frame_source| and |scheduler| may be null (together). In that // case, DrawAndSwap must be called externally when needed. Display(SharedBitmapManager* bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& settings, + const FrameSinkId& frame_sink_id, std::unique_ptr<BeginFrameSource> begin_frame_source, std::unique_ptr<OutputSurface> output_surface, std::unique_ptr<DisplayScheduler> scheduler, @@ -65,13 +63,11 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, ~Display() override; - void Initialize(DisplayClient* client, - SurfaceManager* surface_manager, - const FrameSinkId& frame_sink_id); + void Initialize(DisplayClient* client, SurfaceManager* surface_manager); // device_scale_factor is used to communicate to the external window system // what scale this was rendered at. - void SetSurfaceId(const SurfaceId& id, float device_scale_factor); + void SetLocalFrameId(const LocalFrameId& id, float device_scale_factor); void SetVisible(bool visible); void Resize(const gfx::Size& new_size); void SetColorSpace(const gfx::ColorSpace& color_space); @@ -83,24 +79,16 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, bool DrawAndSwap() override; // OutputSurfaceClient implementation. - void SetBeginFrameSource(BeginFrameSource* source) override; void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override; - void DidSwapBuffersComplete() override; + void DidReceiveSwapBuffersAck() override; void DidReceiveTextureInUseResponses( const gpu::TextureInUseResponses& responses) override; - void ReclaimResources(const ReturnedResourceArray& resources) override; - void DidLoseOutputSurface() override; - void SetExternalTilePriorityConstraints( - const gfx::Rect& viewport_rect, - const gfx::Transform& transform) override; - void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override; - void SetTreeActivationCallback(const base::Closure& callback) override; - void OnDraw(const gfx::Transform& transform, - const gfx::Rect& viewport, - bool resourceless_software_draw) override; - - // SurfaceDamageObserver implementation. + + // SurfaceObserver implementation. void OnSurfaceDamaged(const SurfaceId& surface, bool* changed) override; + void OnSurfaceCreated(const SurfaceId& surface_id, + const gfx::Size& frame, + float device_scale_factor) override; bool has_scheduler() const { return !!scheduler_; } DirectRenderer* renderer_for_testing() const { return renderer_.get(); } @@ -110,6 +98,7 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, private: void InitializeRenderer(); void UpdateRootSurfaceResourcesLocked(); + void DidLoseContextProvider(); SharedBitmapManager* const bitmap_manager_; gpu::GpuMemoryBufferManager* const gpu_memory_buffer_manager_; @@ -117,7 +106,7 @@ class CC_SURFACES_EXPORT Display : public DisplaySchedulerClient, DisplayClient* client_ = nullptr; SurfaceManager* surface_manager_ = nullptr; - FrameSinkId frame_sink_id_; + const FrameSinkId frame_sink_id_; SurfaceId current_surface_id_; gfx::Size current_surface_size_; float device_scale_factor_ = 1.f; diff --git a/chromium/cc/surfaces/display_client.h b/chromium/cc/surfaces/display_client.h index 3f4c8ee10c1..85dff1742da 100644 --- a/chromium/cc/surfaces/display_client.h +++ b/chromium/cc/surfaces/display_client.h @@ -8,7 +8,6 @@ #include "cc/quads/render_pass.h" namespace cc { -struct ManagedMemoryPolicy; class DisplayClient { public: diff --git a/chromium/cc/surfaces/display_scheduler.cc b/chromium/cc/surfaces/display_scheduler.cc index 6a5e1632da2..229bc6306cc 100644 --- a/chromium/cc/surfaces/display_scheduler.cc +++ b/chromium/cc/surfaces/display_scheduler.cc @@ -360,7 +360,7 @@ void DisplayScheduler::DidSwapBuffers() { "pending_frames", pending_swaps_); } -void DisplayScheduler::DidSwapBuffersComplete() { +void DisplayScheduler::DidReceiveSwapBuffersAck() { pending_swaps_--; TRACE_EVENT_ASYNC_END1("cc", "DisplayScheduler:pending_swaps", this, "pending_frames", pending_swaps_); diff --git a/chromium/cc/surfaces/display_scheduler.h b/chromium/cc/surfaces/display_scheduler.h index 8ad91450b68..f6822878936 100644 --- a/chromium/cc/surfaces/display_scheduler.h +++ b/chromium/cc/surfaces/display_scheduler.h @@ -18,7 +18,6 @@ namespace cc { -class OutputSurface; class BeginFrameSource; class CC_SURFACES_EXPORT DisplaySchedulerClient { @@ -45,7 +44,7 @@ class CC_SURFACES_EXPORT DisplayScheduler : public BeginFrameObserverBase { virtual void SurfaceDamaged(const SurfaceId& surface_id); virtual void DidSwapBuffers(); - void DidSwapBuffersComplete(); + void DidReceiveSwapBuffersAck(); void OutputSurfaceLost(); diff --git a/chromium/cc/surfaces/display_scheduler_unittest.cc b/chromium/cc/surfaces/display_scheduler_unittest.cc index d7a78df215f..ea7a22fba5a 100644 --- a/chromium/cc/surfaces/display_scheduler_unittest.cc +++ b/chromium/cc/surfaces/display_scheduler_unittest.cc @@ -106,9 +106,12 @@ class DisplaySchedulerTest : public testing::Test { }; TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) { - SurfaceId root_surface_id1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); - SurfaceId root_surface_id2(kArbitraryFrameSinkId, LocalFrameId(2, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(3, 0)); + SurfaceId root_surface_id1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); + SurfaceId root_surface_id2(kArbitraryFrameSinkId, + LocalFrameId(2, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(3, base::UnguessableToken::Create())); base::TimeTicks late_deadline; scheduler_.SetVisible(true); @@ -143,8 +146,10 @@ TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) { } TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilDamagedSurface) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(1, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(2, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(2, base::UnguessableToken::Create())); base::TimeTicks late_deadline; scheduler_.SetVisible(true); @@ -179,9 +184,12 @@ TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilDamagedSurface) { } TEST_F(DisplaySchedulerTest, SurfaceDamaged) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); - SurfaceId sid2(kArbitraryFrameSinkId, LocalFrameId(2, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); + SurfaceId sid2(kArbitraryFrameSinkId, + LocalFrameId(2, base::UnguessableToken::Create())); scheduler_.SetVisible(true); @@ -245,8 +253,10 @@ TEST_F(DisplaySchedulerTest, SurfaceDamaged) { } TEST_F(DisplaySchedulerTest, OutputSurfaceLost) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); scheduler_.SetVisible(true); @@ -278,8 +288,10 @@ TEST_F(DisplaySchedulerTest, OutputSurfaceLost) { } TEST_F(DisplaySchedulerTest, VisibleWithoutDamageNoTicks) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); EXPECT_EQ(0u, fake_begin_frame_source_.num_observers()); scheduler_.SetVisible(true); @@ -293,8 +305,10 @@ TEST_F(DisplaySchedulerTest, VisibleWithoutDamageNoTicks) { } TEST_F(DisplaySchedulerTest, VisibleWithDamageTicks) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); scheduler_.SetNewRootSurface(root_surface_id); @@ -307,8 +321,10 @@ TEST_F(DisplaySchedulerTest, VisibleWithDamageTicks) { } TEST_F(DisplaySchedulerTest, Visibility) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); scheduler_.SetNewRootSurface(root_surface_id); scheduler_.SetVisible(true); @@ -356,8 +372,10 @@ TEST_F(DisplaySchedulerTest, Visibility) { } TEST_F(DisplaySchedulerTest, ResizeCausesSwap) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); scheduler_.SetVisible(true); @@ -381,8 +399,10 @@ TEST_F(DisplaySchedulerTest, ResizeCausesSwap) { } TEST_F(DisplaySchedulerTest, RootSurfaceResourcesLocked) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); base::TimeTicks late_deadline; scheduler_.SetVisible(true); @@ -429,9 +449,12 @@ TEST_F(DisplaySchedulerTest, RootSurfaceResourcesLocked) { } TEST_F(DisplaySchedulerTest, DidSwapBuffers) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(0, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(1, 0)); - SurfaceId sid2(kArbitraryFrameSinkId, LocalFrameId(2, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(0, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); + SurfaceId sid2(kArbitraryFrameSinkId, + LocalFrameId(2, base::UnguessableToken::Create())); scheduler_.SetVisible(true); @@ -478,7 +501,7 @@ TEST_F(DisplaySchedulerTest, DidSwapBuffers) { base::TimeTicks expected_deadline = scheduler_.LastUsedBeginFrameArgs().deadline - BeginFrameArgs::DefaultEstimatedParentDrawTime(); - scheduler_.DidSwapBuffersComplete(); + scheduler_.DidReceiveSwapBuffersAck(); BeginFrameForTest(); EXPECT_EQ(expected_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest()); @@ -496,8 +519,10 @@ TEST_F(DisplaySchedulerTest, DidSwapBuffers) { // This test verfies that we try to reschedule the deadline // after any event that may change what deadline we want. TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) { - SurfaceId root_surface_id(kArbitraryFrameSinkId, LocalFrameId(1, 0)); - SurfaceId sid1(kArbitraryFrameSinkId, LocalFrameId(2, 0)); + SurfaceId root_surface_id(kArbitraryFrameSinkId, + LocalFrameId(1, base::UnguessableToken::Create())); + SurfaceId sid1(kArbitraryFrameSinkId, + LocalFrameId(2, base::UnguessableToken::Create())); int count = 1; EXPECT_EQ(count, scheduler_.scheduler_begin_frame_deadline_count()); @@ -529,7 +554,7 @@ TEST_F(DisplaySchedulerTest, ScheduleBeginFrameDeadline) { BeginFrameForTest(); EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count()); - scheduler_.DidSwapBuffersComplete(); + scheduler_.DidReceiveSwapBuffersAck(); EXPECT_EQ(++count, scheduler_.scheduler_begin_frame_deadline_count()); scheduler_.DisplayResized(); diff --git a/chromium/cc/surfaces/display_unittest.cc b/chromium/cc/surfaces/display_unittest.cc index b8b814e145e..184fc011286 100644 --- a/chromium/cc/surfaces/display_unittest.cc +++ b/chromium/cc/surfaces/display_unittest.cc @@ -25,6 +25,7 @@ #include "cc/test/fake_output_surface.h" #include "cc/test/scheduler_test_common.h" #include "cc/test/test_shared_bitmap_manager.h" +#include "gpu/GLES2/gl2extchromium.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -115,7 +116,9 @@ class DisplayTest : public testing::Test { std::unique_ptr<FakeOutputSurface> output_surface; if (context) { - output_surface = FakeOutputSurface::Create3d(std::move(context)); + auto provider = TestContextProvider::Create(std::move(context)); + provider->BindToCurrentThread(); + output_surface = FakeOutputSurface::Create3d(std::move(provider)); } else { std::unique_ptr<TestSoftwareOutputDevice> device( new TestSoftwareOutputDevice); @@ -130,8 +133,8 @@ class DisplayTest : public testing::Test { display_ = base::MakeUnique<Display>( &shared_bitmap_manager_, nullptr /* gpu_memory_buffer_manager */, - settings, std::move(begin_frame_source), std::move(output_surface), - std::move(scheduler), + settings, kArbitraryFrameSinkId, std::move(begin_frame_source), + std::move(output_surface), std::move(scheduler), base::MakeUnique<TextureMailboxDeleter>(task_runner_.get())); display_->SetVisible(true); } @@ -181,13 +184,12 @@ TEST_F(DisplayTest, DisplayDamaged) { SetUpDisplay(settings, nullptr); StubDisplayClient client; - display_->Initialize(&client, &manager_, kArbitraryFrameSinkId); + display_->Initialize(&client, &manager_); LocalFrameId local_frame_id(id_allocator_.GenerateId()); - SurfaceId surface_id(factory_.frame_sink_id(), local_frame_id); EXPECT_FALSE(scheduler_->damaged); EXPECT_FALSE(scheduler_->has_new_root_surface); - display_->SetSurfaceId(surface_id, 1.f); + display_->SetLocalFrameId(local_frame_id, 1.f); EXPECT_FALSE(scheduler_->damaged); EXPECT_FALSE(scheduler_->display_resized_); EXPECT_TRUE(scheduler_->has_new_root_surface); @@ -431,7 +433,6 @@ class MockedContext : public TestWebGraphicsContext3D { TEST_F(DisplayTest, Finish) { LocalFrameId local_frame_id(id_allocator_.GenerateId()); - SurfaceId surface_id(factory_.frame_sink_id(), local_frame_id); RendererSettings settings; settings.partial_swap_enabled = true; @@ -444,9 +445,9 @@ TEST_F(DisplayTest, Finish) { SetUpDisplay(settings, std::move(context)); StubDisplayClient client; - display_->Initialize(&client, &manager_, kArbitraryFrameSinkId); + display_->Initialize(&client, &manager_); - display_->SetSurfaceId(surface_id, 1.f); + display_->SetLocalFrameId(local_frame_id, 1.f); display_->Resize(gfx::Size(100, 100)); factory_.Create(local_frame_id); @@ -499,5 +500,31 @@ TEST_F(DisplayTest, Finish) { factory_.Destroy(local_frame_id); } +class CountLossDisplayClient : public StubDisplayClient { + public: + CountLossDisplayClient() = default; + + void DisplayOutputSurfaceLost() override { ++loss_count_; } + + int loss_count() const { return loss_count_; } + + private: + int loss_count_ = 0; +}; + +TEST_F(DisplayTest, ContextLossInformsClient) { + SetUpDisplay(RendererSettings(), TestWebGraphicsContext3D::Create()); + + CountLossDisplayClient client; + display_->Initialize(&client, &manager_); + + // Verify DidLoseOutputSurface callback is hooked up correctly. + EXPECT_EQ(0, client.loss_count()); + output_surface_->context_provider()->ContextGL()->LoseContextCHROMIUM( + GL_GUILTY_CONTEXT_RESET_ARB, GL_INNOCENT_CONTEXT_RESET_ARB); + output_surface_->context_provider()->ContextGL()->Flush(); + EXPECT_EQ(1, client.loss_count()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/surfaces/frame_sink_id.h b/chromium/cc/surfaces/frame_sink_id.h index b8f3675fd21..d65c8de8d47 100644 --- a/chromium/cc/surfaces/frame_sink_id.h +++ b/chromium/cc/surfaces/frame_sink_id.h @@ -23,7 +23,7 @@ class FrameSinkId { constexpr FrameSinkId(uint32_t client_id, uint32_t sink_id) : client_id_(client_id), sink_id_(sink_id) {} - constexpr bool is_null() const { return client_id_ == 0 && sink_id_ == 0; } + constexpr bool is_valid() const { return client_id_ != 0 || sink_id_ != 0; } constexpr uint32_t client_id() const { return client_id_; } diff --git a/chromium/cc/surfaces/local_frame_id.h b/chromium/cc/surfaces/local_frame_id.h index 859e0070e8d..c3ac7822b79 100644 --- a/chromium/cc/surfaces/local_frame_id.h +++ b/chromium/cc/surfaces/local_frame_id.h @@ -10,24 +10,27 @@ #include "base/hash.h" #include "base/strings/stringprintf.h" +#include "base/unguessable_token.h" namespace cc { class LocalFrameId { public: - constexpr LocalFrameId() : local_id_(0), nonce_(0) {} + constexpr LocalFrameId() : local_id_(0) {} constexpr LocalFrameId(const LocalFrameId& other) : local_id_(other.local_id_), nonce_(other.nonce_) {} - constexpr LocalFrameId(uint32_t local_id, uint64_t nonce) + constexpr LocalFrameId(uint32_t local_id, const base::UnguessableToken& nonce) : local_id_(local_id), nonce_(nonce) {} - constexpr bool is_null() const { return local_id_ == 0 && nonce_ == 0; } + constexpr bool is_valid() const { + return local_id_ != 0 && !nonce_.is_empty(); + } constexpr uint32_t local_id() const { return local_id_; } - constexpr uint64_t nonce() const { return nonce_; } + constexpr const base::UnguessableToken& nonce() const { return nonce_; } bool operator==(const LocalFrameId& other) const { return local_id_ == other.local_id_ && nonce_ == other.nonce_; @@ -40,16 +43,19 @@ class LocalFrameId { std::tie(other.local_id_, other.nonce_); } - size_t hash() const { return base::HashInts(local_id_, nonce_); } + size_t hash() const { + return base::HashInts( + local_id_, static_cast<uint64_t>(base::UnguessableTokenHash()(nonce_))); + } std::string ToString() const { - return base::StringPrintf("LocalFrameId(%d, %" PRIu64 ")", local_id_, - nonce_); + return base::StringPrintf("LocalFrameId(%d, %s" PRIu64 ")", local_id_, + nonce_.ToString().c_str()); } private: uint32_t local_id_; - uint64_t nonce_; + base::UnguessableToken nonce_; }; struct LocalFrameIdHash { diff --git a/chromium/cc/surfaces/surface.cc b/chromium/cc/surfaces/surface.cc index c9c24bca2de..6ef97a22c9d 100644 --- a/chromium/cc/surfaces/surface.cc +++ b/chromium/cc/surfaces/surface.cc @@ -22,10 +22,10 @@ namespace cc { // completely damaged the first time they're drawn from. static const int kFrameIndexStart = 2; -Surface::Surface(const SurfaceId& id, SurfaceFactory* factory) +Surface::Surface(const SurfaceId& id, base::WeakPtr<SurfaceFactory> factory) : surface_id_(id), previous_frame_surface_id_(id), - factory_(factory->AsWeakPtr()), + factory_(factory), frame_index_(kFrameIndexStart), destroyed_(false) {} diff --git a/chromium/cc/surfaces/surface.h b/chromium/cc/surfaces/surface.h index 9036d856b3b..2e18b2d6b11 100644 --- a/chromium/cc/surfaces/surface.h +++ b/chromium/cc/surfaces/surface.h @@ -31,17 +31,17 @@ class LatencyInfo; } namespace cc { + +class BeginFrameSource; class CompositorFrame; class CopyOutputRequest; -class SurfaceManager; class SurfaceFactory; -class SurfaceResourceHolder; class CC_SURFACES_EXPORT Surface { public: using DrawCallback = SurfaceFactory::DrawCallback; - Surface(const SurfaceId& id, SurfaceFactory* factory); + Surface(const SurfaceId& id, base::WeakPtr<SurfaceFactory> factory); ~Surface(); const SurfaceId& surface_id() const { return surface_id_; } diff --git a/chromium/cc/surfaces/surface_aggregator_perftest.cc b/chromium/cc/surfaces/surface_aggregator_perftest.cc index 828518d7325..60f636aefc0 100644 --- a/chromium/cc/surfaces/surface_aggregator_perftest.cc +++ b/chromium/cc/surfaces/surface_aggregator_perftest.cc @@ -23,6 +23,8 @@ namespace cc { namespace { static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); +static const base::UnguessableToken kArbitraryToken = + base::UnguessableToken::Create(); class EmptySurfaceFactoryClient : public SurfaceFactoryClient { public: @@ -51,7 +53,7 @@ class SurfaceAggregatorPerfTest : public testing::Test { aggregator_.reset(new SurfaceAggregator(&manager_, resource_provider_.get(), optimize_damage)); for (int i = 1; i <= num_surfaces; i++) { - LocalFrameId local_frame_id(i, 0); + LocalFrameId local_frame_id(i, kArbitraryToken); factory_.Create(local_frame_id); std::unique_ptr<RenderPass> pass(RenderPass::Create()); std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); @@ -88,9 +90,9 @@ class SurfaceAggregatorPerfTest : public testing::Test { if (i > 1) { SurfaceDrawQuad* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); - surface_quad->SetNew( - sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1), - SurfaceId(kArbitraryFrameSinkId, LocalFrameId(i - 1, 0))); + surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1), + SurfaceId(kArbitraryFrameSinkId, + LocalFrameId(i - 1, kArbitraryToken))); } frame_data->render_pass_list.push_back(std::move(pass)); @@ -100,7 +102,7 @@ class SurfaceAggregatorPerfTest : public testing::Test { SurfaceFactory::DrawCallback()); } - factory_.Create(LocalFrameId(num_surfaces + 1, 0)); + factory_.Create(LocalFrameId(num_surfaces + 1, kArbitraryToken)); timer_.Reset(); do { std::unique_ptr<RenderPass> pass(RenderPass::Create()); @@ -111,7 +113,8 @@ class SurfaceAggregatorPerfTest : public testing::Test { pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); surface_quad->SetNew( sqs, gfx::Rect(0, 0, 100, 100), gfx::Rect(0, 0, 100, 100), - SurfaceId(kArbitraryFrameSinkId, LocalFrameId(num_surfaces, 0))); + SurfaceId(kArbitraryFrameSinkId, + LocalFrameId(num_surfaces, kArbitraryToken))); if (full_damage) pass->damage_rect = gfx::Rect(0, 0, 100, 100); @@ -121,21 +124,22 @@ class SurfaceAggregatorPerfTest : public testing::Test { frame_data->render_pass_list.push_back(std::move(pass)); CompositorFrame frame; frame.delegated_frame_data = std::move(frame_data); - factory_.SubmitCompositorFrame(LocalFrameId(num_surfaces + 1, 0), - std::move(frame), - SurfaceFactory::DrawCallback()); + factory_.SubmitCompositorFrame( + LocalFrameId(num_surfaces + 1, kArbitraryToken), std::move(frame), + SurfaceFactory::DrawCallback()); CompositorFrame aggregated = aggregator_->Aggregate( - SurfaceId(kArbitraryFrameSinkId, LocalFrameId(num_surfaces + 1, 0))); + SurfaceId(kArbitraryFrameSinkId, + LocalFrameId(num_surfaces + 1, kArbitraryToken))); timer_.NextLap(); } while (!timer_.HasTimeLimitExpired()); perf_test::PrintResult("aggregator_speed", "", name, timer_.LapsPerSecond(), "runs/s", true); - factory_.Destroy(LocalFrameId(num_surfaces + 1, 0)); + factory_.Destroy(LocalFrameId(num_surfaces + 1, kArbitraryToken)); for (int i = 1; i <= num_surfaces; i++) - factory_.Destroy(LocalFrameId(i, 0)); + factory_.Destroy(LocalFrameId(i, kArbitraryToken)); } protected: diff --git a/chromium/cc/surfaces/surface_aggregator_unittest.cc b/chromium/cc/surfaces/surface_aggregator_unittest.cc index da6a68c0127..aa8210e868a 100644 --- a/chromium/cc/surfaces/surface_aggregator_unittest.cc +++ b/chromium/cc/surfaces/surface_aggregator_unittest.cc @@ -37,9 +37,12 @@ namespace { static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); static constexpr FrameSinkId kArbitraryChildFrameSinkId(2, 2); +static const base::UnguessableToken kArbitraryToken = + base::UnguessableToken::Create(); SurfaceId InvalidSurfaceId() { - static SurfaceId invalid(kArbitraryFrameSinkId, LocalFrameId(0xdeadbeef, 0)); + static SurfaceId invalid(kArbitraryFrameSinkId, + LocalFrameId(0xdeadbeef, kArbitraryToken)); return invalid; } @@ -80,7 +83,7 @@ class SurfaceAggregatorTest : public testing::Test { }; TEST_F(SurfaceAggregatorTest, ValidSurfaceNoFrame) { - LocalFrameId local_frame_id(7, 0); + LocalFrameId local_frame_id(7, base::UnguessableToken::Create()); SurfaceId one_id(kArbitraryFrameSinkId, local_frame_id); factory_.Create(local_frame_id); @@ -1946,7 +1949,7 @@ void SubmitCompositorFrameWithResources(ResourceId* resource_ids, pass->id = RenderPassId(1, 1); SharedQuadState* sqs = pass->CreateAndAppendSharedQuadState(); sqs->opacity = 1.f; - if (!child_id.is_null()) { + if (child_id.is_valid()) { SurfaceDrawQuad* surface_quad = pass->CreateAndAppendDrawQuad<SurfaceDrawQuad>(); surface_quad->SetNew(sqs, gfx::Rect(0, 0, 1, 1), gfx::Rect(0, 0, 1, 1), @@ -1987,7 +1990,7 @@ void SubmitCompositorFrameWithResources(ResourceId* resource_ids, TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) { ResourceTrackingSurfaceFactoryClient client; SurfaceFactory factory(kArbitraryFrameSinkId, &manager_, &client); - LocalFrameId local_frame_id(7u, 0); + LocalFrameId local_frame_id(7u, base::UnguessableToken::Create()); SurfaceId surface_id(kArbitraryFrameSinkId, local_frame_id); factory.Create(local_frame_id); @@ -2018,7 +2021,7 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeResourcesOneSurface) { TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { ResourceTrackingSurfaceFactoryClient client; SurfaceFactory factory(kArbitraryFrameSinkId, &manager_, &client); - LocalFrameId local_frame_id(7u, 0); + LocalFrameId local_frame_id(7u, base::UnguessableToken::Create()); SurfaceId surface_id(kArbitraryFrameSinkId, local_frame_id); factory.Create(local_frame_id); @@ -2053,11 +2056,11 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TakeInvalidResources) { TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) { ResourceTrackingSurfaceFactoryClient client; SurfaceFactory factory(kArbitraryFrameSinkId, &manager_, &client); - LocalFrameId local_frame1_id(7u, 0); + LocalFrameId local_frame1_id(7u, base::UnguessableToken::Create()); SurfaceId surface1_id(kArbitraryFrameSinkId, local_frame1_id); factory.Create(local_frame1_id); - LocalFrameId local_frame2_id(8u, 0); + LocalFrameId local_frame2_id(8u, base::UnguessableToken::Create()); SurfaceId surface2_id(kArbitraryFrameSinkId, local_frame2_id); factory.Create(local_frame2_id); @@ -2096,13 +2099,13 @@ TEST_F(SurfaceAggregatorWithResourcesTest, TwoSurfaces) { TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { ResourceTrackingSurfaceFactoryClient client; SurfaceFactory factory(kArbitraryFrameSinkId, &manager_, &client); - LocalFrameId root_local_frame_id(7u, 0); + LocalFrameId root_local_frame_id(7u, kArbitraryToken); SurfaceId root_surface_id(kArbitraryFrameSinkId, root_local_frame_id); factory.Create(root_local_frame_id); - LocalFrameId middle_local_frame_id(8u, 0); + LocalFrameId middle_local_frame_id(8u, kArbitraryToken); SurfaceId middle_surface_id(kArbitraryFrameSinkId, middle_local_frame_id); factory.Create(middle_local_frame_id); - LocalFrameId child_local_frame_id(9u, 0); + LocalFrameId child_local_frame_id(9u, kArbitraryToken); SurfaceId child_surface_id(kArbitraryFrameSinkId, child_local_frame_id); factory.Create(child_local_frame_id); @@ -2127,7 +2130,6 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { ASSERT_EQ(1u, pass_list->size()); EXPECT_EQ(1u, pass_list->back()->shared_quad_state_list.size()); EXPECT_EQ(3u, pass_list->back()->quad_list.size()); - SubmitCompositorFrameWithResources(ids2, arraysize(ids), true, child_surface_id, &factory, middle_surface_id); @@ -2147,11 +2149,11 @@ TEST_F(SurfaceAggregatorWithResourcesTest, InvalidChildSurface) { TEST_F(SurfaceAggregatorWithResourcesTest, SecureOutputTexture) { ResourceTrackingSurfaceFactoryClient client; SurfaceFactory factory(kArbitraryFrameSinkId, &manager_, &client); - LocalFrameId local_frame1_id(7u, 0); + LocalFrameId local_frame1_id(7u, base::UnguessableToken::Create()); SurfaceId surface1_id(kArbitraryFrameSinkId, local_frame1_id); factory.Create(local_frame1_id); - LocalFrameId local_frame2_id(8u, 0); + LocalFrameId local_frame2_id(8u, base::UnguessableToken::Create()); SurfaceId surface2_id(kArbitraryFrameSinkId, local_frame2_id); factory.Create(local_frame2_id); diff --git a/chromium/cc/surfaces/surface_damage_observer.h b/chromium/cc/surfaces/surface_damage_observer.h deleted file mode 100644 index b266e6e508e..00000000000 --- a/chromium/cc/surfaces/surface_damage_observer.h +++ /dev/null @@ -1,21 +0,0 @@ -// 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. - -#ifndef CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_ -#define CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_ - -namespace cc { - -class SurfaceId; - -class SurfaceDamageObserver { - public: - // Runs when a Surface is damaged. *changed should be set to true if this - // causes a Display to be damaged. - virtual void OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) = 0; -}; - -} // namespace cc - -#endif // CC_SURFACES_SURFACE_DAMAGE_OBSERVER_H_ diff --git a/chromium/cc/surfaces/surface_factory.cc b/chromium/cc/surfaces/surface_factory.cc index ed66e1bd319..3e3ace31351 100644 --- a/chromium/cc/surfaces/surface_factory.cc +++ b/chromium/cc/surfaces/surface_factory.cc @@ -22,7 +22,8 @@ SurfaceFactory::SurfaceFactory(const FrameSinkId& frame_sink_id, manager_(manager), client_(client), holder_(client), - needs_sync_points_(true) {} + needs_sync_points_(true), + weak_factory_(this) {} SurfaceFactory::~SurfaceFactory() { if (!surface_map_.empty()) { @@ -40,9 +41,17 @@ void SurfaceFactory::DestroyAll() { surface_map_.clear(); } +void SurfaceFactory::Reset() { + DestroyAll(); + // Disown Surfaces that are still alive so that they don't try to unref + // resources that we're not tracking any more. + weak_factory_.InvalidateWeakPtrs(); + holder_.Reset(); +} + void SurfaceFactory::Create(const LocalFrameId& local_frame_id) { - std::unique_ptr<Surface> surface(base::MakeUnique<Surface>( - SurfaceId(frame_sink_id_, local_frame_id), this)); + auto surface(base::MakeUnique<Surface>( + SurfaceId(frame_sink_id_, local_frame_id), weak_factory_.GetWeakPtr())); manager_->RegisterSurface(surface.get()); DCHECK(!surface_map_.count(local_frame_id)); surface_map_[local_frame_id] = std::move(surface); @@ -76,6 +85,21 @@ void SurfaceFactory::SubmitCompositorFrame(const LocalFrameId& local_frame_id, OwningSurfaceMap::iterator it = surface_map_.find(local_frame_id); DCHECK(it != surface_map_.end()); DCHECK(it->second->factory().get() == this); + const CompositorFrame& previous_frame = it->second->GetEligibleFrame(); + // Tell the SurfaceManager if this is the first frame submitted with this + // LocalFrameId. + if (!previous_frame.delegated_frame_data) { + float device_scale_factor = frame.metadata.device_scale_factor; + gfx::Size frame_size; + // CompositorFrames may not be populated with a RenderPass in unit tests. + if (frame.delegated_frame_data && + !frame.delegated_frame_data->render_pass_list.empty()) { + frame_size = + frame.delegated_frame_data->render_pass_list[0]->output_rect.size(); + } + manager_->SurfaceCreated(it->second->surface_id(), frame_size, + device_scale_factor); + } it->second->QueueFrame(std::move(frame), callback); if (!manager_->SurfaceModified(SurfaceId(frame_sink_id_, local_frame_id))) { TRACE_EVENT_INSTANT0("cc", "Damage not visible.", TRACE_EVENT_SCOPE_THREAD); diff --git a/chromium/cc/surfaces/surface_factory.h b/chromium/cc/surfaces/surface_factory.h index f392db20f23..cb25678a6c6 100644 --- a/chromium/cc/surfaces/surface_factory.h +++ b/chromium/cc/surfaces/surface_factory.h @@ -19,12 +19,7 @@ #include "cc/surfaces/surface_sequence.h" #include "cc/surfaces/surfaces_export.h" -namespace gfx { -class Size; -} - namespace cc { -class BeginFrameSource; class CopyOutputRequest; class Surface; class SurfaceFactoryClient; @@ -35,8 +30,7 @@ class SurfaceManager; // submitted to frames created by a particular factory will be returned to that // factory's client when they are no longer being used. This is the only class // most users of surfaces will need to directly interact with. -class CC_SURFACES_EXPORT SurfaceFactory - : public base::SupportsWeakPtr<SurfaceFactory> { +class CC_SURFACES_EXPORT SurfaceFactory { public: using DrawCallback = base::Callback<void()>; @@ -49,8 +43,14 @@ class CC_SURFACES_EXPORT SurfaceFactory void Create(const LocalFrameId& local_frame_id); void Destroy(const LocalFrameId& local_frame_id); + + // Destroys all surfaces. void DestroyAll(); + // Destroys and disown all surfaces, and reset all resource references. This + // is useful when resources are invalid (e.g. lost context). + void Reset(); + // Set that the current frame on new_id is to be treated as the successor to // the current frame on old_id for the purposes of calculating damage. void SetPreviousFrameSurface(const LocalFrameId& new_id, @@ -98,6 +98,8 @@ class CC_SURFACES_EXPORT SurfaceFactory unordered_map<LocalFrameId, std::unique_ptr<Surface>, LocalFrameIdHash>; OwningSurfaceMap surface_map_; + base::WeakPtrFactory<SurfaceFactory> weak_factory_; + DISALLOW_COPY_AND_ASSIGN(SurfaceFactory); }; diff --git a/chromium/cc/surfaces/surface_factory_client.h b/chromium/cc/surfaces/surface_factory_client.h index e0c8b5e107d..7f27b4626ce 100644 --- a/chromium/cc/surfaces/surface_factory_client.h +++ b/chromium/cc/surfaces/surface_factory_client.h @@ -13,7 +13,6 @@ namespace cc { class BeginFrameSource; -class SurfaceId; class CC_SURFACES_EXPORT SurfaceFactoryClient { public: diff --git a/chromium/cc/surfaces/surface_factory_unittest.cc b/chromium/cc/surfaces/surface_factory_unittest.cc index 93a7cc58c5e..4964a291d7b 100644 --- a/chromium/cc/surfaces/surface_factory_unittest.cc +++ b/chromium/cc/surfaces/surface_factory_unittest.cc @@ -27,6 +27,9 @@ namespace cc { namespace { static constexpr FrameSinkId kArbitraryFrameSinkId(1, 1); +static constexpr FrameSinkId kAnotherArbitraryFrameSinkId(2, 2); +static const base::UnguessableToken kArbitraryToken = + base::UnguessableToken::Create(); class TestSurfaceFactoryClient : public SurfaceFactoryClient { public: @@ -64,25 +67,36 @@ gpu::SyncToken GenTestSyncToken(int id) { return token; } -class SurfaceFactoryTest : public testing::Test, public SurfaceDamageObserver { +class SurfaceFactoryTest : public testing::Test, public SurfaceObserver { public: SurfaceFactoryTest() : factory_( new SurfaceFactory(kArbitraryFrameSinkId, &manager_, &client_)), - local_frame_id_(3, 0), + local_frame_id_(3, kArbitraryToken), frame_sync_token_(GenTestSyncToken(4)), consumer_sync_token_(GenTestSyncToken(5)) { manager_.AddObserver(this); factory_->Create(local_frame_id_); } - // SurfaceDamageObserver implementation. + const SurfaceId& last_created_surface_id() const { + return last_created_surface_id_; + } + + // SurfaceObserver implementation. + void OnSurfaceCreated(const SurfaceId& surface_id, + const gfx::Size& frame, + float device_scale_factor) override { + EXPECT_EQ(kArbitraryFrameSinkId, surface_id.frame_sink_id()); + last_created_surface_id_ = surface_id; + } + void OnSurfaceDamaged(const SurfaceId& id, bool* changed) override { *changed = true; } ~SurfaceFactoryTest() override { - if (!local_frame_id_.is_null()) + if (local_frame_id_.is_valid()) factory_->Destroy(local_frame_id_); manager_.RemoveObserver(this); } @@ -101,6 +115,7 @@ class SurfaceFactoryTest : public testing::Test, public SurfaceDamageObserver { frame.delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(local_frame_id_, std::move(frame), SurfaceFactory::DrawCallback()); + EXPECT_EQ(last_created_surface_id_.local_frame_id(), local_frame_id_); } void UnrefResources(ResourceId* ids_to_unref, @@ -145,6 +160,7 @@ class SurfaceFactoryTest : public testing::Test, public SurfaceDamageObserver { TestSurfaceFactoryClient client_; std::unique_ptr<SurfaceFactory> factory_; LocalFrameId local_frame_id_; + SurfaceId last_created_surface_id_; // This is the sync token submitted with the frame. It should never be // returned to the client. @@ -423,7 +439,7 @@ TEST_F(SurfaceFactoryTest, ResourceLifetime) { } TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) { - LocalFrameId local_frame_id(6, 0); + LocalFrameId local_frame_id(6, kArbitraryToken); SurfaceId surface_id(kArbitraryFrameSinkId, local_frame_id); factory_->Create(local_frame_id); Surface* surface = manager_.GetSurfaceForId(surface_id); @@ -435,19 +451,20 @@ TEST_F(SurfaceFactoryTest, BlankNoIndexIncrement) { factory_->SubmitCompositorFrame(local_frame_id, std::move(frame), SurfaceFactory::DrawCallback()); EXPECT_EQ(2, surface->frame_index()); + EXPECT_EQ(last_created_surface_id().local_frame_id(), local_frame_id); factory_->Destroy(local_frame_id); } void CreateSurfaceDrawCallback(SurfaceFactory* factory, uint32_t* execute_count) { - LocalFrameId new_id(7, 0); + LocalFrameId new_id(7, base::UnguessableToken::Create()); factory->Create(new_id); factory->Destroy(new_id); *execute_count += 1; } TEST_F(SurfaceFactoryTest, AddDuringDestroy) { - LocalFrameId local_frame_id(6, 0); + LocalFrameId local_frame_id(6, kArbitraryToken); factory_->Create(local_frame_id); CompositorFrame frame; frame.delegated_frame_data.reset(new DelegatedFrameData); @@ -468,7 +485,7 @@ void DrawCallback(uint32_t* execute_count) { // Tests doing a DestroyAll before shutting down the factory; TEST_F(SurfaceFactoryTest, DestroyAll) { - LocalFrameId id(7, 0); + LocalFrameId id(7, kArbitraryToken); factory_->Create(id); std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); @@ -481,14 +498,40 @@ TEST_F(SurfaceFactoryTest, DestroyAll) { uint32_t execute_count = 0; factory_->SubmitCompositorFrame(id, std::move(frame), base::Bind(&DrawCallback, &execute_count)); - + EXPECT_EQ(last_created_surface_id().local_frame_id(), id); local_frame_id_ = LocalFrameId(); factory_->DestroyAll(); EXPECT_EQ(1u, execute_count); } +// Tests that SurfaceFactory doesn't return resources after Reset(). +TEST_F(SurfaceFactoryTest, Reset) { + LocalFrameId id(7, kArbitraryToken); + factory_->Create(id); + + std::unique_ptr<DelegatedFrameData> frame_data(new DelegatedFrameData); + TransferableResource resource; + resource.id = 1; + resource.mailbox_holder.texture_target = GL_TEXTURE_2D; + frame_data->resource_list.push_back(resource); + CompositorFrame frame; + frame.delegated_frame_data = std::move(frame_data); + uint32_t execute_count = 0; + factory_->SubmitCompositorFrame(id, std::move(frame), + base::Bind(&DrawCallback, &execute_count)); + EXPECT_EQ(last_created_surface_id().local_frame_id(), id); + + SurfaceId surface_id(kArbitraryFrameSinkId, id); + manager_.AddSurfaceReference(manager_.GetRootSurfaceId(), surface_id); + factory_->Reset(); + EXPECT_TRUE(client_.returned_resources().empty()); + manager_.RemoveSurfaceReference(manager_.GetRootSurfaceId(), surface_id); + EXPECT_TRUE(client_.returned_resources().empty()); + local_frame_id_ = LocalFrameId(); +} + TEST_F(SurfaceFactoryTest, DestroySequence) { - LocalFrameId local_frame_id2(5, 0); + LocalFrameId local_frame_id2(5, kArbitraryToken); SurfaceId id2(kArbitraryFrameSinkId, local_frame_id2); factory_->Create(local_frame_id2); @@ -507,13 +550,14 @@ TEST_F(SurfaceFactoryTest, DestroySequence) { DCHECK(manager_.GetSurfaceForId(id2)); factory_->SubmitCompositorFrame(local_frame_id_, std::move(frame), SurfaceFactory::DrawCallback()); + EXPECT_EQ(last_created_surface_id().local_frame_id(), local_frame_id_); DCHECK(!manager_.GetSurfaceForId(id2)); // Check that waiting after the sequence is satisfied works. factory_->Create(local_frame_id2); DCHECK(manager_.GetSurfaceForId(id2)); manager_.GetSurfaceForId(id2)->AddDestructionDependency( - SurfaceSequence(FrameSinkId(0, 0), 6)); + SurfaceSequence(kAnotherArbitraryFrameSinkId, 6)); factory_->Destroy(local_frame_id2); DCHECK(!manager_.GetSurfaceForId(id2)); } @@ -523,7 +567,7 @@ TEST_F(SurfaceFactoryTest, DestroySequence) { TEST_F(SurfaceFactoryTest, InvalidFrameSinkId) { FrameSinkId frame_sink_id(1234, 5678); - LocalFrameId local_frame_id(5, 0); + LocalFrameId local_frame_id(5, kArbitraryToken); SurfaceId id(factory_->frame_sink_id(), local_frame_id); factory_->Create(local_frame_id); @@ -543,14 +587,14 @@ TEST_F(SurfaceFactoryTest, InvalidFrameSinkId) { } TEST_F(SurfaceFactoryTest, DestroyCycle) { - LocalFrameId local_frame_id2(5, 0); + LocalFrameId local_frame_id2(5, kArbitraryToken); SurfaceId id2(kArbitraryFrameSinkId, local_frame_id2); factory_->Create(local_frame_id2); - manager_.RegisterFrameSinkId(FrameSinkId(0, 0)); + manager_.RegisterFrameSinkId(kAnotherArbitraryFrameSinkId); manager_.GetSurfaceForId(id2)->AddDestructionDependency( - SurfaceSequence(FrameSinkId(0, 0), 4)); + SurfaceSequence(kAnotherArbitraryFrameSinkId, 4)); // Give id2 a frame that references local_frame_id_. { @@ -563,6 +607,7 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { frame.delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(local_frame_id2, std::move(frame), SurfaceFactory::DrawCallback()); + EXPECT_EQ(last_created_surface_id().local_frame_id(), local_frame_id2); } factory_->Destroy(local_frame_id2); @@ -576,6 +621,7 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { frame.delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(local_frame_id_, std::move(frame), SurfaceFactory::DrawCallback()); + EXPECT_EQ(last_created_surface_id().local_frame_id(), local_frame_id_); } factory_->Destroy(local_frame_id_); EXPECT_TRUE(manager_.GetSurfaceForId(id2)); @@ -586,7 +632,7 @@ TEST_F(SurfaceFactoryTest, DestroyCycle) { // Satisfy last destruction dependency for id2. std::vector<uint32_t> to_satisfy; to_satisfy.push_back(4); - manager_.DidSatisfySequences(FrameSinkId(0, 0), &to_satisfy); + manager_.DidSatisfySequences(kAnotherArbitraryFrameSinkId, &to_satisfy); // id2 and local_frame_id_ are in a reference cycle that has no surface // sequences holding on to it, so they should be destroyed. @@ -613,6 +659,7 @@ TEST_F(SurfaceFactoryTest, DuplicateCopyRequest) { frame.delegated_frame_data = std::move(frame_data); factory_->SubmitCompositorFrame(local_frame_id_, std::move(frame), SurfaceFactory::DrawCallback()); + EXPECT_EQ(last_created_surface_id().local_frame_id(), local_frame_id_); } void* source1 = &source1; void* source2 = &source2; diff --git a/chromium/cc/surfaces/surface_hittest.h b/chromium/cc/surfaces/surface_hittest.h index f934ad65db2..ad5378a13a8 100644 --- a/chromium/cc/surfaces/surface_hittest.h +++ b/chromium/cc/surfaces/surface_hittest.h @@ -18,7 +18,6 @@ class Transform; namespace cc { class DrawQuad; -class QuadList; class RenderPass; class RenderPassId; class SurfaceHittestDelegate; diff --git a/chromium/cc/surfaces/surface_hittest_unittest.cc b/chromium/cc/surfaces/surface_hittest_unittest.cc index 4b31f5f0667..5038188e4ac 100644 --- a/chromium/cc/surfaces/surface_hittest_unittest.cc +++ b/chromium/cc/surfaces/surface_hittest_unittest.cc @@ -72,8 +72,9 @@ TEST(SurfaceHittestTest, Hittest_BadCompositorFrameDoesNotCrash) { CompositorFrame root_frame = CreateCompositorFrame(root_rect, &root_pass); // Add a reference to a non-existant child surface on the root surface. - SurfaceId child_surface_id(kArbitraryFrameSinkId, - LocalFrameId(0xdeadbeef, 0)); + SurfaceId child_surface_id( + kArbitraryFrameSinkId, + LocalFrameId(0xdeadbeef, base::UnguessableToken::Create())); gfx::Rect child_rect(200, 200); CreateSurfaceDrawQuad(root_pass, gfx::Transform(), diff --git a/chromium/cc/surfaces/surface_id.h b/chromium/cc/surfaces/surface_id.h index 5be370ed3fb..aa6c9c5d667 100644 --- a/chromium/cc/surfaces/surface_id.h +++ b/chromium/cc/surfaces/surface_id.h @@ -9,6 +9,7 @@ #include <stdint.h> #include <functional> +#include <string> #include "base/format_macros.h" #include "base/hash.h" @@ -20,29 +21,23 @@ namespace cc { class SurfaceId { public: - SurfaceId() = default; + constexpr SurfaceId() = default; - SurfaceId(const SurfaceId& other) - : frame_sink_id_(other.frame_sink_id_), - local_frame_id_(other.local_frame_id_) {} + constexpr SurfaceId(const SurfaceId& other) = default; - // A SurfaceId consists of three components: FrameSinkId, local Id, and nonce. + // A SurfaceId consists of two components: FrameSinkId and LocalFrameId. // A |frame_sink_id| consists of two components; one is allocated by the // display compositor service and one is allocated by the client. The // |frame_sink_id| uniquely identifies a FrameSink (and frame source). - // A |local_id| is a sequentially allocated ID generated by the frame source - // that uniquely identifies a sequential set of frames of the same size and - // device scale factor. - // A |nonce| is a cryptographically secure unguessable token that makes it - // impossible for an unprivileged frame source to embed another frame source - // without being explicitly given the surface ID of that frame source from a - // privileged process. - SurfaceId(const FrameSinkId& frame_sink_id, - const LocalFrameId& local_frame_id) + // A |local_frame_id| is a sequentially allocated ID generated by the frame + // source that uniquely identifies a sequential set of frames of the same size + // and device scale factor. + constexpr SurfaceId(const FrameSinkId& frame_sink_id, + const LocalFrameId& local_frame_id) : frame_sink_id_(frame_sink_id), local_frame_id_(local_frame_id) {} - bool is_null() const { - return frame_sink_id_.is_null() && local_frame_id_.is_null(); + bool is_valid() const { + return frame_sink_id_.is_valid() && local_frame_id_.is_valid(); } size_t hash() const { diff --git a/chromium/cc/surfaces/surface_id_allocator.cc b/chromium/cc/surfaces/surface_id_allocator.cc index af4d5932df7..24bcfbd46f9 100644 --- a/chromium/cc/surfaces/surface_id_allocator.cc +++ b/chromium/cc/surfaces/surface_id_allocator.cc @@ -7,6 +7,7 @@ #include <stdint.h> #include "base/rand_util.h" +#include "base/unguessable_token.h" namespace cc { @@ -16,8 +17,7 @@ SurfaceIdAllocator::~SurfaceIdAllocator() { } LocalFrameId SurfaceIdAllocator::GenerateId() { - uint64_t nonce = base::RandUint64(); - LocalFrameId id(next_id_, nonce); + LocalFrameId id(next_id_, base::UnguessableToken::Create()); next_id_++; return id; } diff --git a/chromium/cc/surfaces/surface_manager.cc b/chromium/cc/surfaces/surface_manager.cc index 027b8ff5f8b..b8b121142ff 100644 --- a/chromium/cc/surfaces/surface_manager.cc +++ b/chromium/cc/surfaces/surface_manager.cc @@ -7,6 +7,8 @@ #include <stddef.h> #include <stdint.h> +#include <utility> + #include "base/logging.h" #include "cc/surfaces/surface.h" #include "cc/surfaces/surface_factory_client.h" @@ -25,7 +27,9 @@ SurfaceManager::FrameSinkSourceMapping::~FrameSinkSourceMapping() { << ", children: " << children.size(); } -SurfaceManager::SurfaceManager() { +SurfaceManager::SurfaceManager() + : kRootSurfaceId(FrameSinkId(0u, 0u), + LocalFrameId(0u, base::UnguessableToken::Create())) { thread_checker_.DetachFromThread(); } @@ -56,6 +60,8 @@ void SurfaceManager::DeregisterSurface(const SurfaceId& surface_id) { SurfaceMap::iterator it = surface_map_.find(surface_id); DCHECK(it != surface_map_.end()); surface_map_.erase(it); + child_to_parent_refs_.erase(surface_id); + parent_to_child_refs_.erase(surface_id); } void SurfaceManager::Destroy(std::unique_ptr<Surface> surface) { @@ -68,11 +74,8 @@ void SurfaceManager::Destroy(std::unique_ptr<Surface> surface) { void SurfaceManager::DidSatisfySequences(const FrameSinkId& frame_sink_id, std::vector<uint32_t>* sequence) { DCHECK(thread_checker_.CalledOnValidThread()); - for (std::vector<uint32_t>::iterator it = sequence->begin(); - it != sequence->end(); - ++it) { - satisfied_sequences_.insert(SurfaceSequence(frame_sink_id, *it)); - } + for (uint32_t value : *sequence) + satisfied_sequences_.insert(SurfaceSequence(frame_sink_id, value)); sequence->clear(); GarbageCollectSurfaces(); } @@ -87,22 +90,85 @@ void SurfaceManager::InvalidateFrameSinkId(const FrameSinkId& frame_sink_id) { GarbageCollectSurfaces(); } +void SurfaceManager::AddSurfaceReference(const SurfaceId& parent_id, + const SurfaceId& child_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + + // Check some conditions that should never happen. We don't want to crash on + // bad input from a compromised client so just return early. + if (parent_id == child_id) { + LOG(ERROR) << "Cannot add self reference for " << parent_id.ToString(); + return; + } + if (parent_id != kRootSurfaceId && surface_map_.count(parent_id) == 0) { + LOG(ERROR) << "No surface in map for " << parent_id.ToString(); + return; + } + if (surface_map_.count(child_id) == 0) { + LOG(ERROR) << "No surface in map for " << child_id.ToString(); + return; + } + + parent_to_child_refs_[parent_id].insert(child_id); + child_to_parent_refs_[child_id].insert(parent_id); +} + +void SurfaceManager::RemoveSurfaceReference(const SurfaceId& parent_id, + const SurfaceId& child_id) { + DCHECK(thread_checker_.CalledOnValidThread()); + + // Check if we have the reference that is requested to be removed. We don't + // want to crash on bad input from a compromised client so just return early. + if (parent_to_child_refs_.count(parent_id) == 0 || + parent_to_child_refs_[parent_id].count(child_id) == 0) { + LOG(ERROR) << "No reference from " << parent_id.ToString() << " to " + << child_id.ToString(); + return; + } + + RemoveSurfaceReferenceImpl(parent_id, child_id); + GarbageCollectSurfaces(); +} + +size_t SurfaceManager::GetSurfaceReferenceCount( + const SurfaceId& surface_id) const { + auto iter = child_to_parent_refs_.find(surface_id); + if (iter == child_to_parent_refs_.end()) + return 0; + return iter->second.size(); +} + +size_t SurfaceManager::GetReferencedSurfaceCount( + const SurfaceId& surface_id) const { + auto iter = parent_to_child_refs_.find(surface_id); + if (iter == parent_to_child_refs_.end()) + return 0; + return iter->second.size(); +} + void SurfaceManager::GarbageCollectSurfaces() { // Simple mark and sweep GC. // TODO(jbauman): Reduce the amount of work when nothing needs to be // destroyed. std::vector<SurfaceId> live_surfaces; - std::set<SurfaceId> live_surfaces_set; + std::unordered_set<SurfaceId, SurfaceIdHash> live_surfaces_set; // GC roots are surfaces that have not been destroyed, or have not had all // their destruction dependencies satisfied. for (auto& map_entry : surface_map_) { - map_entry.second->SatisfyDestructionDependencies(&satisfied_sequences_, - &valid_frame_sink_ids_); - if (!map_entry.second->destroyed() || - map_entry.second->GetDestructionDependencyCount()) { - live_surfaces_set.insert(map_entry.first); - live_surfaces.push_back(map_entry.first); + const SurfaceId& surface_id = map_entry.first; + Surface* surface = map_entry.second; + surface->SatisfyDestructionDependencies(&satisfied_sequences_, + &valid_frame_sink_ids_); + + // Never use both sequences and references for the same Surface. + DCHECK(surface->GetDestructionDependencyCount() == 0 || + GetSurfaceReferenceCount(surface_id) == 0); + + if (!surface->destroyed() || surface->GetDestructionDependencyCount() > 0 || + GetSurfaceReferenceCount(surface_id) > 0) { + live_surfaces_set.insert(surface_id); + live_surfaces.push_back(surface_id); } } @@ -127,40 +193,60 @@ void SurfaceManager::GarbageCollectSurfaces() { std::vector<std::unique_ptr<Surface>> to_destroy; // Destroy all remaining unreachable surfaces. - for (SurfaceDestroyList::iterator dest_it = surfaces_to_destroy_.begin(); - dest_it != surfaces_to_destroy_.end();) { - if (!live_surfaces_set.count((*dest_it)->surface_id())) { - std::unique_ptr<Surface> surf(std::move(*dest_it)); - DeregisterSurface(surf->surface_id()); - dest_it = surfaces_to_destroy_.erase(dest_it); - to_destroy.push_back(std::move(surf)); + for (auto iter = surfaces_to_destroy_.begin(); + iter != surfaces_to_destroy_.end();) { + SurfaceId surface_id = (*iter)->surface_id(); + if (!live_surfaces_set.count(surface_id)) { + DeregisterSurface(surface_id); + to_destroy.push_back(std::move(*iter)); + iter = surfaces_to_destroy_.erase(iter); } else { - ++dest_it; + ++iter; } } to_destroy.clear(); } +void SurfaceManager::RemoveSurfaceReferenceImpl(const SurfaceId& parent_id, + const SurfaceId& child_id) { + // Remove the reference from parent to child. This doesn't change anything + // about the validity of the parent. + parent_to_child_refs_[parent_id].erase(child_id); + + // Remove the reference from child to parent. This might drop the number of + // references to the child to zero. + DCHECK_EQ(child_to_parent_refs_.count(child_id), 1u); + SurfaceIdSet& child_refs = child_to_parent_refs_[child_id]; + DCHECK_EQ(child_refs.count(parent_id), 1u); + child_refs.erase(parent_id); + + if (!child_refs.empty()) + return; + + // Remove any references the child holds before it gets garbage collected. + // Copy SurfaceIdSet to avoid iterator invalidation problems. + SurfaceIdSet child_child_refs = parent_to_child_refs_[child_id]; + for (auto& child_child_id : child_child_refs) + RemoveSurfaceReferenceImpl(child_id, child_child_id); + DCHECK_EQ(GetReferencedSurfaceCount(child_id), 0u); +} + void SurfaceManager::RegisterSurfaceFactoryClient( const FrameSinkId& frame_sink_id, SurfaceFactoryClient* client) { DCHECK(client); - DCHECK(!frame_sink_source_map_[frame_sink_id].client); DCHECK_EQ(valid_frame_sink_ids_.count(frame_sink_id), 1u); - auto iter = frame_sink_source_map_.find(frame_sink_id); - if (iter == frame_sink_source_map_.end()) { - auto insert_result = frame_sink_source_map_.insert( - std::make_pair(frame_sink_id, FrameSinkSourceMapping())); - DCHECK(insert_result.second); - iter = insert_result.first; - } - iter->second.client = client; + // Will create a new FrameSinkSourceMapping for |frame_sink_id| if necessary. + FrameSinkSourceMapping& frame_sink_source = + frame_sink_source_map_[frame_sink_id]; + DCHECK(!frame_sink_source.client); + frame_sink_source.client = client; // Propagate any previously set sources to the new client. - if (iter->second.source) - client->SetBeginFrameSource(iter->second.source); + if (frame_sink_source.source) + client->SetBeginFrameSource(frame_sink_source.source); } void SurfaceManager::UnregisterSurfaceFactoryClient( @@ -338,16 +424,24 @@ Surface* SurfaceManager::GetSurfaceForId(const SurfaceId& surface_id) { DCHECK(thread_checker_.CalledOnValidThread()); SurfaceMap::iterator it = surface_map_.find(surface_id); if (it == surface_map_.end()) - return NULL; + return nullptr; return it->second; } bool SurfaceManager::SurfaceModified(const SurfaceId& surface_id) { CHECK(thread_checker_.CalledOnValidThread()); bool changed = false; - FOR_EACH_OBSERVER(SurfaceDamageObserver, observer_list_, - OnSurfaceDamaged(surface_id, &changed)); + for (auto& observer : observer_list_) + observer.OnSurfaceDamaged(surface_id, &changed); return changed; } +void SurfaceManager::SurfaceCreated(const SurfaceId& surface_id, + const gfx::Size& frame_size, + float device_scale_factor) { + CHECK(thread_checker_.CalledOnValidThread()); + for (auto& observer : observer_list_) + observer.OnSurfaceCreated(surface_id, frame_size, device_scale_factor); +} + } // namespace cc diff --git a/chromium/cc/surfaces/surface_manager.h b/chromium/cc/surfaces/surface_manager.h index 3420a0730fe..b52fce25ade 100644 --- a/chromium/cc/surfaces/surface_manager.h +++ b/chromium/cc/surfaces/surface_manager.h @@ -17,8 +17,8 @@ #include "base/observer_list.h" #include "base/threading/thread_checker.h" #include "cc/surfaces/frame_sink_id.h" -#include "cc/surfaces/surface_damage_observer.h" #include "cc/surfaces/surface_id.h" +#include "cc/surfaces/surface_observer.h" #include "cc/surfaces/surface_sequence.h" #include "cc/surfaces/surfaces_export.h" @@ -41,16 +41,20 @@ class CC_SURFACES_EXPORT SurfaceManager { Surface* GetSurfaceForId(const SurfaceId& surface_id); - void AddObserver(SurfaceDamageObserver* obs) { - observer_list_.AddObserver(obs); - } + void AddObserver(SurfaceObserver* obs) { observer_list_.AddObserver(obs); } - void RemoveObserver(SurfaceDamageObserver* obs) { + void RemoveObserver(SurfaceObserver* obs) { observer_list_.RemoveObserver(obs); } bool SurfaceModified(const SurfaceId& surface_id); + // Called when a CompositorFrame is submitted to a SurfaceFactory for a given + // |surface_id| for the first time. + void SurfaceCreated(const SurfaceId& surface_id, + const gfx::Size& frame_size, + float device_scale_factor); + // A frame for a surface satisfies a set of sequence numbers in a particular // id namespace. void DidSatisfySequences(const FrameSinkId& frame_sink_id, @@ -62,6 +66,24 @@ class CC_SURFACES_EXPORT SurfaceManager { // possibly because a renderer process has crashed. void InvalidateFrameSinkId(const FrameSinkId& frame_sink_id); + // Adds a reference from a parent surface to a child surface. Any surface + // embedding a child surface should have a reference added so that the child + // surface is not garbage collected until after the parent surface. + void AddSurfaceReference(const SurfaceId& parent_id, + const SurfaceId& child_id); + + // Removes a reference from a parent surface to a child surface. + void RemoveSurfaceReference(const SurfaceId& parent_id, + const SurfaceId& child_id); + + // Returns the number of surfaces that have references to |surface_id|. When + // the count is zero nothing is referencing the surface and it may be garbage + // collected. + size_t GetSurfaceReferenceCount(const SurfaceId& surface_id) const; + + // Returns the number of surfaces that |surface_id| has references to. + size_t GetReferencedSurfaceCount(const SurfaceId& surface_id) const; + // SurfaceFactoryClient, hierarchy, and BeginFrameSource can be registered // and unregistered in any order with respect to each other. // @@ -96,6 +118,8 @@ class CC_SURFACES_EXPORT SurfaceManager { void UnregisterFrameSinkHierarchy(const FrameSinkId& parent_frame_sink_id, const FrameSinkId& child_frame_sink_id); + const SurfaceId& GetRootSurfaceId() { return kRootSurfaceId; } + private: void RecursivelyAttachBeginFrameSource(const FrameSinkId& frame_sink_id, BeginFrameSource* source); @@ -108,9 +132,14 @@ class CC_SURFACES_EXPORT SurfaceManager { void GarbageCollectSurfaces(); + // Removes reference from a parent surface to a child surface. Used to remove + // references without triggered GC. + void RemoveSurfaceReferenceImpl(const SurfaceId& parent_id, + const SurfaceId& child_id); + using SurfaceMap = std::unordered_map<SurfaceId, Surface*, SurfaceIdHash>; SurfaceMap surface_map_; - base::ObserverList<SurfaceDamageObserver> observer_list_; + base::ObserverList<SurfaceObserver> observer_list_; base::ThreadChecker thread_checker_; // List of surfaces to be destroyed, along with what sequences they're still @@ -143,11 +172,27 @@ class CC_SURFACES_EXPORT SurfaceManager { }; std::unordered_map<FrameSinkId, FrameSinkSourceMapping, FrameSinkIdHash> frame_sink_source_map_; + + using SurfaceIdSet = std::unordered_set<SurfaceId, SurfaceIdHash>; + // Tracks references from the child surface to parent surface. If there are + // zero entries in the set for a SurfaceId then nothing is referencing the + // surface and it can be garbage collected. + std::unordered_map<SurfaceId, SurfaceIdSet, SurfaceIdHash> + child_to_parent_refs_; + // Tracks references from the parent surface to child surface. Is the inverse + // of |child_to_parent_refs_|. + std::unordered_map<SurfaceId, SurfaceIdSet, SurfaceIdHash> + parent_to_child_refs_; + // Set of which sources are registered to which namespace. Any child // that is implicitly using this namespace must be reachable by the // parent in the dag. std::unordered_map<BeginFrameSource*, FrameSinkId> registered_sources_; + // Root SurfaceId that references display root surfaces. There is no Surface + // with this id, it's for bookkeeping purposes only. + const SurfaceId kRootSurfaceId; + DISALLOW_COPY_AND_ASSIGN(SurfaceManager); }; diff --git a/chromium/cc/surfaces/surface_manager_ref_unittest.cc b/chromium/cc/surfaces/surface_manager_ref_unittest.cc new file mode 100644 index 00000000000..2b797c71071 --- /dev/null +++ b/chromium/cc/surfaces/surface_manager_ref_unittest.cc @@ -0,0 +1,294 @@ +// 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 <stddef.h> + +#include <unordered_map> +#include <vector> + +#include "base/memory/ptr_util.h" +#include "cc/surfaces/surface.h" +#include "cc/surfaces/surface_factory.h" +#include "cc/surfaces/surface_id.h" +#include "cc/surfaces/surface_manager.h" +#include "cc/surfaces/surface_sequence_generator.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace cc { +namespace { + +constexpr FrameSinkId kFrameSink1(1, 0); +constexpr FrameSinkId kFrameSink2(2, 0); +constexpr FrameSinkId kFrameSink3(3, 0); +const LocalFrameId kLocalFrame1(1, base::UnguessableToken::Create()); +const LocalFrameId kLocalFrame2(2, base::UnguessableToken::Create()); + +// Tests for reference tracking in SurfaceManager. +class SurfaceManagerRefTest : public testing::Test { + public: + SurfaceManager& manager() { return *manager_; } + + // Creates a new Surface with the provided SurfaceId. Will first create the + // SurfaceFactory for |frame_sink_id| if necessary. + SurfaceId CreateSurface(const FrameSinkId& frame_sink_id, + const LocalFrameId& local_frame_id) { + GetFactory(frame_sink_id).Create(local_frame_id); + return SurfaceId(frame_sink_id, local_frame_id); + } + + // Destroy Surface with |surface_id|. + void DestroySurface(const SurfaceId& surface_id) { + GetFactory(surface_id.frame_sink_id()).Destroy(surface_id.local_frame_id()); + } + + protected: + SurfaceFactory& GetFactory(const FrameSinkId& frame_sink_id) { + auto& factory_ptr = factories_[frame_sink_id]; + if (!factory_ptr) + factory_ptr = base::MakeUnique<SurfaceFactory>(frame_sink_id, + manager_.get(), nullptr); + return *factory_ptr; + } + + // testing::Test: + void SetUp() override { + // Start each test with a fresh SurfaceManager instance. + manager_ = base::MakeUnique<SurfaceManager>(); + } + void TearDown() override { + factories_.clear(); + manager_.reset(); + } + + std::unordered_map<FrameSinkId, + std::unique_ptr<SurfaceFactory>, + FrameSinkIdHash> + factories_; + std::unique_ptr<SurfaceManager> manager_; +}; + +} // namespace + +TEST_F(SurfaceManagerRefTest, AddReference) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + + EXPECT_EQ(manager().GetSurfaceReferenceCount(id1), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 0u); +} + +TEST_F(SurfaceManagerRefTest, AddRemoveReference) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + manager().AddSurfaceReference(id1, id2); + + EXPECT_EQ(manager().GetSurfaceReferenceCount(id1), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id2), 0u); + + manager().RemoveSurfaceReference(id1, id2); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id1), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 0u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 0u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id2), 0u); +} + +TEST_F(SurfaceManagerRefTest, AddRemoveReferenceRecursive) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + SurfaceId id3 = CreateSurface(kFrameSink3, kLocalFrame1); + + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + manager().AddSurfaceReference(id1, id2); + manager().AddSurfaceReference(id2, id3); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id1), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id3), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id2), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id3), 0u); + + // Should remove reference from id1 -> id2 and then since id2 has zero + // references all references it holds should be removed. + manager().RemoveSurfaceReference(id1, id2); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id1), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 0u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id3), 0u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 0u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id2), 0u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id3), 0u); +} + +TEST_F(SurfaceManagerRefTest, NewSurfaceFromFrameSink) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + SurfaceId id3 = CreateSurface(kFrameSink3, kLocalFrame1); + + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + manager().AddSurfaceReference(id1, id2); + manager().AddSurfaceReference(id2, id3); + + // |kFramesink2| received a CompositorFrame with a new size, so it destroys + // |id2| and creates |id2_next|. No reference have been removed yet. + DestroySurface(id2); + SurfaceId id2_next = CreateSurface(kFrameSink2, kLocalFrame2); + EXPECT_NE(manager().GetSurfaceForId(id2), nullptr); + EXPECT_NE(manager().GetSurfaceForId(id2_next), nullptr); + + // Add references to and from |id2_next|. + manager().AddSurfaceReference(id1, id2_next); + manager().AddSurfaceReference(id2_next, id3); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2_next), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id3), 2u); + + manager().RemoveSurfaceReference(id1, id2); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 0u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2_next), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id3), 1u); + + // |id2| should be deleted during GC but other surfaces shouldn't. + EXPECT_EQ(manager().GetSurfaceForId(id2), nullptr); + EXPECT_NE(manager().GetSurfaceForId(id2_next), nullptr); + EXPECT_NE(manager().GetSurfaceForId(id3), nullptr); +} + +TEST_F(SurfaceManagerRefTest, CheckGC) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + manager().AddSurfaceReference(id1, id2); + + EXPECT_NE(manager().GetSurfaceForId(id1), nullptr); + EXPECT_NE(manager().GetSurfaceForId(id2), nullptr); + + // Destroying the surfaces shouldn't delete them yet, since there is still an + // active reference on all surfaces. + DestroySurface(id1); + DestroySurface(id2); + EXPECT_NE(manager().GetSurfaceForId(id1), nullptr); + EXPECT_NE(manager().GetSurfaceForId(id2), nullptr); + + // Should delete |id2| when the only reference to it is removed. + manager().RemoveSurfaceReference(id1, id2); + EXPECT_EQ(manager().GetSurfaceForId(id2), nullptr); + + // Should delete |id1| when the only reference to it is removed. + manager().RemoveSurfaceReference(manager().GetRootSurfaceId(), id1); + EXPECT_EQ(manager().GetSurfaceForId(id1), nullptr); +} + +TEST_F(SurfaceManagerRefTest, CheckGCRecusiveFull) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + SurfaceId id3 = CreateSurface(kFrameSink3, kLocalFrame1); + + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + manager().AddSurfaceReference(id1, id2); + manager().AddSurfaceReference(id2, id3); + + DestroySurface(id3); + DestroySurface(id2); + DestroySurface(id1); + + // Destroying the surfaces shouldn't delete them yet, since there is still an + // active reference on all surfaces. + EXPECT_NE(manager().GetSurfaceForId(id3), nullptr); + EXPECT_NE(manager().GetSurfaceForId(id2), nullptr); + EXPECT_NE(manager().GetSurfaceForId(id1), nullptr); + + manager().RemoveSurfaceReference(manager().GetRootSurfaceId(), id1); + + // Removing the reference from the root to id1 should allow all three surfaces + // to be deleted during GC. + EXPECT_EQ(manager().GetSurfaceForId(id1), nullptr); + EXPECT_EQ(manager().GetSurfaceForId(id2), nullptr); + EXPECT_EQ(manager().GetSurfaceForId(id3), nullptr); +} + +TEST_F(SurfaceManagerRefTest, CheckGCWithSequences) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + manager().AddSurfaceReference(id1, id2); + + SurfaceId id3 = CreateSurface(kFrameSink3, kLocalFrame1); + Surface* surface3 = manager().GetSurfaceForId(id3); + + // Add destruction dependency from |id2| to |id3|. + manager().RegisterFrameSinkId(kFrameSink2); + SurfaceSequence sequence(kFrameSink2, 1u); + surface3->AddDestructionDependency(sequence); + EXPECT_EQ(surface3->GetDestructionDependencyCount(), 1u); + + // Surface for |id3| isn't delete yet because it has a valid destruction + // dependency from |kFrameSink2|. + DestroySurface(id3); + EXPECT_NE(manager().GetSurfaceForId(id3), nullptr); + + // Surface for |id2| isn't deleted because it has a reference. + DestroySurface(id2); + EXPECT_NE(manager().GetSurfaceForId(id2), nullptr); + + // Satisfy destruction dependency on |id3| and delete during GC. + std::vector<uint32_t> satisfied({sequence.sequence}); + manager().DidSatisfySequences(kFrameSink2, &satisfied); + EXPECT_EQ(manager().GetSurfaceForId(id3), nullptr); + + // Remove ref on |id2| and delete during GC. + manager().RemoveSurfaceReference(id1, id2); + EXPECT_EQ(manager().GetSurfaceForId(id2), nullptr); +} + +TEST_F(SurfaceManagerRefTest, TryAddReferenceToBadSurface) { + // Not creating an accompanying Surface and SurfaceFactory. + SurfaceId id(FrameSinkId(100u, 200u), + LocalFrameId(1u, base::UnguessableToken::Create())); + + // Adding reference from root to the Surface should do nothing because + // SurfaceManager doesn't know Surface for |id| exists. + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id), 0u); +} + +TEST_F(SurfaceManagerRefTest, TryDoubleAddReference) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + + manager().AddSurfaceReference(manager().GetRootSurfaceId(), id1); + manager().AddSurfaceReference(id1, id2); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 1u); + + // The second request should be ignored without crashing. + manager().AddSurfaceReference(id1, id2); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 1u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 1u); +} + +TEST_F(SurfaceManagerRefTest, TryAddSelfReference) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + + // Adding a self reference should be ignored without crashing. + manager().AddSurfaceReference(id1, id1); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id1), 0u); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 0u); +} + +TEST_F(SurfaceManagerRefTest, TryRemoveBadReference) { + SurfaceId id1 = CreateSurface(kFrameSink1, kLocalFrame1); + SurfaceId id2 = CreateSurface(kFrameSink2, kLocalFrame1); + + // Removing non-existent reference should be ignored. + manager().AddSurfaceReference(id1, id2); + manager().RemoveSurfaceReference(id2, id1); + EXPECT_EQ(manager().GetReferencedSurfaceCount(id1), 1u); + EXPECT_EQ(manager().GetSurfaceReferenceCount(id2), 1u); +} + +} // namespace cc diff --git a/chromium/cc/surfaces/surface_observer.h b/chromium/cc/surfaces/surface_observer.h new file mode 100644 index 00000000000..3e829b47875 --- /dev/null +++ b/chromium/cc/surfaces/surface_observer.h @@ -0,0 +1,31 @@ +// 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_SURFACES_SURFACE_OBSERVER_H_ +#define CC_SURFACES_SURFACE_OBSERVER_H_ + +namespace gfx { +class Size; +} + +namespace cc { + +class SurfaceId; + +class SurfaceObserver { + public: + // Runs when a CompositorFrame is received for the given |surface_id| for the + // first time. + virtual void OnSurfaceCreated(const SurfaceId& surface_id, + const gfx::Size& frame_size, + float device_scale_factor) = 0; + + // Runs when a Surface is damaged. *changed should be set to true if this + // causes a Display to be damaged. + virtual void OnSurfaceDamaged(const SurfaceId& surface_id, bool* changed) = 0; +}; + +} // namespace cc + +#endif // CC_SURFACES_SURFACE_OBSERVER_H_ diff --git a/chromium/cc/surfaces/surface_resource_holder.cc b/chromium/cc/surfaces/surface_resource_holder.cc index ec794895906..6d1e60d0c6a 100644 --- a/chromium/cc/surfaces/surface_resource_holder.cc +++ b/chromium/cc/surfaces/surface_resource_holder.cc @@ -19,6 +19,10 @@ SurfaceResourceHolder::ResourceRefs::ResourceRefs() : refs_received_from_child(0), refs_holding_resource_alive(0) { } +void SurfaceResourceHolder::Reset() { + resource_id_info_map_.clear(); +} + void SurfaceResourceHolder::ReceiveFromChild( const TransferableResourceArray& resources) { for (TransferableResourceArray::const_iterator it = resources.begin(); diff --git a/chromium/cc/surfaces/surface_resource_holder.h b/chromium/cc/surfaces/surface_resource_holder.h index 9a9344e7f78..5d222864e8b 100644 --- a/chromium/cc/surfaces/surface_resource_holder.h +++ b/chromium/cc/surfaces/surface_resource_holder.h @@ -25,6 +25,7 @@ class CC_SURFACES_EXPORT SurfaceResourceHolder { explicit SurfaceResourceHolder(SurfaceFactoryClient* client); ~SurfaceResourceHolder(); + void Reset(); void ReceiveFromChild(const TransferableResourceArray& resources); void RefResources(const TransferableResourceArray& resources); void UnrefResources(const ReturnedResourceArray& resources); diff --git a/chromium/cc/surfaces/surface_sequence.h b/chromium/cc/surfaces/surface_sequence.h index f847d0b5338..3437394c779 100644 --- a/chromium/cc/surfaces/surface_sequence.h +++ b/chromium/cc/surfaces/surface_sequence.h @@ -22,7 +22,7 @@ struct SurfaceSequence { SurfaceSequence() : sequence(0u) {} SurfaceSequence(const FrameSinkId& frame_sink_id, uint32_t sequence) : frame_sink_id(frame_sink_id), sequence(sequence) {} - bool is_null() const { return frame_sink_id.is_null() && sequence == 0u; } + bool is_valid() const { return frame_sink_id.is_valid() && sequence > 0u; } FrameSinkId frame_sink_id; uint32_t sequence; diff --git a/chromium/cc/surfaces/surface_unittest.cc b/chromium/cc/surfaces/surface_unittest.cc index c2d5b4f8ba6..5b8e614f4fe 100644 --- a/chromium/cc/surfaces/surface_unittest.cc +++ b/chromium/cc/surfaces/surface_unittest.cc @@ -38,7 +38,7 @@ TEST(SurfaceTest, SurfaceLifetime) { SurfaceFactory factory(kArbitraryFrameSinkId, &manager, &surface_factory_client); - LocalFrameId local_frame_id(6, 0); + LocalFrameId local_frame_id(6, base::UnguessableToken::Create()); SurfaceId surface_id(kArbitraryFrameSinkId, local_frame_id); { factory.Create(local_frame_id); diff --git a/chromium/cc/tiles/gpu_image_decode_controller.cc b/chromium/cc/tiles/gpu_image_decode_controller.cc index 730ea6fa576..d78f55fdb03 100644 --- a/chromium/cc/tiles/gpu_image_decode_controller.cc +++ b/chromium/cc/tiles/gpu_image_decode_controller.cc @@ -161,6 +161,9 @@ class ImageDecodeTaskImpl : public TileTask { void RunOnWorkerThread() override { TRACE_EVENT2("cc", "ImageDecodeTaskImpl::RunOnWorkerThread", "mode", "gpu", "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); + devtools_instrumentation::ScopedImageDecodeTask image_decode_task( + image_.image().get(), + devtools_instrumentation::ScopedImageDecodeTask::GPU); controller_->DecodeImage(image_); } @@ -377,7 +380,7 @@ bool GpuImageDecodeController::GetTaskForImageAndRef( const DrawImage& draw_image, const TracingInfo& tracing_info, scoped_refptr<TileTask>* task) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::GetTaskForImageAndRef"); if (SkipImage(draw_image)) { *task = nullptr; @@ -439,7 +442,7 @@ bool GpuImageDecodeController::GetTaskForImageAndRef( } void GpuImageDecodeController::UnrefImage(const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::UnrefImage"); base::AutoLock lock(lock_); UnrefImageInternal(draw_image); @@ -517,7 +520,7 @@ void GpuImageDecodeController::DrawWithImageFinished( } void GpuImageDecodeController::ReduceCacheUsage() { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::ReduceCacheUsage"); base::AutoLock lock(lock_); EnsureCapacity(0); @@ -525,7 +528,7 @@ void GpuImageDecodeController::ReduceCacheUsage() { void GpuImageDecodeController::SetShouldAggressivelyFreeResources( bool aggressively_free_resources) { - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::SetShouldAggressivelyFreeResources", "agressive_free_resources", aggressively_free_resources); if (aggressively_free_resources) { @@ -548,8 +551,25 @@ void GpuImageDecodeController::SetShouldAggressivelyFreeResources( bool GpuImageDecodeController::OnMemoryDump( const base::trace_event::MemoryDumpArgs& args, base::trace_event::ProcessMemoryDump* pmd) { - TRACE_EVENT0("disabled-by-default-cc.debug", + using base::trace_event::MemoryAllocatorDump; + using base::trace_event::MemoryAllocatorDumpGuid; + using base::trace_event::MemoryDumpLevelOfDetail; + + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::OnMemoryDump"); + + if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { + std::string dump_name = + base::StringPrintf("cc/image_memory/controller_0x%" PRIXPTR, + reinterpret_cast<uintptr_t>(this)); + MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name); + dump->AddScalar(MemoryAllocatorDump::kNameSize, + MemoryAllocatorDump::kUnitsBytes, bytes_used_); + + // Early out, no need for more detail in a BACKGROUND dump. + return true; + } + for (const auto& image_pair : persistent_cache_) { const ImageData* image_data = image_pair.second.get(); const uint32_t image_id = image_pair.first; @@ -559,41 +579,40 @@ bool GpuImageDecodeController::OnMemoryDump( std::string discardable_dump_name = base::StringPrintf( "cc/image_memory/controller_0x%" PRIXPTR "/discardable/image_%d", reinterpret_cast<uintptr_t>(this), image_id); - base::trace_event::MemoryAllocatorDump* dump = + MemoryAllocatorDump* dump = image_data->decode.data()->CreateMemoryAllocatorDump( discardable_dump_name.c_str(), pmd); - // If our image is locked, dump the "locked_size" as an additional column. + // If our image is locked, dump the "locked_size" as an additional + // column. // This lets us see the amount of discardable which is contributing to // memory pressure. if (image_data->decode.is_locked()) { - dump->AddScalar("locked_size", - base::trace_event::MemoryAllocatorDump::kUnitsBytes, + dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, image_data->size); } } - // If we have an uploaded image (that is actually on the GPU, not just a CPU + // If we have an uploaded image (that is actually on the GPU, not just a + // CPU // wrapper), upload it here. if (image_data->upload.image() && image_data->mode == DecodedDataMode::GPU) { std::string gpu_dump_name = base::StringPrintf( "cc/image_memory/controller_0x%" PRIXPTR "/gpu/image_%d", reinterpret_cast<uintptr_t>(this), image_id); - base::trace_event::MemoryAllocatorDump* dump = - pmd->CreateAllocatorDump(gpu_dump_name); - dump->AddScalar(base::trace_event::MemoryAllocatorDump::kNameSize, - base::trace_event::MemoryAllocatorDump::kUnitsBytes, - image_data->size); + MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(gpu_dump_name); + dump->AddScalar(MemoryAllocatorDump::kNameSize, + MemoryAllocatorDump::kUnitsBytes, image_data->size); - // Create a global shred GUID to associate this data with its GPU process + // Create a global shred GUID to associate this data with its GPU + // process // counterpart. GLuint gl_id = skia::GrBackendObjectToGrGLTextureInfo( image_data->upload.image()->getTextureHandle( false /* flushPendingGrContextIO */)) ->fID; - base::trace_event::MemoryAllocatorDumpGuid guid = - gl::GetGLTextureClientGUIDForTracing( - context_->ContextSupport()->ShareGroupTracingGUID(), gl_id); + MemoryAllocatorDumpGuid guid = gl::GetGLTextureClientGUIDForTracing( + context_->ContextSupport()->ShareGroupTracingGUID(), gl_id); // kImportance is somewhat arbitrary - we chose 3 to be higher than the // value used in the GPU process (1), and Skia (2), causing us to appear @@ -608,7 +627,7 @@ bool GpuImageDecodeController::OnMemoryDump( } void GpuImageDecodeController::DecodeImage(const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::DecodeImage"); base::AutoLock lock(lock_); ImageData* image_data = GetImageDataForDrawImage(draw_image); @@ -618,7 +637,7 @@ void GpuImageDecodeController::DecodeImage(const DrawImage& draw_image) { } void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::UploadImage"); ContextProvider::ScopedContextLock context_lock(context_); base::AutoLock lock(lock_); @@ -630,7 +649,7 @@ void GpuImageDecodeController::UploadImage(const DrawImage& draw_image) { void GpuImageDecodeController::OnImageDecodeTaskCompleted( const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::OnImageDecodeTaskCompleted"); base::AutoLock lock(lock_); // Decode task is complete, remove our reference to it. @@ -646,7 +665,7 @@ void GpuImageDecodeController::OnImageDecodeTaskCompleted( void GpuImageDecodeController::OnImageUploadTaskCompleted( const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::OnImageUploadTaskCompleted"); base::AutoLock lock(lock_); // Upload task is complete, remove our reference to it. @@ -667,7 +686,7 @@ void GpuImageDecodeController::OnImageUploadTaskCompleted( scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef( const DrawImage& draw_image, const TracingInfo& tracing_info) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::GetImageDecodeTaskAndRef"); lock_.AssertAcquired(); @@ -698,7 +717,7 @@ scoped_refptr<TileTask> GpuImageDecodeController::GetImageDecodeTaskAndRef( } void GpuImageDecodeController::RefImageDecode(const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::RefImageDecode"); lock_.AssertAcquired(); auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); @@ -709,7 +728,7 @@ void GpuImageDecodeController::RefImageDecode(const DrawImage& draw_image) { } void GpuImageDecodeController::UnrefImageDecode(const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::UnrefImageDecode"); lock_.AssertAcquired(); auto found = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); @@ -725,7 +744,7 @@ void GpuImageDecodeController::UnrefImageDecode(const DrawImage& draw_image) { } void GpuImageDecodeController::RefImage(const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::RefImage"); lock_.AssertAcquired(); InUseCacheKey key = GenerateInUseCacheKey(draw_image); @@ -865,7 +884,7 @@ void GpuImageDecodeController::OwnershipChanged(const DrawImage& draw_image, // doing so, this function will free unreferenced image data as necessary to // create rooom. bool GpuImageDecodeController::EnsureCapacity(size_t required_size) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::EnsureCapacity"); lock_.AssertAcquired(); @@ -1091,7 +1110,7 @@ void GpuImageDecodeController::UploadImageIfNecessary( scoped_refptr<GpuImageDecodeController::ImageData> GpuImageDecodeController::CreateImageData(const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::CreateImageData"); lock_.AssertAcquired(); @@ -1138,7 +1157,7 @@ SkImageInfo GpuImageDecodeController::CreateImageInfoForDrawImage( GpuImageDecodeController::ImageData* GpuImageDecodeController::GetImageDataForDrawImage( const DrawImage& draw_image) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "GpuImageDecodeController::GetImageDataForDrawImage"); lock_.AssertAcquired(); auto found_in_use = in_use_cache_.find(GenerateInUseCacheKey(draw_image)); diff --git a/chromium/cc/tiles/gpu_image_decode_controller.h b/chromium/cc/tiles/gpu_image_decode_controller.h index f49e206cf78..50cef6c8a13 100644 --- a/chromium/cc/tiles/gpu_image_decode_controller.h +++ b/chromium/cc/tiles/gpu_image_decode_controller.h @@ -19,8 +19,6 @@ #include "cc/tiles/image_decode_controller.h" #include "third_party/skia/include/core/SkRefCnt.h" -class SkImageTextureData; - namespace cc { class ContextProvider; diff --git a/chromium/cc/tiles/picture_layer_tiling.cc b/chromium/cc/tiles/picture_layer_tiling.cc index 52840a57b5f..74804dc5112 100644 --- a/chromium/cc/tiles/picture_layer_tiling.cc +++ b/chromium/cc/tiles/picture_layer_tiling.cc @@ -29,41 +29,49 @@ #include "ui/gfx/geometry/size_conversions.h" namespace cc { +namespace { +// The math is similar to gfx::Rect::ManhattanInternalDistance except that each +// component is scaled by the specified |scale|. +float ComputeScaledManhattalInternalDistance(const gfx::Rect& a, + const gfx::Rect& b, + const gfx::SizeF& scale) { + gfx::Rect combined(a); + combined.Union(b); + + float x = + scale.width() * std::max(0, combined.width() - a.width() - b.width() + 1); + float y = scale.height() * + std::max(0, combined.height() - a.height() - b.height() + 1); + return x + y; +} +} // namespace PictureLayerTiling::PictureLayerTiling( WhichTree tree, - float contents_scale, + const gfx::SizeF& raster_scales, scoped_refptr<RasterSource> raster_source, PictureLayerTilingClient* client, float min_preraster_distance, float max_preraster_distance) - : contents_scale_(contents_scale), + : raster_scales_(raster_scales), client_(client), tree_(tree), raster_source_(raster_source), min_preraster_distance_(min_preraster_distance), - max_preraster_distance_(max_preraster_distance), - resolution_(NON_IDEAL_RESOLUTION), - may_contain_low_resolution_tiles_(false), - tiling_data_(gfx::Size(), gfx::Size(), kBorderTexels), - can_require_tiles_for_activation_(false), - current_content_to_screen_scale_(0.f), - max_skewport_extent_in_screen_space_(0.f), - has_visible_rect_tiles_(false), - has_skewport_rect_tiles_(false), - has_soon_border_rect_tiles_(false), - has_eventually_rect_tiles_(false), - all_tiles_done_(true) { + max_preraster_distance_(max_preraster_distance) { DCHECK(!raster_source->IsSolidColor()); gfx::Size content_bounds = - gfx::ScaleToCeiledSize(raster_source_->GetSize(), contents_scale); + gfx::ScaleToCeiledSize(raster_source_->GetSize(), raster_scales_.width(), + raster_scales_.height()); gfx::Size tile_size = client_->CalculateTileSize(content_bounds); - DCHECK(!gfx::ScaleToFlooredSize(raster_source_->GetSize(), contents_scale) + DCHECK(!gfx::ScaleToFlooredSize(raster_source_->GetSize(), + raster_scales_.width(), + raster_scales_.height()) .IsEmpty()) << "Tiling created with scale too small as contents become empty." << " Layer bounds: " << raster_source_->GetSize().ToString() - << " Contents scale: " << contents_scale; + << " Raster scales: " << raster_scales_.ToString(); tiling_data_.SetTilingSize(content_bounds); tiling_data_.SetMaxTextureSize(tile_size); @@ -118,8 +126,8 @@ void PictureLayerTiling::CreateMissingTilesInLiveTilesRect() { gfx::Rect invalidated; for (Region::Iterator iter(*invalidation); iter.has_rect(); iter.next()) { - gfx::Rect invalid_content_rect = - gfx::ScaleToEnclosingRect(iter.rect(), contents_scale_); + gfx::Rect invalid_content_rect = gfx::ScaleToEnclosingRect( + iter.rect(), raster_scales_.width(), raster_scales_.height()); invalid_content_rect.Intersect(tile_rect); invalidated.Union(invalid_content_rect); } @@ -181,8 +189,8 @@ void PictureLayerTiling::SetRasterSourceAndResize( gfx::Size old_layer_bounds = raster_source_->GetSize(); raster_source_ = std::move(raster_source); gfx::Size new_layer_bounds = raster_source_->GetSize(); - gfx::Size content_bounds = - gfx::ScaleToCeiledSize(new_layer_bounds, contents_scale_); + gfx::Size content_bounds = gfx::ScaleToCeiledSize( + new_layer_bounds, raster_scales_.width(), raster_scales_.height()); gfx::Size tile_size = client_->CalculateTileSize(content_bounds); if (tile_size != tiling_data_.max_texture_size()) { @@ -276,8 +284,8 @@ void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, iter.next()) { gfx::Rect layer_rect = iter.rect(); // The pixels which are invalid in content space. - gfx::Rect invalid_content_rect = - gfx::ScaleToEnclosingRect(layer_rect, contents_scale_); + gfx::Rect invalid_content_rect = gfx::ScaleToEnclosingRect( + layer_rect, raster_scales_.width(), raster_scales_.height()); gfx::Rect coverage_content_rect = invalid_content_rect; // Avoid needless work by not bothering to invalidate where there aren't // tiles. @@ -313,10 +321,10 @@ void PictureLayerTiling::RemoveTilesInRegion(const Region& layer_invalidation, Tile::CreateInfo PictureLayerTiling::CreateInfoForTile(int i, int j) const { gfx::Rect tile_rect = tiling_data_.TileBoundsWithBorder(i, j); tile_rect.set_size(tiling_data_.max_texture_size()); - gfx::Rect enclosing_layer_rect = - gfx::ScaleToEnclosingRect(tile_rect, 1.f / contents_scale_); + gfx::Rect enclosing_layer_rect = gfx::ScaleToEnclosingRect( + tile_rect, 1.f / raster_scales_.width(), 1.f / raster_scales_.height()); return Tile::CreateInfo(i, j, enclosing_layer_rect, tile_rect, - contents_scale_); + raster_scales_); } bool PictureLayerTiling::ShouldCreateTileAt( @@ -355,8 +363,8 @@ bool PictureLayerTiling::ShouldCreateTileAt( // on the active tree and avoid floating point inconsistencies. for (Region::Iterator iter(*layer_invalidation); iter.has_rect(); iter.next()) { - gfx::Rect invalid_content_rect = - gfx::ScaleToEnclosingRect(iter.rect(), contents_scale_); + gfx::Rect invalid_content_rect = gfx::ScaleToEnclosingRect( + iter.rect(), raster_scales_.width(), raster_scales_.height()); if (invalid_content_rect.Intersects(info.content_rect)) return true; } @@ -379,42 +387,30 @@ bool PictureLayerTiling::TilingMatchesTileIndices( twin->tiling_data_.max_texture_size(); } -PictureLayerTiling::CoverageIterator::CoverageIterator() - : tiling_(NULL), - current_tile_(NULL), - tile_i_(0), - tile_j_(0), - left_(0), - top_(0), - right_(-1), - bottom_(-1) { -} +PictureLayerTiling::CoverageIterator::CoverageIterator() = default; PictureLayerTiling::CoverageIterator::CoverageIterator( const PictureLayerTiling* tiling, - float dest_scale, - const gfx::Rect& dest_rect) - : tiling_(tiling), - dest_rect_(dest_rect), - dest_to_content_scale_(0), - current_tile_(NULL), - tile_i_(0), - tile_j_(0), - left_(0), - top_(0), - right_(-1), - bottom_(-1) { + float coverage_scale, + const gfx::Rect& coverage_rect) + : tiling_(tiling), coverage_rect_(coverage_rect) { DCHECK(tiling_); - DCHECK_GE(dest_scale, tiling_->contents_scale_); - - // Clamp dest_rect_ to the bounds of the layer. - dest_layer_bounds_ = - gfx::ScaleToCeiledSize(tiling->raster_source_->GetSize(), dest_scale); - dest_rect_.Intersect(gfx::Rect(dest_layer_bounds_)); - if (dest_rect_.IsEmpty()) + // In order to avoid artifacts in geometry_rect scaling and clamping to ints, + // the |coverage_scale| should always be at least as big as the tiling's + // raster scales. + DCHECK_GE(coverage_scale, tiling_->raster_scales_.width()); + DCHECK_GE(coverage_scale, tiling_->raster_scales_.height()); + + // Clamp |coverage_rect| to the bounds of this tiling's raster source. + coverage_rect_max_bounds_ = + gfx::ScaleToCeiledSize(tiling->raster_source_->GetSize(), coverage_scale); + coverage_rect_.Intersect(gfx::Rect(coverage_rect_max_bounds_)); + if (coverage_rect_.IsEmpty()) return; - dest_to_content_scale_ = tiling_->contents_scale_ / dest_scale; + coverage_to_content_scale_ = + gfx::SizeF(tiling_->raster_scales_.width() / coverage_scale, + tiling_->raster_scales_.height() / coverage_scale); // Find the indices of the texel samples that enclose the rect we want to // cover. @@ -432,8 +428,9 @@ PictureLayerTiling::CoverageIterator::CoverageIterator( // wanted_texels(sample coordinates) = (l:99.5, t:189.5, r:280.5, b:371.5) // Or in integer index: // wanted_texels(integer index) = (l:99, t:189, r:280, b:371) - gfx::RectF content_rect = - gfx::ScaleRect(gfx::RectF(dest_rect_), dest_to_content_scale_); + gfx::RectF content_rect = gfx::ScaleRect(gfx::RectF(coverage_rect_), + coverage_to_content_scale_.width(), + coverage_to_content_scale_.height()); content_rect.Offset(-0.5f, -0.5f); gfx::Rect wanted_texels = gfx::ToEnclosingRect(content_rect); @@ -492,29 +489,34 @@ PictureLayerTiling::CoverageIterator::operator++() { texel_extent.Inset(-epsilon, -epsilon); } + // Convert texel_extent to coverage scale, which is what we have to report + // geometry_rect in. current_geometry_rect_ = gfx::ToEnclosedRect( - gfx::ScaleRect(texel_extent, 1 / dest_to_content_scale_)); + gfx::ScaleRect(texel_extent, 1.f / coverage_to_content_scale_.width(), + 1.f / coverage_to_content_scale_.height())); { // Adjust external edges to cover the whole layer in dest space. // // For external edges, extend the tile to scaled layer bounds. This is - // needed to fully cover the dest space because the sample extent doesn't - // cover the last 0.5 texel to layer edge, and also the dest space can be - // rounded up for up to 1 pixel. This overhang will never be sampled as the - // AA fragment shader clamps sample coordinate and antialiasing itself. + // needed to fully cover the coverage space because the sample extent + // doesn't cover the last 0.5 texel to layer edge, and also the coverage + // space can be rounded up for up to 1 pixel. This overhang will never be + // sampled as the AA fragment shader clamps sample coordinate and + // antialiasing itself. const TilingData& data = tiling_->tiling_data_; - current_geometry_rect_.Inset( - tile_i_ ? 0 : -current_geometry_rect_.x(), - tile_j_ ? 0 : -current_geometry_rect_.y(), - (tile_i_ != data.num_tiles_x() - 1) - ? 0 - : current_geometry_rect_.right() - dest_layer_bounds_.width(), - (tile_j_ != data.num_tiles_y() - 1) - ? 0 - : current_geometry_rect_.bottom() - dest_layer_bounds_.height()); + current_geometry_rect_.Inset(tile_i_ ? 0 : -current_geometry_rect_.x(), + tile_j_ ? 0 : -current_geometry_rect_.y(), + (tile_i_ != data.num_tiles_x() - 1) + ? 0 + : current_geometry_rect_.right() - + coverage_rect_max_bounds_.width(), + (tile_j_ != data.num_tiles_y() - 1) + ? 0 + : current_geometry_rect_.bottom() - + coverage_rect_max_bounds_.height()); } - current_geometry_rect_.Intersect(dest_rect_); + current_geometry_rect_.Intersect(coverage_rect_); DCHECK(!current_geometry_rect_.IsEmpty()); if (first_time) @@ -526,7 +528,7 @@ PictureLayerTiling::CoverageIterator::operator++() { int min_left; int min_top; if (new_row) { - min_left = dest_rect_.x(); + min_left = coverage_rect_.x(); min_top = last_geometry_rect.bottom(); } else { min_left = last_geometry_rect.right(); @@ -556,8 +558,8 @@ gfx::RectF PictureLayerTiling::CoverageIterator::texture_rect() const { // Convert from dest space => content space => texture space. gfx::RectF texture_rect(current_geometry_rect_); - texture_rect.Scale(dest_to_content_scale_, - dest_to_content_scale_); + texture_rect.Scale(coverage_to_content_scale_.width(), + coverage_to_content_scale_.height()); texture_rect.Intersect(gfx::RectF(gfx::SizeF(tiling_->tiling_size()))); if (texture_rect.IsEmpty()) return texture_rect; @@ -603,7 +605,9 @@ void PictureLayerTiling::ComputeTilePriorityRects( set_all_tiles_done(false); } - const float content_to_screen_scale = ideal_contents_scale / contents_scale_; + gfx::SizeF content_to_screen_scale( + ideal_contents_scale / raster_scales_.width(), + ideal_contents_scale / raster_scales_.height()); const gfx::Rect* input_rects[] = { &visible_rect_in_layer_space, &skewport_in_layer_space, @@ -611,7 +615,8 @@ void PictureLayerTiling::ComputeTilePriorityRects( gfx::Rect output_rects[4]; for (size_t i = 0; i < arraysize(input_rects); ++i) { output_rects[i] = gfx::ToEnclosingRect( - gfx::ScaleRect(gfx::RectF(*input_rects[i]), contents_scale_)); + gfx::ScaleRect(gfx::RectF(*input_rects[i]), raster_scales_.width(), + raster_scales_.height())); } // Make sure the eventually rect is aligned to tile bounds. output_rects[3] = @@ -624,7 +629,7 @@ void PictureLayerTiling::ComputeTilePriorityRects( } void PictureLayerTiling::SetTilePriorityRects( - float content_to_screen_scale, + const gfx::SizeF& content_to_screen_scale, const gfx::Rect& visible_rect_in_content_space, const gfx::Rect& skewport, const gfx::Rect& soon_border_rect, @@ -647,14 +652,15 @@ void PictureLayerTiling::SetTilePriorityRects( // Note that we use the largest skewport extent from the viewport as the // "skewport extent". Also note that this math can't produce negative numbers, // 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())); + max_skewport_extent_in_screen_space_ = std::max( + current_content_to_screen_scale_.width() * + std::max( + current_visible_rect_.x() - current_skewport_rect_.x(), + current_skewport_rect_.right() - current_visible_rect_.right()), + current_content_to_screen_scale_.height() * + std::max(current_visible_rect_.y() - current_skewport_rect_.y(), + current_skewport_rect_.bottom() - + current_visible_rect_.bottom())); } void PictureLayerTiling::SetLiveTilesRect( @@ -755,9 +761,10 @@ bool PictureLayerTiling::IsTileOccludedOnCurrentTree(const Tile* tile) const { if (tile_query_rect.IsEmpty()) return false; - if (contents_scale_ != 1.f) { + if (raster_scales_ != gfx::SizeF(1.f, 1.f)) { tile_query_rect = - gfx::ScaleToEnclosingRect(tile_query_rect, 1.f / contents_scale_); + gfx::ScaleToEnclosingRect(tile_query_rect, 1.f / raster_scales_.width(), + 1.f / raster_scales_.height()); } return current_occlusion_in_layer_space_.IsOccluded(tile_query_rect); } @@ -841,7 +848,8 @@ PrioritizedTile PictureLayerTiling::MakePrioritizedTile( DCHECK(raster_source()->CoversRect(tile->enclosing_layer_rect())) << "Recording rect: " << gfx::ScaleToEnclosingRect(tile->content_rect(), - 1.f / tile->contents_scale()) + 1.f / tile->raster_scales().width(), + 1.f / tile->raster_scales().height()) .ToString(); const auto& tile_priority = ComputePriorityForTile(tile, priority_rect_type); @@ -896,10 +904,10 @@ TilePriority PictureLayerTiling::ComputePriorityForTile( gfx::Rect tile_bounds = tiling_data_.TileBounds(tile->tiling_i_index(), tile->tiling_j_index()); - DCHECK_GT(current_content_to_screen_scale_, 0.f); - float distance_to_visible = - current_visible_rect_.ManhattanInternalDistance(tile_bounds) * - current_content_to_screen_scale_; + DCHECK_GT(current_content_to_screen_scale_.width(), 0.f); + DCHECK_GT(current_content_to_screen_scale_.height(), 0.f); + float distance_to_visible = ComputeScaledManhattalInternalDistance( + current_visible_rect_, tile_bounds, current_content_to_screen_scale_); return TilePriority(resolution_, priority_bin, distance_to_visible); } @@ -938,7 +946,14 @@ void PictureLayerTiling::GetAllPrioritizedTilesForTracing( void PictureLayerTiling::AsValueInto( base::trace_event::TracedValue* state) const { state->SetInteger("num_tiles", base::saturated_cast<int>(tiles_.size())); - state->SetDouble("content_scale", contents_scale_); + // TODO(vmpstr): Change frameviewer to use raster scales. + state->SetDouble("content_scale", contents_scale_key()); + + state->BeginArray("raster_scales"); + state->AppendDouble(raster_scales_.width()); + state->AppendDouble(raster_scales_.height()); + state->EndArray(); + MathUtil::AddToTracedValue("visible_rect", current_visible_rect_, state); MathUtil::AddToTracedValue("skewport_rect", current_skewport_rect_, state); MathUtil::AddToTracedValue("soon_rect", current_soon_border_rect_, state); diff --git a/chromium/cc/tiles/picture_layer_tiling.h b/chromium/cc/tiles/picture_layer_tiling.h index 2768344a96b..99e30d9f054 100644 --- a/chromium/cc/tiles/picture_layer_tiling.h +++ b/chromium/cc/tiles/picture_layer_tiling.h @@ -81,7 +81,7 @@ class CC_EXPORT PictureLayerTiling { static const int kBorderTexels = 1; PictureLayerTiling(WhichTree tree, - float contents_scale, + const gfx::SizeF& raster_scales, scoped_refptr<RasterSource> raster_source, PictureLayerTilingClient* client, float min_preraster_distance, @@ -120,7 +120,8 @@ class CC_EXPORT PictureLayerTiling { gfx::Size tiling_size() const { return tiling_data_.tiling_size(); } gfx::Rect live_tiles_rect() const { return live_tiles_rect_; } gfx::Size tile_size() const { return tiling_data_.max_texture_size(); } - float contents_scale() const { return contents_scale_; } + float contents_scale_key() const { return raster_scales_.width(); } + const gfx::SizeF& raster_scales() const { return raster_scales_; } const TilingData* tiling_data() const { return &tiling_data_; } Tile* TileAt(int i, int j) const { @@ -164,8 +165,9 @@ class CC_EXPORT PictureLayerTiling { UpdateAndGetAllPrioritizedTilesForTesting() const; void SetAllTilesOccludedForTesting() { - gfx::Rect viewport_in_layer_space = - ScaleToEnclosingRect(current_visible_rect_, 1.0f / contents_scale_); + gfx::Rect viewport_in_layer_space = ScaleToEnclosingRect( + current_visible_rect_, 1.f / raster_scales_.width(), + 1.f / raster_scales_.height()); current_occlusion_in_layer_space_ = Occlusion(gfx::Transform(), SimpleEnclosedRegion(viewport_in_layer_space), @@ -179,8 +181,9 @@ class CC_EXPORT PictureLayerTiling { const gfx::Rect& skewport, const gfx::Rect& soon_border_rect, const gfx::Rect& eventually_rect) { - SetTilePriorityRects(1.0f, visible_rect_in_content_space, skewport, - soon_border_rect, eventually_rect, Occlusion()); + SetTilePriorityRects(gfx::SizeF(1.f, 1.f), visible_rect_in_content_space, + skewport, soon_border_rect, eventually_rect, + Occlusion()); } // Iterate over all tiles to fill content_rect. Even if tiles are invalid @@ -190,12 +193,14 @@ class CC_EXPORT PictureLayerTiling { class CC_EXPORT CoverageIterator { public: CoverageIterator(); + // This requests an iterator that produces a coverage of the + // |coverage_rect|, which is specified at |coverage_scale|. CoverageIterator(const PictureLayerTiling* tiling, - float dest_scale, - const gfx::Rect& rect); + float coverage_scale, + const gfx::Rect& coverage_rect); ~CoverageIterator(); - // Visible rect (no borders), always in the space of content_rect, + // Visible rect (no borders), always in the space of |coverage_rect|, // regardless of the contents scale of the tiling. gfx::Rect geometry_rect() const; // Texture rect (in texels) for geometry_rect @@ -211,19 +216,19 @@ class CC_EXPORT PictureLayerTiling { int j() const { return tile_j_; } private: - const PictureLayerTiling* tiling_; - gfx::Size dest_layer_bounds_; - gfx::Rect dest_rect_; - float dest_to_content_scale_; + const PictureLayerTiling* tiling_ = nullptr; + gfx::Size coverage_rect_max_bounds_; + gfx::Rect coverage_rect_; + gfx::SizeF coverage_to_content_scale_; - Tile* current_tile_; + Tile* current_tile_ = nullptr; gfx::Rect current_geometry_rect_; - int tile_i_; - int tile_j_; - int left_; - int top_; - int right_; - int bottom_; + int tile_i_ = 0; + int tile_j_ = 0; + int left_ = 0; + int top_ = 0; + int right_ = -1; + int bottom_ = -1; friend class PictureLayerTiling; }; @@ -274,7 +279,7 @@ class CC_EXPORT PictureLayerTiling { bool TilingMatchesTileIndices(const PictureLayerTiling* twin) const; // Save the required data for computing tile priorities later. - void SetTilePriorityRects(float content_to_screen_scale_, + void SetTilePriorityRects(const gfx::SizeF& content_to_screen_scale, const gfx::Rect& visible_rect_in_content_space, const gfx::Rect& skewport, const gfx::Rect& soon_border_rect, @@ -323,21 +328,21 @@ class CC_EXPORT PictureLayerTiling { void RemoveTilesInRegion(const Region& layer_region, bool recreate_tiles); // Given properties. - const float contents_scale_; + const gfx::SizeF raster_scales_; PictureLayerTilingClient* const client_; const WhichTree tree_; scoped_refptr<RasterSource> raster_source_; const float min_preraster_distance_; const float max_preraster_distance_; - TileResolution resolution_; - bool may_contain_low_resolution_tiles_; + TileResolution resolution_ = NON_IDEAL_RESOLUTION; + bool may_contain_low_resolution_tiles_ = false; // Internal data. - TilingData tiling_data_; + TilingData tiling_data_ = TilingData(gfx::Size(), gfx::Size(), kBorderTexels); TileMap tiles_; // It is not legal to have a NULL tile in the tiles_ map. gfx::Rect live_tiles_rect_; - bool can_require_tiles_for_activation_; + bool can_require_tiles_for_activation_ = false; // Iteration rects in content space. gfx::Rect current_visible_rect_; @@ -345,15 +350,15 @@ class CC_EXPORT PictureLayerTiling { gfx::Rect current_soon_border_rect_; gfx::Rect current_eventually_rect_; // Other properties used for tile iteration and prioritization. - float current_content_to_screen_scale_; + gfx::SizeF current_content_to_screen_scale_; Occlusion current_occlusion_in_layer_space_; - float max_skewport_extent_in_screen_space_; + float max_skewport_extent_in_screen_space_ = 0.f; - bool has_visible_rect_tiles_; - bool has_skewport_rect_tiles_; - bool has_soon_border_rect_tiles_; - bool has_eventually_rect_tiles_; - bool all_tiles_done_; + bool has_visible_rect_tiles_ = false; + bool has_skewport_rect_tiles_ = false; + bool has_soon_border_rect_tiles_ = false; + bool has_eventually_rect_tiles_ = false; + bool all_tiles_done_ = true; private: DISALLOW_COPY_AND_ASSIGN(PictureLayerTiling); diff --git a/chromium/cc/tiles/picture_layer_tiling_set.cc b/chromium/cc/tiles/picture_layer_tiling_set.cc index 0136b89d5bd..55b86ae95a4 100644 --- a/chromium/cc/tiles/picture_layer_tiling_set.cc +++ b/chromium/cc/tiles/picture_layer_tiling_set.cc @@ -11,6 +11,7 @@ #include <vector> #include "base/memory/ptr_util.h" +#include "base/trace_event/trace_event.h" #include "cc/playback/raster_source.h" #include "ui/gfx/geometry/rect_conversions.h" @@ -22,7 +23,7 @@ class LargestToSmallestScaleFunctor { public: bool operator()(const std::unique_ptr<PictureLayerTiling>& left, const std::unique_ptr<PictureLayerTiling>& right) { - return left->contents_scale() > right->contents_scale(); + return left->contents_scale_key() > right->contents_scale_key(); } }; @@ -66,8 +67,7 @@ PictureLayerTilingSet::PictureLayerTilingSet( client_(client), max_preraster_distance_(max_preraster_distance) {} -PictureLayerTilingSet::~PictureLayerTilingSet() { -} +PictureLayerTilingSet::~PictureLayerTilingSet() = default; void PictureLayerTilingSet::CopyTilingsAndPropertiesFromPendingTwin( const PictureLayerTilingSet* pending_twin_set, @@ -83,11 +83,11 @@ void PictureLayerTilingSet::CopyTilingsAndPropertiesFromPendingTwin( bool tiling_sort_required = false; for (const auto& pending_twin_tiling : pending_twin_set->tilings_) { - float contents_scale = pending_twin_tiling->contents_scale(); - PictureLayerTiling* this_tiling = FindTilingWithScale(contents_scale); + PictureLayerTiling* this_tiling = + FindTilingWithScaleKey(pending_twin_tiling->contents_scale_key()); if (!this_tiling) { std::unique_ptr<PictureLayerTiling> new_tiling(new PictureLayerTiling( - tree_, contents_scale, raster_source_, client_, + tree_, pending_twin_tiling->raster_scales(), raster_source_, client_, kMaxSoonBorderDistanceInScreenPixels, max_preraster_distance_)); tilings_.push_back(std::move(new_tiling)); this_tiling = tilings_.back().get(); @@ -108,10 +108,10 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation( scoped_refptr<RasterSource> raster_source, const PictureLayerTilingSet* pending_twin_set, const Region& layer_invalidation, - float minimum_contents_scale, - float maximum_contents_scale) { - RemoveTilingsBelowScale(minimum_contents_scale); - RemoveTilingsAboveScale(maximum_contents_scale); + float minimum_contents_scale_key, + float maximum_contents_scale_key) { + RemoveTilingsBelowScaleKey(minimum_contents_scale_key); + RemoveTilingsAboveScaleKey(maximum_contents_scale_key); raster_source_ = raster_source; @@ -123,7 +123,7 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation( // If the tiling is not shared (FindTilingWithScale returns nullptr), then // invalidate tiles and update them to the new raster source. for (const auto& tiling : tilings_) { - if (pending_twin_set->FindTilingWithScale(tiling->contents_scale())) + if (pending_twin_set->FindTilingWithScaleKey(tiling->contents_scale_key())) continue; tiling->SetRasterSourceAndResize(raster_source); @@ -149,10 +149,10 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForActivation( void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit( scoped_refptr<RasterSource> raster_source, const Region& layer_invalidation, - float minimum_contents_scale, - float maximum_contents_scale) { - RemoveTilingsBelowScale(minimum_contents_scale); - RemoveTilingsAboveScale(maximum_contents_scale); + float minimum_contents_scale_key, + float maximum_contents_scale_key) { + RemoveTilingsBelowScaleKey(minimum_contents_scale_key); + RemoveTilingsAboveScaleKey(maximum_contents_scale_key); raster_source_ = raster_source; @@ -161,12 +161,17 @@ void PictureLayerTilingSet::UpdateTilingsToCurrentRasterSourceForCommit( DCHECK(tree_ != PENDING_TREE || !tiling->has_tiles()); tiling->SetRasterSourceAndResize(raster_source); + // Force |UpdateTilePriorities| on commit for cases where the compositor is + // heavily pipelined resulting in back to back draw and commit. This + // prevents the early out from |UpdateTilePriorities| because frame time + // didn't change. That in turn causes an early out from PrepareTiles which + // can cause checkerboarding. + state_since_last_tile_priority_update_.invalidated = true; + // We can commit on either active or pending trees, but only active one can // have tiles at this point. - if (tree_ == ACTIVE_TREE) { + if (tree_ == ACTIVE_TREE) tiling->Invalidate(layer_invalidation); - state_since_last_tile_priority_update_.invalidated = true; - } // This is needed for cases where the live tiles rect didn't change but // recordings exist in the raster source that did not exist on the last @@ -219,15 +224,15 @@ void PictureLayerTilingSet::VerifyTilings( } void PictureLayerTilingSet::CleanUpTilings( - float min_acceptable_high_res_scale, - float max_acceptable_high_res_scale, + float min_acceptable_high_res_scale_key, + float max_acceptable_high_res_scale_key, const std::vector<PictureLayerTiling*>& needed_tilings, PictureLayerTilingSet* twin_set) { std::vector<PictureLayerTiling*> to_remove; for (const auto& tiling : tilings_) { // Keep all tilings within the min/max scales. - if (tiling->contents_scale() >= min_acceptable_high_res_scale && - tiling->contents_scale() <= max_acceptable_high_res_scale) { + if (tiling->contents_scale_key() >= min_acceptable_high_res_scale_key && + tiling->contents_scale_key() <= max_acceptable_high_res_scale_key) { continue; } @@ -265,18 +270,22 @@ void PictureLayerTilingSet::MarkAllTilingsNonIdeal() { } PictureLayerTiling* PictureLayerTilingSet::AddTiling( - float contents_scale, + float contents_scale_key, scoped_refptr<RasterSource> raster_source) { if (!raster_source_) raster_source_ = raster_source; +#if DCHECK_IS_ON() for (size_t i = 0; i < tilings_.size(); ++i) { - DCHECK_NE(tilings_[i]->contents_scale(), contents_scale); + DCHECK_NE(tilings_[i]->contents_scale_key(), contents_scale_key); DCHECK_EQ(tilings_[i]->raster_source(), raster_source.get()); } +#endif // DCHECK_IS_ON() + gfx::SizeF raster_scales(contents_scale_key, + contents_scale_key / aspect_ratio_); tilings_.push_back(base::MakeUnique<PictureLayerTiling>( - tree_, contents_scale, raster_source, client_, + tree_, raster_scales, raster_source, client_, kMaxSoonBorderDistanceInScreenPixels, max_preraster_distance_)); PictureLayerTiling* appended = tilings_.back().get(); state_since_last_tile_priority_update_.added_tilings = true; @@ -292,10 +301,10 @@ int PictureLayerTilingSet::NumHighResTilings() const { }); } -PictureLayerTiling* PictureLayerTilingSet::FindTilingWithScale( - float scale) const { +PictureLayerTiling* PictureLayerTilingSet::FindTilingWithScaleKey( + float scale_key) const { for (size_t i = 0; i < tilings_.size(); ++i) { - if (tilings_[i]->contents_scale() == scale) + if (tilings_[i]->contents_scale_key() == scale_key) return tilings_[i].get(); } return nullptr; @@ -313,20 +322,22 @@ PictureLayerTiling* PictureLayerTilingSet::FindTilingWithResolution( return iter->get(); } -void PictureLayerTilingSet::RemoveTilingsBelowScale(float minimum_scale) { +void PictureLayerTilingSet::RemoveTilingsBelowScaleKey( + float minimum_scale_key) { auto to_remove = std::remove_if( tilings_.begin(), tilings_.end(), - [minimum_scale](const std::unique_ptr<PictureLayerTiling>& tiling) { - return tiling->contents_scale() < minimum_scale; + [minimum_scale_key](const std::unique_ptr<PictureLayerTiling>& tiling) { + return tiling->contents_scale_key() < minimum_scale_key; }); tilings_.erase(to_remove, tilings_.end()); } -void PictureLayerTilingSet::RemoveTilingsAboveScale(float maximum_scale) { +void PictureLayerTilingSet::RemoveTilingsAboveScaleKey( + float maximum_scale_key) { auto to_remove = std::remove_if( tilings_.begin(), tilings_.end(), - [maximum_scale](const std::unique_ptr<PictureLayerTiling>& tiling) { - return tiling->contents_scale() > maximum_scale; + [maximum_scale_key](const std::unique_ptr<PictureLayerTiling>& tiling) { + return tiling->contents_scale_key() > maximum_scale_key; }); tilings_.erase(to_remove, tilings_.end()); } @@ -351,14 +362,14 @@ void PictureLayerTilingSet::RemoveAllTiles() { tilings_[i]->Reset(); } -float PictureLayerTilingSet::GetSnappedContentsScale( +float PictureLayerTilingSet::GetSnappedContentsScaleKey( float start_scale, float snap_to_existing_tiling_ratio) const { // If a tiling exists within the max snapping ratio, snap to its scale. float snapped_contents_scale = start_scale; float snapped_ratio = snap_to_existing_tiling_ratio; for (const auto& tiling : tilings_) { - float tiling_contents_scale = tiling->contents_scale(); + float tiling_contents_scale = tiling->contents_scale_key(); float ratio = LargerRatio(tiling_contents_scale, start_scale); if (ratio < snapped_ratio) { snapped_contents_scale = tiling_contents_scale; @@ -372,7 +383,8 @@ float PictureLayerTilingSet::GetMaximumContentsScale() const { if (tilings_.empty()) return 0.f; // The first tiling has the largest contents scale. - return tilings_[0]->contents_scale(); + return std::max(tilings_[0]->raster_scales().width(), + tilings_[0]->raster_scales().height()); } bool PictureLayerTilingSet::TilingsNeedUpdate( @@ -539,6 +551,15 @@ bool PictureLayerTilingSet::UpdateTilePriorities( return true; } +void PictureLayerTilingSet::SetAspectRatio(float ratio) { + if (std::abs(ratio - aspect_ratio_) < std::numeric_limits<float>::epsilon()) + return; + TRACE_EVENT1("cc", "PictureLayerTilingSet::SetAspectRatio", "aspect_ratio", + ratio); + aspect_ratio_ = ratio; + RemoveAllTilings(); +} + void PictureLayerTilingSet::GetAllPrioritizedTilesForTracing( std::vector<PrioritizedTile>* prioritized_tiles) const { for (const auto& tiling : tilings_) @@ -547,35 +568,39 @@ void PictureLayerTilingSet::GetAllPrioritizedTilesForTracing( PictureLayerTilingSet::CoverageIterator::CoverageIterator( const PictureLayerTilingSet* set, - float contents_scale, - const gfx::Rect& content_rect, + float coverage_scale, + const gfx::Rect& coverage_rect, float ideal_contents_scale) : set_(set), - contents_scale_(contents_scale), - ideal_contents_scale_(ideal_contents_scale), + coverage_scale_(coverage_scale), current_tiling_(std::numeric_limits<size_t>::max()) { - missing_region_.Union(content_rect); + missing_region_.Union(coverage_rect); + // Determine the smallest content_scale tiling which a scale higher than the + // ideal (or the first tiling if all tilings have a scale less than ideal). size_t tilings_size = set_->tilings_.size(); for (ideal_tiling_ = 0; ideal_tiling_ < tilings_size; ++ideal_tiling_) { PictureLayerTiling* tiling = set_->tilings_[ideal_tiling_].get(); - if (tiling->contents_scale() < ideal_contents_scale_) { + if (tiling->contents_scale_key() < ideal_contents_scale) { if (ideal_tiling_ > 0) ideal_tiling_--; break; } } + // If all tilings have a scale larger than the ideal, then use the smallest + // scale (which is the last one). if (ideal_tiling_ == tilings_size && ideal_tiling_ > 0) ideal_tiling_--; ++(*this); } -PictureLayerTilingSet::CoverageIterator::~CoverageIterator() { -} +PictureLayerTilingSet::CoverageIterator::~CoverageIterator() = default; gfx::Rect PictureLayerTilingSet::CoverageIterator::geometry_rect() const { + // If we don't have any more tilings to process, then return the region + // iterator rect that we need to fill, so that the caller can checkerboard it. if (!tiling_iter_) { if (!region_iter_.has_rect()) return gfx::Rect(); @@ -585,6 +610,7 @@ gfx::Rect PictureLayerTilingSet::CoverageIterator::geometry_rect() const { } gfx::RectF PictureLayerTilingSet::CoverageIterator::texture_rect() const { + // Texture rects are only valid if we have a tiling. if (!tiling_iter_) return gfx::RectF(); return tiling_iter_.texture_rect(); @@ -645,11 +671,15 @@ PictureLayerTilingSet::CoverageIterator::operator++() { // Loop until we find a valid place to stop. while (true) { + // While we don't have a ready to draw tile, accumulate the geometry rects + // back into the missing region, which will be iterated after this tiling is + // processed. while (tiling_iter_ && (!*tiling_iter_ || !tiling_iter_->draw_info().IsReadyToDraw())) { missing_region_.Union(tiling_iter_.geometry_rect()); ++tiling_iter_; } + // We found a ready tile, yield it! if (tiling_iter_) return *this; @@ -685,7 +715,7 @@ PictureLayerTilingSet::CoverageIterator::operator++() { // Construct a new iterator for the next tiling, but we need to loop // again until we get to a valid one. tiling_iter_ = PictureLayerTiling::CoverageIterator( - set_->tilings_[current_tiling_].get(), contents_scale_, last_rect); + set_->tilings_[current_tiling_].get(), coverage_scale_, last_rect); } return *this; diff --git a/chromium/cc/tiles/picture_layer_tiling_set.h b/chromium/cc/tiles/picture_layer_tiling_set.h index 20e7a76ef57..8addadfbd8d 100644 --- a/chromium/cc/tiles/picture_layer_tiling_set.h +++ b/chromium/cc/tiles/picture_layer_tiling_set.h @@ -52,8 +52,8 @@ class CC_EXPORT PictureLayerTilingSet { const PictureLayerTilingClient* client() const { return client_; } - void CleanUpTilings(float min_acceptable_high_res_scale, - float max_acceptable_high_res_scale, + void CleanUpTilings(float min_acceptable_high_res_scale_key, + float max_acceptable_high_res_scale_key, const std::vector<PictureLayerTiling*>& needed_tilings, PictureLayerTilingSet* twin_set); void RemoveNonIdealTilings(); @@ -63,22 +63,22 @@ class CC_EXPORT PictureLayerTilingSet { scoped_refptr<RasterSource> raster_source, const PictureLayerTilingSet* pending_twin_set, const Region& layer_invalidation, - float minimum_contents_scale, - float maximum_contents_scale); + float minimum_contents_scale_key, + float maximum_contents_scale_key); // This function is called on the sync tree during commit. void UpdateTilingsToCurrentRasterSourceForCommit( scoped_refptr<RasterSource> raster_source, const Region& layer_invalidation, - float minimum_contents_scale, - float maximum_contents_scale); + float minimum_contents_scale_key, + float maximum_contents_scale_key); // This function is called on the sync tree right after commit. void UpdateRasterSourceDueToLCDChange( scoped_refptr<RasterSource> raster_source, const Region& layer_invalidation); - PictureLayerTiling* AddTiling(float contents_scale, + PictureLayerTiling* AddTiling(float contents_scale_key, scoped_refptr<RasterSource> raster_source); size_t num_tilings() const { return tilings_.size(); } int NumHighResTilings() const; @@ -88,7 +88,7 @@ class CC_EXPORT PictureLayerTilingSet { } WhichTree tree() const { return tree_; } - PictureLayerTiling* FindTilingWithScale(float scale) const; + PictureLayerTiling* FindTilingWithScaleKey(float scale_key) const; PictureLayerTiling* FindTilingWithResolution(TileResolution resolution) const; void MarkAllTilingsNonIdeal(); @@ -97,18 +97,19 @@ class CC_EXPORT PictureLayerTilingSet { // ratio of |start_scale|, then return that tiling's scale. Otherwise, return // |start_scale|. If multiple tilings match the criteria, return the one with // the least ratio to |start_scale|. - float GetSnappedContentsScale(float start_scale, - float snap_to_existing_tiling_ratio) const; + float GetSnappedContentsScaleKey(float start_scale, + float snap_to_existing_tiling_ratio) const; // Returns the maximum contents scale of all tilings, or 0 if no tilings - // exist. + // exist. Note that this returns the maximum of x and y scales depending on + // the aspect ratio. float GetMaximumContentsScale() const; - // Removes all tilings with a contents scale < |minimum_scale|. - void RemoveTilingsBelowScale(float minimum_scale); + // Removes all tilings with a contents scale key < |minimum_scale_key|. + void RemoveTilingsBelowScaleKey(float minimum_scale_key); - // Removes all tilings with a contents scale > |maximum_scale|. - void RemoveTilingsAboveScale(float maximum_scale); + // Removes all tilings with a contents scale key > |maximum_scale_key|. + void RemoveTilingsAboveScaleKey(float maximum_scale); // Remove all tilings. void RemoveAllTilings(); @@ -124,6 +125,9 @@ class CC_EXPORT PictureLayerTilingSet { const Occlusion& occlusion_in_layer_space, bool can_require_tiles_for_activation); + void SetAspectRatio(float ratio); + float aspect_ratio() const { return aspect_ratio_; } + void GetAllPrioritizedTilesForTracing( std::vector<PrioritizedTile>* prioritized_tiles) const; @@ -134,16 +138,24 @@ class CC_EXPORT PictureLayerTilingSet { // exactly fill rect with no overlap. class CC_EXPORT CoverageIterator { public: + // |coverage_scale| is the scale at which we want to produce the coverage. + // This is the scale at which |coverage_rect| is specified (relative to + // identity). + // |coverage_rect| is a rect that we want to cover during this iteration. + // |ideal_contents_scale| is the ideal scale that we want, which determines + // the order in which tilings are processed to get the best ("crispest") + // coverage. CoverageIterator(const PictureLayerTilingSet* set, - float contents_scale, - const gfx::Rect& content_rect, - float ideal_contents_scale); + float coverage_scale, + const gfx::Rect& coverage_rect, + float ideal_contents_scale); ~CoverageIterator(); - // Visible rect (no borders), always in the space of rect, - // regardless of the relative contents scale of the tiling. + // Visible rect (no borders), in the space of |coverage_rect| (ie at + // |coverage_scale| from identity). This is clipped to the coverage_rect. gfx::Rect geometry_rect() const; - // Texture rect (in texels) for geometry_rect + // A geometry_rect scaled to the tiling's contents scale, which represents + // the texture rect in texels. gfx::RectF texture_rect() const; Tile* operator->() const; @@ -159,8 +171,7 @@ class CC_EXPORT PictureLayerTilingSet { size_t NextTiling() const; const PictureLayerTilingSet* set_; - float contents_scale_; - float ideal_contents_scale_; + float coverage_scale_; PictureLayerTiling::CoverageIterator tiling_iter_; size_t current_tiling_; size_t ideal_tiling_; @@ -251,6 +262,8 @@ class CC_EXPORT PictureLayerTilingSet { gfx::Rect soon_border_rect_in_layer_space_; gfx::Rect eventually_rect_in_layer_space_; + float aspect_ratio_ = 1.f; + friend class Iterator; private: diff --git a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc index 6069d0028e0..e4fa86d15ed 100644 --- a/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc +++ b/chromium/cc/tiles/picture_layer_tiling_set_unittest.cc @@ -276,7 +276,7 @@ class PictureLayerTilingSetTestWithResources : public testing::Test { ASSERT_TRUE(remaining.Contains(geometry_rect)); remaining.Subtract(geometry_rect); - float scale = iter.CurrentTiling()->contents_scale(); + float scale = iter.CurrentTiling()->contents_scale_key(); EXPECT_EQ(expected_scale, scale); if (num_tilings) @@ -984,5 +984,58 @@ TEST(PictureLayerTilingTest, InvalidateAfterComputeTilePriorityRects) { tiling_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true)); } +TEST(PictureLayerTilingTest, InvalidateAfterUpdateRasterSourceForCommit) { + FakePictureLayerTilingClient pending_client; + FakePictureLayerTilingClient active_client; + std::unique_ptr<PictureLayerTilingSet> pending_set = + PictureLayerTilingSet::Create(PENDING_TREE, &pending_client, 1000, 1.f, + 1000, 1000.f); + std::unique_ptr<PictureLayerTilingSet> active_set = + PictureLayerTilingSet::Create(ACTIVE_TREE, &active_client, 1000, 1.f, + 1000, 1000.f); + + gfx::Size layer_bounds(100, 100); + scoped_refptr<FakeRasterSource> raster_source = + FakeRasterSource::CreateFilled(layer_bounds); + + auto* pending_tiling = pending_set->AddTiling(1.f, raster_source); + pending_tiling->set_resolution(HIGH_RESOLUTION); + active_client.set_twin_tiling_set(pending_set.get()); + + double time = 1.; + gfx::Rect viewport(0, 0, 100, 100); + + // The first commit will update the raster source for pending tilings. + pending_set->UpdateTilingsToCurrentRasterSourceForCommit(raster_source, + Region(), 1.f, 1.f); + // UpdateTilePriorities for pending set gets called during UDP in commit. + EXPECT_TRUE(pending_set->UpdateTilePriorities(viewport, 1.f, time, + Occlusion(), true)); + // The active set doesn't have tilings yet. + EXPECT_FALSE( + active_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true)); + + // On activation tilings are copied from pending set to active set. + active_set->UpdateTilingsToCurrentRasterSourceForActivation( + raster_source, pending_set.get(), Region(), 1.f, 1.f); + // Pending set doesn't have any tilings now. + EXPECT_FALSE(pending_set->UpdateTilePriorities(viewport, 1.f, time, + Occlusion(), true)); + // UpdateTilePriorities for active set gets called during UDP in draw. + EXPECT_TRUE( + active_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true)); + + // Even though frame time and viewport haven't changed since last commit we + // update tile priorities because of potential invalidations. + pending_set->UpdateTilingsToCurrentRasterSourceForCommit(raster_source, + Region(), 1.f, 1.f); + // UpdateTilePriorities for pending set gets called during UDP in commit. + EXPECT_TRUE(pending_set->UpdateTilePriorities(viewport, 1.f, time, + Occlusion(), true)); + // No changes for active set until activation. + EXPECT_FALSE( + active_set->UpdateTilePriorities(viewport, 1.f, time, Occlusion(), true)); +} + } // namespace } // namespace cc diff --git a/chromium/cc/tiles/picture_layer_tiling_unittest.cc b/chromium/cc/tiles/picture_layer_tiling_unittest.cc index db739287acf..3291a33e1c9 100644 --- a/chromium/cc/tiles/picture_layer_tiling_unittest.cc +++ b/chromium/cc/tiles/picture_layer_tiling_unittest.cc @@ -18,7 +18,6 @@ #include "cc/test/fake_picture_layer_tiling_client.h" #include "cc/test/fake_raster_source.h" #include "cc/test/test_context_provider.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/tiles/picture_layer_tiling_set.h" #include "cc/trees/layer_tree_settings.h" #include "testing/gtest/include/gtest/gtest.h" @@ -77,7 +76,7 @@ class TestablePictureLayerTiling : public PictureLayerTiling { float min_preraster_distance, float max_preraster_distance) : PictureLayerTiling(tree, - contents_scale, + gfx::SizeF(contents_scale, contents_scale), raster_source, client, min_preraster_distance, @@ -134,7 +133,7 @@ class PictureLayerTilingIteratorTest : public testing::Test { // tiling scale. This is because coverage computation is done in integer // grids in the dest space, and the overlap between tiles may not guarantee // to enclose an integer grid line to round to if scaled down. - ASSERT_GE(rect_scale, tiling_->contents_scale()); + ASSERT_GE(rect_scale, tiling_->contents_scale_key()); Region remaining = expect_rect; for (PictureLayerTiling::CoverageIterator @@ -202,7 +201,7 @@ class PictureLayerTilingIteratorTest : public testing::Test { void VerifyTilesCoverNonContainedRect(float rect_scale, const gfx::Rect& dest_rect) { - float dest_to_contents_scale = tiling_->contents_scale() / rect_scale; + float dest_to_contents_scale = tiling_->contents_scale_key() / rect_scale; gfx::Rect clamped_rect = gfx::ScaleToEnclosingRect( gfx::Rect(tiling_->tiling_size()), 1.f / dest_to_contents_scale); clamped_rect.Intersect(dest_rect); diff --git a/chromium/cc/tiles/software_image_decode_controller.cc b/chromium/cc/tiles/software_image_decode_controller.cc index ce7ca8e2d6f..1277ed57e7d 100644 --- a/chromium/cc/tiles/software_image_decode_controller.cc +++ b/chromium/cc/tiles/software_image_decode_controller.cc @@ -28,6 +28,9 @@ #include "third_party/skia/include/core/SkPixmap.h" #include "ui/gfx/skia_util.h" +using base::trace_event::MemoryAllocatorDump; +using base::trace_event::MemoryDumpLevelOfDetail; + namespace cc { namespace { @@ -104,7 +107,8 @@ class ImageDecodeTaskImpl : public TileTask { "software", "source_prepare_tiles_id", tracing_info_.prepare_tiles_id); devtools_instrumentation::ScopedImageDecodeTask image_decode_task( - image_.image().get()); + image_.image().get(), + devtools_instrumentation::ScopedImageDecodeTask::SOFTWARE); controller_->DecodeImage(image_key_, image_); } @@ -213,7 +217,7 @@ bool SoftwareImageDecodeController::GetTaskForImageAndRef( // will be decoded at raster time which is when it will be temporarily put in // the cache. ImageKey key = ImageKey::FromDrawImage(image); - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::GetTaskForImageAndRef", "key", key.ToString()); @@ -287,7 +291,7 @@ bool SoftwareImageDecodeController::GetTaskForImageAndRef( } void SoftwareImageDecodeController::RefImage(const ImageKey& key) { - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::RefImage", "key", key.ToString()); lock_.AssertAcquired(); @@ -306,7 +310,7 @@ void SoftwareImageDecodeController::UnrefImage(const DrawImage& image) { // it yet (or failed to decode it). // 2b. Unlock the image but keep it in list. const ImageKey& key = ImageKey::FromDrawImage(image); - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::UnrefImage", "key", key.ToString()); @@ -395,7 +399,7 @@ std::unique_ptr<SoftwareImageDecodeController::DecodedImage> SoftwareImageDecodeController::DecodeImageInternal( const ImageKey& key, const DrawImage& draw_image) { - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::DecodeImageInternal", "key", key.ToString()); sk_sp<const SkImage> image = draw_image.image(); @@ -420,7 +424,7 @@ SoftwareImageDecodeController::DecodeImageInternal( DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( const DrawImage& draw_image) { ImageKey key = ImageKey::FromDrawImage(draw_image); - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::GetDecodedImageForDraw", "key", key.ToString()); // If the target size is empty, we can skip this image draw. @@ -433,7 +437,7 @@ DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDraw( DecodedDrawImage SoftwareImageDecodeController::GetDecodedImageForDrawInternal( const ImageKey& key, const DrawImage& draw_image) { - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::GetDecodedImageForDrawInternal", "key", key.ToString()); base::AutoLock lock(lock_); @@ -533,7 +537,7 @@ SoftwareImageDecodeController::GetOriginalImageDecode( CreateImageInfo(image->width(), image->height(), format_); std::unique_ptr<base::DiscardableMemory> decoded_pixels; { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::GetOriginalImageDecode - " "allocate decoded pixels"); decoded_pixels = @@ -542,7 +546,7 @@ SoftwareImageDecodeController::GetOriginalImageDecode( decoded_info.height()); } { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::GetOriginalImageDecode - " "read pixels"); bool result = image->readPixels(decoded_info, decoded_pixels->data(), @@ -587,16 +591,20 @@ SoftwareImageDecodeController::GetSubrectImageDecode( key.target_size().width(), key.target_size().height(), format_); std::unique_ptr<base::DiscardableMemory> subrect_pixels; { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::GetSubrectImageDecode - " "allocate subrect pixels"); + // TODO(vmpstr): This is using checked math to diagnose a problem reported + // in crbug.com/662217. If this is causing crashes, then it should be fixed + // elsewhere by skipping images that are too large. + base::CheckedNumeric<size_t> byte_size = subrect_info.minRowBytes(); + byte_size *= subrect_info.height(); subrect_pixels = base::DiscardableMemoryAllocator::GetInstance() - ->AllocateLockedDiscardableMemory(subrect_info.minRowBytes() * - subrect_info.height()); + ->AllocateLockedDiscardableMemory(byte_size.ValueOrDie()); } { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::GetOriginalImageDecode - " "read pixels"); bool result = decoded_draw_image.image()->readPixels( @@ -651,7 +659,7 @@ SoftwareImageDecodeController::GetScaledImageDecode( std::unique_ptr<base::DiscardableMemory> scaled_pixels; { TRACE_EVENT0( - "disabled-by-default-cc.debug", + TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::ScaleImage - allocate scaled pixels"); scaled_pixels = base::DiscardableMemoryAllocator::GetInstance() ->AllocateLockedDiscardableMemory( @@ -662,7 +670,7 @@ SoftwareImageDecodeController::GetScaledImageDecode( DCHECK(key.filter_quality() == kHigh_SkFilterQuality || key.filter_quality() == kMedium_SkFilterQuality); { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::ScaleImage - scale pixels"); bool result = decoded_pixmap.scalePixels(scaled_pixmap, key.filter_quality()); @@ -678,7 +686,7 @@ SoftwareImageDecodeController::GetScaledImageDecode( void SoftwareImageDecodeController::DrawWithImageFinished( const DrawImage& image, const DecodedDrawImage& decoded_image) { - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::DrawWithImageFinished", "key", ImageKey::FromDrawImage(image).ToString()); ImageKey key = ImageKey::FromDrawImage(image); @@ -693,7 +701,7 @@ void SoftwareImageDecodeController::DrawWithImageFinished( } void SoftwareImageDecodeController::RefAtRasterImage(const ImageKey& key) { - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::RefAtRasterImage", "key", key.ToString()); DCHECK(at_raster_decoded_images_.Peek(key) != @@ -702,7 +710,7 @@ void SoftwareImageDecodeController::RefAtRasterImage(const ImageKey& key) { } void SoftwareImageDecodeController::UnrefAtRasterImage(const ImageKey& key) { - TRACE_EVENT1("disabled-by-default-cc.debug", + TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "SoftwareImageDecodeController::UnrefAtRasterImage", "key", key.ToString()); base::AutoLock lock(lock_); @@ -777,9 +785,18 @@ bool SoftwareImageDecodeController::OnMemoryDump( base::trace_event::ProcessMemoryDump* pmd) { base::AutoLock lock(lock_); - // Dump each of our caches. - DumpImageMemoryForCache(decoded_images_, "cached", pmd); - DumpImageMemoryForCache(at_raster_decoded_images_, "at_raster", pmd); + if (args.level_of_detail == MemoryDumpLevelOfDetail::BACKGROUND) { + std::string dump_name = + base::StringPrintf("cc/image_memory/controller_0x%" PRIXPTR, + reinterpret_cast<uintptr_t>(this)); + MemoryAllocatorDump* dump = pmd->CreateAllocatorDump(dump_name); + dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, + locked_images_budget_.GetCurrentUsageSafe()); + } else { + // Dump each of our caches. + DumpImageMemoryForCache(decoded_images_, "cached", pmd); + DumpImageMemoryForCache(at_raster_decoded_images_, "at_raster", pmd); + } // Memory dump can't fail, always return true. return true; @@ -796,13 +813,14 @@ void SoftwareImageDecodeController::DumpImageMemoryForCache( "cc/image_memory/controller_0x%" PRIXPTR "/%s/image_%" PRIu64 "_id_%d", reinterpret_cast<uintptr_t>(this), cache_name, image_pair.second->tracing_id(), image_pair.first.image_id()); - base::trace_event::MemoryAllocatorDump* dump = + // CreateMemoryAllocatorDump will automatically add tracking values for the + // total size. If locked, we also add a "locked_size" below. + MemoryAllocatorDump* dump = image_pair.second->memory()->CreateMemoryAllocatorDump( dump_name.c_str(), pmd); DCHECK(dump); if (image_pair.second->is_locked()) { - dump->AddScalar("locked_size", - base::trace_event::MemoryAllocatorDump::kUnitsBytes, + dump->AddScalar("locked_size", MemoryAllocatorDump::kUnitsBytes, image_pair.first.locked_bytes()); } } diff --git a/chromium/cc/tiles/software_image_decode_controller.h b/chromium/cc/tiles/software_image_decode_controller.h index e1427c71e21..f801ffc21c9 100644 --- a/chromium/cc/tiles/software_image_decode_controller.h +++ b/chromium/cc/tiles/software_image_decode_controller.h @@ -198,10 +198,9 @@ class CC_EXPORT SoftwareImageDecodeController void SubtractUsage(size_t usage); void ResetUsage(); size_t total_limit_bytes() const { return limit_bytes_; } - - private: size_t GetCurrentUsageSafe() const; + private: size_t limit_bytes_; base::CheckedNumeric<size_t> current_usage_bytes_; }; diff --git a/chromium/cc/tiles/tile.cc b/chromium/cc/tiles/tile.cc index 84422658259..1ed26bb4c10 100644 --- a/chromium/cc/tiles/tile.cc +++ b/chromium/cc/tiles/tile.cc @@ -25,7 +25,7 @@ Tile::Tile(TileManager* tile_manager, : tile_manager_(tile_manager), content_rect_(info.content_rect), enclosing_layer_rect_(info.enclosing_layer_rect), - contents_scale_(info.contents_scale), + raster_scales_(info.raster_scales), layer_id_(layer_id), source_frame_number_(source_frame_number), flags_(flags), @@ -47,7 +47,13 @@ Tile::~Tile() { void Tile::AsValueInto(base::trace_event::TracedValue* value) const { TracedValue::MakeDictIntoImplicitSnapshotWithCategory( TRACE_DISABLED_BY_DEFAULT("cc.debug"), value, "cc::Tile", this); - value->SetDouble("contents_scale", contents_scale_); + // TODO(vmpstr): Update tracing to use x/y scales. + value->SetDouble("contents_scale", contents_scale_key()); + + value->BeginArray("raster_scales"); + value->AppendDouble(raster_scales_.width()); + value->AppendDouble(raster_scales_.height()); + value->EndArray(); MathUtil::AddToTracedValue("content_rect", content_rect_, value); diff --git a/chromium/cc/tiles/tile.h b/chromium/cc/tiles/tile.h index b504ea1160d..8da46d69657 100644 --- a/chromium/cc/tiles/tile.h +++ b/chromium/cc/tiles/tile.h @@ -17,9 +17,7 @@ namespace cc { -class PrioritizedTile; class TileManager; -struct TilePriority; class CC_EXPORT Tile { public: @@ -34,18 +32,18 @@ class CC_EXPORT Tile { int tiling_j_index; gfx::Rect enclosing_layer_rect; gfx::Rect content_rect; - float contents_scale; + gfx::SizeF raster_scales; CreateInfo(int tiling_i_index, int tiling_j_index, const gfx::Rect& enclosing_layer_rect, const gfx::Rect& content_rect, - float contents_scale) + const gfx::SizeF& raster_scales) : tiling_i_index(tiling_i_index), tiling_j_index(tiling_j_index), enclosing_layer_rect(enclosing_layer_rect), content_rect(content_rect), - contents_scale(contents_scale) {} + raster_scales(raster_scales) {} }; enum TileRasterFlags { USE_PICTURE_ANALYSIS = 1 << 0, IS_OPAQUE = 1 << 1 }; @@ -77,7 +75,8 @@ class CC_EXPORT Tile { const TileDrawInfo& draw_info() const { return draw_info_; } TileDrawInfo& draw_info() { return draw_info_; } - float contents_scale() const { return contents_scale_; } + float contents_scale_key() const { return raster_scales_.width(); } + const gfx::SizeF& raster_scales() const { return raster_scales_; } const gfx::Rect& content_rect() const { return content_rect_; } const gfx::Rect& enclosing_layer_rect() const { return enclosing_layer_rect_; @@ -130,7 +129,7 @@ class CC_EXPORT Tile { TileManager* const tile_manager_; const gfx::Rect content_rect_; const gfx::Rect enclosing_layer_rect_; - const float contents_scale_; + const gfx::SizeF raster_scales_; TileDrawInfo draw_info_; diff --git a/chromium/cc/tiles/tile_draw_info.h b/chromium/cc/tiles/tile_draw_info.h index 731e75fd331..a51d27b9916 100644 --- a/chromium/cc/tiles/tile_draw_info.h +++ b/chromium/cc/tiles/tile_draw_info.h @@ -54,7 +54,7 @@ class CC_EXPORT TileDrawInfo { return resource_->id(); } - gfx::Size resource_size() const { + const gfx::Size& resource_size() const { DCHECK(mode_ == RESOURCE_MODE); DCHECK(resource_); return resource_->size(); diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc index 56f6664c6df..4a13c410ea5 100644 --- a/chromium/cc/tiles/tile_manager.cc +++ b/chromium/cc/tiles/tile_manager.cc @@ -98,7 +98,7 @@ class RasterTaskImpl : public TileTask { raster_source_(std::move(raster_source)), content_rect_(tile->content_rect()), invalid_content_rect_(invalidated_rect), - contents_scale_(tile->contents_scale()), + raster_scales_(tile->raster_scales()), playback_settings_(playback_settings), tile_resolution_(tile_resolution), layer_id_(tile->layer_id()), @@ -128,7 +128,7 @@ class RasterTaskImpl : public TileTask { raster_buffer_->Playback(raster_source_.get(), content_rect_, invalid_content_rect_, new_content_id_, - contents_scale_, playback_settings_); + raster_scales_, playback_settings_); } // Overridden from TileTask: @@ -162,7 +162,7 @@ class RasterTaskImpl : public TileTask { scoped_refptr<RasterSource> raster_source_; gfx::Rect content_rect_; gfx::Rect invalid_content_rect_; - float contents_scale_; + gfx::SizeF raster_scales_; RasterSource::PlaybackSettings playback_settings_; TileResolution tile_resolution_; int layer_id_; @@ -404,18 +404,18 @@ void TileManager::FinishTasksAndCleanUp() { void TileManager::SetResources(ResourcePool* resource_pool, ImageDecodeController* image_decode_controller, - TileTaskManager* tile_task_manager, + TaskGraphRunner* task_graph_runner, RasterBufferProvider* raster_buffer_provider, size_t scheduled_raster_task_limit, bool use_gpu_rasterization) { DCHECK(!tile_task_manager_); - DCHECK(tile_task_manager); + DCHECK(task_graph_runner); use_gpu_rasterization_ = use_gpu_rasterization; scheduled_raster_task_limit_ = scheduled_raster_task_limit; resource_pool_ = resource_pool; image_manager_.SetImageDecodeController(image_decode_controller); - tile_task_manager_ = tile_task_manager; + tile_task_manager_ = TileTaskManagerImpl::Create(task_graph_runner); raster_buffer_provider_ = raster_buffer_provider; } @@ -474,11 +474,8 @@ void TileManager::DidFinishRunningAllTileTasks() { has_scheduled_tile_tasks_ = false; - bool memory_usage_above_limit = resource_pool_->memory_usage_bytes() > - global_state_.soft_memory_limit_in_bytes; - if (all_tiles_that_need_to_be_rasterized_are_scheduled_ && - !memory_usage_above_limit) { + !resource_pool_->ResourceUsageTooHigh()) { // TODO(ericrk): We should find a better way to safely handle re-entrant // notifications than always having to schedule a new task. // http://crbug.com/498439 @@ -684,7 +681,7 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() { SkColor color = SK_ColorTRANSPARENT; bool is_solid_color = prioritized_tile.raster_source()->PerformSolidColorAnalysis( - tile->content_rect(), tile->contents_scale(), &color); + tile->content_rect(), tile->raster_scales(), &color); if (is_solid_color) { tile->draw_info().set_solid_color(color); tile->draw_info().set_was_ever_ready_to_draw(); @@ -886,7 +883,7 @@ void TileManager::ScheduleTasks( std::vector<DrawImage> images; prioritized_tile.raster_source()->GetDiscardableImagesInRect( - tile->enclosing_layer_rect(), tile->contents_scale(), &images); + tile->enclosing_layer_rect(), tile->raster_scales(), &images); new_locked_images.insert(new_locked_images.end(), images.begin(), images.end()); } @@ -1000,7 +997,7 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask( images.clear(); if (!playback_settings.skip_images) { prioritized_tile.raster_source()->GetDiscardableImagesInRect( - tile->enclosing_layer_rect(), tile->contents_scale(), &images); + tile->enclosing_layer_rect(), tile->raster_scales(), &images); } // We can skip the image hijack canvas if we have no images. @@ -1074,16 +1071,6 @@ ScopedTilePtr TileManager::CreateTile(const Tile::CreateInfo& info, return tile; } -void TileManager::SetTileTaskManagerForTesting( - TileTaskManager* tile_task_manager) { - tile_task_manager_ = tile_task_manager; -} - -void TileManager::SetRasterBufferProviderForTesting( - RasterBufferProvider* raster_buffer_provider) { - raster_buffer_provider_ = raster_buffer_provider; -} - bool TileManager::AreRequiredTilesReadyToDraw( RasterTilePriorityQueue::Type type) const { std::unique_ptr<RasterTilePriorityQueue> raster_priority_queue( @@ -1131,7 +1118,7 @@ void TileManager::CheckAndIssueSignals() { if (signals_.ready_to_activate && !signals_.did_notify_ready_to_activate) { signals_.ready_to_activate = false; if (IsReadyToActivate()) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "TileManager::CheckAndIssueSignals - ready to activate"); signals_.did_notify_ready_to_activate = true; client_->NotifyReadyToActivate(); @@ -1142,7 +1129,7 @@ void TileManager::CheckAndIssueSignals() { if (signals_.ready_to_draw && !signals_.did_notify_ready_to_draw) { signals_.ready_to_draw = false; if (IsReadyToDraw()) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "TileManager::CheckAndIssueSignals - ready to draw"); signals_.did_notify_ready_to_draw = true; client_->NotifyReadyToDraw(); @@ -1155,7 +1142,7 @@ void TileManager::CheckAndIssueSignals() { signals_.all_tile_tasks_completed = false; if (!has_scheduled_tile_tasks_) { TRACE_EVENT0( - "disabled-by-default-cc.debug", + TRACE_DISABLED_BY_DEFAULT("cc.debug"), "TileManager::CheckAndIssueSignals - all tile tasks completed"); signals_.did_notify_all_tile_tasks_completed = true; client_->NotifyAllTileTasksCompleted(); @@ -1222,30 +1209,28 @@ void TileManager::CheckIfMoreTilesNeedToBePrepared() { // even when OOM. Note that we can't reuse the queue we used for // AssignGpuMemoryToTiles, since the AssignGpuMemoryToTiles call could have // evicted some tiles that would not be picked up by the old raster queue. - bool need_to_signal_activate = MarkTilesOutOfMemory(client_->BuildRasterQueue( + MarkTilesOutOfMemory(client_->BuildRasterQueue( global_state_.tree_priority, RasterTilePriorityQueue::Type::REQUIRED_FOR_ACTIVATION)); - bool need_to_signal_draw = MarkTilesOutOfMemory(client_->BuildRasterQueue( + MarkTilesOutOfMemory(client_->BuildRasterQueue( global_state_.tree_priority, RasterTilePriorityQueue::Type::REQUIRED_FOR_DRAW)); // TODO(vmpstr): Temporary check to debug crbug.com/642927. CHECK(tile_task_manager_); + DCHECK(IsReadyToActivate()); DCHECK(IsReadyToDraw()); - signals_.ready_to_activate = need_to_signal_activate; - signals_.ready_to_draw = need_to_signal_draw; + signals_.ready_to_activate = true; + signals_.ready_to_draw = true; // TODO(ericrk): Investigate why we need to schedule this (not just call it // inline). http://crbug.com/498439 signals_check_notifier_.Schedule(); } -bool TileManager::MarkTilesOutOfMemory( +void TileManager::MarkTilesOutOfMemory( std::unique_ptr<RasterTilePriorityQueue> queue) const { // Mark required tiles as OOM so that we can activate/draw without them. - if (queue->IsEmpty()) - return false; - for (; !queue->IsEmpty(); queue->Pop()) { Tile* tile = queue->Top().tile(); if (tile->draw_info().IsReadyToDraw()) @@ -1253,7 +1238,6 @@ bool TileManager::MarkTilesOutOfMemory( tile->draw_info().set_oom(); client_->NotifyTileStateChanged(tile); } - return true; } ResourceFormat TileManager::DetermineResourceFormat(const Tile* tile) const { diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h index c043f6248cf..ac82118752d 100644 --- a/chromium/cc/tiles/tile_manager.h +++ b/chromium/cc/tiles/tile_manager.h @@ -36,8 +36,6 @@ class TracedValue; } namespace cc { -class PictureLayerImpl; -class ResourceProvider; class ImageDecodeController; class CC_EXPORT TileManagerClient { @@ -122,7 +120,7 @@ class CC_EXPORT TileManager { // SetResources. void SetResources(ResourcePool* resource_pool, ImageDecodeController* image_decode_controller, - TileTaskManager* tile_task_manager, + TaskGraphRunner* task_graph_runner, RasterBufferProvider* raster_buffer_provider, size_t scheduled_raster_task_limit, bool use_gpu_rasterization); @@ -169,10 +167,15 @@ class CC_EXPORT TileManager { global_state_ = state; } - void SetTileTaskManagerForTesting(TileTaskManager* tile_task_manager); + void SetTileTaskManagerForTesting( + std::unique_ptr<TileTaskManager> tile_task_manager) { + tile_task_manager_ = std::move(tile_task_manager); + } void SetRasterBufferProviderForTesting( - RasterBufferProvider* raster_buffer_provider); + RasterBufferProvider* raster_buffer_provider) { + raster_buffer_provider_ = raster_buffer_provider; + } void FreeResourcesAndCleanUpReleasedTilesForTesting() { FreeResourcesForReleasedTiles(); @@ -198,6 +201,8 @@ class CC_EXPORT TileManager { all_tiles_that_need_to_be_rasterized_are_scheduled_ = false; } + void ResetSignalsForTesting() { signals_.reset(); } + bool HasScheduledTileTasksForTesting() const { return has_scheduled_tile_tasks_; } @@ -280,7 +285,7 @@ class CC_EXPORT TileManager { bool AreRequiredTilesReadyToDraw(RasterTilePriorityQueue::Type type) const; void CheckIfMoreTilesNeedToBePrepared(); void CheckAndIssueSignals(); - bool MarkTilesOutOfMemory( + void MarkTilesOutOfMemory( std::unique_ptr<RasterTilePriorityQueue> queue) const; ResourceFormat DetermineResourceFormat(const Tile* tile) const; @@ -303,7 +308,7 @@ class CC_EXPORT TileManager { TileManagerClient* client_; base::SequencedTaskRunner* task_runner_; ResourcePool* resource_pool_; - TileTaskManager* tile_task_manager_; + std::unique_ptr<TileTaskManager> tile_task_manager_; RasterBufferProvider* raster_buffer_provider_; GlobalStateThatImpactsTilePriority global_state_; size_t scheduled_raster_task_limit_; diff --git a/chromium/cc/tiles/tile_manager_perftest.cc b/chromium/cc/tiles/tile_manager_perftest.cc index 3ee0914747a..d2724a7e834 100644 --- a/chromium/cc/tiles/tile_manager_perftest.cc +++ b/chromium/cc/tiles/tile_manager_perftest.cc @@ -22,7 +22,6 @@ #include "cc/test/fake_tile_manager_client.h" #include "cc/test/fake_tile_task_manager.h" #include "cc/test/test_layer_tree_host_base.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_tile_priorities.h" #include "cc/tiles/tile.h" @@ -39,9 +38,6 @@ static const int kTimeLimitMillis = 2000; static const int kWarmupRuns = 5; static const int kTimeCheckInterval = 10; -base::LazyInstance<FakeTileTaskManagerImpl> g_fake_tile_task_manager = - LAZY_INSTANCE_INITIALIZER; - class TileManagerPerfTest : public TestLayerTreeHostBase { public: TileManagerPerfTest() @@ -53,7 +49,7 @@ class TileManagerPerfTest : public TestLayerTreeHostBase { host_impl()->SetVisible(true); host_impl()->InitializeRenderer(compositor_frame_sink()); tile_manager()->SetTileTaskManagerForTesting( - g_fake_tile_task_manager.Pointer()); + base::MakeUnique<FakeTileTaskManagerImpl>()); } void SetupDefaultTreesWithFixedTileSize(const gfx::Size& layer_bounds, diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc index 8e34eb57dc6..fb92d3f75be 100644 --- a/chromium/cc/tiles/tile_manager_unittest.cc +++ b/chromium/cc/tiles/tile_manager_unittest.cc @@ -25,9 +25,7 @@ #include "cc/test/fake_tile_manager.h" #include "cc/test/fake_tile_task_manager.h" #include "cc/test/layer_tree_settings_for_testing.h" -#include "cc/test/test_gpu_memory_buffer_manager.h" #include "cc/test/test_layer_tree_host_base.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_tile_priorities.h" #include "cc/tiles/eviction_tile_priority_queue.h" @@ -332,7 +330,7 @@ TEST_F(TileManagerTilePriorityQueueTest, std::set<Tile*> all_expected_tiles; for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); - if (tiling->contents_scale() == 1.f) { + if (tiling->contents_scale_key() == 1.f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); all_expected_tiles.insert(all_tiles.begin(), all_tiles.end()); @@ -343,7 +341,7 @@ TEST_F(TileManagerTilePriorityQueueTest, for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); - if (tiling->contents_scale() == 1.5f) { + if (tiling->contents_scale_key() == 1.5f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); all_expected_tiles.insert(all_tiles.begin(), all_tiles.end()); @@ -351,7 +349,7 @@ TEST_F(TileManagerTilePriorityQueueTest, tiling->set_resolution(NON_IDEAL_RESOLUTION); // Non ideal tilings with a high res pending twin have to be processed // because of possible activation tiles. - if (tiling->contents_scale() == 1.f) { + if (tiling->contents_scale_key() == 1.f) { tiling->UpdateAndGetAllPrioritizedTilesForTesting(); const auto& all_tiles = tiling->AllTilesForTesting(); for (auto* tile : all_tiles) @@ -399,7 +397,7 @@ TEST_F(TileManagerTilePriorityQueueTest, std::set<Tile*> all_expected_tiles; for (size_t i = 0; i < pending_layer()->num_tilings(); ++i) { PictureLayerTiling* tiling = pending_layer()->tilings()->tiling_at(i); - if (tiling->contents_scale() == 1.f) { + if (tiling->contents_scale_key() == 1.f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); all_expected_tiles.insert(all_tiles.begin(), all_tiles.end()); @@ -410,7 +408,7 @@ TEST_F(TileManagerTilePriorityQueueTest, for (size_t i = 0; i < active_layer()->num_tilings(); ++i) { PictureLayerTiling* tiling = active_layer()->tilings()->tiling_at(i); - if (tiling->contents_scale() == 1.5f) { + if (tiling->contents_scale_key() == 1.5f) { tiling->set_resolution(HIGH_RESOLUTION); const auto& all_tiles = tiling->AllTilesForTesting(); all_expected_tiles.insert(all_tiles.begin(), all_tiles.end()); @@ -418,7 +416,7 @@ TEST_F(TileManagerTilePriorityQueueTest, tiling->set_resolution(LOW_RESOLUTION); // Low res tilings with a high res pending twin have to be processed // because of possible activation tiles. - if (tiling->contents_scale() == 1.f) { + if (tiling->contents_scale_key() == 1.f) { tiling->UpdateAndGetAllPrioritizedTilesForTesting(); const auto& all_tiles = tiling->AllTilesForTesting(); for (auto* tile : all_tiles) @@ -876,8 +874,8 @@ TEST_F(TileManagerTilePriorityQueueTest, EXPECT_TRUE((tile_priority_bin < last_tile_priority_bin) || prioritized_tile.tile()->required_for_activation() || - (prioritized_tile.tile()->contents_scale() != - last_tile.tile()->contents_scale())); + (prioritized_tile.tile()->contents_scale_key() != + last_tile.tile()->contents_scale_key())); } } last_tile = prioritized_tile; @@ -1090,7 +1088,6 @@ TEST_F(TileManagerTilePriorityQueueTest, client.SetTileSize(gfx::Size(30, 30)); LayerTreeSettings settings; settings.verify_clip_tree_calculations = true; - settings.verify_transform_tree_calculations = true; std::unique_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( @@ -1203,7 +1200,6 @@ TEST_F(TileManagerTilePriorityQueueTest, client.SetTileSize(gfx::Size(30, 30)); LayerTreeSettings settings; settings.verify_clip_tree_calculations = true; - settings.verify_transform_tree_calculations = true; std::unique_ptr<PictureLayerTilingSet> tiling_set = PictureLayerTilingSet::Create( @@ -1477,31 +1473,24 @@ class TileManagerTest : public TestLayerTreeHostBase { // MockLayerTreeHostImpl allows us to intercept tile manager callbacks. class MockLayerTreeHostImpl : public FakeLayerTreeHostImpl { public: - MockLayerTreeHostImpl( - const LayerTreeSettings& settings, - TaskRunnerProvider* task_runner_provider, - SharedBitmapManager* manager, - TaskGraphRunner* task_graph_runner, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) + MockLayerTreeHostImpl(const LayerTreeSettings& settings, + TaskRunnerProvider* task_runner_provider, + TaskGraphRunner* task_graph_runner) : FakeLayerTreeHostImpl(settings, task_runner_provider, - manager, - task_graph_runner, - gpu_memory_buffer_manager) {} + task_graph_runner) {} - MOCK_METHOD0(NotifyAllTileTasksCompleted, void()); + MOCK_METHOD0(NotifyReadyToActivate, void()); MOCK_METHOD0(NotifyReadyToDraw, void()); + MOCK_METHOD0(NotifyAllTileTasksCompleted, void()); }; std::unique_ptr<FakeLayerTreeHostImpl> CreateHostImpl( const LayerTreeSettings& settings, TaskRunnerProvider* task_runner_provider, - SharedBitmapManager* shared_bitmap_manager, - TaskGraphRunner* task_graph_runner, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager) override { + TaskGraphRunner* task_graph_runner) override { return base::MakeUnique<MockLayerTreeHostImpl>( - settings, task_runner_provider, shared_bitmap_manager, - task_graph_runner, gpu_memory_buffer_manager); + settings, task_runner_provider, task_graph_runner); } // By default use software compositing (no context provider). @@ -1516,12 +1505,14 @@ class TileManagerTest : public TestLayerTreeHostBase { // Test to ensure that we call NotifyAllTileTasksCompleted when PrepareTiles is // called. -TEST_F(TileManagerTest, AllWorkFinishedTest) { +TEST_F(TileManagerTest, AllWorkFinished) { // Check with no tile work enqueued. { base::RunLoop run_loop; EXPECT_FALSE( host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()); EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); @@ -1535,6 +1526,8 @@ TEST_F(TileManagerTest, AllWorkFinishedTest) { base::RunLoop run_loop; EXPECT_FALSE( host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()); EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); host_impl()->tile_manager()->PrepareTiles(host_impl()->global_tile_state()); @@ -1542,6 +1535,22 @@ TEST_F(TileManagerTest, AllWorkFinishedTest) { EXPECT_TRUE(host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); run_loop.Run(); } + + // Check that if callbacks are called by CheckIfMoreTilesNeedToBePrepared if + // they haven't been called already. + { + base::RunLoop run_loop; + EXPECT_FALSE( + host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()); + EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) + .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); + host_impl()->tile_manager()->ResetSignalsForTesting(); + host_impl()->tile_manager()->SetMoreTilesNeedToBeRasterizedForTesting(); + host_impl()->tile_manager()->CheckIfMoreTilesNeedToBePreparedForTesting(); + run_loop.Run(); + } } TEST_F(TileManagerTest, ActivateAndDrawWhenOOM) { @@ -1555,6 +1564,8 @@ TEST_F(TileManagerTest, ActivateAndDrawWhenOOM) { base::RunLoop run_loop; EXPECT_FALSE( host_impl()->tile_manager()->HasScheduledTileTasksForTesting()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()); EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); host_impl()->tile_manager()->PrepareTiles(global_state); @@ -1571,6 +1582,8 @@ TEST_F(TileManagerTest, ActivateAndDrawWhenOOM) { { base::RunLoop run_loop; host_impl()->set_notify_tile_state_changed_called(false); + EXPECT_CALL(MockHostImpl(), NotifyReadyToActivate()); + EXPECT_CALL(MockHostImpl(), NotifyReadyToDraw()); EXPECT_CALL(MockHostImpl(), NotifyAllTileTasksCompleted()) .WillOnce(testing::Invoke([&run_loop]() { run_loop.Quit(); })); host_impl()->tile_manager()->PrepareTiles(global_state); @@ -1744,8 +1757,8 @@ TEST_F(PartialRasterTileManagerTest, CancelledTasksHaveNoContentId) { // Create a FakeTileTaskManagerImpl and set it on the tile manager so that all // scheduled work is immediately cancelled. - FakeTileTaskManagerImpl tile_task_manager; - host_impl()->tile_manager()->SetTileTaskManagerForTesting(&tile_task_manager); + host_impl()->tile_manager()->SetTileTaskManagerForTesting( + base::MakeUnique<FakeTileTaskManagerImpl>()); // Pick arbitrary IDs - they don't really matter as long as they're constant. const int kLayerId = 7; @@ -1833,8 +1846,8 @@ void RunPartialRasterCheck(std::unique_ptr<LayerTreeHostImpl> host_impl, // Create a VerifyResourceContentIdTileTaskManager to ensure that the // raster task we see is created with |kExpectedId|. - FakeTileTaskManagerImpl tile_task_manager; - host_impl->tile_manager()->SetTileTaskManagerForTesting(&tile_task_manager); + host_impl->tile_manager()->SetTileTaskManagerForTesting( + base::MakeUnique<FakeTileTaskManagerImpl>()); VerifyResourceContentIdRasterBufferProvider raster_buffer_provider( kExpectedId); diff --git a/chromium/cc/tiles/tile_task_manager.cc b/chromium/cc/tiles/tile_task_manager.cc index b57b0572d1a..06ba66c7bc2 100644 --- a/chromium/cc/tiles/tile_task_manager.cc +++ b/chromium/cc/tiles/tile_task_manager.cc @@ -22,7 +22,7 @@ std::unique_ptr<TileTaskManagerImpl> TileTaskManagerImpl::Create( TileTaskManagerImpl::TileTaskManagerImpl(TaskGraphRunner* task_graph_runner) : task_graph_runner_(task_graph_runner), - namespace_token_(task_graph_runner->GetNamespaceToken()) {} + namespace_token_(task_graph_runner->GenerateNamespaceToken()) {} TileTaskManagerImpl::~TileTaskManagerImpl() {} diff --git a/chromium/cc/trees/channel_impl.h b/chromium/cc/trees/channel_impl.h index aec9b4a6d61..6fdd4df9a11 100644 --- a/chromium/cc/trees/channel_impl.h +++ b/chromium/cc/trees/channel_impl.h @@ -10,7 +10,7 @@ namespace cc { -class AnimationEvents; +class MutatorEvents; // Channel used to send commands to and receive commands from ProxyMain. // The ChannelImpl implementation creates and owns ProxyImpl on receiving the @@ -19,10 +19,10 @@ class AnimationEvents; class CC_EXPORT ChannelImpl { public: // Interface for commands sent to ProxyMain - virtual void DidCompleteSwapBuffers() = 0; + virtual void DidReceiveCompositorFrameAck() = 0; virtual void BeginMainFrameNotExpectedSoon() = 0; virtual void DidCommitAndDrawFrame() = 0; - virtual void SetAnimationEvents(std::unique_ptr<AnimationEvents> queue) = 0; + virtual void SetAnimationEvents(std::unique_ptr<MutatorEvents> queue) = 0; virtual void DidLoseCompositorFrameSink() = 0; virtual void RequestNewCompositorFrameSink() = 0; virtual void DidInitializeCompositorFrameSink(bool success) = 0; diff --git a/chromium/cc/trees/channel_main.h b/chromium/cc/trees/channel_main.h index 538d4c8678d..3359d9c2c64 100644 --- a/chromium/cc/trees/channel_main.h +++ b/chromium/cc/trees/channel_main.h @@ -7,7 +7,7 @@ #include "cc/base/cc_export.h" #include "cc/base/completion_event.h" -#include "cc/input/top_controls_state.h" +#include "cc/input/browser_controls_state.h" #include "cc/output/compositor_frame_sink.h" #include "cc/scheduler/begin_frame_source.h" #include "cc/scheduler/commit_earlyout_reason.h" @@ -32,9 +32,10 @@ class CC_EXPORT ChannelMain { virtual ~ChannelMain() {} // Interface for commands sent to ProxyImpl - virtual void UpdateTopControlsStateOnImpl(TopControlsState constraints, - TopControlsState current, - bool animate) = 0; + virtual void UpdateBrowserControlsStateOnImpl( + BrowserControlsState constraints, + BrowserControlsState current, + bool animate) = 0; virtual void InitializeCompositorFrameSinkOnImpl( CompositorFrameSink* compositor_frame_sink) = 0; virtual void InitializeMutatorOnImpl( diff --git a/chromium/cc/trees/clip_node.cc b/chromium/cc/trees/clip_node.cc index b7d8164381c..04011596835 100644 --- a/chromium/cc/trees/clip_node.cc +++ b/chromium/cc/trees/clip_node.cc @@ -4,8 +4,8 @@ #include "base/trace_event/trace_event_argument.h" #include "cc/base/math_util.h" +#include "cc/proto/cc_conversions.h" #include "cc/proto/gfx_conversions.h" -#include "cc/proto/property_tree.pb.h" #include "cc/trees/clip_node.h" namespace cc { @@ -14,10 +14,10 @@ ClipNode::ClipNode() : id(-1), parent_id(-1), owner_id(-1), + clip_type(ClipType::NONE), transform_id(-1), target_transform_id(-1), target_effect_id(-1), - applies_local_clip(true), layer_clipping_uses_only_local_clip(false), target_is_clipped(false), layers_are_clipped(false), @@ -28,13 +28,13 @@ ClipNode::ClipNode(const ClipNode& other) = default; bool ClipNode::operator==(const ClipNode& other) const { return id == other.id && parent_id == other.parent_id && - owner_id == other.owner_id && clip == other.clip && + owner_id == other.owner_id && clip_type == other.clip_type && + clip == other.clip && combined_clip_in_target_space == other.combined_clip_in_target_space && clip_in_target_space == other.clip_in_target_space && transform_id == other.transform_id && target_transform_id == other.target_transform_id && target_effect_id == other.target_effect_id && - applies_local_clip == other.applies_local_clip && layer_clipping_uses_only_local_clip == other.layer_clipping_uses_only_local_clip && target_is_clipped == other.target_is_clipped && @@ -44,67 +44,15 @@ bool ClipNode::operator==(const ClipNode& other) const { resets_clip == other.resets_clip; } -void ClipNode::ToProtobuf(proto::TreeNode* proto) const { - proto->set_id(id); - proto->set_parent_id(parent_id); - proto->set_owner_id(owner_id); - - DCHECK(!proto->has_clip_node_data()); - proto::ClipNodeData* data = proto->mutable_clip_node_data(); - - RectFToProto(clip, data->mutable_clip()); - RectFToProto(combined_clip_in_target_space, - data->mutable_combined_clip_in_target_space()); - RectFToProto(clip_in_target_space, data->mutable_clip_in_target_space()); - - data->set_transform_id(transform_id); - data->set_target_transform_id(target_transform_id); - data->set_target_effect_id(target_effect_id); - data->set_applies_local_clip(applies_local_clip); - data->set_layer_clipping_uses_only_local_clip( - layer_clipping_uses_only_local_clip); - data->set_target_is_clipped(target_is_clipped); - data->set_layers_are_clipped(layers_are_clipped); - data->set_layers_are_clipped_when_surfaces_disabled( - layers_are_clipped_when_surfaces_disabled); - data->set_resets_clip(resets_clip); -} - -void ClipNode::FromProtobuf(const proto::TreeNode& proto) { - id = proto.id(); - parent_id = proto.parent_id(); - owner_id = proto.owner_id(); - - DCHECK(proto.has_clip_node_data()); - const proto::ClipNodeData& data = proto.clip_node_data(); - - clip = ProtoToRectF(data.clip()); - combined_clip_in_target_space = - ProtoToRectF(data.combined_clip_in_target_space()); - clip_in_target_space = ProtoToRectF(data.clip_in_target_space()); - - transform_id = data.transform_id(); - target_transform_id = data.target_transform_id(); - target_effect_id = data.target_effect_id(); - applies_local_clip = data.applies_local_clip(); - layer_clipping_uses_only_local_clip = - data.layer_clipping_uses_only_local_clip(); - target_is_clipped = data.target_is_clipped(); - layers_are_clipped = data.layers_are_clipped(); - layers_are_clipped_when_surfaces_disabled = - data.layers_are_clipped_when_surfaces_disabled(); - resets_clip = data.resets_clip(); -} - void ClipNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); value->SetInteger("owner_id", owner_id); + value->SetInteger("clip_type", static_cast<int>(clip_type)); MathUtil::AddToTracedValue("clip", clip, value); value->SetInteger("transform_id", transform_id); value->SetInteger("target_transform_id", target_transform_id); value->SetInteger("target_effect_id", target_effect_id); - value->SetBoolean("applies_local_clip", applies_local_clip); value->SetBoolean("layer_clipping_uses_only_local_clip", layer_clipping_uses_only_local_clip); value->SetBoolean("target_is_clipped", target_is_clipped); diff --git a/chromium/cc/trees/clip_node.h b/chromium/cc/trees/clip_node.h index e9dfede8342..5ce9f9b645a 100644 --- a/chromium/cc/trees/clip_node.h +++ b/chromium/cc/trees/clip_node.h @@ -16,10 +16,6 @@ class TracedValue; namespace cc { -namespace proto { -class TreeNode; -} // namespace proto - struct CC_EXPORT ClipNode { ClipNode(); ClipNode(const ClipNode& other); @@ -28,11 +24,22 @@ struct CC_EXPORT ClipNode { int parent_id; int owner_id; + enum class ClipType { + // The node doesn't contribute a new clip. It exists only for caching clips + // or for resetting clipping state. + NONE, + + // The node contributes a new clip (that is, |clip| needs to be applied). + APPLIES_LOCAL_CLIP + }; + + ClipType clip_type; + // The clip rect that this node contributes, expressed in the space of its // transform node. gfx::RectF clip; - // Clip nodes are uses for two reasons. First, they are used for determining + // Clip nodes are used for two reasons. First, they are used for determining // which parts of each layer are visible. Second, they are used for // determining whether a clip needs to be applied when drawing a layer, and if // so, the rect that needs to be used. These can be different since not all @@ -54,10 +61,6 @@ struct CC_EXPORT ClipNode { // The id of the effect node that defines the clip node's target space. int target_effect_id; - // Whether this node contributes a new clip (that is, whether |clip| needs to - // be applied), rather than only inheriting ancestor clips. - bool applies_local_clip : 1; - // When true, |clip_in_target_space| does not include clips from ancestor // nodes. bool layer_clipping_uses_only_local_clip : 1; @@ -75,8 +78,6 @@ struct CC_EXPORT ClipNode { bool operator==(const ClipNode& other) const; - void ToProtobuf(proto::TreeNode* proto) const; - void FromProtobuf(const proto::TreeNode& proto); void AsValueInto(base::trace_event::TracedValue* value) const; }; diff --git a/chromium/cc/trees/damage_tracker.h b/chromium/cc/trees/damage_tracker.h index 4111d65dae0..ea5f3167f30 100644 --- a/chromium/cc/trees/damage_tracker.h +++ b/chromium/cc/trees/damage_tracker.h @@ -13,8 +13,6 @@ #include "cc/layers/layer_collections.h" #include "ui/gfx/geometry/rect.h" -class SkImageFilter; - namespace gfx { class Rect; } diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc index 4975bfdccdd..c0429871e7f 100644 --- a/chromium/cc/trees/damage_tracker_unittest.cc +++ b/chromium/cc/trees/damage_tracker_unittest.cc @@ -13,7 +13,6 @@ #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_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_impl.h" @@ -86,9 +85,7 @@ void EmulateDrawingOneFrame( class DamageTrackerTest : public testing::Test { public: DamageTrackerTest() - : host_impl_(&task_runner_provider_, - &shared_bitmap_manager_, - &task_graph_runner_) {} + : host_impl_(&task_runner_provider_, &task_graph_runner_) {} LayerImpl* CreateTestTreeWithOneSurface() { host_impl_.active_tree()->DetachLayers(); @@ -186,7 +183,6 @@ class DamageTrackerTest : public testing::Test { protected: FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; }; diff --git a/chromium/cc/trees/draw_property_utils.cc b/chromium/cc/trees/draw_property_utils.cc index 27baf419d83..38b391c96a4 100644 --- a/chromium/cc/trees/draw_property_utils.cc +++ b/chromium/cc/trees/draw_property_utils.cc @@ -53,26 +53,6 @@ static void ValidateRenderSurfaceForLayer(LayerImpl* layer) { DCHECK(effect_node->filters.IsEmpty()); DCHECK(effect_node->background_filters.IsEmpty()); } - -void VerifySurfaceContentsScalesMatch(const int target_effect_id, - const int target_transform_id, - const EffectTree& effect_tree, - const TransformTree& transform_tree) { - if (target_effect_id == EffectTree::kInvalidNodeId) { - // This can happen when PaintArtifactCompositor builds property trees as it - // doesn't set effect ids on clip nodes. - return; - } - const TransformNode* target_transform_node = - transform_tree.Node(target_transform_id); - const EffectNode* target_effect_node = effect_tree.Node(target_effect_id); - DCHECK(target_transform_node->surface_contents_scale == - target_effect_node->surface_contents_scale) - << " surface contents scale from transform tree: " - << target_transform_node->surface_contents_scale.ToString() - << " surface contents scale from effect tree: " - << target_effect_node->surface_contents_scale.ToString(); -} #endif static const EffectNode* ContentsTargetEffectNode( @@ -106,25 +86,11 @@ bool ComputeClipRectInTargetSpace(const LayerImpl* layer, // In this case, layer has a scroll parent. We need to keep the scale // at the layer's target but remove the scale at the scroll parent's // target. - if (property_trees->ComputeTransformToTarget(clip_node->target_transform_id, - target_effect_node->id, - &clip_to_target)) { - PostConcatSurfaceContentsScale(target_effect_node, &clip_to_target); -#if DCHECK_IS_ON() - const TransformTree& transform_tree = property_trees->transform_tree; - VerifySurfaceContentsScalesMatch(layer->effect_tree_index(), - target_node_id, effect_tree, - transform_tree); -#endif - + if (property_trees->GetToTarget(clip_node->target_transform_id, + target_effect_node->id, &clip_to_target)) { const EffectNode* source_node = effect_tree.Node(clip_node->target_effect_id); ConcatInverseSurfaceContentsScale(source_node, &clip_to_target); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(clip_node->target_effect_id, - clip_node->target_transform_id, - effect_tree, transform_tree); -#endif *clip_rect_in_target_space = MathUtil::MapClippedRect(clip_to_target, clip_from_clip_node); } else { @@ -178,19 +144,11 @@ static ConditionalClip ComputeLocalRectInTargetSpace( int target_transform_id, int target_effect_id) { gfx::Transform current_to_target; - if (!property_trees->ComputeTransformToTarget( - current_transform_id, target_effect_id, ¤t_to_target)) { + if (!property_trees->GetToTarget(current_transform_id, target_effect_id, + ¤t_to_target)) { // If transform is not invertible, cannot apply clip. return ConditionalClip{false, gfx::RectF()}; } - const EffectTree& effect_tree = property_trees->effect_tree; - const EffectNode* target_effect_node = effect_tree.Node(target_effect_id); - PostConcatSurfaceContentsScale(target_effect_node, ¤t_to_target); -#if DCHECK_IS_ON() - const TransformTree& transform_tree = property_trees->transform_tree; - VerifySurfaceContentsScalesMatch(target_effect_id, target_transform_id, - effect_tree, transform_tree); -#endif if (current_transform_id > target_transform_id) return ConditionalClip{true, // is_clipped. @@ -213,7 +171,7 @@ static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, gfx::RectF current_clip = clip_node->clip; gfx::Vector2dF surface_contents_scale = effect_tree.Node(target_effect_id)->surface_contents_scale; - // The viewport clip should not be scaled + // The viewport clip should not be scaled. if (surface_contents_scale.x() > 0 && surface_contents_scale.y() > 0 && clip_node->transform_id != TransformTree::kRootNodeId) current_clip.Scale(surface_contents_scale.x(), surface_contents_scale.y()); @@ -222,8 +180,11 @@ static ConditionalClip ComputeCurrentClip(const ClipNode* clip_node, static ConditionalClip ComputeAccumulatedClip( const PropertyTrees* property_trees, + bool include_viewport_clip, int local_clip_id, int target_id) { + DCHECK(!include_viewport_clip || + target_id == EffectTree::kContentsRootNodeId); const ClipTree& clip_tree = property_trees->clip_tree; const EffectTree& effect_tree = property_trees->effect_tree; @@ -237,36 +198,37 @@ static ConditionalClip ComputeAccumulatedClip( // If target is not direct ancestor of clip, this will find least common // ancestor between the target and the clip. - while (target_node->id != EffectTree::kInvalidNodeId && - clip_node->id != ClipTree::kInvalidNodeId) { - while (target_node->clip_id > clip_node->id || - target_node->has_unclipped_descendants) { - target_node = effect_tree.Node(target_node->target_id); - } - if (target_node->clip_id == clip_node->id) - break; - while (target_node->clip_id < clip_node->id) { - parent_chain.push(clip_node); - clip_node = clip_tree.parent(clip_node); - } - if (target_node->clip_id == clip_node->id) { - // Target is responsible for applying this clip_node (id equals to - // target_node's clip id), no need to accumulate this as part of clip - // rect. - clip_node = parent_chain.top(); - parent_chain.pop(); - break; - } + while (target_node->clip_id > clip_node->id || + target_node->has_unclipped_descendants) { + target_node = effect_tree.Node(target_node->target_id); + } + + // Collect clip nodes up to the least common ancestor. + while (target_node->clip_id < clip_node->id) { + parent_chain.push(clip_node); + clip_node = clip_tree.parent(clip_node); + } + DCHECK_EQ(target_node->clip_id, clip_node->id); + + if (!include_viewport_clip && parent_chain.size() == 0) { + // There aren't any clips to apply. + return ConditionalClip{false, gfx::RectF()}; + } + + if (!include_viewport_clip) { + clip_node = parent_chain.top(); + parent_chain.pop(); } // TODO(weiliangc): If we don't create clip for render surface, we don't need // to check applies_local_clip. - while (!clip_node->applies_local_clip && parent_chain.size() > 0) { + while (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP && + parent_chain.size() > 0) { clip_node = parent_chain.top(); parent_chain.pop(); } - if (!clip_node->applies_local_clip) + if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) // No clip node applying clip in between. return ConditionalClip{false, gfx::RectF()}; @@ -278,7 +240,7 @@ static ConditionalClip ComputeAccumulatedClip( while (parent_chain.size() > 0) { clip_node = parent_chain.top(); parent_chain.pop(); - if (!clip_node->applies_local_clip) { + if (clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP) { continue; } ConditionalClip current_clip = ComputeCurrentClip( @@ -301,73 +263,63 @@ static gfx::RectF ComputeAccumulatedClipInRootSpaceForVisibleRect( const PropertyTrees* property_trees, int local_clip_id) { const int root_effect_id = EffectTree::kContentsRootNodeId; - ConditionalClip accumulated_clip = - ComputeAccumulatedClip(property_trees, local_clip_id, root_effect_id); - - gfx::RectF accumulated_clip_rect = accumulated_clip.clip_rect; - const ClipNode* root_effect_node = - property_trees->clip_tree.Node(root_effect_id); - if (accumulated_clip.is_clipped) { - accumulated_clip_rect.Intersect(root_effect_node->clip_in_target_space); - } else { - // In this case, we need only the viewport clip as the accumulated clip is - // unclipped. - accumulated_clip_rect = root_effect_node->clip_in_target_space; - } - return accumulated_clip_rect; + bool include_viewport_clip = true; + ConditionalClip accumulated_clip = ComputeAccumulatedClip( + property_trees, include_viewport_clip, local_clip_id, root_effect_id); + DCHECK(accumulated_clip.is_clipped); + return accumulated_clip.clip_rect; } -template <typename LayerType> -void CalculateClipRects( - const typename LayerType::LayerListType& visible_layer_list, - const PropertyTrees* property_trees, - bool non_root_surfaces_enabled) { +void CalculateClipRects(const std::vector<LayerImpl*>& visible_layer_list, + const PropertyTrees* property_trees, + bool non_root_surfaces_enabled) { const ClipTree& clip_tree = property_trees->clip_tree; for (auto& layer : visible_layer_list) { const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); + bool layer_needs_clip_rect = + non_root_surfaces_enabled + ? clip_node->layers_are_clipped + : clip_node->layers_are_clipped_when_surfaces_disabled; + if (!layer_needs_clip_rect) { + layer->set_clip_rect(gfx::Rect()); + continue; + } if (!non_root_surfaces_enabled) { layer->set_clip_rect( gfx::ToEnclosingRect(clip_node->clip_in_target_space)); continue; } - // When both the layer and the target are unclipped, the entire layer - // content rect is visible. - const bool fully_visible = - !clip_node->layers_are_clipped && !clip_node->target_is_clipped; + const TransformTree& transform_tree = property_trees->transform_tree; + const TransformNode* transform_node = + transform_tree.Node(layer->transform_tree_index()); + int target_node_id = transform_tree.ContentTargetId(transform_node->id); - if (!fully_visible) { - const TransformTree& transform_tree = property_trees->transform_tree; - const TransformNode* transform_node = - transform_tree.Node(layer->transform_tree_index()); - int target_node_id = transform_tree.ContentTargetId(transform_node->id); - - // The clip node stores clip rect in its target space. - gfx::RectF clip_rect_in_target_space = clip_node->clip_in_target_space; - - // If required, this clip rect should be mapped to the current layer's - // target space. - if (clip_node->target_transform_id != target_node_id) { - // In this case, layer has a clip parent or scroll parent (or shares the - // target with an ancestor layer that has clip parent) and the clip - // parent's target is different from the layer's target. As the layer's - // target has unclippped descendants, it is unclippped. - if (!clip_node->layers_are_clipped) - continue; - - // Compute the clip rect in target space and store it. - bool for_visible_rect_calculation = false; - if (!ComputeClipRectInTargetSpace( - layer, clip_node, property_trees, target_node_id, - for_visible_rect_calculation, &clip_rect_in_target_space)) - continue; - } + // The clip node stores clip rect in its target space. + gfx::RectF clip_rect_in_target_space = clip_node->clip_in_target_space; - if (!clip_rect_in_target_space.IsEmpty()) { - layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space)); - } else { - layer->set_clip_rect(gfx::Rect()); - } + // If required, this clip rect should be mapped to the current layer's + // target space. + if (clip_node->target_transform_id != target_node_id) { + // In this case, layer has a clip parent or scroll parent (or shares the + // target with an ancestor layer that has clip parent) and the clip + // parent's target is different from the layer's target. As the layer's + // target has unclippped descendants, it is unclippped. + if (!clip_node->layers_are_clipped) + continue; + + // Compute the clip rect in target space and store it. + bool for_visible_rect_calculation = false; + if (!ComputeClipRectInTargetSpace( + layer, clip_node, property_trees, target_node_id, + for_visible_rect_calculation, &clip_rect_in_target_space)) + continue; + } + + if (!clip_rect_in_target_space.IsEmpty()) { + layer->set_clip_rect(gfx::ToEnclosingRect(clip_rect_in_target_space)); + } else { + layer->set_clip_rect(gfx::Rect()); } } } @@ -385,9 +337,10 @@ void CalculateVisibleRects(const LayerImplList& visible_layer_list, effect_tree.ClosestAncestorWithCopyRequest(layer->effect_tree_index()); if (effect_ancestor_with_copy_request > 1) { // Non root copy request. - ConditionalClip accumulated_clip_rect = - ComputeAccumulatedClip(property_trees, layer->clip_tree_index(), - effect_ancestor_with_copy_request); + bool include_viewport_clip = false; + ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( + property_trees, include_viewport_clip, layer->clip_tree_index(), + effect_ancestor_with_copy_request); if (!accumulated_clip_rect.is_clipped) { layer->set_visible_layer_rect(gfx::Rect(layer_bounds)); continue; @@ -497,8 +450,10 @@ void CalculateVisibleRects(const LayerImplList& visible_layer_list, } // The clip rect should be intersected with layer rect in target space. - gfx::Transform content_to_target = transform_tree.ToTarget( - transform_node->id, layer->render_target_effect_tree_index()); + gfx::Transform content_to_target; + property_trees->GetToTarget(transform_node->id, + layer->render_target_effect_tree_index(), + &content_to_target); content_to_target.Translate(layer->offset_to_transform_parent().x(), layer->offset_to_transform_parent().y()); gfx::Rect layer_content_rect = gfx::Rect(layer_bounds); @@ -522,8 +477,9 @@ void CalculateVisibleRects(const LayerImplList& visible_layer_list, gfx::Transform target_to_layer; if (transform_node->ancestors_are_invertible) { - target_to_layer = transform_tree.FromTarget( - transform_node->id, layer->render_target_effect_tree_index()); + property_trees->GetFromTarget(transform_node->id, + layer->render_target_effect_tree_index(), + &target_to_layer); } else { const EffectNode* target_effect_node = ContentsTargetEffectNode(layer->effect_tree_index(), effect_tree); @@ -537,10 +493,6 @@ void CalculateVisibleRects(const LayerImplList& visible_layer_list, continue; } ConcatInverseSurfaceContentsScale(target_effect_node, &target_to_layer); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(target_effect_node->id, target_node_id, - effect_tree, transform_tree); -#endif } gfx::Transform target_to_content; target_to_content.Translate(-layer->offset_to_transform_parent().x(), @@ -569,31 +521,36 @@ static int TransformTreeIndexForBackfaceVisibility(LayerType* layer, return layer->id() == node->owner_id ? tree.parent(node)->id : node->id; } -static bool IsTargetSpaceTransformBackFaceVisible(Layer* layer, - int transform_tree_index, - const TransformTree& tree) { +static bool IsTargetSpaceTransformBackFaceVisible( + Layer* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { // We do not skip back face invisible layers on main thread as target space // transform will not be available here. return false; } -static bool IsTargetSpaceTransformBackFaceVisible(LayerImpl* layer, - int transform_tree_index, - const TransformTree& tree) { - return tree - .ToTarget(transform_tree_index, layer->render_target_effect_tree_index()) - .IsBackFaceVisible(); +static bool IsTargetSpaceTransformBackFaceVisible( + LayerImpl* layer, + int transform_tree_index, + const PropertyTrees* property_trees) { + gfx::Transform to_target; + property_trees->GetToTarget(transform_tree_index, + layer->render_target_effect_tree_index(), + &to_target); + return to_target.IsBackFaceVisible(); } template <typename LayerType> static bool IsLayerBackFaceVisible(LayerType* layer, int transform_tree_index, - const TransformTree& tree) { - const TransformNode* node = tree.Node(transform_tree_index); + const PropertyTrees* property_trees) { + const TransformNode* node = + property_trees->transform_tree.Node(transform_tree_index); return layer->use_local_transform_for_backface_visibility() ? node->local.IsBackFaceVisible() : IsTargetSpaceTransformBackFaceVisible( - layer, transform_tree_index, tree); + layer, transform_tree_index, property_trees); } static inline bool TransformToScreenIsKnown(Layer* layer, @@ -612,7 +569,7 @@ static inline bool TransformToScreenIsKnown(LayerImpl* layer, template <typename LayerType> static bool LayerNeedsUpdateInternal(LayerType* layer, bool layer_is_drawn, - const TransformTree& tree) { + 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). @@ -637,6 +594,7 @@ static bool LayerNeedsUpdateInternal(LayerType* layer, // The layer should not be drawn if (1) it is not double-sided and (2) the // back of the layer is known to be facing the screen. + const TransformTree& tree = property_trees->transform_tree; if (layer->should_check_backface_visibility()) { int backface_transform_id = TransformTreeIndexForBackfaceVisibility(layer, tree); @@ -644,7 +602,7 @@ static bool LayerNeedsUpdateInternal(LayerType* layer, // backface is not visible. if (TransformToScreenIsKnown(layer, backface_transform_id, tree) && !HasSingularTransform(backface_transform_id, tree) && - IsLayerBackFaceVisible(layer, backface_transform_id, tree)) + IsLayerBackFaceVisible(layer, backface_transform_id, property_trees)) return false; } @@ -652,19 +610,20 @@ static bool LayerNeedsUpdateInternal(LayerType* layer, } void FindLayersThatNeedUpdates(LayerTreeImpl* layer_tree_impl, - const TransformTree& transform_tree, - const EffectTree& effect_tree, + const PropertyTrees* property_trees, std::vector<LayerImpl*>* visible_layer_list) { - for (auto* layer_impl : *layer_tree_impl) { - bool layer_is_drawn = - effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; + const TransformTree& transform_tree = property_trees->transform_tree; + const EffectTree& effect_tree = property_trees->effect_tree; + for (auto* layer_impl : *layer_tree_impl) { if (!IsRootLayer(layer_impl) && - LayerShouldBeSkipped(layer_impl, layer_is_drawn, transform_tree, - effect_tree)) + LayerShouldBeSkipped(layer_impl, transform_tree, effect_tree)) continue; - if (LayerNeedsUpdate(layer_impl, layer_is_drawn, transform_tree)) + bool layer_is_drawn = + effect_tree.Node(layer_impl->effect_tree_index())->is_drawn; + + if (LayerNeedsUpdate(layer_impl, layer_is_drawn, property_trees)) visible_layer_list->push_back(layer_impl); } } @@ -689,7 +648,6 @@ void UpdateRenderSurfaceForLayer(EffectTree* effect_tree, template <typename LayerType> static inline bool LayerShouldBeSkippedInternal( LayerType* layer, - bool layer_is_drawn, const TransformTree& transform_tree, const EffectTree& effect_tree) { const TransformNode* transform_node = @@ -708,35 +666,31 @@ static inline bool LayerShouldBeSkippedInternal( } bool LayerShouldBeSkipped(LayerImpl* layer, - bool layer_is_drawn, const TransformTree& transform_tree, const EffectTree& effect_tree) { - return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, - effect_tree); + return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); } bool LayerShouldBeSkipped(Layer* layer, - bool layer_is_drawn, const TransformTree& transform_tree, const EffectTree& effect_tree) { - return LayerShouldBeSkippedInternal(layer, layer_is_drawn, transform_tree, - effect_tree); + return LayerShouldBeSkippedInternal(layer, transform_tree, effect_tree); } void FindLayersThatNeedUpdates(LayerTree* layer_tree, - const TransformTree& transform_tree, - const EffectTree& effect_tree, + const PropertyTrees* property_trees, LayerList* update_layer_list) { + const TransformTree& transform_tree = property_trees->transform_tree; + const EffectTree& effect_tree = property_trees->effect_tree; for (auto* layer : *layer_tree) { - bool layer_is_drawn = - effect_tree.Node(layer->effect_tree_index())->is_drawn; - if (!IsRootLayer(layer) && - LayerShouldBeSkipped(layer, layer_is_drawn, transform_tree, - effect_tree)) + LayerShouldBeSkipped(layer, transform_tree, effect_tree)) continue; - if (LayerNeedsUpdate(layer, layer_is_drawn, transform_tree)) { + bool layer_is_drawn = + effect_tree.Node(layer->effect_tree_index())->is_drawn; + + if (LayerNeedsUpdate(layer, layer_is_drawn, property_trees)) { update_layer_list->push_back(layer); } @@ -822,20 +776,10 @@ void ComputeClips(PropertyTrees* property_trees, const EffectNode* target_effect_node = effect_tree.Node(clip_node->target_effect_id); PostConcatSurfaceContentsScale(target_effect_node, &parent_to_current); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(clip_node->target_effect_id, - clip_node->target_transform_id, - effect_tree, transform_tree); -#endif const EffectNode* parent_target_effect_node = effect_tree.Node(parent_clip_node->target_effect_id); ConcatInverseSurfaceContentsScale(parent_target_effect_node, &parent_to_current); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(parent_clip_node->target_effect_id, - parent_clip_node->target_transform_id, - effect_tree, transform_tree); -#endif // If we can't compute a transform, it's because we had to use the inverse // of a singular transform. We won't draw in this case, so there's no need // to compute clips. @@ -852,11 +796,12 @@ void ComputeClips(PropertyTrees* property_trees, // need to clip using our parent clip and if we don't propagate it here, // it will be lost. if (clip_node->resets_clip && non_root_surfaces_enabled) { - if (clip_node->applies_local_clip) { - clip_node->clip_in_target_space = MathUtil::MapClippedRect( - transform_tree.ToTarget(clip_node->transform_id, - clip_node->target_effect_id), - clip_node->clip); + if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) { + gfx::Transform to_target; + property_trees->GetToTarget(clip_node->transform_id, + clip_node->target_effect_id, &to_target); + clip_node->clip_in_target_space = + MathUtil::MapClippedRect(to_target, clip_node->clip); ResetIfHasNanCoordinate(&clip_node->clip_in_target_space); clip_node->combined_clip_in_target_space = gfx::IntersectRects(clip_node->clip_in_target_space, @@ -870,7 +815,8 @@ void ComputeClips(PropertyTrees* property_trees, ResetIfHasNanCoordinate(&clip_node->combined_clip_in_target_space); continue; } - bool use_only_parent_clip = !clip_node->applies_local_clip; + bool use_only_parent_clip = + clip_node->clip_type != ClipNode::ClipType::APPLIES_LOCAL_CLIP; if (use_only_parent_clip) { clip_node->combined_clip_in_target_space = parent_combined_clip_in_target_space; @@ -892,19 +838,12 @@ void ComputeClips(PropertyTrees* property_trees, source_to_target = transform_tree.ToScreen(clip_node->transform_id); } else if (transform_tree.ContentTargetId(transform_node->id) == clip_node->target_transform_id) { - source_to_target = transform_tree.ToTarget(clip_node->transform_id, - clip_node->target_effect_id); + property_trees->GetToTarget(clip_node->transform_id, + clip_node->target_effect_id, + &source_to_target); } else { - success = property_trees->ComputeTransformToTarget( + success = property_trees->GetToTarget( transform_node->id, clip_node->target_effect_id, &source_to_target); - const EffectNode* target_effect_node = - effect_tree.Node(clip_node->target_effect_id); - PostConcatSurfaceContentsScale(target_effect_node, &source_to_target); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(clip_node->target_effect_id, - clip_node->target_transform_id, - effect_tree, transform_tree); -#endif // source_to_target computation should be successful as target is an // ancestor of the transform node. DCHECK(success); @@ -949,7 +888,7 @@ void UpdateRenderTarget(EffectTree* effect_tree, for (int i = 1; i < static_cast<int>(effect_tree->size()); ++i) { EffectNode* node = effect_tree->Node(i); if (i == 1) { - // Render target on the node corresponding to root is itself. + // Render target of the node corresponding to root is itself. node->target_id = 1; } else if (!can_render_to_separate_surface) { node->target_id = 1; @@ -985,8 +924,10 @@ static void ComputeClipsWithEffectTree(PropertyTrees* property_trees) { for (int i = 2; i < static_cast<int>(effect_tree->size()); ++i) { EffectNode* effect_node = effect_tree->Node(i); const EffectNode* target_node = effect_tree->Node(effect_node->target_id); - ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( - property_trees, effect_node->clip_id, target_node->id); + bool include_viewport_clip = false; + ConditionalClip accumulated_clip_rect = + ComputeAccumulatedClip(property_trees, include_viewport_clip, + effect_node->clip_id, target_node->id); gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; const RenderSurfaceImpl* render_surface = effect_node->render_surface; if (render_surface && render_surface->is_clipped()) { @@ -1004,6 +945,7 @@ static void ComputeLayerClipRect(const PropertyTrees* property_trees, const LayerImpl* layer) { const EffectTree* effect_tree = &property_trees->effect_tree; const ClipTree* clip_tree = &property_trees->clip_tree; + const ClipNode* clip_node = clip_tree->Node(layer->clip_tree_index()); const EffectNode* effect_node = effect_tree->Node(layer->effect_tree_index()); const EffectNode* target_node = effect_node->has_render_surface @@ -1015,65 +957,25 @@ static void ComputeLayerClipRect(const PropertyTrees* property_trees, target_node = effect_tree->Node(1); } - ConditionalClip accumulated_clip_rect = ComputeAccumulatedClip( - property_trees, layer->clip_tree_index(), target_node->id); + bool include_viewport_clip = false; + ConditionalClip accumulated_clip_rect = + ComputeAccumulatedClip(property_trees, include_viewport_clip, + layer->clip_tree_index(), target_node->id); - gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; + bool is_clipped_from_clip_tree = + property_trees->non_root_surfaces_enabled + ? clip_node->layers_are_clipped + : clip_node->layers_are_clipped_when_surfaces_disabled; + DCHECK_EQ(is_clipped_from_clip_tree, accumulated_clip_rect.is_clipped); - if ((!property_trees->non_root_surfaces_enabled && - clip_tree->Node(layer->clip_tree_index()) - ->layers_are_clipped_when_surfaces_disabled) || - clip_tree->Node(layer->clip_tree_index())->layers_are_clipped) { - DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip)) - << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() - << " layer clip: " << layer->clip_rect().ToString() << " v.s. " - << gfx::ToEnclosingRect(accumulated_clip).ToString() - << " and clip node clip: " - << gfx::ToEnclosingRect( - clip_tree->Node(layer->clip_tree_index())->clip_in_target_space) - .ToString(); - } -} + gfx::RectF accumulated_clip = accumulated_clip_rect.clip_rect; -static int FindTargetTransformTreeIndexFromEffectTree( - const EffectTree& effect_tree, - const int effect_tree_index) { - const EffectNode* node = effect_tree.Node(effect_tree_index); - if (node->has_render_surface) - return node->transform_id; - node = effect_tree.Node(node->target_id); - return node->transform_id; -} - -static void VerifyDrawTransformsMatch(LayerImpl* layer, - PropertyTrees* property_trees) { - const int source_id = layer->transform_tree_index(); - int destination_id = FindTargetTransformTreeIndexFromEffectTree( - property_trees->effect_tree, layer->effect_tree_index()); - const EffectNode* target_effect_node = ContentsTargetEffectNode( - layer->effect_tree_index(), property_trees->effect_tree); - gfx::Transform draw_transform; - property_trees->ComputeTransformToTarget(source_id, target_effect_node->id, - &draw_transform); - PostConcatSurfaceContentsScale(target_effect_node, &draw_transform); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(layer->effect_tree_index(), destination_id, - property_trees->effect_tree, - property_trees->transform_tree); -#endif - if (layer->should_flatten_transform_from_property_tree()) - draw_transform.FlattenTo2d(); - draw_transform.Translate(layer->offset_to_transform_parent().x(), - layer->offset_to_transform_parent().y()); - DCHECK(draw_transform.ApproximatelyEqual(DrawTransform( - layer, property_trees->transform_tree, property_trees->effect_tree))) - << " layer: " << layer->id() << " source transform id: " << source_id - << " destination transform id: " << destination_id - << " draw transform from transform tree: " - << DrawTransform(layer, property_trees->transform_tree, - property_trees->effect_tree) - .ToString() - << " v.s." << draw_transform.ToString(); + DCHECK(layer->clip_rect() == gfx::ToEnclosingRect(accumulated_clip)) + << " layer: " << layer->id() << " clip id: " << layer->clip_tree_index() + << " layer clip: " << layer->clip_rect().ToString() << " v.s. " + << gfx::ToEnclosingRect(accumulated_clip).ToString() + << " and clip node clip: " + << gfx::ToEnclosingRect(clip_node->clip_in_target_space).ToString(); } static void ComputeVisibleRectsInternal( @@ -1098,11 +1000,10 @@ static void ComputeVisibleRectsInternal( ComputeEffects(&property_trees->effect_tree); ComputeClips(property_trees, can_render_to_separate_surface); - FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), - property_trees->transform_tree, - property_trees->effect_tree, visible_layer_list); - CalculateClipRects<LayerImpl>(*visible_layer_list, property_trees, - can_render_to_separate_surface); + FindLayersThatNeedUpdates(root_layer->layer_tree_impl(), property_trees, + visible_layer_list); + CalculateClipRects(*visible_layer_list, property_trees, + can_render_to_separate_surface); CalculateVisibleRects(*visible_layer_list, property_trees, can_render_to_separate_surface); } @@ -1157,12 +1058,6 @@ void VerifyClipTreeCalculations(const LayerImplList& layer_list, ComputeLayerClipRect(property_trees, layer); } -void VerifyTransformTreeCalculations(const LayerImplList& layer_list, - PropertyTrees* property_trees) { - for (auto* layer : layer_list) - VerifyDrawTransformsMatch(layer, property_trees); -} - void ComputeVisibleRects(LayerImpl* root_layer, PropertyTrees* property_trees, bool can_render_to_separate_surface, @@ -1194,9 +1089,10 @@ gfx::Rect ComputeLayerVisibleRectDynamic(const PropertyTrees* property_trees, gfx::Rect layer_content_rect = gfx::Rect(layer->bounds()); gfx::RectF accumulated_clip_in_root_space; if (non_root_copy_request) { - ConditionalClip accumulated_clip = - ComputeAccumulatedClip(property_trees, layer->clip_tree_index(), - effect_ancestor_with_copy_request); + bool include_viewport_clip = false; + ConditionalClip accumulated_clip = ComputeAccumulatedClip( + property_trees, include_viewport_clip, layer->clip_tree_index(), + effect_ancestor_with_copy_request); if (!accumulated_clip.is_clipped) return layer_content_rect; accumulated_clip_in_root_space = accumulated_clip.clip_rect; @@ -1240,46 +1136,33 @@ void VerifyVisibleRectsCalculations(const LayerImplList& layer_list, bool LayerNeedsUpdate(Layer* layer, bool layer_is_drawn, - const TransformTree& tree) { - return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree); + const PropertyTrees* property_trees) { + return LayerNeedsUpdateInternal(layer, layer_is_drawn, property_trees); } bool LayerNeedsUpdate(LayerImpl* layer, bool layer_is_drawn, - const TransformTree& tree) { - return LayerNeedsUpdateInternal(layer, layer_is_drawn, tree); + 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) { + // TransformTree::ToTarget computes transform between the layer's transform + // node and surface's transform node and scales it by the surface's content + // scale. gfx::Transform xform; - const bool owns_non_root_surface = - !IsRootLayer(layer) && layer->render_surface(); - if (!owns_non_root_surface) { - // If you're not the root, or you don't own a surface, you need to apply - // your local offset. - xform = - transform_tree.property_trees()->non_root_surfaces_enabled - ? transform_tree.ToTarget(layer->transform_tree_index(), - layer->render_target_effect_tree_index()) - : transform_tree.ToScreen(layer->transform_tree_index()); - if (layer->should_flatten_transform_from_property_tree()) - xform.FlattenTo2d(); - xform.Translate(layer->offset_to_transform_parent().x(), - layer->offset_to_transform_parent().y()); - } else { - // Surfaces need to apply their surface contents scale. - const EffectNode* effect_node = - effect_tree.Node(layer->effect_tree_index()); - xform.Scale(effect_node->surface_contents_scale.x(), - effect_node->surface_contents_scale.y()); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(layer->effect_tree_index(), - layer->transform_tree_index(), effect_tree, - transform_tree); -#endif - } + if (transform_tree.property_trees()->non_root_surfaces_enabled) + transform_tree.property_trees()->GetToTarget( + layer->transform_tree_index(), layer->render_target_effect_tree_index(), + &xform); + else + xform = transform_tree.ToScreen(layer->transform_tree_index()); + if (layer->should_flatten_transform_from_property_tree()) + xform.FlattenTo2d(); + xform.Translate(layer->offset_to_transform_parent().x(), + layer->offset_to_transform_parent().y()); return xform; } @@ -1300,22 +1183,10 @@ static void SetSurfaceDrawTransform(const PropertyTrees* property_trees, gfx::Transform render_surface_transform; const EffectNode* target_effect_node = effect_tree.Node(effect_node->target_id); - property_trees->ComputeTransformToTarget( - transform_node->id, target_effect_node->id, &render_surface_transform); - PostConcatSurfaceContentsScale(target_effect_node, &render_surface_transform); -#if DCHECK_IS_ON() - const TransformNode* target_transform_node = - transform_tree.Node(transform_tree.TargetId(transform_node->id)); - VerifySurfaceContentsScalesMatch(effect_node->target_id, - target_transform_node->id, effect_tree, - transform_tree); -#endif + property_trees->GetToTarget(transform_node->id, target_effect_node->id, + &render_surface_transform); ConcatInverseSurfaceContentsScale(effect_node, &render_surface_transform); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(effect_node->id, transform_node->id, - effect_tree, transform_tree); -#endif render_surface->SetDrawTransform(render_surface_transform); } @@ -1353,7 +1224,7 @@ static void SetSurfaceClipRect(const ClipNode* parent_clip_node, const EffectNode* effect_node = effect_tree.Node(render_surface->EffectTreeIndex()); int target_effect_id = effect_node->target_id; - const bool success = property_trees->ComputeTransformToTarget( + const bool success = property_trees->GetToTarget( parent_clip_node->target_transform_id, target_effect_id, &clip_parent_target_to_target); @@ -1362,13 +1233,6 @@ static void SetSurfaceClipRect(const ClipNode* parent_clip_node, return; } - PostConcatSurfaceContentsScale(effect_node, &clip_parent_target_to_target); -#if DCHECK_IS_ON() - VerifySurfaceContentsScalesMatch(render_surface->EffectTreeIndex(), - transform_tree.TargetId(transform_node->id), - effect_tree, transform_tree); -#endif - DCHECK_LT(parent_clip_node->target_transform_id, transform_tree.TargetId(transform_node->id)); render_surface->SetClipRect(gfx::ToEnclosingRect(MathUtil::ProjectClippedRect( diff --git a/chromium/cc/trees/draw_property_utils.h b/chromium/cc/trees/draw_property_utils.h index 329d25c690b..4e9e0227336 100644 --- a/chromium/cc/trees/draw_property_utils.h +++ b/chromium/cc/trees/draw_property_utils.h @@ -16,8 +16,6 @@ class Vector2dF; namespace cc { -class ClipTree; -struct DrawProperties; class Layer; class LayerImpl; class LayerTree; @@ -36,8 +34,7 @@ void CC_EXPORT ConcatInverseSurfaceContentsScale(const EffectNode* effect_node, gfx::Transform* transform); // Computes combined clips for every node in |clip_tree|. This function requires // that |transform_tree| has been updated via |ComputeTransforms|. -void CC_EXPORT ComputeClips(ClipTree* clip_tree, - const TransformTree& transform_tree, +void CC_EXPORT ComputeClips(PropertyTrees* property_trees, bool non_root_surfaces_enabled); // Computes combined (screen space) transforms for every node in the transform @@ -66,15 +63,9 @@ void CC_EXPORT UpdatePropertyTrees(PropertyTrees* property_trees, bool can_render_to_separate_surface); void CC_EXPORT FindLayersThatNeedUpdates(LayerTree* layer_tree, - const TransformTree& transform_tree, - const EffectTree& effect_tree, + const PropertyTrees* property_trees, LayerList* update_layer_list); -void CC_EXPORT -ComputeVisibleRectsForTesting(PropertyTrees* property_trees, - bool can_render_to_separate_surface, - LayerList* visible_layer_list); - void CC_EXPORT ComputeVisibleRects(LayerImpl* root_layer, PropertyTrees* property_trees, bool can_render_to_separate_surface, @@ -97,24 +88,20 @@ void CC_EXPORT ComputeSurfaceDrawProperties(const PropertyTrees* property_trees, RenderSurfaceImpl* render_surface); bool CC_EXPORT LayerShouldBeSkipped(LayerImpl* layer, - bool layer_is_drawn, const TransformTree& transform_tree, const EffectTree& effect_tree); bool CC_EXPORT LayerNeedsUpdate(Layer* layer, bool layer_is_drawn, - const TransformTree& tree); + const PropertyTrees* property_trees); bool CC_EXPORT LayerNeedsUpdate(LayerImpl* layer, bool layer_is_drawn, - const TransformTree& tree); + const PropertyTrees* property_trees); void CC_EXPORT VerifyClipTreeCalculations(const LayerImplList& layer_list, PropertyTrees* property_trees); -void CC_EXPORT VerifyTransformTreeCalculations(const LayerImplList& layer_list, - PropertyTrees* property_trees); - gfx::Transform CC_EXPORT DrawTransform(const LayerImpl* layer, const TransformTree& transform_tree, const EffectTree& effect_tree); diff --git a/chromium/cc/trees/effect_node.cc b/chromium/cc/trees/effect_node.cc index 893a033254a..7d987460f48 100644 --- a/chromium/cc/trees/effect_node.cc +++ b/chromium/cc/trees/effect_node.cc @@ -4,7 +4,6 @@ #include "base/trace_event/trace_event_argument.h" #include "cc/proto/gfx_conversions.h" -#include "cc/proto/property_tree.pb.h" #include "cc/proto/skia_conversions.h" #include "cc/trees/effect_node.h" @@ -66,69 +65,6 @@ bool EffectNode::operator==(const EffectNode& other) const { target_id == other.target_id && mask_layer_id == other.mask_layer_id; } -void EffectNode::ToProtobuf(proto::TreeNode* proto) const { - proto->set_id(id); - proto->set_parent_id(parent_id); - proto->set_owner_id(owner_id); - - DCHECK(!proto->has_effect_node_data()); - proto::EffectNodeData* data = proto->mutable_effect_node_data(); - data->set_opacity(opacity); - data->set_screen_space_opacity(screen_space_opacity); - data->set_blend_mode(SkXfermodeModeToProto(blend_mode)); - data->set_has_render_surface(has_render_surface); - data->set_has_copy_request(has_copy_request); - data->set_hidden_by_backface_visibility(hidden_by_backface_visibility); - data->set_double_sided(double_sided); - data->set_is_drawn(is_drawn); - data->set_subtree_hidden(subtree_hidden); - data->set_has_potential_filter_animation(has_potential_filter_animation); - data->set_has_potential_opacity_animation(has_potential_opacity_animation); - data->set_is_currently_animating_filter(is_currently_animating_filter); - data->set_is_currently_animating_opacity(is_currently_animating_opacity); - data->set_effect_changed(effect_changed); - data->set_num_copy_requests_in_subtree(num_copy_requests_in_subtree); - data->set_transform_id(transform_id); - data->set_clip_id(clip_id); - data->set_target_id(target_id); - data->set_mask_layer_id(mask_layer_id); - Vector2dFToProto(surface_contents_scale, - data->mutable_surface_contents_scale()); - SizeToProto(unscaled_mask_target_size, - data->mutable_unscaled_mask_target_size()); -} - -void EffectNode::FromProtobuf(const proto::TreeNode& proto) { - id = proto.id(); - parent_id = proto.parent_id(); - owner_id = proto.owner_id(); - - DCHECK(proto.has_effect_node_data()); - const proto::EffectNodeData& data = proto.effect_node_data(); - - opacity = data.opacity(); - screen_space_opacity = data.screen_space_opacity(); - blend_mode = SkXfermodeModeFromProto(data.blend_mode()); - unscaled_mask_target_size = ProtoToSize(data.unscaled_mask_target_size()); - has_render_surface = data.has_render_surface(); - has_copy_request = data.has_copy_request(); - hidden_by_backface_visibility = data.hidden_by_backface_visibility(); - double_sided = data.double_sided(); - is_drawn = data.is_drawn(); - subtree_hidden = data.subtree_hidden(); - has_potential_filter_animation = data.has_potential_filter_animation(); - has_potential_opacity_animation = data.has_potential_opacity_animation(); - is_currently_animating_filter = data.is_currently_animating_filter(); - is_currently_animating_opacity = data.is_currently_animating_opacity(); - effect_changed = data.effect_changed(); - num_copy_requests_in_subtree = data.num_copy_requests_in_subtree(); - transform_id = data.transform_id(); - clip_id = data.clip_id(); - target_id = data.target_id(); - mask_layer_id = data.mask_layer_id(); - surface_contents_scale = ProtoToVector2dF(data.surface_contents_scale()); -} - void EffectNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); diff --git a/chromium/cc/trees/effect_node.h b/chromium/cc/trees/effect_node.h index a38acdd241f..e1699be82e3 100644 --- a/chromium/cc/trees/effect_node.h +++ b/chromium/cc/trees/effect_node.h @@ -21,10 +21,6 @@ namespace cc { class RenderSurfaceImpl; -namespace proto { -class TreeNode; -} // namespace proto - struct CC_EXPORT EffectNode { EffectNode(); EffectNode(const EffectNode& other); @@ -72,8 +68,6 @@ struct CC_EXPORT EffectNode { bool operator==(const EffectNode& other) const; - void ToProtobuf(proto::TreeNode* proto) const; - void FromProtobuf(const proto::TreeNode& proto); void AsValueInto(base::trace_event::TracedValue* value) const; }; diff --git a/chromium/cc/animation/element_id.cc b/chromium/cc/trees/element_id.cc index 242cd32e621..45913303c10 100644 --- a/chromium/cc/animation/element_id.cc +++ b/chromium/cc/trees/element_id.cc @@ -2,14 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/animation/element_id.h" +#include "cc/trees/element_id.h" #include <limits> #include <ostream> #include "base/trace_event/trace_event_argument.h" #include "base/values.h" -#include "cc/proto/element_id.pb.h" namespace cc { @@ -46,16 +45,6 @@ std::unique_ptr<base::Value> ElementId::AsValue() const { return std::move(res); } -void ElementId::ToProtobuf(proto::ElementId* proto) const { - proto->set_primary_id(primaryId); - proto->set_secondary_id(secondaryId); -} - -void ElementId::FromProtobuf(const proto::ElementId& proto) { - primaryId = proto.primary_id(); - secondaryId = proto.secondary_id(); -} - size_t ElementIdHash::operator()(ElementId key) const { return base::HashInts(key.primaryId, key.secondaryId); } diff --git a/chromium/cc/animation/element_id.h b/chromium/cc/trees/element_id.h index 1da52a42e19..4c0b652cc88 100644 --- a/chromium/cc/animation/element_id.h +++ b/chromium/cc/trees/element_id.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_ANIMATION_ELEMENT_ID_H_ -#define CC_ANIMATION_ELEMENT_ID_H_ +#ifndef CC_TREES_ELEMENT_ID_H_ +#define CC_TREES_ELEMENT_ID_H_ #include <stddef.h> @@ -24,14 +24,6 @@ class TracedValue; namespace cc { -namespace proto { -class ElementId; -} // namespace proto - -// ------------------------------*IMPORTANT*--------------------------------- -// ElementId has a corresponding proto defined in cc/proto/element_id.proto. -// When making any changes here, but sure to update the proto. - // An "element" is really an animation target. It retains the name element to be // symmetric with ElementAnimations and blink::ElementAnimations, but is not // in fact tied to the notion of a blink element. It is also not associated with @@ -57,9 +49,6 @@ struct CC_EXPORT ElementId { void AddToTracedValue(base::trace_event::TracedValue* res) const; std::unique_ptr<base::Value> AsValue() const; - void ToProtobuf(proto::ElementId* proto) const; - void FromProtobuf(const proto::ElementId& proto); - // The compositor treats this as an opaque handle and should not know how to // interpret these bits. Non-blink cc clients typically operate in terms of // layers and may set this value to match the client's layer id. @@ -78,4 +67,4 @@ CC_EXPORT std::ostream& operator<<(std::ostream& out, const ElementId& id); } // namespace cc -#endif // CC_ANIMATION_ELEMENT_ID_H_ +#endif // CC_TREES_ELEMENT_ID_H_ diff --git a/chromium/cc/trees/layer_tree.cc b/chromium/cc/trees/layer_tree.cc index 3d46e3fae10..bf07576cc69 100644 --- a/chromium/cc/trees/layer_tree.cc +++ b/chromium/cc/trees/layer_tree.cc @@ -6,46 +6,24 @@ #include "base/auto_reset.h" #include "base/time/time.h" -#include "cc/animation/animation_host.h" #include "cc/input/page_scale_animation.h" #include "cc/layers/heads_up_display_layer.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer.h" -#include "cc/layers/layer_proto_converter.h" #include "cc/proto/gfx_conversions.h" #include "cc/proto/layer_tree.pb.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/mutator_host.h" #include "cc/trees/property_tree_builder.h" namespace cc { -namespace { - -Layer* UpdateAndGetLayer(Layer* current_layer, - int layer_id, - LayerTree* layer_tree) { - if (layer_id == Layer::INVALID_ID) { - if (current_layer) - current_layer->SetLayerTreeHost(nullptr); - - return nullptr; - } - Layer* layer = layer_tree->LayerById(layer_id); - DCHECK(layer); - if (current_layer && current_layer != layer) - current_layer->SetLayerTreeHost(nullptr); - - return layer; -} - -} // namespace - LayerTree::Inputs::Inputs() : top_controls_height(0.f), top_controls_shown_ratio(0.f), - top_controls_shrink_blink_size(false), + browser_controls_shrink_blink_size(false), bottom_controls_height(0.f), device_scale_factor(1.f), painted_device_scale_factor(1.f), @@ -59,20 +37,19 @@ LayerTree::Inputs::Inputs() LayerTree::Inputs::~Inputs() = default; -LayerTree::LayerTree(std::unique_ptr<AnimationHost> animation_host, - LayerTreeHost* layer_tree_host) +LayerTree::LayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host) : needs_full_tree_sync_(true), needs_meta_info_recomputation_(true), in_paint_layer_contents_(false), - animation_host_(std::move(animation_host)), + mutator_host_(mutator_host), layer_tree_host_(layer_tree_host) { - DCHECK(animation_host_); + DCHECK(mutator_host_); DCHECK(layer_tree_host_); - animation_host_->SetMutatorHostClient(this); + mutator_host_->SetMutatorHostClient(this); } LayerTree::~LayerTree() { - animation_host_->SetMutatorHostClient(nullptr); + mutator_host_->SetMutatorHostClient(nullptr); // We must clear any pointers into the layer tree prior to destroying it. RegisterViewportLayers(nullptr, nullptr, nullptr, nullptr); @@ -158,17 +135,17 @@ void LayerTree::SetViewportSize(const gfx::Size& device_viewport_size) { SetNeedsCommit(); } -void LayerTree::SetTopControlsHeight(float height, bool shrink) { +void LayerTree::SetBrowserControlsHeight(float height, bool shrink) { if (inputs_.top_controls_height == height && - inputs_.top_controls_shrink_blink_size == shrink) + inputs_.browser_controls_shrink_blink_size == shrink) return; inputs_.top_controls_height = height; - inputs_.top_controls_shrink_blink_size = shrink; + inputs_.browser_controls_shrink_blink_size = shrink; SetNeedsCommit(); } -void LayerTree::SetTopControlsShownRatio(float ratio) { +void LayerTree::SetBrowserControlsShownRatio(float ratio) { if (inputs_.top_controls_shown_ratio == ratio) return; @@ -243,8 +220,8 @@ void LayerTree::RegisterLayer(Layer* layer) { DCHECK(!in_paint_layer_contents_); layer_id_map_[layer->id()] = layer; if (layer->element_id()) { - animation_host_->RegisterElement(layer->element_id(), - ElementListType::ACTIVE); + mutator_host_->RegisterElement(layer->element_id(), + ElementListType::ACTIVE); } } @@ -252,8 +229,8 @@ void LayerTree::UnregisterLayer(Layer* layer) { DCHECK(LayerById(layer->id())); DCHECK(!in_paint_layer_contents_); if (layer->element_id()) { - animation_host_->UnregisterElement(layer->element_id(), - ElementListType::ACTIVE); + mutator_host_->UnregisterElement(layer->element_id(), + ElementListType::ACTIVE); } RemoveLayerShouldPushProperties(layer); layer_id_map_.erase(layer->id()); @@ -343,7 +320,8 @@ void LayerTree::SetPropertyTreesNeedRebuild() { layer_tree_host_->SetNeedsUpdateLayers(); } -void LayerTree::PushPropertiesTo(LayerTreeImpl* tree_impl) { +void LayerTree::PushPropertiesTo(LayerTreeImpl* tree_impl, + float unapplied_page_scale_delta) { tree_impl->set_needs_full_tree_sync(needs_full_tree_sync_); needs_full_tree_sync_ = false; @@ -400,15 +378,16 @@ void LayerTree::PushPropertiesTo(LayerTreeImpl* tree_impl) { // Setting property trees must happen before pushing the page scale. tree_impl->SetPropertyTrees(&property_trees_); - tree_impl->PushPageScaleFromMainThread(inputs_.page_scale_factor, - inputs_.min_page_scale_factor, - inputs_.max_page_scale_factor); + tree_impl->PushPageScaleFromMainThread( + inputs_.page_scale_factor * unapplied_page_scale_delta, + inputs_.min_page_scale_factor, inputs_.max_page_scale_factor); - tree_impl->set_top_controls_shrink_blink_size( - inputs_.top_controls_shrink_blink_size); + tree_impl->set_browser_controls_shrink_blink_size( + inputs_.browser_controls_shrink_blink_size); tree_impl->set_top_controls_height(inputs_.top_controls_height); tree_impl->set_bottom_controls_height(inputs_.bottom_controls_height); - tree_impl->PushTopControlsFromMainThread(inputs_.top_controls_shown_ratio); + tree_impl->PushBrowserControlsFromMainThread( + inputs_.top_controls_shown_ratio); tree_impl->elastic_overscroll()->PushFromMainThread(elastic_overscroll_); if (tree_impl->IsActiveTree()) tree_impl->elastic_overscroll()->PushPendingToActive(); @@ -428,11 +407,9 @@ void LayerTree::PushPropertiesTo(LayerTreeImpl* tree_impl) { tree_impl->set_has_ever_been_drawn(false); } -void LayerTree::ToProtobuf(proto::LayerTree* proto, bool inputs_only) { +void LayerTree::ToProtobuf(proto::LayerTree* proto) { TRACE_EVENT0("cc.remote", "LayerProtoConverter::SerializeLayerHierarchy"); - // LayerTree::Inputs Serialization ----------------------------------------- - // TODO(khushalsagar): Why walk the tree twice? Why not serialize properties // for dirty layers as you serialize the hierarchy? if (inputs_.root_layer) @@ -455,8 +432,8 @@ void LayerTree::ToProtobuf(proto::LayerTree* proto, bool inputs_only) { ? inputs_.outer_viewport_scroll_layer->id() : Layer::INVALID_ID); - // Top Controls ignored. They are not supported. - DCHECK(!inputs_.top_controls_shrink_blink_size); + // Browser Controls ignored. They are not supported. + DCHECK(!inputs_.browser_controls_shrink_blink_size); proto->set_device_scale_factor(inputs_.device_scale_factor); proto->set_painted_device_scale_factor(inputs_.painted_device_scale_factor); @@ -480,95 +457,6 @@ void LayerTree::ToProtobuf(proto::LayerTree* proto, bool inputs_only) { proto->set_touch_end_or_cancel_event_listener_properties( static_cast<uint32_t>( event_listener_properties(EventListenerClass::kTouchEndOrCancel))); - - if (inputs_only) - return; - // ---------------------------------------------------------------------- - - for (auto* layer : layers_that_should_push_properties_) { - proto->add_layers_that_should_push_properties(layer->id()); - } - proto->set_in_paint_layer_contents(in_paint_layer_contents()); - - proto->set_needs_full_tree_sync(needs_full_tree_sync_); - proto->set_needs_meta_info_recomputation(needs_meta_info_recomputation_); - proto->set_hud_layer_id(hud_layer_ ? hud_layer_->id() : Layer::INVALID_ID); - - property_trees_.ToProtobuf(proto->mutable_property_trees()); - Vector2dFToProto(elastic_overscroll_, proto->mutable_elastic_overscroll()); -} - -void LayerTree::FromProtobuf(const proto::LayerTree& proto) { - // Layer hierarchy. - scoped_refptr<Layer> new_root_layer; - if (proto.has_root_layer()) - new_root_layer = LayerProtoConverter::DeserializeLayerHierarchy( - inputs_.root_layer, proto.root_layer(), layer_tree_host_); - if (inputs_.root_layer != new_root_layer) { - inputs_.root_layer = new_root_layer; - } - - for (auto layer_id : proto.layers_that_should_push_properties()) { - AddLayerShouldPushProperties(layer_id_map_[layer_id]); - } - in_paint_layer_contents_ = proto.in_paint_layer_contents(); - - needs_full_tree_sync_ = proto.needs_full_tree_sync(); - needs_meta_info_recomputation_ = proto.needs_meta_info_recomputation(); - - inputs_.overscroll_elasticity_layer = - UpdateAndGetLayer(inputs_.overscroll_elasticity_layer.get(), - proto.overscroll_elasticity_layer_id(), this); - inputs_.page_scale_layer = UpdateAndGetLayer( - inputs_.page_scale_layer.get(), proto.page_scale_layer_id(), this); - inputs_.inner_viewport_scroll_layer = - UpdateAndGetLayer(inputs_.inner_viewport_scroll_layer.get(), - proto.inner_viewport_scroll_layer_id(), this); - inputs_.outer_viewport_scroll_layer = - UpdateAndGetLayer(inputs_.outer_viewport_scroll_layer.get(), - proto.outer_viewport_scroll_layer_id(), this); - - inputs_.device_viewport_size = ProtoToSize(proto.device_viewport_size()); - inputs_.device_scale_factor = proto.device_scale_factor(); - inputs_.painted_device_scale_factor = proto.painted_device_scale_factor(); - inputs_.page_scale_factor = proto.page_scale_factor(); - inputs_.min_page_scale_factor = proto.min_page_scale_factor(); - inputs_.max_page_scale_factor = proto.max_page_scale_factor(); - inputs_.background_color = proto.background_color(); - inputs_.has_transparent_background = proto.has_transparent_background(); - inputs_.have_scroll_event_handlers = proto.have_scroll_event_handlers(); - inputs_.event_listener_properties[static_cast<size_t>( - EventListenerClass::kMouseWheel)] = - static_cast<EventListenerProperties>( - proto.wheel_event_listener_properties()); - inputs_.event_listener_properties[static_cast<size_t>( - EventListenerClass::kTouchStartOrMove)] = - static_cast<EventListenerProperties>( - proto.touch_start_or_move_event_listener_properties()); - inputs_.event_listener_properties[static_cast<size_t>( - EventListenerClass::kTouchEndOrCancel)] = - static_cast<EventListenerProperties>( - proto.touch_end_or_cancel_event_listener_properties()); - - hud_layer_ = static_cast<HeadsUpDisplayLayer*>( - UpdateAndGetLayer(hud_layer_.get(), proto.hud_layer_id(), this)); - - LayerSelectionFromProtobuf(&inputs_.selection, proto.selection()); - elastic_overscroll_ = ProtoToVector2dF(proto.elastic_overscroll()); - - // It is required to create new PropertyTrees before deserializing it. - property_trees_ = PropertyTrees(); - property_trees_.FromProtobuf(proto.property_trees()); - - // Forcefully override the sequence number of all layers in the tree to have - // a valid sequence number. Changing the sequence number for a layer does not - // need a commit, so the value will become out of date for layers that are not - // updated for other reasons. All layers that at this point are part of the - // layer tree are valid, so it is OK that they have a valid sequence number. - int seq_num = property_trees_.sequence_number; - LayerTreeHostCommon::CallFunctionForEveryLayer(this, [seq_num](Layer* layer) { - layer->set_property_tree_sequence_number(seq_num); - }); } Layer* LayerTree::LayerByElementId(ElementId element_id) const { @@ -583,13 +471,13 @@ void LayerTree::RegisterElement(ElementId element_id, element_layers_map_[layer->element_id()] = layer; } - animation_host_->RegisterElement(element_id, list_type); + mutator_host_->RegisterElement(element_id, list_type); } void LayerTree::UnregisterElement(ElementId element_id, ElementListType list_type, Layer* layer) { - animation_host_->UnregisterElement(element_id, list_type); + mutator_host_->UnregisterElement(element_id, list_type); if (layer->element_id()) { element_layers_map_.erase(layer->element_id()); diff --git a/chromium/cc/trees/layer_tree.h b/chromium/cc/trees/layer_tree.h index 9f749bfe077..e58e71cb1f4 100644 --- a/chromium/cc/trees/layer_tree.h +++ b/chromium/cc/trees/layer_tree.h @@ -30,10 +30,8 @@ namespace cc { namespace proto { class LayerTree; -class LayerUpdate; } // namespace proto -class AnimationHost; class ClientPictureCache; class EnginePictureCache; class HeadsUpDisplayLayer; @@ -41,18 +39,15 @@ class Layer; class LayerTreeHost; class LayerTreeImpl; class LayerTreeSettings; +class MutatorHost; struct PendingPageScaleAnimation; -class UIResourceManager; -class SwapPromiseManager; -class SurfaceSequenceGenerator; class CC_EXPORT LayerTree : public MutatorHostClient { public: using LayerSet = std::unordered_set<Layer*>; using LayerIdMap = std::unordered_map<int, Layer*>; - LayerTree(std::unique_ptr<AnimationHost> animation_host, - LayerTreeHost* layer_tree_host); + LayerTree(MutatorHost* mutator_host, LayerTreeHost* layer_tree_host); virtual ~LayerTree(); void SetRootLayer(scoped_refptr<Layer> root_layer); @@ -76,6 +71,7 @@ class CC_EXPORT LayerTree : public MutatorHostClient { } void RegisterSelection(const LayerSelection& selection); + const LayerSelection& selection() const { return inputs_.selection; } void SetHaveScrollEventHandlers(bool have_event_handlers); bool have_scroll_event_handlers() const { @@ -94,14 +90,16 @@ class CC_EXPORT LayerTree : public MutatorHostClient { return inputs_.device_viewport_size; } - void SetTopControlsHeight(float height, bool shrink); - void SetTopControlsShownRatio(float ratio); + void SetBrowserControlsHeight(float height, bool shrink); + void SetBrowserControlsShownRatio(float ratio); void SetBottomControlsHeight(float height); void SetPageScaleFactorAndLimits(float page_scale_factor, float min_page_scale_factor, float max_page_scale_factor); float page_scale_factor() const { return inputs_.page_scale_factor; } + float min_page_scale_factor() const { return inputs_.min_page_scale_factor; } + float max_page_scale_factor() const { return inputs_.max_page_scale_factor; } void set_background_color(SkColor color) { inputs_.background_color = color; } SkColor background_color() const { return inputs_.background_color; } @@ -109,6 +107,9 @@ class CC_EXPORT LayerTree : public MutatorHostClient { void set_has_transparent_background(bool transparent) { inputs_.has_transparent_background = transparent; } + bool has_transparent_background() const { + return inputs_.has_transparent_background; + } void StartPageScaleAnimation(const gfx::Vector2d& target_offset, bool use_anchor, @@ -120,6 +121,9 @@ class CC_EXPORT LayerTree : public MutatorHostClient { float device_scale_factor() const { return inputs_.device_scale_factor; } void SetPaintedDeviceScaleFactor(float painted_device_scale_factor); + float painted_device_scale_factor() const { + return inputs_.painted_device_scale_factor; + } void SetDeviceColorSpace(const gfx::ColorSpace& device_color_space); const gfx::ColorSpace& device_color_space() const { @@ -181,12 +185,12 @@ class CC_EXPORT LayerTree : public MutatorHostClient { void SetPropertyTreesNeedRebuild(); - void PushPropertiesTo(LayerTreeImpl* tree_impl); + void PushPropertiesTo(LayerTreeImpl* tree_impl, + float unapplied_page_scale_delta); - void ToProtobuf(proto::LayerTree* proto, bool inputs_only); - void FromProtobuf(const proto::LayerTree& proto); + void ToProtobuf(proto::LayerTree* proto); - AnimationHost* animation_host() const { return animation_host_.get(); } + MutatorHost* mutator_host() const { return mutator_host_; } Layer* LayerByElementId(ElementId element_id) const; void RegisterElement(ElementId element_id, @@ -207,8 +211,6 @@ class CC_EXPORT LayerTree : public MutatorHostClient { // --------------------------------------------------------------------- private: - friend class LayerTreeHostSerializationTest; - // MutatorHostClient implementation. bool IsElementInList(ElementId element_id, ElementListType list_type) const override; @@ -251,7 +253,7 @@ class CC_EXPORT LayerTree : public MutatorHostClient { float top_controls_height; float top_controls_shown_ratio; - bool top_controls_shrink_blink_size; + bool browser_controls_shrink_blink_size; float bottom_controls_height; @@ -298,7 +300,7 @@ class CC_EXPORT LayerTree : public MutatorHostClient { bool in_paint_layer_contents_; - std::unique_ptr<AnimationHost> animation_host_; + MutatorHost* mutator_host_; LayerTreeHost* layer_tree_host_; // TODO(khushalsagar): Make these go away once we transition blimp to an diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h index 5f02fefd5dd..3b8ff9decca 100644 --- a/chromium/cc/trees/layer_tree_host.h +++ b/chromium/cc/trees/layer_tree_host.h @@ -9,7 +9,7 @@ #include "base/memory/weak_ptr.h" #include "cc/base/cc_export.h" #include "cc/debug/micro_benchmark.h" -#include "cc/input/top_controls_state.h" +#include "cc/input/browser_controls_state.h" namespace base { class TimeTicks; @@ -143,9 +143,6 @@ class CC_EXPORT LayerTreeHost { // scheduling is disabled. virtual void Composite(base::TimeTicks frame_begin_time) = 0; - // Requests a redraw (compositor frame) for the complete viewport. - virtual void SetNeedsRedraw() = 0; - // Requests a redraw (compositor frame) for the given rect. virtual void SetNeedsRedrawRect(const gfx::Rect& damage_rect) = 0; @@ -161,11 +158,11 @@ class CC_EXPORT LayerTreeHost { // tree so a commit can be performed. virtual void NotifyInputThrottledUntilCommit() = 0; - // Sets the state of the top controls. (Used for URL bar animations on + // Sets the state of the browser controls. (Used for URL bar animations on // android). - virtual void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) = 0; + virtual void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) = 0; // Returns a reference to the InputHandler used to respond to input events on // the compositor thread. diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h index f0a64b8eb16..c0fcb4bef14 100644 --- a/chromium/cc/trees/layer_tree_host_client.h +++ b/chromium/cc/trees/layer_tree_host_client.h @@ -10,13 +10,10 @@ #include "base/memory/ref_counted.h" namespace gfx { -class Vector2d; class Vector2dF; } namespace cc { -class ContextProvider; -class InputHandlerClient; class CompositorFrameSink; struct BeginFrameArgs; @@ -56,7 +53,7 @@ class LayerTreeHostClient { virtual void WillCommit() = 0; virtual void DidCommit() = 0; virtual void DidCommitAndDrawFrame() = 0; - virtual void DidCompleteSwapBuffers() = 0; + virtual void DidReceiveCompositorFrameAck() = 0; virtual void DidCompletePageScaleAnimation() = 0; protected: diff --git a/chromium/cc/trees/layer_tree_host_common.cc b/chromium/cc/trees/layer_tree_host_common.cc index edce74f5928..8fcfccb40fc 100644 --- a/chromium/cc/trees/layer_tree_host_common.cc +++ b/chromium/cc/trees/layer_tree_host_common.cc @@ -15,8 +15,6 @@ #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" #include "cc/layers/layer_iterator.h" -#include "cc/proto/begin_main_frame_and_commit_state.pb.h" -#include "cc/proto/gfx_conversions.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host.h" @@ -84,7 +82,6 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( bool can_adjust_raster_scales, bool verify_clip_tree_calculations, bool verify_visible_rect_calculations, - bool verify_transform_tree_calculations, LayerImplList* render_surface_layer_list, PropertyTrees* property_trees) : root_layer(root_layer), @@ -103,7 +100,6 @@ LayerTreeHostCommon::CalcDrawPropsImplInputs::CalcDrawPropsImplInputs( can_adjust_raster_scales(can_adjust_raster_scales), verify_clip_tree_calculations(verify_clip_tree_calculations), verify_visible_rect_calculations(verify_visible_rect_calculations), - verify_transform_tree_calculations(verify_transform_tree_calculations), render_surface_layer_list(render_surface_layer_list), property_trees(property_trees) {} @@ -128,7 +124,6 @@ LayerTreeHostCommon::CalcDrawPropsImplInputsForTesting:: false, true, true, - true, render_surface_layer_list, GetPropertyTrees(root_layer)) { DCHECK(root_layer); @@ -175,50 +170,27 @@ bool LayerTreeHostCommon::ScrollUpdateInfo::operator==( return layer_id == other.layer_id && scroll_delta == other.scroll_delta; } -void LayerTreeHostCommon::ScrollUpdateInfo::ToProtobuf( - proto::ScrollUpdateInfo* proto) const { - proto->set_layer_id(layer_id); - Vector2dToProto(scroll_delta, proto->mutable_scroll_delta()); -} +LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo() + : layer_id(Layer::INVALID_ID), hidden(true) {} -void LayerTreeHostCommon::ScrollUpdateInfo::FromProtobuf( - const proto::ScrollUpdateInfo& proto) { - layer_id = proto.layer_id(); - scroll_delta = ProtoToVector2d(proto.scroll_delta()); -} +LayerTreeHostCommon::ScrollbarsUpdateInfo::ScrollbarsUpdateInfo(int layer_id, + bool hidden) + : layer_id(layer_id), hidden(hidden) {} -ScrollAndScaleSet::ScrollAndScaleSet() - : page_scale_delta(1.f), top_controls_delta(0.f) { +bool LayerTreeHostCommon::ScrollbarsUpdateInfo::operator==( + const LayerTreeHostCommon::ScrollbarsUpdateInfo& other) const { + return layer_id == other.layer_id && hidden == other.hidden; } -ScrollAndScaleSet::~ScrollAndScaleSet() {} +ReflectedMainFrameState::ReflectedMainFrameState() : page_scale_delta(1.0f) {} -bool ScrollAndScaleSet::EqualsForTesting(const ScrollAndScaleSet& other) const { - return scrolls == other.scrolls && - page_scale_delta == other.page_scale_delta && - elastic_overscroll_delta == other.elastic_overscroll_delta && - top_controls_delta == other.top_controls_delta; -} +ReflectedMainFrameState::~ReflectedMainFrameState() = default; -void ScrollAndScaleSet::ToProtobuf(proto::ScrollAndScaleSet* proto) const { - for (const auto& scroll : scrolls) - scroll.ToProtobuf(proto->add_scrolls()); - proto->set_page_scale_delta(page_scale_delta); - Vector2dFToProto(elastic_overscroll_delta, - proto->mutable_elastic_overscroll_delta()); - proto->set_top_controls_delta(top_controls_delta); +ScrollAndScaleSet::ScrollAndScaleSet() + : page_scale_delta(1.f), top_controls_delta(0.f) { } -void ScrollAndScaleSet::FromProtobuf(const proto::ScrollAndScaleSet& proto) { - DCHECK_EQ(scrolls.size(), 0u); - for (int i = 0; i < proto.scrolls_size(); ++i) { - scrolls.push_back(LayerTreeHostCommon::ScrollUpdateInfo()); - scrolls[i].FromProtobuf(proto.scrolls(i)); - } - page_scale_delta = proto.page_scale_delta(); - elastic_overscroll_delta = ProtoToVector2dF(proto.elastic_overscroll_delta()); - top_controls_delta = proto.top_controls_delta(); -} +ScrollAndScaleSet::~ScrollAndScaleSet() {} static inline void SetMaskLayersAreDrawnRenderSurfaceLayerListMembers( RenderSurfaceImpl* surface, @@ -240,15 +212,8 @@ static inline void ClearMaskLayersAreDrawnRenderSurfaceLayerListMembers( static inline void ClearIsDrawnRenderSurfaceLayerListMember( LayerImplList* layer_list, ScrollTree* scroll_tree) { - for (LayerImpl* layer : *layer_list) { - if (layer->is_drawn_render_surface_layer_list_member()) { - DCHECK_GT( - scroll_tree->Node(layer->scroll_tree_index())->num_drawn_descendants, - 0); - scroll_tree->Node(layer->scroll_tree_index())->num_drawn_descendants--; - } + for (LayerImpl* layer : *layer_list) layer->set_is_drawn_render_surface_layer_list_member(false); - } } static bool CdpPerfTracingEnabled() { @@ -321,33 +286,11 @@ enum PropertyTreeOption { DONT_BUILD_PROPERTY_TREES }; -static void ComputeLayerScrollsDrawnDescendants(LayerTreeImpl* layer_tree_impl, - ScrollTree* scroll_tree) { - for (int i = static_cast<int>(scroll_tree->size()) - 1; i > 0; --i) { - ScrollNode* node = scroll_tree->Node(i); - scroll_tree->parent(node)->num_drawn_descendants += - node->num_drawn_descendants; - } - for (LayerImpl* layer : *layer_tree_impl) { - bool scrolls_drawn_descendant = false; - if (layer->scrollable()) { - ScrollNode* node = scroll_tree->Node(layer->scroll_tree_index()); - if (node->num_drawn_descendants > 0) - scrolls_drawn_descendant = true; - } - layer->set_scrolls_drawn_descendant(scrolls_drawn_descendant); - } -} - static void ComputeInitialRenderSurfaceLayerList( LayerTreeImpl* layer_tree_impl, PropertyTrees* property_trees, LayerImplList* render_surface_layer_list, bool can_render_to_separate_surface) { - ScrollTree* scroll_tree = &property_trees->scroll_tree; - for (int i = 0; i < static_cast<int>(scroll_tree->size()); ++i) - scroll_tree->Node(i)->num_drawn_descendants = 0; - // Add all non-skipped surfaces to the initial render surface layer list. Add // all non-skipped layers to the layer list of their target surface, and // add their content rect to their target surface's accumulated content rect. @@ -359,13 +302,10 @@ static void ComputeInitialRenderSurfaceLayerList( } layer->set_is_drawn_render_surface_layer_list_member(false); - bool layer_is_drawn = - property_trees->effect_tree.Node(layer->effect_tree_index())->is_drawn; bool is_root = layer_tree_impl->IsRootLayer(layer); - bool skip_layer = - !is_root && draw_property_utils::LayerShouldBeSkipped( - layer, layer_is_drawn, property_trees->transform_tree, - property_trees->effect_tree); + bool skip_layer = !is_root && draw_property_utils::LayerShouldBeSkipped( + layer, property_trees->transform_tree, + property_trees->effect_tree); if (skip_layer) continue; @@ -414,13 +354,14 @@ static void ComputeInitialRenderSurfaceLayerList( surface->render_target()->nearest_occlusion_immune_ancestor()); } } + 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->transform_tree); + layer, layer_is_drawn, property_trees); if (!layer_should_be_drawn) continue; layer->set_is_drawn_render_surface_layer_list_member(true); - scroll_tree->Node(layer->scroll_tree_index())->num_drawn_descendants++; layer->render_target()->layer_list().push_back(layer); // The layer contributes its drawable content rect to its render target. @@ -516,9 +457,6 @@ static void CalculateRenderSurfaceLayerList( ComputeListOfNonEmptySurfaces(layer_tree_impl, property_trees, &initial_render_surface_list, render_surface_layer_list); - - ComputeLayerScrollsDrawnDescendants(layer_tree_impl, - &property_trees->scroll_tree); } void CalculateDrawPropertiesInternal( @@ -623,9 +561,6 @@ void CalculateDrawPropertiesInternal( if (inputs->verify_visible_rect_calculations) draw_property_utils::VerifyVisibleRectsCalculations(visible_layer_list, inputs->property_trees); - if (inputs->verify_transform_tree_calculations) - draw_property_utils::VerifyTransformTreeCalculations( - visible_layer_list, inputs->property_trees); if (should_measure_property_tree_performance) { TRACE_EVENT_END0(TRACE_DISABLED_BY_DEFAULT("cc.debug.cdp-perf"), @@ -655,8 +590,7 @@ void LayerTreeHostCommon::CalculateDrawPropertiesForTesting( draw_property_utils::UpdatePropertyTrees(property_trees, can_render_to_separate_surface); draw_property_utils::FindLayersThatNeedUpdates( - inputs->root_layer->GetLayerTree(), property_trees->transform_tree, - property_trees->effect_tree, &update_layer_list); + inputs->root_layer->GetLayerTree(), property_trees, &update_layer_list); } void LayerTreeHostCommon::CalculateDrawProperties( diff --git a/chromium/cc/trees/layer_tree_host_common.h b/chromium/cc/trees/layer_tree_host_common.h index 6945415d429..0b7034c2434 100644 --- a/chromium/cc/trees/layer_tree_host_common.h +++ b/chromium/cc/trees/layer_tree_host_common.h @@ -26,11 +26,6 @@ namespace cc { -namespace proto { -class ScrollUpdateInfo; -class ScrollAndScaleSet; -} - class LayerImpl; class Layer; class SwapPromise; @@ -81,7 +76,6 @@ class CC_EXPORT LayerTreeHostCommon { bool can_adjust_raster_scales, bool verify_clip_tree_calculations, bool verify_visible_rect_calculations, - bool verify_transform_tree_calculations, LayerImplList* render_surface_layer_list, PropertyTrees* property_trees); @@ -100,7 +94,6 @@ class CC_EXPORT LayerTreeHostCommon { bool can_adjust_raster_scales; bool verify_clip_tree_calculations; bool verify_visible_rect_calculations; - bool verify_transform_tree_calculations; LayerImplList* render_surface_layer_list; PropertyTrees* property_trees; }; @@ -144,18 +137,45 @@ class CC_EXPORT LayerTreeHostCommon { struct CC_EXPORT ScrollUpdateInfo { int layer_id; // TODO(miletus): Use ScrollOffset once LayerTreeHost/Blink fully supports - // franctional scroll offset. + // fractional scroll offset. gfx::Vector2d scroll_delta; ScrollUpdateInfo(); bool operator==(const ScrollUpdateInfo& other) const; + }; - void ToProtobuf(proto::ScrollUpdateInfo* proto) const; - void FromProtobuf(const proto::ScrollUpdateInfo& proto); + // 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 { + int layer_id; + bool hidden; + + ScrollbarsUpdateInfo(); + ScrollbarsUpdateInfo(int layer_id, bool hidden); + + bool operator==(const ScrollbarsUpdateInfo& other) const; }; }; +// A container for the state that was reported to the main thread during +// BeginMainFrame, but could not be applied/resolved on the main thread. +struct CC_EXPORT ReflectedMainFrameState { + struct ScrollUpdate { + int layer_id = Layer::LayerIdLabels::INVALID_ID; + gfx::Vector2dF scroll_delta; + }; + + ReflectedMainFrameState(); + ~ReflectedMainFrameState(); + + std::vector<ScrollUpdate> scrolls; + float page_scale_delta; +}; + struct CC_EXPORT ScrollAndScaleSet { ScrollAndScaleSet(); ~ScrollAndScaleSet(); @@ -170,12 +190,9 @@ struct CC_EXPORT ScrollAndScaleSet { float page_scale_delta; gfx::Vector2dF elastic_overscroll_delta; float top_controls_delta; + std::vector<LayerTreeHostCommon::ScrollbarsUpdateInfo> scrollbars; std::vector<std::unique_ptr<SwapPromise>> swap_promises; - bool EqualsForTesting(const ScrollAndScaleSet& other) const; - void ToProtobuf(proto::ScrollAndScaleSet* proto) const; - void FromProtobuf(const proto::ScrollAndScaleSet& proto); - private: DISALLOW_COPY_AND_ASSIGN(ScrollAndScaleSet); }; diff --git a/chromium/cc/trees/layer_tree_host_common_perftest.cc b/chromium/cc/trees/layer_tree_host_common_perftest.cc index a6c0d98baf9..23f7c4fbcb2 100644 --- a/chromium/cc/trees/layer_tree_host_common_perftest.cc +++ b/chromium/cc/trees/layer_tree_host_common_perftest.cc @@ -117,7 +117,6 @@ class CalcDrawPropsTest : public LayerTreeHostCommonPerfTest { host_impl->settings().layer_transforms_should_scale_layer_contents, false, // do not verify_clip_tree_calculation for perf tests false, // do not verify_visible_rect_calculation for perf tests - false, // do not verify_transform_tree_calculation for perf tests &update_list, active_tree->property_trees()); LayerTreeHostCommon::CalculateDrawProperties(&inputs); } diff --git a/chromium/cc/trees/layer_tree_host_common_unittest.cc b/chromium/cc/trees/layer_tree_host_common_unittest.cc index b677cd08b14..8b7a4fcc195 100644 --- a/chromium/cc/trees/layer_tree_host_common_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_common_unittest.cc @@ -28,8 +28,6 @@ #include "cc/layers/texture_layer_impl.h" #include "cc/output/copy_output_request.h" #include "cc/output/copy_output_result.h" -#include "cc/proto/begin_main_frame_and_commit_state.pb.h" -#include "cc/proto/gfx_conversions.h" #include "cc/test/animation_test_common.h" #include "cc/test/fake_compositor_frame_sink.h" #include "cc/test/fake_content_layer_client.h" @@ -62,7 +60,6 @@ namespace { class VerifyTreeCalcsLayerTreeSettings : public LayerTreeSettings { public: VerifyTreeCalcsLayerTreeSettings() { - verify_transform_tree_calculations = true; verify_clip_tree_calculations = true; } }; @@ -102,7 +99,9 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { void ExecuteCalculateDrawProperties(Layer* root_layer, float device_scale_factor, float page_scale_factor, - Layer* page_scale_layer) { + Layer* page_scale_layer, + Layer* inner_viewport_scroll_layer, + Layer* outer_viewport_scroll_layer) { PropertyTreeBuilder::PreCalculateMetaInformation(root_layer); EXPECT_TRUE(page_scale_layer || (page_scale_factor == 1.f)); @@ -118,6 +117,8 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { inputs.device_scale_factor = device_scale_factor; inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = page_scale_layer; + inputs.inner_viewport_scroll_layer = inner_viewport_scroll_layer; + inputs.outer_viewport_scroll_layer = outer_viewport_scroll_layer; LayerTreeHostCommon::CalculateDrawPropertiesForTesting(&inputs); } @@ -126,6 +127,8 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { float device_scale_factor, float page_scale_factor, LayerImpl* page_scale_layer, + LayerImpl* inner_viewport_scroll_layer, + LayerImpl* outer_viewport_scroll_layer, bool skip_verify_visible_rect_calculations = false) { if (device_scale_factor != root_layer->layer_tree_impl()->device_scale_factor()) @@ -150,6 +153,8 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { inputs.device_scale_factor = device_scale_factor; inputs.page_scale_factor = page_scale_factor; inputs.page_scale_layer = page_scale_layer; + inputs.inner_viewport_scroll_layer = inner_viewport_scroll_layer; + inputs.outer_viewport_scroll_layer = outer_viewport_scroll_layer; inputs.can_adjust_raster_scales = true; if (skip_verify_visible_rect_calculations) inputs.verify_visible_rect_calculations = false; @@ -160,16 +165,22 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { template <class LayerType> void ExecuteCalculateDrawProperties(LayerType* root_layer) { LayerType* page_scale_application_layer = nullptr; - ExecuteCalculateDrawProperties(root_layer, 1.f, 1.f, - page_scale_application_layer); + LayerType* inner_viewport_scroll_layer = nullptr; + LayerType* outer_viewport_scroll_layer = nullptr; + ExecuteCalculateDrawProperties( + root_layer, 1.f, 1.f, page_scale_application_layer, + inner_viewport_scroll_layer, outer_viewport_scroll_layer); } template <class LayerType> void ExecuteCalculateDrawProperties(LayerType* root_layer, float device_scale_factor) { LayerType* page_scale_application_layer = nullptr; - ExecuteCalculateDrawProperties(root_layer, device_scale_factor, 1.f, - page_scale_application_layer); + LayerType* inner_viewport_scroll_layer = nullptr; + LayerType* outer_viewport_scroll_layer = nullptr; + ExecuteCalculateDrawProperties( + root_layer, device_scale_factor, 1.f, page_scale_application_layer, + inner_viewport_scroll_layer, outer_viewport_scroll_layer); } const LayerList* GetUpdateLayerList() { return &update_layer_list_; } @@ -206,8 +217,7 @@ class LayerTreeHostCommonTestBase : public LayerTestCommon::LayerImplTest { draw_property_utils::UpdatePropertyTrees(property_trees, can_render_to_separate_surface); draw_property_utils::FindLayersThatNeedUpdates( - root_layer->GetLayerTree(), property_trees->transform_tree, - property_trees->effect_tree, &update_layer_list_); + root_layer->GetLayerTree(), property_trees, &update_layer_list_); } void ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList( @@ -515,10 +525,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { const float kDeviceScale = 1.666f; FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> sublayer_scoped_ptr( LayerImpl::Create(host_impl.active_tree(), 1)); @@ -558,7 +566,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); ExecuteCalculateDrawProperties(root_layer, kDeviceScale, page_scale, - scroll_layer->test_properties()->parent); + scroll_layer->test_properties()->parent, + nullptr, nullptr); gfx::Transform expected_transform; gfx::PointF sub_layer_screen_position = kScrollLayerPosition - kScrollDelta; expected_transform.Translate(MathUtil::Round(sub_layer_screen_position.x() * @@ -579,7 +588,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { scroll_layer->test_properties()->transform = arbitrary_translate; root_layer->layer_tree_impl()->property_trees()->needs_rebuild = true; ExecuteCalculateDrawProperties(root_layer, kDeviceScale, page_scale, - scroll_layer->test_properties()->parent); + scroll_layer->test_properties()->parent, + nullptr, nullptr); expected_transform.MakeIdentity(); expected_transform.Translate( MathUtil::Round(kTranslateX * page_scale * kDeviceScale + @@ -601,7 +611,8 @@ TEST_F(LayerTreeHostCommonTest, TransformsAboutScrollOffset) { root_layer->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale); EXPECT_FALSE(root_layer->layer_tree_impl()->property_trees()->needs_rebuild); ExecuteCalculateDrawProperties(root_layer, kDeviceScale, page_scale, - scroll_layer->test_properties()->parent); + scroll_layer->test_properties()->parent, + nullptr, nullptr); expected_transform.MakeIdentity(); expected_transform.Translate( @@ -1110,12 +1121,15 @@ TEST_F(LayerTreeHostCommonTest, LayerFullyContainedWithinClipInTargetSpace) { float device_scale_factor = 1.f; float page_scale_factor = 1.f; LayerImpl* page_scale_layer = nullptr; + LayerImpl* inner_viewport_scroll_layer = nullptr; + LayerImpl* outer_viewport_scroll_layer = nullptr; // Visible rects computed by combining clips in target space and root space // don't match because of rotation transforms. So, we skip // verify_visible_rect_calculations. bool skip_verify_visible_rect_calculations = true; ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - page_scale_layer, + page_scale_layer, inner_viewport_scroll_layer, + outer_viewport_scroll_layer, skip_verify_visible_rect_calculations); // Mapping grand_child's bounds to target space produces a non-empty rect @@ -1193,6 +1207,8 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceWithSublayerScale) { } TEST_F(LayerTreeHostCommonTest, 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* child = AddChild<LayerImpl>(root); @@ -3453,12 +3469,10 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); @@ -3528,15 +3542,54 @@ TEST_F(LayerTreeHostCommonTest, OcclusionBySiblingOfTarget) { EXPECT_TRUE(expected_occlusion.IsEqual(actual_occlusion)); } +TEST_F(LayerTreeHostCommonTest, TextureLayerSnapping) { + FakeImplTaskRunnerProvider task_runner_provider; + TestTaskGraphRunner task_graph_runner; + std::unique_ptr<CompositorFrameSink> compositor_frame_sink = + FakeCompositorFrameSink::Create3d(); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); + + std::unique_ptr<LayerImpl> root = + LayerImpl::Create(host_impl.active_tree(), 1); + std::unique_ptr<TextureLayerImpl> child = + TextureLayerImpl::Create(host_impl.active_tree(), 2); + + LayerImpl* child_ptr = child.get(); + + root->SetBounds(gfx::Size(100, 100)); + child->SetBounds(gfx::Size(100, 100)); + child->SetDrawsContent(true); + gfx::Transform fractional_translate; + fractional_translate.Translate(10.5f, 20.3f); + child->test_properties()->transform = fractional_translate; + + host_impl.SetViewportSize(root->bounds()); + + root->test_properties()->AddChild(std::move(child)); + host_impl.active_tree()->SetRootLayerForTesting(std::move(root)); + host_impl.SetVisible(true); + host_impl.InitializeRenderer(compositor_frame_sink.get()); + host_impl.active_tree()->BuildLayerListAndPropertyTreesForTesting(); + bool update_lcd_text = false; + host_impl.active_tree()->UpdateDrawProperties(update_lcd_text); + + EXPECT_NE(child_ptr->ScreenSpaceTransform(), fractional_translate); + fractional_translate.RoundTranslationComponents(); + EXPECT_TRANSFORMATION_MATRIX_EQ(child_ptr->ScreenSpaceTransform(), + fractional_translate); + gfx::RectF layer_bounds_in_screen_space = + MathUtil::MapClippedRect(child_ptr->ScreenSpaceTransform(), + gfx::RectF(gfx::SizeF(child_ptr->bounds()))); + EXPECT_EQ(layer_bounds_in_screen_space, gfx::RectF(11.f, 20.f, 100.f, 100.f)); +} + TEST_F(LayerTreeHostCommonTest, OcclusionForLayerWithUninvertibleDrawTransform) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; std::unique_ptr<CompositorFrameSink> compositor_frame_sink = FakeCompositorFrameSink::Create3d(); - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); @@ -4158,13 +4211,11 @@ TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithoutPreserves3d) { EXPECT_FALSE(front_facing_child_of_back_facing_surface->has_render_surface()); EXPECT_FALSE(back_facing_child_of_back_facing_surface->has_render_surface()); - EXPECT_EQ(4u, update_layer_list_impl()->size()); + EXPECT_EQ(3u, update_layer_list_impl()->size()); EXPECT_TRUE(UpdateLayerListImplContains(front_facing_child->id())); EXPECT_TRUE(UpdateLayerListImplContains(front_facing_surface->id())); EXPECT_TRUE(UpdateLayerListImplContains( front_facing_child_of_front_facing_surface->id())); - EXPECT_TRUE(UpdateLayerListImplContains( - front_facing_child_of_back_facing_surface->id())); } TEST_F(LayerTreeHostCommonTest, BackFaceCullingWithPreserves3d) { @@ -4527,7 +4578,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SurfaceLayerTransformsInHighDPI) { root->layer_tree_impl()->BuildLayerListAndPropertyTreesForTesting(); root->layer_tree_impl()->SetPageScaleOnActiveTree(page_scale_factor); ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - root); + root, nullptr, nullptr); EXPECT_FLOAT_EQ(device_scale_factor * page_scale_factor, parent->GetIdealContentsScale()); @@ -4613,7 +4664,7 @@ TEST_F(LayerTreeHostCommonScalingTest, SmallIdealScale) { { ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - root); + root, nullptr, nullptr); // The ideal scale is able to go below 1. float expected_ideal_scale = @@ -4801,10 +4852,9 @@ TEST_F(LayerTreeHostCommonTest, TransparentChildRenderSurfaceCreation) { TEST_F(LayerTreeHostCommonTest, OpacityAnimatingOnPendingTree) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl host_impl(host()->GetSettings(), &task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + &task_graph_runner); host_impl.CreatePendingTree(); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.pending_tree(), 1); @@ -4906,7 +4956,6 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, : LayerTreeHostCommonTestBase(LCDTextTestLayerTreeSettings()), host_impl_(LCDTextTestLayerTreeSettings(), &task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_) {} scoped_refptr<AnimationTimeline> timeline() { return timeline_; } @@ -4965,7 +5014,6 @@ class LCDTextTest : public LayerTreeHostCommonTestBase, bool layers_always_allowed_lcd_text_; FakeImplTaskRunnerProvider task_runner_provider_; - TestSharedBitmapManager shared_bitmap_manager_; TestTaskGraphRunner task_graph_runner_; FakeLayerTreeHostImpl host_impl_; scoped_refptr<AnimationTimeline> timeline_; @@ -4980,7 +5028,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { bool expect_not_lcd_text = layers_always_allowed_lcd_text_; // Case 1: Identity transform. - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -4990,7 +5038,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { integral_translation.Translate(1.0, 2.0); child_->test_properties()->transform = integral_translation; child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -5000,7 +5048,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { non_integral_translation.Translate(1.5, 2.5); child_->test_properties()->transform = non_integral_translation; child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -5010,7 +5058,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { rotation.Rotate(10.0); child_->test_properties()->transform = rotation; child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -5020,7 +5068,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { scale.Scale(2.0, 2.0); child_->test_properties()->transform = scale; child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -5030,7 +5078,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { skew.Skew(10.0, 0.0); child_->test_properties()->transform = skew; child_->layer_tree_impl()->property_trees()->needs_rebuild = true; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -5039,7 +5087,7 @@ TEST_P(LCDTextTest, CanUseLCDText) { child_->test_properties()->transform = gfx::Transform(); child_->layer_tree_impl()->property_trees()->needs_rebuild = true; child_->test_properties()->opacity = 0.5f; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, grand_child_->CanUseLCDText()); @@ -5048,21 +5096,21 @@ TEST_P(LCDTextTest, CanUseLCDText) { child_->test_properties()->transform = gfx::Transform(); child_->layer_tree_impl()->property_trees()->needs_rebuild = true; child_->test_properties()->opacity = 1.f; - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); 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_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); 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_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -5073,7 +5121,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_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -5086,7 +5134,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimation) { AddOpacityTransitionToElementWithPlayer(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); // Text LCD should be adjusted while animation is active. EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_not_lcd_text, child_->CanUseLCDText()); @@ -5098,7 +5146,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_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); EXPECT_EQ(expect_lcd_text, root_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, child_->CanUseLCDText()); EXPECT_EQ(expect_lcd_text, grand_child_->CanUseLCDText()); @@ -5108,7 +5156,7 @@ TEST_P(LCDTextTest, CanUseLCDTextWithAnimationContentsOpaque) { child_->SetContentsOpaque(false); AddOpacityTransitionToElementWithPlayer(child_->element_id(), timeline(), 10.0, 0.9f, 0.1f, false); - ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr); + ExecuteCalculateDrawProperties(root_, 1.f, 1.f, nullptr, nullptr, nullptr); // 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()); @@ -5123,10 +5171,8 @@ INSTANTIATE_TEST_CASE_P(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.CreatePendingTree(); std::unique_ptr<LayerImpl> root = @@ -5167,10 +5213,8 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHidden_SingleLayerImpl) { TEST_F(LayerTreeHostCommonTest, SubtreeHidden_TwoLayersImpl) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.CreatePendingTree(); std::unique_ptr<LayerImpl> root = @@ -5211,10 +5255,8 @@ void EmptyCopyOutputCallback(std::unique_ptr<CopyOutputResult> result) {} TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.CreatePendingTree(); std::unique_ptr<LayerImpl> root = @@ -5357,10 +5399,8 @@ TEST_F(LayerTreeHostCommonTest, SubtreeHiddenWithCopyRequest) { TEST_F(LayerTreeHostCommonTest, ClippedOutCopyRequest) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.CreatePendingTree(); std::unique_ptr<LayerImpl> root = @@ -5867,10 +5907,8 @@ TEST_F(LayerTreeHostCommonTest, TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 12345); @@ -5972,38 +6010,36 @@ TEST_F(LayerTreeHostCommonTest, CanRenderToSeparateSurface) { TEST_F(LayerTreeHostCommonTest, DoNotIncludeBackfaceInvisibleSurfaces) { LayerImpl* root = root_layer_for_testing(); LayerImpl* back_facing = AddChild<LayerImpl>(root); + LayerImpl* render_surface1 = AddChild<LayerImpl>(back_facing); - LayerImpl* render_surface2 = AddChild<LayerImpl>(back_facing); LayerImpl* child1 = AddChild<LayerImpl>(render_surface1); + + LayerImpl* flattener = AddChild<LayerImpl>(back_facing); + LayerImpl* render_surface2 = AddChild<LayerImpl>(flattener); LayerImpl* child2 = AddChild<LayerImpl>(render_surface2); child1->SetDrawsContent(true); child2->SetDrawsContent(true); root->SetBounds(gfx::Size(50, 50)); - root->Set3dSortingContextId(1); - root->test_properties()->should_flatten_transform = false; back_facing->SetBounds(gfx::Size(50, 50)); - back_facing->Set3dSortingContextId(1); back_facing->test_properties()->should_flatten_transform = false; + render_surface1->SetBounds(gfx::Size(30, 30)); - render_surface1->Set3dSortingContextId(1); render_surface1->test_properties()->should_flatten_transform = false; render_surface1->test_properties()->force_render_surface = true; render_surface1->test_properties()->double_sided = false; + child1->SetBounds(gfx::Size(20, 20)); + + flattener->SetBounds(gfx::Size(30, 30)); render_surface2->SetBounds(gfx::Size(30, 30)); - // Different context from the rest. - render_surface2->Set3dSortingContextId(2); render_surface2->test_properties()->should_flatten_transform = false; render_surface2->test_properties()->force_render_surface = true; render_surface2->test_properties()->double_sided = false; - child1->SetBounds(gfx::Size(20, 20)); child2->SetBounds(gfx::Size(20, 20)); ExecuteCalculateDrawProperties(root); - EXPECT_EQ(render_surface1->sorting_context_id(), root->sorting_context_id()); - EXPECT_NE(render_surface2->sorting_context_id(), root->sorting_context_id()); EXPECT_EQ(3u, render_surface_layer_list_impl()->size()); EXPECT_EQ(2u, render_surface_layer_list_impl() ->at(0) @@ -6567,10 +6603,8 @@ TEST_F(LayerTreeHostCommonTest, ScrollCompensationWithRounding) { // + fixed // FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.CreatePendingTree(); std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl.active_tree(), 1); @@ -6809,6 +6843,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTop) { sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(10, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6865,6 +6900,126 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionTop) { sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); } +TEST_F(LayerTreeHostCommonTest, StickyPositionTopScrollParent) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> container = Layer::Create(); + scoped_refptr<Layer> scroller = Layer::Create(); + scoped_refptr<Layer> sticky_pos = Layer::Create(); + root->AddChild(container); + container->AddChild(scroller); + root->AddChild(sticky_pos); + sticky_pos->SetScrollParent(scroller.get()); + host()->SetRootLayer(root); + scroller->SetScrollClipLayerId(container->id()); + + LayerStickyPositionConstraint sticky_position; + sticky_position.is_sticky = true; + sticky_position.is_anchored_top = true; + sticky_position.top_offset = 10.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); + sticky_position.scroll_container_relative_sticky_box_rect = + gfx::Rect(10, 20, 10, 10); + sticky_position.scroll_container_relative_containing_block_rect = + gfx::Rect(0, 0, 50, 50); + sticky_pos->SetStickyPositionConstraint(sticky_position); + + root->SetBounds(gfx::Size(200, 200)); + container->SetBounds(gfx::Size(100, 100)); + container->SetPosition(gfx::PointF(50, 50)); + scroller->SetBounds(gfx::Size(1000, 1000)); + sticky_pos->SetBounds(gfx::Size(10, 10)); + sticky_pos->SetPosition(gfx::PointF(60, 70)); + + ExecuteCalculateDrawProperties(root.get()); + host()->host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + host()->host_impl()->ActivateSyncTree(); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); + LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id()); + LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + + ExecuteCalculateDrawProperties(root_impl); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(60.f, 70.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // 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(5.f, 5.f)); + ExecuteCalculateDrawProperties(root_impl); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(55.f, 65.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); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(45.f, 60.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(15.f, 25.f)); + ExecuteCalculateDrawProperties(root_impl); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(45.f, 60.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // 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); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(45.f, 40.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); +} + +TEST_F(LayerTreeHostCommonTest, StickyPositionSubpixelScroll) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> container = Layer::Create(); + scoped_refptr<Layer> scroller = Layer::Create(); + scoped_refptr<Layer> sticky_pos = Layer::Create(); + root->AddChild(container); + container->AddChild(scroller); + scroller->AddChild(sticky_pos); + host()->SetRootLayer(root); + scroller->SetScrollClipLayerId(container->id()); + + LayerStickyPositionConstraint sticky_position; + sticky_position.is_sticky = true; + sticky_position.is_anchored_bottom = true; + sticky_position.bottom_offset = 10.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 200); + sticky_position.scroll_container_relative_sticky_box_rect = + gfx::Rect(0, 200, 10, 10); + sticky_position.scroll_container_relative_containing_block_rect = + gfx::Rect(0, 0, 100, 500); + sticky_pos->SetStickyPositionConstraint(sticky_position); + + root->SetBounds(gfx::Size(100, 100)); + container->SetBounds(gfx::Size(100, 100)); + scroller->SetBounds(gfx::Size(100, 1000)); + sticky_pos->SetBounds(gfx::Size(10, 10)); + sticky_pos->SetPosition(gfx::PointF(0, 200)); + + ExecuteCalculateDrawProperties(root.get()); + host()->host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + host()->host_impl()->ActivateSyncTree(); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); + LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id()); + LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + + ExecuteCalculateDrawProperties(root_impl); + SetScrollOffsetDelta(scroller_impl, gfx::Vector2dF(0.f, 0.8f)); + ExecuteCalculateDrawProperties(root_impl); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 80.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); +} + TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> container = Layer::Create(); @@ -6880,6 +7035,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { sticky_position.is_sticky = true; sticky_position.is_anchored_bottom = true; sticky_position.bottom_offset = 10.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 150); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 150, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -6934,6 +7090,155 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionBottom) { sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); } +TEST_F(LayerTreeHostCommonTest, StickyPositionBottomInnerViewportDelta) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> scroller = Layer::Create(); + scoped_refptr<Layer> sticky_pos = Layer::Create(); + root->AddChild(scroller); + scroller->AddChild(sticky_pos); + host()->SetRootLayer(root); + scroller->SetScrollClipLayerId(root->id()); + host()->GetLayerTree()->RegisterViewportLayers(nullptr, root, scroller, + nullptr); + + LayerStickyPositionConstraint sticky_position; + sticky_position.is_sticky = true; + sticky_position.is_anchored_bottom = true; + sticky_position.bottom_offset = 10.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 70); + sticky_position.scroll_container_relative_sticky_box_rect = + gfx::Rect(0, 70, 10, 10); + sticky_position.scroll_container_relative_containing_block_rect = + gfx::Rect(0, 60, 100, 100); + sticky_pos->SetStickyPositionConstraint(sticky_position); + + root->SetBounds(gfx::Size(100, 100)); + scroller->SetBounds(gfx::Size(100, 1000)); + sticky_pos->SetBounds(gfx::Size(10, 10)); + sticky_pos->SetPosition(gfx::PointF(0, 70)); + + ExecuteCalculateDrawProperties(root.get(), 1.f, 1.f, root.get(), + scroller.get(), nullptr); + host()->CommitAndCreateLayerImplTree(); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); + ASSERT_EQ(scroller->id(), layer_tree_impl->InnerViewportScrollLayer()->id()); + + LayerImpl* inner_scroll = layer_tree_impl->InnerViewportScrollLayer(); + LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + + // Initially the sticky element is moved to the bottom of the container. + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 70.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // We start to hide the toolbar, but not far enough that the sticky element + // should be moved up yet. + root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -10.f)); + ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, + nullptr); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 70.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // On hiding more of the toolbar the sticky element starts to stick. + root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -20.f)); + ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, + nullptr); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 60.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // On hiding more the sticky element stops moving as it has reached its + // limit. + root_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -30.f)); + ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, + nullptr); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 60.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); +} + +TEST_F(LayerTreeHostCommonTest, StickyPositionBottomOuterViewportDelta) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> scroller = Layer::Create(); + scoped_refptr<Layer> outer_clip = Layer::Create(); + scoped_refptr<Layer> outer_viewport = Layer::Create(); + scoped_refptr<Layer> sticky_pos = Layer::Create(); + root->AddChild(scroller); + scroller->AddChild(outer_clip); + outer_clip->AddChild(outer_viewport); + outer_viewport->AddChild(sticky_pos); + host()->SetRootLayer(root); + scroller->SetScrollClipLayerId(root->id()); + outer_viewport->SetScrollClipLayerId(outer_clip->id()); + host()->GetLayerTree()->RegisterViewportLayers(nullptr, root, scroller, + outer_viewport); + + LayerStickyPositionConstraint sticky_position; + sticky_position.is_sticky = true; + sticky_position.is_anchored_bottom = true; + sticky_position.bottom_offset = 10.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 70); + sticky_position.scroll_container_relative_sticky_box_rect = + gfx::Rect(0, 70, 10, 10); + sticky_position.scroll_container_relative_containing_block_rect = + gfx::Rect(0, 60, 100, 100); + sticky_pos->SetStickyPositionConstraint(sticky_position); + + root->SetBounds(gfx::Size(100, 100)); + scroller->SetBounds(gfx::Size(100, 1000)); + outer_clip->SetBounds(gfx::Size(100, 100)); + sticky_pos->SetBounds(gfx::Size(10, 10)); + sticky_pos->SetPosition(gfx::PointF(0, 70)); + + ExecuteCalculateDrawProperties(root.get(), 1.f, 1.f, root.get(), + scroller.get(), outer_viewport.get()); + host()->CommitAndCreateLayerImplTree(); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); + ASSERT_EQ(outer_viewport->id(), + layer_tree_impl->OuterViewportScrollLayer()->id()); + + LayerImpl* inner_scroll = layer_tree_impl->InnerViewportScrollLayer(); + LayerImpl* outer_scroll = layer_tree_impl->OuterViewportScrollLayer(); + LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + LayerImpl* outer_clip_impl = layer_tree_impl->LayerById(outer_clip->id()); + + // Initially the sticky element is moved to the bottom of the container. + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 70.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // We start to hide the toolbar, but not far enough that the sticky element + // should be moved up yet. + outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -10.f)); + ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, + outer_scroll); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 70.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // On hiding more of the toolbar the sticky element starts to stick. + outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -20.f)); + ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, + outer_scroll); + + // On hiding more the sticky element stops moving as it has reached its + // limit. + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 60.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + outer_clip_impl->SetBoundsDelta(gfx::Vector2dF(0.f, -30.f)); + ExecuteCalculateDrawProperties(root_impl, 1.f, 1.f, root_impl, inner_scroll, + outer_scroll); + + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(0.f, 60.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); +} + TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) { scoped_refptr<Layer> root = Layer::Create(); scoped_refptr<Layer> container = Layer::Create(); @@ -6951,6 +7256,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionLeftRight) { sticky_position.is_anchored_right = true; sticky_position.left_offset = 10.f; sticky_position.right_offset = 10.f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(145, 0); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(145, 0, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -7053,6 +7359,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) { sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 10.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(10, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(10, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -7124,6 +7431,110 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionMainThreadUpdates) { sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); } +// 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(LayerTreeHostCommonTest, StickyPositionCompositedContainer) { + scoped_refptr<Layer> root = Layer::Create(); + scoped_refptr<Layer> container = Layer::Create(); + scoped_refptr<Layer> scroller = Layer::Create(); + scoped_refptr<Layer> sticky_container = Layer::Create(); + scoped_refptr<Layer> sticky_pos = Layer::Create(); + root->AddChild(container); + container->AddChild(scroller); + scroller->AddChild(sticky_container); + sticky_container->AddChild(sticky_pos); + host()->SetRootLayer(root); + scroller->SetScrollClipLayerId(container->id()); + + LayerStickyPositionConstraint sticky_position; + sticky_position.is_sticky = true; + sticky_position.is_anchored_top = true; + sticky_position.top_offset = 10.0f; + // The sticky position layer is only offset by (0, 10) from its parent + // layer, this position is used to determine the offset applied by the main + // thread. + sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 10); + sticky_position.scroll_container_relative_sticky_box_rect = + gfx::Rect(20, 30, 10, 10); + sticky_position.scroll_container_relative_containing_block_rect = + gfx::Rect(20, 20, 30, 30); + sticky_pos->SetStickyPositionConstraint(sticky_position); + + root->SetBounds(gfx::Size(100, 100)); + container->SetBounds(gfx::Size(100, 100)); + scroller->SetBounds(gfx::Size(1000, 1000)); + sticky_container->SetPosition(gfx::PointF(20, 20)); + sticky_container->SetBounds(gfx::Size(30, 30)); + sticky_pos->SetBounds(gfx::Size(10, 10)); + sticky_pos->SetPosition(gfx::PointF(0, 10)); + + ExecuteCalculateDrawProperties(root.get()); + host()->host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + host()->host_impl()->ActivateSyncTree(); + LayerTreeImpl* layer_tree_impl = host()->host_impl()->active_tree(); + + LayerImpl* root_impl = layer_tree_impl->LayerById(root->id()); + LayerImpl* scroller_impl = layer_tree_impl->LayerById(scroller->id()); + LayerImpl* sticky_pos_impl = layer_tree_impl->LayerById(sticky_pos->id()); + + ExecuteCalculateDrawProperties(root_impl); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(20.f, 30.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // 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); + 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); + EXPECT_VECTOR2DF_EQ( + gfx::Vector2dF(20.f, 10.f), + sticky_pos_impl->ScreenSpaceTransform().To2dTranslation()); + + // Now the main thread commits the new position of the sticky element. + scroller->SetScrollOffset(gfx::ScrollOffset(0, 25)); + sticky_pos->SetPosition(gfx::PointF(0, 15)); + ExecuteCalculateDrawProperties(root.get()); + host()->host_impl()->CreatePendingTree(); + host()->CommitAndCreatePendingTree(); + host()->host_impl()->ActivateSyncTree(); + layer_tree_impl = host()->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()); + + // The element should still be where it was before. We reset the delta to + // (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); + 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); + 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); + 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(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) { scoped_refptr<Layer> root = Layer::Create(); @@ -7143,6 +7554,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledStickyBox) { sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 0.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -7221,6 +7633,7 @@ TEST_F(LayerTreeHostCommonTest, StickyPositionScaledContainer) { sticky_position.is_sticky = true; sticky_position.is_anchored_top = true; sticky_position.top_offset = 0.0f; + sticky_position.parent_relative_sticky_box_offset = gfx::Point(0, 20); sticky_position.scroll_container_relative_sticky_box_rect = gfx::Rect(0, 20, 10, 10); sticky_position.scroll_container_relative_containing_block_rect = @@ -7390,12 +7803,11 @@ class AnimationScaleFactorTrackingLayerImpl : public LayerImpl { TEST_F(LayerTreeHostCommonTest, MaximumAnimationScaleFactor) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings = host()->GetSettings(); settings.layer_transforms_should_scale_layer_contents = true; FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + &task_graph_runner); std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> grand_parent = AnimationScaleFactorTrackingLayerImpl::Create(host_impl.active_tree(), 1); std::unique_ptr<AnimationScaleFactorTrackingLayerImpl> parent = @@ -7648,10 +8060,8 @@ static void GatherDrawnLayers(const LayerImplList* rsll, TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> grand_parent = LayerImpl::Create(host_impl.active_tree(), 1); @@ -7874,12 +8284,11 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceLayerListMembership) { TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings = host()->GetSettings(); settings.layer_transforms_should_scale_layer_contents = true; FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + &task_graph_runner); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); @@ -7989,12 +8398,11 @@ TEST_F(LayerTreeHostCommonTest, DrawPropertyScales) { TEST_F(LayerTreeHostCommonTest, AnimationScales) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings = host()->GetSettings(); settings.layer_transforms_should_scale_layer_contents = true; FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + &task_graph_runner); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); @@ -8068,12 +8476,11 @@ TEST_F(LayerTreeHostCommonTest, // Returns empty scale if layer_transforms_should_scale_layer_contents is // false. FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings = host()->GetSettings(); settings.layer_transforms_should_scale_layer_contents = false; FakeLayerTreeHostImpl host_impl(settings, &task_runner_provider, - &shared_bitmap_manager, &task_graph_runner); + &task_graph_runner); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); @@ -8148,10 +8555,8 @@ TEST_F(LayerTreeHostCommonTest, VisibleContentRectInChildRenderSurface) { TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); // Set two layers: the root layer clips it's child, // the child draws its content. @@ -8161,7 +8566,7 @@ TEST_F(LayerTreeHostCommonTest, BoundsDeltaAffectVisibleContentRect) { // Sublayer should be bigger than the root enlarged by bounds_delta. gfx::Size sublayer_size = gfx::Size(300, 1000); - // Device viewport accomidated the root and the top controls. + // Device viewport accomidated the root and the browser controls. gfx::Size device_viewport_size = gfx::Size(300, 600); host_impl.SetViewportSize(device_viewport_size); @@ -8779,10 +9184,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingSubtreeMain) { TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); std::unique_ptr<LayerImpl> root = LayerImpl::Create(host_impl.active_tree(), 1); @@ -8906,8 +9309,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { std::unique_ptr<Animation> transform_animation( Animation::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM)); scoped_refptr<AnimationPlayer> player(AnimationPlayer::Create(1)); - host_impl.active_tree()->animation_host()->RegisterPlayerForElement( - root_ptr->element_id(), player.get()); + host_impl.animation_host()->RegisterPlayerForElement(root_ptr->element_id(), + player.get()); player->AddAnimation(std::move(transform_animation)); grandchild_ptr->set_visible_layer_rect(gfx::Rect()); child_ptr->SetScrollClipLayer(root_ptr->id()); @@ -8917,8 +9320,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingLayerImpl) { ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); EXPECT_EQ(gfx::Rect(0, 0), grandchild_ptr->visible_layer_rect()); - host_impl.active_tree()->animation_host()->UnregisterPlayerForElement( - root_ptr->element_id(), player.get()); + host_impl.animation_host()->UnregisterPlayerForElement(root_ptr->element_id(), + player.get()); } TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { @@ -8954,7 +9357,7 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { std::unique_ptr<Animation> transform_animation( Animation::Create(std::move(curve), 3, 3, TargetProperty::TRANSFORM)); scoped_refptr<AnimationPlayer> player(AnimationPlayer::Create(1)); - host_impl()->active_tree()->animation_host()->RegisterPlayerForElement( + host_impl()->animation_host()->RegisterPlayerForElement( grand_child->element_id(), player.get()); player->AddAnimation(std::move(transform_animation)); @@ -8962,16 +9365,14 @@ TEST_F(LayerTreeHostCommonTest, LayerSkippingInSubtreeOfSingularTransform) { EXPECT_EQ(gfx::Rect(0, 0), grand_child->visible_layer_rect()); EXPECT_EQ(gfx::Rect(0, 0), child->visible_layer_rect()); - host_impl()->active_tree()->animation_host()->UnregisterPlayerForElement( + host_impl()->animation_host()->UnregisterPlayerForElement( grand_child->element_id(), player.get()); } TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { FakeImplTaskRunnerProvider task_runner_provider; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; - FakeLayerTreeHostImpl host_impl(&task_runner_provider, &shared_bitmap_manager, - &task_graph_runner); + FakeLayerTreeHostImpl host_impl(&task_runner_provider, &task_graph_runner); host_impl.CreatePendingTree(); std::unique_ptr<LayerImpl> root = @@ -9016,8 +9417,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { std::unique_ptr<Animation> animation( Animation::Create(std::move(curve), 3, 3, TargetProperty::OPACITY)); scoped_refptr<AnimationPlayer> player(AnimationPlayer::Create(1)); - host_impl.active_tree()->animation_host()->RegisterPlayerForElement( - root_ptr->element_id(), player.get()); + host_impl.animation_host()->RegisterPlayerForElement(root_ptr->element_id(), + player.get()); player->AddAnimation(std::move(animation)); root_ptr->test_properties()->opacity = 0.f; grandchild_ptr->set_visible_layer_rect(gfx::Rect()); @@ -9025,8 +9426,8 @@ TEST_F(LayerTreeHostCommonTest, SkippingPendingLayerImpl) { ExecuteCalculateDrawPropertiesAndSaveUpdateLayerList(root_ptr); EXPECT_EQ(gfx::Rect(10, 10), grandchild_ptr->visible_layer_rect()); - host_impl.active_tree()->animation_host()->UnregisterPlayerForElement( - root_ptr->element_id(), player.get()); + host_impl.animation_host()->UnregisterPlayerForElement(root_ptr->element_id(), + player.get()); } TEST_F(LayerTreeHostCommonTest, SkippingLayer) { @@ -9153,12 +9554,15 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { float device_scale_factor = 1.f; float page_scale_factor = 1.f; LayerImpl* page_scale_layer = nullptr; + LayerImpl* inner_viewport_scroll_layer = nullptr; + LayerImpl* outer_viewport_scroll_layer = nullptr; // Visible rects computed by combining clips in target space and root space // don't match because of rotation transforms. So, we skip // verify_visible_rect_calculations. bool skip_verify_visible_rect_calculations = true; ExecuteCalculateDrawProperties(root, device_scale_factor, page_scale_factor, - page_scale_layer, + page_scale_layer, inner_viewport_scroll_layer, + outer_viewport_scroll_layer, skip_verify_visible_rect_calculations); TransformTree& transform_tree = @@ -9175,7 +9579,7 @@ TEST_F(LayerTreeHostCommonTest, RenderSurfaceClipsSubtree) { ClipTree& clip_tree = root->layer_tree_impl()->property_trees()->clip_tree; ClipNode* clip_node = clip_tree.Node(render_surface->clip_tree_index()); - EXPECT_FALSE(clip_node->applies_local_clip); + EXPECT_EQ(clip_node->clip_type, ClipNode::ClipType::NONE); EXPECT_EQ(gfx::Rect(20, 20), test_layer->visible_layer_rect()); // Also test the visible rects computed by combining clips in root space. @@ -9688,22 +10092,21 @@ TEST_F(LayerTreeHostCommonTest, test_layer->SetBounds(gfx::Size(30, 30)); test_layer->SetDrawsContent(true); - // We want layer between the two targets to create a clip node and transform + // 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); - between_targets->Set3dSortingContextId(2); + between_targets->test_properties()->opacity = 0.5f; ExecuteCalculateDrawProperties(root); - TransformTree& tree = - root->layer_tree_impl()->property_trees()->transform_tree; - TransformNode* node = tree.Node(render_surface1->transform_tree_index()); + EffectTree& tree = root->layer_tree_impl()->property_trees()->effect_tree; + EffectNode* node = tree.Node(render_surface1->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); - node = tree.Node(between_targets->transform_tree_index()); + node = tree.Node(between_targets->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f)); - node = tree.Node(render_surface2->transform_tree_index()); + node = tree.Node(render_surface2->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); EXPECT_EQ(gfx::Rect(15, 15), test_layer->visible_layer_rect()); @@ -9943,43 +10346,6 @@ TEST_F(LayerTreeHostCommonTest, TransformAnimationsTrackingTest) { EXPECT_FALSE(node->has_potential_animation); } -TEST_F(LayerTreeHostCommonTest, SerializeScrollUpdateInfo) { - LayerTreeHostCommon::ScrollUpdateInfo scroll; - scroll.layer_id = 2; - scroll.scroll_delta = gfx::Vector2d(5, 10); - - proto::ScrollUpdateInfo proto; - scroll.ToProtobuf(&proto); - LayerTreeHostCommon::ScrollUpdateInfo new_scroll; - new_scroll.FromProtobuf(proto); - - EXPECT_EQ(scroll, new_scroll); -} - -TEST_F(LayerTreeHostCommonTest, SerializeScrollAndScale) { - ScrollAndScaleSet scroll_and_scale_set; - - LayerTreeHostCommon::ScrollUpdateInfo scroll1; - scroll1.layer_id = 1; - scroll1.scroll_delta = gfx::Vector2d(5, 10); - LayerTreeHostCommon::ScrollUpdateInfo scroll2; - scroll2.layer_id = 2; - scroll2.scroll_delta = gfx::Vector2d(1, 5); - scroll_and_scale_set.scrolls.push_back(scroll1); - scroll_and_scale_set.scrolls.push_back(scroll2); - - scroll_and_scale_set.page_scale_delta = 0.3f; - scroll_and_scale_set.elastic_overscroll_delta = gfx::Vector2dF(0.5f, 0.6f); - scroll_and_scale_set.top_controls_delta = 0.9f; - - proto::ScrollAndScaleSet proto; - scroll_and_scale_set.ToProtobuf(&proto); - ScrollAndScaleSet new_scroll_and_scale_set; - new_scroll_and_scale_set.FromProtobuf(proto); - - EXPECT_TRUE(scroll_and_scale_set.EqualsForTesting(new_scroll_and_scale_set)); -} - TEST_F(LayerTreeHostCommonTest, ScrollTreeBuilderTest) { // Test the behavior of scroll tree builder // Topology: diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc index dbd9e0fb214..c986b160798 100644 --- a/chromium/cc/trees/layer_tree_host_impl.cc +++ b/chromium/cc/trees/layer_tree_host_impl.cc @@ -24,8 +24,6 @@ #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "base/trace_event/trace_event_argument.h" -#include "cc/animation/animation_events.h" -#include "cc/animation/animation_host.h" #include "cc/base/histograms.h" #include "cc/base/math_util.h" #include "cc/debug/benchmark_instrumentation.h" @@ -35,12 +33,12 @@ #include "cc/debug/frame_viewer_instrumentation.h" #include "cc/debug/rendering_stats_instrumentation.h" #include "cc/debug/traced_value.h" +#include "cc/input/browser_controls_offset_manager.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/input/page_scale_animation.h" #include "cc/input/scroll_elasticity_helper.h" #include "cc/input/scroll_state.h" #include "cc/input/scrollbar_animation_controller.h" -#include "cc/input/top_controls_manager.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer_impl.h" @@ -73,12 +71,12 @@ #include "cc/tiles/picture_layer_tiling.h" #include "cc/tiles/raster_tile_priority_queue.h" #include "cc/tiles/software_image_decode_controller.h" -#include "cc/tiles/tile_task_manager.h" #include "cc/trees/damage_tracker.h" #include "cc/trees/draw_property_utils.h" #include "cc/trees/latency_info_swap_promise_monitor.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/scroll_node.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/tree_synchronizer.h" @@ -173,15 +171,12 @@ std::unique_ptr<LayerTreeHostImpl> LayerTreeHostImpl::Create( LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* shared_bitmap_manager, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, TaskGraphRunner* task_graph_runner, - std::unique_ptr<AnimationHost> animation_host, + std::unique_ptr<MutatorHost> mutator_host, int id) { return base::WrapUnique(new LayerTreeHostImpl( settings, client, task_runner_provider, rendering_stats_instrumentation, - shared_bitmap_manager, gpu_memory_buffer_manager, task_graph_runner, - std::move(animation_host), id)); + task_graph_runner, std::move(mutator_host), id)); } LayerTreeHostImpl::LayerTreeHostImpl( @@ -189,10 +184,8 @@ LayerTreeHostImpl::LayerTreeHostImpl( LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* shared_bitmap_manager, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, TaskGraphRunner* task_graph_runner, - std::unique_ptr<AnimationHost> animation_host, + std::unique_ptr<MutatorHost> mutator_host, int id) : client_(client), task_runner_provider_(task_runner_provider), @@ -208,8 +201,7 @@ LayerTreeHostImpl::LayerTreeHostImpl( did_lock_scrolling_layer_(false), wheel_scrolling_(false), scroll_affects_scroll_handler_(false), - scroll_layer_id_when_mouse_over_scrollbar_(Layer::INVALID_ID), - captured_scrollbar_layer_id_(Layer::INVALID_ID), + scroll_layer_id_mouse_currently_over_(Layer::INVALID_ID), tile_priorities_dirty_(false), settings_(settings), visible_(false), @@ -232,19 +224,17 @@ LayerTreeHostImpl::LayerTreeHostImpl( debug_rect_history_(DebugRectHistory::Create()), max_memory_needed_bytes_(0), resourceless_software_draw_(false), - animation_host_(std::move(animation_host)), + mutator_host_(std::move(mutator_host)), rendering_stats_instrumentation_(rendering_stats_instrumentation), micro_benchmark_controller_(this), - shared_bitmap_manager_(shared_bitmap_manager), - gpu_memory_buffer_manager_(gpu_memory_buffer_manager), task_graph_runner_(task_graph_runner), id_(id), requires_high_res_to_draw_(false), is_likely_to_require_a_draw_(false), has_valid_compositor_frame_sink_(false), mutator_(nullptr) { - DCHECK(animation_host_); - animation_host_->SetMutatorHostClient(this); + DCHECK(mutator_host_); + mutator_host_->SetMutatorHostClient(this); DCHECK(task_runner_provider_->IsImplThread()); DidVisibilityChange(this, visible_); @@ -253,7 +243,7 @@ LayerTreeHostImpl::LayerTreeHostImpl( // LTHI always has an active tree. active_tree_ = base::MakeUnique<LayerTreeImpl>( - this, new SyncedProperty<ScaleGroup>, new SyncedTopControls, + this, new SyncedProperty<ScaleGroup>, new SyncedBrowserControls, new SyncedElasticOverscroll); active_tree_->property_trees()->is_active = true; @@ -262,9 +252,9 @@ LayerTreeHostImpl::LayerTreeHostImpl( TRACE_EVENT_OBJECT_CREATED_WITH_ID(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "cc::LayerTreeHostImpl", id_); - top_controls_manager_ = - TopControlsManager::Create(this, settings.top_controls_show_threshold, - settings.top_controls_hide_threshold); + browser_controls_offset_manager_ = BrowserControlsOffsetManager::Create( + this, settings.top_controls_show_threshold, + settings.top_controls_hide_threshold); } LayerTreeHostImpl::~LayerTreeHostImpl() { @@ -278,7 +268,6 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { DCHECK(!resource_provider_); DCHECK(!resource_pool_); - DCHECK(!tile_task_manager_); DCHECK(!single_thread_synchronous_task_graph_runner_); DCHECK(!image_decode_controller_); @@ -289,9 +278,7 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { if (scroll_elasticity_helper_) scroll_elasticity_helper_.reset(); - // The layer trees must be destroyed before the layer tree host. We've - // made a contract with our animation controllers that the animation_host - // will outlive them, and we must make good. + // The layer trees must be destroyed before the layer tree host. if (recycle_tree_) recycle_tree_->Shutdown(); if (pending_tree_) @@ -301,8 +288,8 @@ LayerTreeHostImpl::~LayerTreeHostImpl() { pending_tree_ = nullptr; active_tree_ = nullptr; - animation_host_->ClearTimelines(); - animation_host_->SetMutatorHostClient(nullptr); + mutator_host_->ClearMutators(); + mutator_host_->SetMutatorHostClient(nullptr); } void LayerTreeHostImpl::BeginMainFrameAborted( @@ -465,7 +452,7 @@ void LayerTreeHostImpl::AnimateInternal(bool active_tree) { did_animate |= AnimatePageScale(monotonic_time); did_animate |= AnimateLayers(monotonic_time); did_animate |= AnimateScrollbars(monotonic_time); - did_animate |= AnimateTopControls(monotonic_time); + did_animate |= AnimateBrowserControls(monotonic_time); if (active_tree) { did_animate |= Mutate(monotonic_time); @@ -1035,7 +1022,7 @@ DrawResult LayerTreeHostImpl::CalculateRenderPasses(FrameData* frame) { } void LayerTreeHostImpl::MainThreadHasStoppedFlinging() { - top_controls_manager_->MainThreadHasStoppedFlinging(); + browser_controls_offset_manager_->MainThreadHasStoppedFlinging(); if (input_handler_client_) input_handler_client_->MainThreadHasStoppedFlinging(); } @@ -1235,10 +1222,10 @@ void LayerTreeHostImpl::UpdateTileManagerMemoryPolicy( if (global_tile_state_.hard_memory_limit_in_bytes > 0) { // If |global_tile_state_.hard_memory_limit_in_bytes| is greater than 0, we - // are visible. Notify the worker context here. We handle becoming - // invisible in NotifyAllTileTasksComplete to avoid interrupting running - // work. - SetWorkerContextVisibility(true); + // consider our contexts visible. Notify the contexts here. We handle + // becoming invisible in NotifyAllTileTasksComplete to avoid interrupting + // running work. + SetContextVisibility(true); // If |global_tile_state_.hard_memory_limit_in_bytes| is greater than 0, we // allow the image decode controller to retain resources. We handle the @@ -1268,7 +1255,7 @@ void LayerTreeHostImpl::DidModifyTilePriorities() { std::unique_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue( TreePriority tree_priority, RasterTilePriorityQueue::Type type) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "LayerTreeHostImpl::BuildRasterQueue"); return RasterTilePriorityQueue::Create(active_tree_->picture_layers(), @@ -1280,7 +1267,7 @@ std::unique_ptr<RasterTilePriorityQueue> LayerTreeHostImpl::BuildRasterQueue( std::unique_ptr<EvictionTilePriorityQueue> LayerTreeHostImpl::BuildEvictionQueue(TreePriority tree_priority) { - TRACE_EVENT0("disabled-by-default-cc.debug", + TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"), "LayerTreeHostImpl::BuildEvictionQueue"); std::unique_ptr<EvictionTilePriorityQueue> queue( @@ -1324,13 +1311,13 @@ void LayerTreeHostImpl::NotifyAllTileTasksCompleted() { // The tile tasks started by the most recent call to PrepareTiles have // completed. Now is a good time to free resources if necessary. if (global_tile_state_.hard_memory_limit_in_bytes == 0) { - // Free image decode controller resources before notifying the worker - // context of visibility change. This ensures that the imaged decode + // Free image decode controller resources before notifying the + // contexts of visibility change. This ensures that the imaged decode // controller has released all Skia refs at the time Skia's cleanup // executes (within worker context's cleanup). if (image_decode_controller_) image_decode_controller_->SetShouldAggressivelyFreeResources(true); - SetWorkerContextVisibility(false); + SetContextVisibility(false); } } @@ -1449,8 +1436,8 @@ void LayerTreeHostImpl::SetExternalTilePriorityConstraints( } } -void LayerTreeHostImpl::DidSwapBuffersComplete() { - client_->DidSwapBuffersCompleteOnImplThread(); +void LayerTreeHostImpl::DidReceiveCompositorFrameAck() { + client_->DidReceiveCompositorFrameAckOnImplThread(); } void LayerTreeHostImpl::ReclaimResources( @@ -1542,13 +1529,14 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { metadata.root_layer_size = active_tree_->ScrollableSize(); metadata.min_page_scale_factor = active_tree_->min_page_scale_factor(); metadata.max_page_scale_factor = active_tree_->max_page_scale_factor(); - metadata.top_controls_height = top_controls_manager_->TopControlsHeight(); + metadata.top_controls_height = + browser_controls_offset_manager_->TopControlsHeight(); metadata.top_controls_shown_ratio = - top_controls_manager_->TopControlsShownRatio(); + browser_controls_offset_manager_->TopControlsShownRatio(); metadata.bottom_controls_height = - top_controls_manager_->BottomControlsHeight(); + browser_controls_offset_manager_->BottomControlsHeight(); metadata.bottom_controls_shown_ratio = - top_controls_manager_->BottomControlsShownRatio(); + browser_controls_offset_manager_->BottomControlsShownRatio(); metadata.root_background_color = active_tree_->background_color(); active_tree_->GetViewportSelection(&metadata.selection); @@ -1562,7 +1550,7 @@ CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() const { if (GetDrawMode() == DRAW_MODE_RESOURCELESS_SOFTWARE) { metadata.is_resourceless_software_draw_with_scroll_or_animation = - IsActivelyScrolling() || animation_host_->NeedsAnimateLayers(); + IsActivelyScrolling() || mutator_host_->NeedsAnimateLayers(); } for (LayerImpl* surface_layer : active_tree_->SurfaceLayers()) { @@ -1588,7 +1576,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { DCHECK(CanDraw()); DCHECK_EQ(frame->has_no_damage, frame->render_passes.empty()); - TRACE_EVENT0("cc", "LayerTreeHostImpl::DrawLayers"); + TRACE_EVENT0("cc,benchmark", "LayerTreeHostImpl::DrawLayers"); ResetRequiresHighResToDraw(); @@ -1674,7 +1662,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) { CompositorFrame compositor_frame; compositor_frame.metadata = std::move(metadata); compositor_frame.delegated_frame_data = std::move(data); - compositor_frame_sink_->SwapBuffers(std::move(compositor_frame)); + compositor_frame_sink_->SubmitCompositorFrame(std::move(compositor_frame)); // The next frame should start by assuming nothing has changed, and changes // are noted as they occur. @@ -1861,20 +1849,22 @@ void LayerTreeHostImpl::UpdateViewportContainerSizes() { ViewportAnchor anchor(InnerViewportScrollLayer(), OuterViewportScrollLayer()); float top_controls_layout_height = - active_tree_->top_controls_shrink_blink_size() + active_tree_->browser_controls_shrink_blink_size() ? active_tree_->top_controls_height() : 0.f; float delta_from_top_controls = - top_controls_layout_height - top_controls_manager_->ContentTopOffset(); + top_controls_layout_height - + browser_controls_offset_manager_->ContentTopOffset(); float bottom_controls_layout_height = - active_tree_->top_controls_shrink_blink_size() + active_tree_->browser_controls_shrink_blink_size() ? active_tree_->bottom_controls_height() : 0.f; - delta_from_top_controls += bottom_controls_layout_height - - top_controls_manager_->ContentBottomOffset(); + delta_from_top_controls += + bottom_controls_layout_height - + browser_controls_offset_manager_->ContentBottomOffset(); // Adjust the viewport layers by shrinking/expanding the container to account - // for changes in the size (e.g. top controls) since the last resize from + // for changes in the size (e.g. browser controls) since the last resize from // Blink. gfx::Vector2dF amount_to_expand(0.f, delta_from_top_controls); inner_container->SetBoundsDelta(amount_to_expand); @@ -2051,9 +2041,6 @@ void LayerTreeHostImpl::SetVisible(bool visible) { // Call PrepareTiles to evict tiles when we become invisible. PrepareTiles(); } - - // Update visibility for the compositor context provider. - SetCompositorContextVisibility(visible); } void LayerTreeHostImpl::SetNeedsOneBeginImplFrame() { @@ -2132,12 +2119,10 @@ void LayerTreeHostImpl::CreateTileManagerResources() { task_graph_runner = single_thread_synchronous_task_graph_runner_.get(); } - tile_task_manager_ = TileTaskManagerImpl::Create(task_graph_runner); - // TODO(vmpstr): Initialize tile task limit at ctor time. tile_manager_.SetResources( - resource_pool_.get(), image_decode_controller_.get(), - tile_task_manager_.get(), raster_buffer_provider_.get(), + resource_pool_.get(), image_decode_controller_.get(), task_graph_runner, + raster_buffer_provider_.get(), is_synchronous_single_threaded_ ? std::numeric_limits<size_t>::max() : settings_.scheduled_raster_task_limit, use_gpu_rasterization_); @@ -2229,11 +2214,18 @@ void LayerTreeHostImpl::SetLayerTreeMutator( mutator_->SetClient(this); } +LayerImpl* LayerTreeHostImpl::ViewportMainScrollLayer() { + return viewport()->MainScrollLayer(); +} + +void LayerTreeHostImpl::DidChangeScrollbarVisibility() { + client_->SetNeedsCommitOnImplThread(); +} + void LayerTreeHostImpl::CleanUpTileManagerAndUIResources() { ClearUIResources(); tile_manager_.FinishTasksAndCleanUp(); resource_pool_ = nullptr; - tile_task_manager_ = nullptr; single_thread_synchronous_task_graph_runner_ = nullptr; image_decode_controller_ = nullptr; @@ -2271,13 +2263,7 @@ void LayerTreeHostImpl::ReleaseCompositorFrameSink() { resource_provider_ = nullptr; // Release any context visibility before we destroy the CompositorFrameSink. - if (visible_) - SetCompositorContextVisibility(false); - // Worker context visibility is based on both LTHI visibility as well as - // memory policy, so we directly check |worker_context_visibility_| here, - // rather than just relying on |visibility_|. - if (worker_context_visibility_) - SetWorkerContextVisibility(false); + SetContextVisibility(false); // Detach from the old CompositorFrameSink and reset |compositor_frame_sink_| // pointer as this surface is going to be destroyed independent of if binding @@ -2312,21 +2298,17 @@ bool LayerTreeHostImpl::InitializeRenderer( compositor_frame_sink_ = compositor_frame_sink; has_valid_compositor_frame_sink_ = true; resource_provider_ = base::MakeUnique<ResourceProvider>( - compositor_frame_sink_->context_provider(), shared_bitmap_manager_, - gpu_memory_buffer_manager_, + compositor_frame_sink_->context_provider(), + compositor_frame_sink_->shared_bitmap_manager(), + compositor_frame_sink_->gpu_memory_buffer_manager(), task_runner_provider_->blocking_main_thread_task_runner(), settings_.renderer_settings.highp_threshold_min, settings_.renderer_settings.texture_id_allocation_chunk_size, compositor_frame_sink_->capabilities().delegated_sync_points_required, - settings_.renderer_settings.use_gpu_memory_buffer_resources, false, + settings_.renderer_settings.use_gpu_memory_buffer_resources, + settings_.enable_color_correct_rendering, settings_.renderer_settings.buffer_to_texture_target_map); - // Make sure the main context visibility is restored. Worker context - // visibility will be set via the memory policy update in - // CreateTileManagerResources below. - if (visible_) - SetCompositorContextVisibility(true); - // Since the new context may be capable of MSAA, update status here. We don't // need to check the return value since we are recreating all resources // already. @@ -2399,7 +2381,7 @@ const gfx::Transform& LayerTreeHostImpl::DrawTransform() const { return external_transform_; } -void LayerTreeHostImpl::DidChangeTopControlsPosition() { +void LayerTreeHostImpl::DidChangeBrowserControlsPosition() { UpdateViewportContainerSizes(); SetNeedsRedraw(); SetNeedsOneBeginImplFrame(); @@ -2415,13 +2397,13 @@ float LayerTreeHostImpl::BottomControlsHeight() const { return active_tree_->bottom_controls_height(); } -void LayerTreeHostImpl::SetCurrentTopControlsShownRatio(float ratio) { - if (active_tree_->SetCurrentTopControlsShownRatio(ratio)) - DidChangeTopControlsPosition(); +void LayerTreeHostImpl::SetCurrentBrowserControlsShownRatio(float ratio) { + if (active_tree_->SetCurrentBrowserControlsShownRatio(ratio)) + DidChangeBrowserControlsPosition(); } -float LayerTreeHostImpl::CurrentTopControlsShownRatio() const { - return active_tree_->CurrentTopControlsShownRatio(); +float LayerTreeHostImpl::CurrentBrowserControlsShownRatio() const { + return active_tree_->CurrentBrowserControlsShownRatio(); } void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) { @@ -2616,7 +2598,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl( scroll_status.thread = SCROLL_ON_IMPL_THREAD; ScrollAnimationAbort(scrolling_layer_impl); - top_controls_manager_->ScrollBegin(); + browser_controls_offset_manager_->ScrollBegin(); active_tree_->SetCurrentlyScrollingLayer(scrolling_layer_impl); // TODO(majidvp): get rid of wheel_scrolling_ and set is_direct_manipulation @@ -2782,7 +2764,7 @@ bool LayerTreeHostImpl::ScrollAnimationCreate(ScrollNode* scroll_node, ElementId(active_tree()->LayerById(scroll_node->owner_id)->element_id()), scroll_node->element_id); - animation_host_->ImplOnlyScrollAnimationCreate( + mutator_host_->ImplOnlyScrollAnimationCreate( scroll_node->element_id, target_offset, current_offset, delayed_by); SetNeedsOneBeginImplFrame(); @@ -2833,19 +2815,18 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated( if (scroll_node) { for (; scroll_tree.parent(scroll_node); scroll_node = scroll_tree.parent(scroll_node)) { - if (!scroll_node->scrollable || - scroll_node->is_outer_viewport_scroll_layer) + if (!scroll_node->scrollable) continue; - if (scroll_node->is_inner_viewport_scroll_layer) { + if (viewport()->MainScrollLayer() && + scroll_node->owner_id == viewport()->MainScrollLayer()->id()) { gfx::Vector2dF scrolled = viewport()->ScrollAnimated(pending_delta, delayed_by); // Viewport::ScrollAnimated returns pending_delta as long as it // starts an animation. if (scrolled == pending_delta) return scroll_status; - pending_delta -= scrolled; - continue; + break; } gfx::Vector2dF scroll_delta = @@ -2979,6 +2960,7 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node, scroll_state->position_y()); const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y()); gfx::Vector2dF applied_delta; + gfx::Vector2dF delta_applied_to_content; // TODO(tdresser): Use a more rational epsilon. See crbug.com/510550 for // details. const float kEpsilon = 0.1f; @@ -2987,16 +2969,21 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node, viewport()->MainScrollLayer() && scroll_node->owner_id == viewport()->MainScrollLayer()->id(); - if (is_viewport_scroll_layer) { - bool affect_top_controls = !wheel_scrolling_; + // This is needed if the scroll chains up to the viewport without going + // through the outer viewport scroll layer. This can happen if we scroll an + // element that's not a descendant of the document.rootScroller. In that case + // we want to scroll the inner viewport -- to allow panning while zoomed -- + // but also move browser controls if needed. + bool is_inner_viewport_scroll_layer = + scroll_node->owner_id == InnerViewportScrollLayer()->id(); + + if (is_viewport_scroll_layer || is_inner_viewport_scroll_layer) { Viewport::ScrollResult result = viewport()->ScrollBy( delta, viewport_point, scroll_state->is_direct_manipulation(), - affect_top_controls); + !wheel_scrolling_, is_viewport_scroll_layer); + applied_delta = result.consumed_delta; - scroll_state->set_caused_scroll( - std::abs(result.content_scrolled_delta.x()) > kEpsilon, - std::abs(result.content_scrolled_delta.y()) > kEpsilon); - scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); + delta_applied_to_content = result.content_scrolled_delta; } else { applied_delta = ScrollSingleNode( scroll_node, delta, viewport_point, @@ -3007,8 +2994,16 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node, // If the layer wasn't able to move, try the next one in the hierarchy. bool scrolled = std::abs(applied_delta.x()) > kEpsilon; scrolled = scrolled || std::abs(applied_delta.y()) > kEpsilon; + if (!scrolled) { + // TODO(bokan): This preserves existing behavior by not allowing tiny + // scrolls to produce overscroll but is inconsistent in how delta gets + // chained up. We need to clean this up. + if (is_viewport_scroll_layer) + scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); + return; + } - if (scrolled && !is_viewport_scroll_layer) { + if (!is_viewport_scroll_layer && !is_inner_viewport_scroll_layer) { // If the applied delta is within 45 degrees of the input // delta, bail out to make it easier to scroll just one layer // in one direction without affecting any of its parents. @@ -3021,13 +3016,13 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node, // in which the layer moved. applied_delta = MathUtil::ProjectVector(delta, applied_delta); } - scroll_state->set_caused_scroll(std::abs(applied_delta.x()) > kEpsilon, - std::abs(applied_delta.y()) > kEpsilon); - scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); + delta_applied_to_content = applied_delta; } - if (!scrolled) - return; + scroll_state->set_caused_scroll( + std::abs(delta_applied_to_content.x()) > kEpsilon, + std::abs(delta_applied_to_content.y()) > kEpsilon); + scroll_state->ConsumeDelta(applied_delta.x(), applied_delta.y()); scroll_state->set_current_native_scrolling_node(scroll_node); } @@ -3040,18 +3035,19 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) { std::list<const ScrollNode*> current_scroll_chain; ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree; ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode(); + ScrollNode* viewport_scroll_node = + viewport()->MainScrollLayer() + ? scroll_tree.Node(viewport()->MainScrollLayer()->scroll_tree_index()) + : nullptr; if (scroll_node) { + // TODO(bokan): The loop checks for a null parent but don't we still want to + // distribute to the root scroll node? for (; scroll_tree.parent(scroll_node); scroll_node = scroll_tree.parent(scroll_node)) { - if (scroll_node->is_outer_viewport_scroll_layer) { - // TODO(bokan): This should use Viewport::MainScrollLayer once that - // returns the outer viewport scroll layer. + if (scroll_node == viewport_scroll_node) { // Don't chain scrolls past the outer viewport scroll layer. Once we // reach that, we should scroll the viewport which is represented by the // main viewport scroll layer. - DCHECK(viewport()->MainScrollLayer()); - ScrollNode* viewport_scroll_node = scroll_tree.Node( - viewport()->MainScrollLayer()->scroll_tree_index()); DCHECK(viewport_scroll_node); current_scroll_chain.push_front(viewport_scroll_node); break; @@ -3077,7 +3073,7 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( return InputHandlerScrollResult(); float initial_top_controls_offset = - top_controls_manager_->ControlsTopOffset(); + browser_controls_offset_manager_->ControlsTopOffset(); scroll_state->set_delta_consumed_for_scroll_sequence( did_lock_scrolling_layer_); @@ -3125,7 +3121,8 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy( accumulated_root_overscroll_ += unused_root_delta; bool did_scroll_top_controls = - initial_top_controls_offset != top_controls_manager_->ControlsTopOffset(); + initial_top_controls_offset != + browser_controls_offset_manager_->ControlsTopOffset(); InputHandlerScrollResult scroll_result; scroll_result.did_scroll = did_scroll_content || did_scroll_top_controls; @@ -3175,7 +3172,7 @@ void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state) { DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0); DistributeScrollDelta(scroll_state); - top_controls_manager_->ScrollEnd(); + browser_controls_offset_manager_->ScrollEnd(); ClearCurrentlyScrollingLayer(); } @@ -3209,84 +3206,77 @@ float LayerTreeHostImpl::DeviceSpaceDistanceToLayer( } void LayerTreeHostImpl::MouseDown() { - if (scroll_layer_id_when_mouse_over_scrollbar_ == Layer::INVALID_ID) - return; - - captured_scrollbar_layer_id_ = scroll_layer_id_when_mouse_over_scrollbar_; ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId(captured_scrollbar_layer_id_); + ScrollbarAnimationControllerForId(scroll_layer_id_mouse_currently_over_); if (animation_controller) - animation_controller->DidCaptureScrollbarBegin(); + animation_controller->DidMouseDown(); } void LayerTreeHostImpl::MouseUp() { - if (captured_scrollbar_layer_id_ == Layer::INVALID_ID) - return; - ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId(captured_scrollbar_layer_id_); + ScrollbarAnimationControllerForId(scroll_layer_id_mouse_currently_over_); if (animation_controller) - animation_controller->DidCaptureScrollbarEnd(); - captured_scrollbar_layer_id_ = Layer::INVALID_ID; + animation_controller->DidMouseUp(); } void LayerTreeHostImpl::MouseMoveAt(const gfx::Point& viewport_point) { + float distance_to_scrollbar = std::numeric_limits<float>::max(); gfx::PointF device_viewport_point = gfx::ScalePoint( gfx::PointF(viewport_point), active_tree_->device_scale_factor()); LayerImpl* layer_impl = active_tree_->FindLayerThatIsHitByPoint(device_viewport_point); - HandleMouseOverScrollbar(layer_impl); - if (scroll_layer_id_when_mouse_over_scrollbar_ != Layer::INVALID_ID) - return; - - bool scroll_on_main_thread = false; - uint32_t main_thread_scrolling_reasons; - LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( - device_viewport_point, InputHandler::TOUCHSCREEN, layer_impl, - &scroll_on_main_thread, &main_thread_scrolling_reasons); - // Scrollbars for the viewport are registered with the outer viewport layer. - if (scroll_layer_impl == InnerViewportScrollLayer()) - scroll_layer_impl = OuterViewportScrollLayer(); - if (scroll_on_main_thread || !scroll_layer_impl) - return; - - ScrollbarAnimationController* animation_controller = - ScrollbarAnimationControllerForId(scroll_layer_impl->id()); - if (!animation_controller) - return; - - float distance_to_scrollbar = std::numeric_limits<float>::max(); - for (ScrollbarLayerImplBase* scrollbar : - ScrollbarsFor(scroll_layer_impl->id())) - distance_to_scrollbar = - std::min(distance_to_scrollbar, - DeviceSpaceDistanceToLayer(device_viewport_point, scrollbar)); - - animation_controller->DidMouseMoveNear(distance_to_scrollbar / - active_tree_->device_scale_factor()); -} -void LayerTreeHostImpl::HandleMouseOverScrollbar(LayerImpl* layer_impl) { + // Check if mouse is over a scrollbar or not. + // TODO(sahel): get rid of this extera checking when + // FindScrollLayerForDeviceViewportPoint finds the proper layer for + // scrolling on main thread, as well. int new_id = Layer::INVALID_ID; if (layer_impl && layer_impl->ToScrollbarLayer()) new_id = layer_impl->ToScrollbarLayer()->ScrollLayerId(); + if (new_id != Layer::INVALID_ID) { + // Mouse over a scrollbar. + distance_to_scrollbar = 0; + } else { + bool scroll_on_main_thread = false; + uint32_t main_thread_scrolling_reasons; + LayerImpl* scroll_layer_impl = FindScrollLayerForDeviceViewportPoint( + device_viewport_point, InputHandler::TOUCHSCREEN, layer_impl, + &scroll_on_main_thread, &main_thread_scrolling_reasons); - if (new_id == scroll_layer_id_when_mouse_over_scrollbar_) - return; + // Scrollbars for the viewport are registered with the outer viewport layer. + if (scroll_layer_impl == InnerViewportScrollLayer()) + scroll_layer_impl = OuterViewportScrollLayer(); - ScrollbarAnimationController* old_animation_controller = - ScrollbarAnimationControllerForId( - scroll_layer_id_when_mouse_over_scrollbar_); - if (old_animation_controller) - old_animation_controller->DidMouseMoveOffScrollbar(); + new_id = scroll_layer_impl ? scroll_layer_impl->id() : Layer::INVALID_ID; + } - scroll_layer_id_when_mouse_over_scrollbar_ = new_id; + if (new_id != scroll_layer_id_mouse_currently_over_) { + ScrollbarAnimationController* old_animation_controller = + ScrollbarAnimationControllerForId( + scroll_layer_id_mouse_currently_over_); + if (old_animation_controller) { + old_animation_controller->DidMouseLeave(); + } + scroll_layer_id_mouse_currently_over_ = new_id; + } ScrollbarAnimationController* new_animation_controller = - ScrollbarAnimationControllerForId( - scroll_layer_id_when_mouse_over_scrollbar_); - if (new_animation_controller) - new_animation_controller->DidMouseMoveNear(0); + ScrollbarAnimationControllerForId(new_id); + if (!new_animation_controller) + return; + + for (ScrollbarLayerImplBase* scrollbar : ScrollbarsFor(new_id)) + distance_to_scrollbar = + std::min(distance_to_scrollbar, + DeviceSpaceDistanceToLayer(device_viewport_point, scrollbar)); + new_animation_controller->DidMouseMoveNear( + distance_to_scrollbar / active_tree_->device_scale_factor()); +} + +void LayerTreeHostImpl::MouseLeave() { + for (auto& pair : scrollbar_animation_controllers_) + pair.second->DidMouseLeave(); + scroll_layer_id_mouse_currently_over_ = Layer::INVALID_ID; } void LayerTreeHostImpl::PinchGestureBegin() { @@ -3294,7 +3284,7 @@ void LayerTreeHostImpl::PinchGestureBegin() { client_->RenewTreePriority(); pinch_gesture_end_should_clear_scrolling_layer_ = !CurrentlyScrollingLayer(); active_tree_->SetCurrentlyScrollingLayer(viewport()->MainScrollLayer()); - top_controls_manager_->PinchBegin(); + browser_controls_offset_manager_->PinchBegin(); } void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta, @@ -3318,7 +3308,7 @@ void LayerTreeHostImpl::PinchGestureEnd() { ClearCurrentlyScrollingLayer(); } viewport()->PinchEnd(); - top_controls_manager_->PinchEnd(); + browser_controls_offset_manager_->PinchEnd(); client_->SetNeedsCommitOnImplThread(); // When a pinch ends, we may be displaying content cached at incorrect scales, // so updating draw properties and drawing will ensure we are using the right @@ -3348,14 +3338,26 @@ static void CollectScrollDeltas(ScrollAndScaleSet* scroll_info, ? tree_impl->InnerViewportScrollLayer()->id() : Layer::INVALID_ID; - return tree_impl->property_trees()->scroll_tree.CollectScrollDeltas( + tree_impl->property_trees()->scroll_tree.CollectScrollDeltas( scroll_info, inner_viewport_layer_id); } +static void CollectScrollbarUpdates( + ScrollAndScaleSet* scroll_info, + std::unordered_map<int, std::unique_ptr<ScrollbarAnimationController>>* + controllers) { + scroll_info->scrollbars.reserve(controllers->size()); + for (auto& pair : *controllers) { + scroll_info->scrollbars.push_back(LayerTreeHostCommon::ScrollbarsUpdateInfo( + pair.first, pair.second->ScrollbarsHidden())); + } +} + std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() { std::unique_ptr<ScrollAndScaleSet> scroll_info(new ScrollAndScaleSet()); CollectScrollDeltas(scroll_info.get(), active_tree_.get()); + CollectScrollbarUpdates(scroll_info.get(), &scrollbar_animation_controllers_); scroll_info->page_scale_delta = active_tree_->page_scale_factor()->PullDeltaForMainThread(); scroll_info->top_controls_delta = @@ -3399,13 +3401,13 @@ bool LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) { return true; } -bool LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) { - if (!top_controls_manager_->has_animation()) +bool LayerTreeHostImpl::AnimateBrowserControls(base::TimeTicks time) { + if (!browser_controls_offset_manager_->has_animation()) return false; - gfx::Vector2dF scroll = top_controls_manager_->Animate(time); + gfx::Vector2dF scroll = browser_controls_offset_manager_->Animate(time); - if (top_controls_manager_->has_animation()) + if (browser_controls_offset_manager_->has_animation()) SetNeedsOneBeginImplFrame(); if (active_tree_->TotalScrollOffset().y() == 0.f) @@ -3415,7 +3417,7 @@ bool LayerTreeHostImpl::AnimateTopControls(base::TimeTicks time) { return false; DCHECK(viewport()); - viewport()->ScrollBy(scroll, gfx::Point(), false, false); + viewport()->ScrollBy(scroll, gfx::Point(), false, false, true); client_->SetNeedsCommitOnImplThread(); client_->RenewTreePriority(); return true; @@ -3429,7 +3431,7 @@ bool LayerTreeHostImpl::AnimateScrollbars(base::TimeTicks monotonic_time) { } bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { - const bool animated = animation_host_->AnimateLayers(monotonic_time); + const bool animated = mutator_host_->AnimateLayers(monotonic_time); // TODO(crbug.com/551134): Only do this if the animations are on the active // tree, or if they are on the pending tree waiting for some future time to @@ -3446,12 +3448,12 @@ bool LayerTreeHostImpl::AnimateLayers(base::TimeTicks monotonic_time) { } void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) { - std::unique_ptr<AnimationEvents> events = animation_host_->CreateEvents(); + std::unique_ptr<MutatorEvents> events = mutator_host_->CreateEvents(); - const bool has_active_animations = animation_host_->UpdateAnimationState( - start_ready_animations, events.get()); + const bool has_active_animations = + mutator_host_->UpdateAnimationState(start_ready_animations, events.get()); - if (!events->events_.empty()) + if (!events->IsEmpty()) client_->PostAnimationEventsToMainThreadOnImplThread(std::move(events)); if (has_active_animations) @@ -3459,7 +3461,7 @@ void LayerTreeHostImpl::UpdateAnimationState(bool start_ready_animations) { } void LayerTreeHostImpl::ActivateAnimations() { - const bool activated = animation_host_->ActivateAnimations(); + const bool activated = mutator_host_->ActivateAnimations(); if (activated) { // Activating an animation changes layer draw properties, such as // screen_space_transform_is_animating. So when we see a new animation get @@ -3830,7 +3832,7 @@ void LayerTreeHostImpl::UpdateRootLayerStateForSynchronousInputHandler() { } void LayerTreeHostImpl::ScrollAnimationAbort(LayerImpl* layer_impl) { - return animation_host_->ScrollAnimationAbort(false /* needs_completion */); + return mutator_host_->ScrollAnimationAbort(false /* needs_completion */); } bool LayerTreeHostImpl::ScrollAnimationUpdateTarget( @@ -3841,7 +3843,7 @@ bool LayerTreeHostImpl::ScrollAnimationUpdateTarget( ElementId(active_tree()->LayerById(scroll_node->owner_id)->element_id()), scroll_node->element_id); - return animation_host_->ImplOnlyScrollAnimationUpdateTarget( + return mutator_host_->ImplOnlyScrollAnimationUpdateTarget( scroll_node->element_id, scroll_delta, active_tree_->property_trees()->scroll_tree.MaxScrollOffset( scroll_node->id), @@ -3948,7 +3950,11 @@ void LayerTreeHostImpl::SetTreeLayerScrollOffsetMutated( bool LayerTreeHostImpl::AnimationsPreserveAxisAlignment( const LayerImpl* layer) const { - return animation_host_->AnimationsPreserveAxisAlignment(layer->element_id()); + return mutator_host_->AnimationsPreserveAxisAlignment(layer->element_id()); +} + +void LayerTreeHostImpl::SetNeedUpdateGpuRasterizationStatus() { + need_update_gpu_rasterization_status_ = true; } void LayerTreeHostImpl::SetElementFilterMutated( @@ -4041,46 +4047,37 @@ bool LayerTreeHostImpl::CommitToActiveTree() const { return !task_runner_provider_->HasImplThread(); } -void LayerTreeHostImpl::SetCompositorContextVisibility(bool is_visible) { +void LayerTreeHostImpl::SetContextVisibility(bool is_visible) { if (!compositor_frame_sink_) return; + // Update the compositor context. If we are already in the correct visibility + // state, skip. This can happen if we transition invisible/visible rapidly, + // before we get a chance to go invisible in NotifyAllTileTasksComplete. auto* compositor_context = compositor_frame_sink_->context_provider(); - if (!compositor_context) - return; - - DCHECK_NE(is_visible, !!compositor_context_visibility_); - - if (is_visible) { - compositor_context_visibility_ = - compositor_context->CacheController()->ClientBecameVisible(); - } else { - compositor_context->CacheController()->ClientBecameNotVisible( - std::move(compositor_context_visibility_)); + if (compositor_context && is_visible != !!compositor_context_visibility_) { + if (is_visible) { + compositor_context_visibility_ = + compositor_context->CacheController()->ClientBecameVisible(); + } else { + compositor_context->CacheController()->ClientBecameNotVisible( + std::move(compositor_context_visibility_)); + } } -} - -void LayerTreeHostImpl::SetWorkerContextVisibility(bool is_visible) { - if (!compositor_frame_sink_) - return; + // Update the worker context. If we are already in the correct visibility + // state, skip. This can happen if we transition invisible/visible rapidly, + // before we get a chance to go invisible in NotifyAllTileTasksComplete. auto* worker_context = compositor_frame_sink_->worker_context_provider(); - if (!worker_context) - return; - - // TODO(ericrk): This check is here because worker context visibility is a - // bit less controlled, being settable both by memory policy changes as well - // as direct visibility changes. We should simplify this. crbug.com/642154 - if (is_visible == !!worker_context_visibility_) - return; - - ContextProvider::ScopedContextLock hold(worker_context); - if (is_visible) { - worker_context_visibility_ = - worker_context->CacheController()->ClientBecameVisible(); - } else { - worker_context->CacheController()->ClientBecameNotVisible( - std::move(worker_context_visibility_)); + if (worker_context && is_visible != !!worker_context_visibility_) { + ContextProvider::ScopedContextLock hold(worker_context); + if (is_visible) { + worker_context_visibility_ = + worker_context->CacheController()->ClientBecameVisible(); + } else { + worker_context->CacheController()->ClientBecameNotVisible( + std::move(worker_context_visibility_)); + } } } diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h index fcf74d005d3..189de43f689 100644 --- a/chromium/cc/trees/layer_tree_host_impl.h +++ b/chromium/cc/trees/layer_tree_host_impl.h @@ -17,13 +17,12 @@ #include "base/callback.h" #include "base/macros.h" #include "base/time/time.h" -#include "cc/animation/layer_tree_mutator.h" #include "cc/base/cc_export.h" #include "cc/base/synced_property.h" #include "cc/debug/micro_benchmark_controller_impl.h" +#include "cc/input/browser_controls_offset_manager_client.h" #include "cc/input/input_handler.h" #include "cc/input/scrollbar_animation_controller.h" -#include "cc/input/top_controls_manager_client.h" #include "cc/layers/layer_collections.h" #include "cc/layers/render_pass_sink.h" #include "cc/output/begin_frame_args.h" @@ -39,6 +38,7 @@ #include "cc/scheduler/video_frame_controller.h" #include "cc/tiles/image_decode_controller.h" #include "cc/tiles/tile_manager.h" +#include "cc/trees/layer_tree_mutator.h" #include "cc/trees/layer_tree_settings.h" #include "cc/trees/mutator_host_client.h" #include "cc/trees/task_runner_provider.h" @@ -50,9 +50,7 @@ class ScrollOffset; namespace cc { -class AnimationEvents; -class AnimationHost; -class CompletionEvent; +class BrowserControlsOffsetManager; class CompositorFrameMetadata; class CompositorFrameSink; class DebugRectHistory; @@ -61,25 +59,20 @@ class FrameRateCounter; class LayerImpl; class LayerTreeImpl; class MemoryHistory; +class MutatorEvents; +class MutatorHost; class PageScaleAnimation; class PendingTreeDurationHistogramTimer; -class PictureLayerImpl; class RasterTilePriorityQueue; -class TileTaskManager; class RasterBufferProvider; -class RenderPassDrawQuad; class RenderingStatsInstrumentation; class ResourcePool; class ScrollElasticityHelper; -class ScrollbarLayerImplBase; class SwapPromise; class SwapPromiseMonitor; class SynchronousTaskGraphRunner; class TaskGraphRunner; -class TextureMailboxDeleter; -class TopControlsManager; class UIResourceBitmap; -class UIResourceRequest; struct ScrollAndScaleSet; class Viewport; @@ -99,7 +92,7 @@ class LayerTreeHostImplClient { public: virtual void DidLoseCompositorFrameSinkOnImplThread() = 0; virtual void SetBeginFrameSource(BeginFrameSource* source) = 0; - virtual void DidSwapBuffersCompleteOnImplThread() = 0; + virtual void DidReceiveCompositorFrameAckOnImplThread() = 0; virtual void OnCanDrawStateChanged(bool can_draw) = 0; virtual void NotifyReadyToActivate() = 0; virtual void NotifyReadyToDraw() = 0; @@ -111,7 +104,7 @@ class LayerTreeHostImplClient { virtual void SetNeedsPrepareTilesOnImplThread() = 0; virtual void SetVideoNeedsBeginFrames(bool needs_begin_frames) = 0; virtual void PostAnimationEventsToMainThreadOnImplThread( - std::unique_ptr<AnimationEvents> events) = 0; + std::unique_ptr<MutatorEvents> events) = 0; virtual bool IsInsideDraw() = 0; virtual void RenewTreePriority() = 0; virtual void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -137,7 +130,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler, public TileManagerClient, public CompositorFrameSinkClient, - public TopControlsManagerClient, + public BrowserControlsOffsetManagerClient, public ScrollbarAnimationControllerClient, public VideoFrameControllerClient, public LayerTreeMutatorClient, @@ -149,10 +142,8 @@ class CC_EXPORT LayerTreeHostImpl LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* shared_bitmap_manager, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, TaskGraphRunner* task_graph_runner, - std::unique_ptr<AnimationHost> animation_host, + std::unique_ptr<MutatorHost> mutator_host, int id); ~LayerTreeHostImpl() override; @@ -180,6 +171,7 @@ class CC_EXPORT LayerTreeHostImpl void MouseDown() override; void MouseUp() override; void MouseMoveAt(const gfx::Point& viewport_point) override; + void MouseLeave() override; void PinchGestureBegin() override; void PinchGestureUpdate(float magnify_delta, @@ -204,12 +196,12 @@ class CC_EXPORT LayerTreeHostImpl gfx::ScrollOffset* offset) override; bool ScrollLayerTo(int layer_id, const gfx::ScrollOffset& offset) override; - // TopControlsManagerClient implementation. + // BrowserControlsOffsetManagerClient implementation. float TopControlsHeight() const override; float BottomControlsHeight() const override; - void SetCurrentTopControlsShownRatio(float offset) override; - float CurrentTopControlsShownRatio() const override; - void DidChangeTopControlsPosition() override; + void SetCurrentBrowserControlsShownRatio(float offset) override; + float CurrentBrowserControlsShownRatio() const override; + void DidChangeBrowserControlsPosition() override; bool HaveRootScrollLayer() const override; void UpdateViewportContainerSizes(); @@ -267,6 +259,7 @@ class CC_EXPORT LayerTreeHostImpl LayerTreeImpl* tree, const gfx::ScrollOffset& scroll_offset); bool AnimationsPreserveAxisAlignment(const LayerImpl* layer) const; + void SetNeedUpdateGpuRasterizationStatus(); // MutatorHostClient implementation. bool IsElementInList(ElementId element_id, @@ -354,6 +347,7 @@ class CC_EXPORT LayerTreeHostImpl void SetNeedsAnimateForScrollbarAnimation() override; void SetNeedsRedrawForScrollbarAnimation() override; ScrollbarSet ScrollbarsFor(int scroll_layer_id) const override; + void DidChangeScrollbarVisibility() override; // VideoBeginFrameSource implementation. void AddVideoFrameController(VideoFrameController* controller) override; @@ -365,7 +359,7 @@ class CC_EXPORT LayerTreeHostImpl const gfx::Rect& viewport_rect, const gfx::Transform& transform) override; void DidLoseCompositorFrameSink() override; - void DidSwapBuffersComplete() override; + void DidReceiveCompositorFrameAck() override; void ReclaimResources(const ReturnedResourceArray& resources) override; void SetMemoryPolicy(const ManagedMemoryPolicy& policy) override; void SetTreeActivationCallback(const base::Closure& callback) override; @@ -437,9 +431,6 @@ class CC_EXPORT LayerTreeHostImpl LayerImpl* OuterViewportScrollLayer() const; LayerImpl* CurrentlyScrollingLayer() const; - int scroll_layer_id_when_mouse_over_scrollbar() const { - return scroll_layer_id_when_mouse_over_scrollbar_; - } bool scroll_affects_scroll_handler() const { return scroll_affects_scroll_handler_; } @@ -474,8 +465,8 @@ class CC_EXPORT LayerTreeHostImpl MemoryHistory* memory_history() { return memory_history_.get(); } DebugRectHistory* debug_rect_history() { return debug_rect_history_.get(); } ResourceProvider* resource_provider() { return resource_provider_.get(); } - TopControlsManager* top_controls_manager() { - return top_controls_manager_.get(); + BrowserControlsOffsetManager* browser_controls_manager() { + return browser_controls_offset_manager_.get(); } const GlobalStateThatImpactsTilePriority& global_tile_state() { return global_tile_state_; @@ -485,7 +476,7 @@ class CC_EXPORT LayerTreeHostImpl return task_runner_provider_; } - AnimationHost* animation_host() const { return animation_host_.get(); } + MutatorHost* mutator_host() const { return mutator_host_.get(); } void SetDebugState(const LayerTreeDebugState& new_debug_state); const LayerTreeDebugState& debug_state() const { return debug_state_; } @@ -594,16 +585,16 @@ class CC_EXPORT LayerTreeHostImpl void SetLayerTreeMutator(std::unique_ptr<LayerTreeMutator> mutator); LayerTreeMutator* mutator() { return mutator_.get(); } + LayerImpl* ViewportMainScrollLayer(); + protected: LayerTreeHostImpl( const LayerTreeSettings& settings, LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, RenderingStatsInstrumentation* rendering_stats_instrumentation, - SharedBitmapManager* shared_bitmap_manager, - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, TaskGraphRunner* task_graph_runner, - std::unique_ptr<AnimationHost> animation_host, + std::unique_ptr<MutatorHost> mutator_host, int id); // Virtual for testing. @@ -650,7 +641,7 @@ class CC_EXPORT LayerTreeHostImpl bool AnimatePageScale(base::TimeTicks monotonic_time); bool AnimateScrollbars(base::TimeTicks monotonic_time); - bool AnimateTopControls(base::TimeTicks monotonic_time); + bool AnimateBrowserControls(base::TimeTicks monotonic_time); void TrackDamageForAllSurfaces( const LayerImplList& render_surface_layer_list); @@ -664,8 +655,6 @@ class CC_EXPORT LayerTreeHostImpl void ClearCurrentlyScrollingLayer(); - void HandleMouseOverScrollbar(LayerImpl* layer_impl); - LayerImpl* FindScrollLayerForDeviceViewportPoint( const gfx::PointF& device_viewport_point, InputHandler::ScrollInputType type, @@ -691,8 +680,7 @@ class CC_EXPORT LayerTreeHostImpl const gfx::Vector2dF& scroll_delta, base::TimeDelta delayed_by); - void SetCompositorContextVisibility(bool is_visible); - void SetWorkerContextVisibility(bool is_visible); + void SetContextVisibility(bool is_visible); using UIResourceMap = std::unordered_map<UIResourceId, UIResourceData>; UIResourceMap ui_resource_map_; @@ -721,7 +709,6 @@ class CC_EXPORT LayerTreeHostImpl bool use_msaa_; GpuRasterizationStatus gpu_rasterization_status_; std::unique_ptr<RasterBufferProvider> raster_buffer_provider_; - std::unique_ptr<TileTaskManager> tile_task_manager_; std::unique_ptr<ResourcePool> resource_pool_; std::unique_ptr<ImageDecodeController> image_decode_controller_; @@ -742,8 +729,7 @@ class CC_EXPORT LayerTreeHostImpl bool did_lock_scrolling_layer_; bool wheel_scrolling_; bool scroll_affects_scroll_handler_; - int scroll_layer_id_when_mouse_over_scrollbar_; - int captured_scrollbar_layer_id_; + int scroll_layer_id_mouse_currently_over_; std::vector<std::unique_ptr<SwapPromise>> swap_promises_for_main_thread_scroll_update_; @@ -767,7 +753,8 @@ class CC_EXPORT LayerTreeHostImpl bool pinch_gesture_active_; bool pinch_gesture_end_should_clear_scrolling_layer_; - std::unique_ptr<TopControlsManager> top_controls_manager_; + std::unique_ptr<BrowserControlsOffsetManager> + browser_controls_offset_manager_; std::unique_ptr<PageScaleAnimation> page_scale_animation_; @@ -798,7 +785,7 @@ class CC_EXPORT LayerTreeHostImpl gfx::Rect viewport_damage_rect_; - std::unique_ptr<AnimationHost> animation_host_; + std::unique_ptr<MutatorHost> mutator_host_; std::set<VideoFrameController*> video_frame_controllers_; // Map from scroll layer ID to scrollbar animation controller. @@ -814,8 +801,6 @@ class CC_EXPORT LayerTreeHostImpl // Optional callback to notify of new tree activations. base::Closure tree_activation_callback_; - SharedBitmapManager* shared_bitmap_manager_; - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; TaskGraphRunner* task_graph_runner_; int id_; diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc index c9aa95ec5f8..f2702a30d84 100644 --- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc @@ -15,15 +15,14 @@ #include "base/location.h" #include "base/memory/ptr_util.h" #include "base/threading/thread_task_runner_handle.h" -#include "cc/animation/animation_events.h" #include "cc/animation/animation_host.h" #include "cc/animation/animation_id_provider.h" #include "cc/animation/transform_operations.h" #include "cc/base/math_util.h" +#include "cc/input/browser_controls_offset_manager.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/input/page_scale_animation.h" #include "cc/input/scrollbar_animation_controller_thinning.h" -#include "cc/input/top_controls_manager.h" #include "cc/layers/append_quads_data.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer_impl.h" @@ -60,13 +59,12 @@ #include "cc/test/layer_test_common.h" #include "cc/test/layer_tree_test.h" #include "cc/test/test_compositor_frame_sink.h" -#include "cc/test/test_gpu_memory_buffer_manager.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/test/test_web_graphics_context_3d.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/mutator_host.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/transform_node.h" #include "media/base/media.h" @@ -116,7 +114,6 @@ class LayerTreeHostImplTest : public testing::Test, settings.renderer_settings.texture_id_allocation_chunk_size = 1; settings.gpu_rasterization_enabled = true; settings.verify_clip_tree_calculations = true; - settings.verify_transform_tree_calculations = true; settings.renderer_settings.buffer_to_texture_target_map = DefaultBufferToTextureTargetMapForTesting(); return settings; @@ -133,7 +130,7 @@ class LayerTreeHostImplTest : public testing::Test, void DidLoseCompositorFrameSinkOnImplThread() override {} void SetBeginFrameSource(BeginFrameSource* source) override {} - void DidSwapBuffersCompleteOnImplThread() override {} + void DidReceiveCompositorFrameAckOnImplThread() override {} void OnCanDrawStateChanged(bool can_draw) override { on_can_draw_state_changed_called_ = true; } @@ -152,7 +149,7 @@ class LayerTreeHostImplTest : public testing::Test, void SetNeedsCommitOnImplThread() override { did_request_commit_ = true; } void SetVideoNeedsBeginFrames(bool needs_begin_frames) override {} void PostAnimationEventsToMainThreadOnImplThread( - std::unique_ptr<AnimationEvents> events) override {} + std::unique_ptr<MutatorEvents> events) override {} bool IsInsideDraw() override { return false; } void RenewTreePriority() override {} void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -188,6 +185,10 @@ class LayerTreeHostImplTest : public testing::Test, settings, std::move(compositor_frame_sink), &task_runner_provider_); } + AnimationHost* GetImplAnimationHost() const { + return static_cast<AnimationHost*>(host_impl_->mutator_host()); + } + virtual bool CreateHostImplWithTaskRunnerProvider( const LayerTreeSettings& settings, std::unique_ptr<CompositorFrameSink> compositor_frame_sink, @@ -196,7 +197,6 @@ class LayerTreeHostImplTest : public testing::Test, host_impl_->ReleaseCompositorFrameSink(); host_impl_ = LayerTreeHostImpl::Create( settings, this, task_runner_provider, &stats_instrumentation_, - &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0); compositor_frame_sink_ = std::move(compositor_frame_sink); @@ -212,7 +212,7 @@ class LayerTreeHostImplTest : public testing::Test, timeline_ = AnimationTimeline::Create(AnimationIdProvider::NextTimelineId()); - host_impl_->animation_host()->AddAnimationTimeline(timeline_); + GetImplAnimationHost()->AddAnimationTimeline(timeline_); return init; } @@ -497,8 +497,6 @@ class LayerTreeHostImplTest : public testing::Test, FakeImplTaskRunnerProvider task_runner_provider_; DebugScopedSetMainThreadBlocked always_main_thread_blocked_; - TestSharedBitmapManager shared_bitmap_manager_; - TestGpuMemoryBufferManager gpu_memory_buffer_manager_; TestTaskGraphRunner task_graph_runner_; std::unique_ptr<CompositorFrameSink> compositor_frame_sink_; std::unique_ptr<LayerTreeHostImpl> host_impl_; @@ -2659,15 +2657,12 @@ class LayerTreeHostImplOverridePhysicalTime : public LayerTreeHostImpl { const LayerTreeSettings& settings, LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, - SharedBitmapManager* manager, TaskGraphRunner* task_graph_runner, RenderingStatsInstrumentation* rendering_stats_instrumentation) : LayerTreeHostImpl(settings, client, task_runner_provider, rendering_stats_instrumentation, - manager, - nullptr, task_graph_runner, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0) {} @@ -2695,8 +2690,8 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { LayerTreeHostImplOverridePhysicalTime* host_impl_override_time = new LayerTreeHostImplOverridePhysicalTime( - settings, this, &task_runner_provider_, &shared_bitmap_manager_, - &task_graph_runner_, &stats_instrumentation_); + settings, this, &task_runner_provider_, &task_graph_runner_, + &stats_instrumentation_); host_impl_ = base::WrapUnique(host_impl_override_time); compositor_frame_sink_ = CreateCompositorFrameSink(); host_impl_->SetVisible(true); @@ -2725,8 +2720,8 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest { void RunTest(LayerTreeSettings::ScrollbarAnimator animator) { LayerTreeSettings settings = DefaultSettings(); settings.scrollbar_animator = animator; - settings.scrollbar_fade_delay_ms = 20; - settings.scrollbar_fade_duration_ms = 20; + settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); + settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); // If no animator is set, scrollbar won't show and no animation is expected. bool expecting_animations = animator != LayerTreeSettings::NO_ANIMATOR; @@ -2916,8 +2911,8 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest { void RunTest(LayerTreeSettings::ScrollbarAnimator animator) { LayerTreeSettings settings = DefaultSettings(); settings.scrollbar_animator = animator; - settings.scrollbar_fade_delay_ms = 20; - settings.scrollbar_fade_duration_ms = 20; + settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); + settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); gfx::Size content_size(100, 100); // If no animator is set, scrollbar won't show and no animation is expected. @@ -3047,8 +3042,8 @@ TEST_F(LayerTreeHostImplTest, ScrollbarInnerLargerThanOuter) { TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { LayerTreeSettings settings = DefaultSettings(); settings.scrollbar_animator = LayerTreeSettings::LINEAR_FADE; - settings.scrollbar_fade_delay_ms = 20; - settings.scrollbar_fade_duration_ms = 20; + settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(20); + settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(20); CreateHostImpl(settings, CreateCompositorFrameSink()); gfx::Size viewport_size(300, 200); @@ -3167,8 +3162,8 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) { void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( float device_scale_factor) { LayerTreeSettings settings = DefaultSettings(); - settings.scrollbar_fade_delay_ms = 500; - settings.scrollbar_fade_duration_ms = 300; + settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(500); + settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300); settings.scrollbar_animator = LayerTreeSettings::THINNING; gfx::Size viewport_size(300, 200); @@ -3223,15 +3218,13 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale( EXPECT_TRUE(scrollbar_animation_controller->mouse_is_near_scrollbar()); did_request_redraw_ = false; - EXPECT_EQ(Layer::INVALID_ID, - host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + EXPECT_FALSE(scrollbar_animation_controller->mouse_is_over_scrollbar()); host_impl_->MouseMoveAt(gfx::Point(10, 100)); - EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + EXPECT_TRUE(scrollbar_animation_controller->mouse_is_over_scrollbar()); host_impl_->MouseMoveAt(gfx::Point(10, 120)); - EXPECT_EQ(117, host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + EXPECT_TRUE(scrollbar_animation_controller->mouse_is_over_scrollbar()); host_impl_->MouseMoveAt(gfx::Point(150, 120)); - EXPECT_EQ(Layer::INVALID_ID, - host_impl_->scroll_layer_id_when_mouse_over_scrollbar()); + EXPECT_FALSE(scrollbar_animation_controller->mouse_is_over_scrollbar()); } TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) { @@ -3898,9 +3891,9 @@ TEST_F(LayerTreeHostImplTest, ClampingAfterActivation) { EXPECT_EQ(active_outer_layer->CurrentScrollOffset(), gfx::ScrollOffset(0, 0)); } -class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { +class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest { public: - LayerTreeHostImplTopControlsTest() + LayerTreeHostImplBrowserControlsTest() // Make the clip size the same as the layer (content) size so the layer is // non-scrollable. : layer_size_(10, 10), @@ -3917,33 +3910,33 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { settings, std::move(compositor_frame_sink)); if (init) { host_impl_->active_tree()->set_top_controls_height(top_controls_height_); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); } return init; } - void SetupTopControlsAndScrollLayerWithVirtualViewport( + void SetupBrowserControlsAndScrollLayerWithVirtualViewport( const gfx::Size& inner_viewport_size, const gfx::Size& outer_viewport_size, const gfx::Size& scroll_layer_size) { settings_ = DefaultSettings(); CreateHostImpl(settings_, CreateCompositorFrameSink()); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( host_impl_->active_tree(), inner_viewport_size, outer_viewport_size, scroll_layer_size); } - void SetupTopControlsAndScrollLayerWithVirtualViewport( + void SetupBrowserControlsAndScrollLayerWithVirtualViewport( LayerTreeImpl* tree_impl, const gfx::Size& inner_viewport_size, const gfx::Size& outer_viewport_size, const gfx::Size& scroll_layer_size) { - tree_impl->set_top_controls_shrink_blink_size(true); + tree_impl->set_browser_controls_shrink_blink_size(true); tree_impl->set_top_controls_height(top_controls_height_); - tree_impl->SetCurrentTopControlsShownRatio(1.f); + tree_impl->SetCurrentBrowserControlsShownRatio(1.f); tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - host_impl_->DidChangeTopControlsPosition(); + host_impl_->DidChangeBrowserControlsPosition(); std::unique_ptr<LayerImpl> root = LayerImpl::Create(tree_impl, 1); std::unique_ptr<LayerImpl> root_clip = LayerImpl::Create(tree_impl, 2); @@ -3994,16 +3987,16 @@ class LayerTreeHostImplTopControlsTest : public LayerTreeHostImplTest { float top_controls_height_; LayerTreeSettings settings_; -}; // class LayerTreeHostImplTopControlsTest +}; // class LayerTreeHostImplBrowserControlsTest // Tests that, on a page with content the same size as the viewport, hiding -// the top controls also increases the ScrollableSize (i.e. the content size). -// Since the viewport got larger, the effective scrollable "content" also did. -// This ensures, for one thing, that the overscroll glow is shown in the right -// place. -TEST_F(LayerTreeHostImplTopControlsTest, - HidingTopControlsExpandsScrollableSize) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +// the browser controls also increases the ScrollableSize (i.e. the content +// size). Since the viewport got larger, the effective scrollable "content" also +// did. This ensures, for one thing, that the overscroll glow is shown in the +// right place. +TEST_F(LayerTreeHostImplBrowserControlsTest, + HidingBrowserControlsExpandsScrollableSize) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(50, 50), gfx::Size(50, 50), gfx::Size(50, 50)); LayerTreeImpl* active_tree = host_impl_->active_tree(); @@ -4022,7 +4015,8 @@ TEST_F(LayerTreeHostImplTopControlsTest, LayerImpl* inner_container = active_tree->InnerViewportContainerLayer(); LayerImpl* outer_container = active_tree->OuterViewportContainerLayer(); - // The top controls should start off showing so the viewport should be shrunk. + // 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()); @@ -4034,21 +4028,21 @@ TEST_F(LayerTreeHostImplTopControlsTest, InputHandler::TOUCHSCREEN) .thread); - host_impl_->top_controls_manager()->ScrollBegin(); + host_impl_->browser_controls_manager()->ScrollBegin(); - // Hide the top controls by a bit, the scrollable size should increase but the - // actual content bounds shouldn't. + // Hide the browser controls by a bit, the scrollable size should increase but + // the actual content bounds shouldn't. { - host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + 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()); } - // Fully hide the top controls. + // Fully hide the browser controls. { - host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + 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()); @@ -4057,19 +4051,20 @@ TEST_F(LayerTreeHostImplTopControlsTest, // Scrolling additionally shouldn't have any effect. { - host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f)); + 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_->top_controls_manager()->ScrollEnd(); + host_impl_->browser_controls_manager()->ScrollEnd(); host_impl_->ScrollEnd(EndState().get()); } -TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +TEST_F(LayerTreeHostImplBrowserControlsTest, + ScrollBrowserControlsByFractionalAmount) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10)); DrawFrame(); @@ -4081,11 +4076,11 @@ TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) { // Make the test scroll delta a fractional amount, to verify that the // fixed container size delta is (1) non-zero, and (2) fractional, and - // (3) matches the movement of the top controls. + // (3) matches the movement of the browser controls. gfx::Vector2dF top_controls_scroll_delta(0.f, 5.25f); - host_impl_->top_controls_manager()->ScrollBegin(); - host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); - host_impl_->top_controls_manager()->ScrollEnd(); + host_impl_->browser_controls_manager()->ScrollBegin(); + host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); + host_impl_->browser_controls_manager()->ScrollEnd(); LayerImpl* inner_viewport_scroll_layer = host_impl_->active_tree()->InnerViewportScrollLayer(); @@ -4096,11 +4091,12 @@ TEST_F(LayerTreeHostImplTopControlsTest, ScrollTopControlsByFractionalAmount) { } // In this test, the outer viewport is initially unscrollable. We test that a -// scroll initiated on the inner viewport, causing the top controls to show and -// thus making the outer viewport scrollable, still scrolls the outer viewport. -TEST_F(LayerTreeHostImplTopControlsTest, - TopControlsOuterViewportBecomesScrollable) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +// scroll initiated on the inner viewport, causing the browser controls to show +// and thus making the outer viewport scrollable, still scrolls the outer +// viewport. +TEST_F(LayerTreeHostImplBrowserControlsTest, + BrowserControlsOuterViewportBecomesScrollable) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100)); DrawFrame(); @@ -4127,9 +4123,9 @@ TEST_F(LayerTreeHostImplTopControlsTest, host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 50.f)).get()); - // The entire scroll delta should have been used to hide the top controls. + // The entire scroll delta should have been used to hide the browser controls. // The viewport layers should be resized back to their full sizes. - EXPECT_EQ(0.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + 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()); @@ -4148,15 +4144,15 @@ TEST_F(LayerTreeHostImplTopControlsTest, ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll); + EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), outer_scroll); host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50.f)).get()); - // The entire scroll delta should have been used to show the top controls. + // The entire scroll delta should have been used to show the browser controls. // 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()->CurrentTopControlsShownRatio()); + 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(25.f, outer_scroll->CurrentScrollOffset().y()); @@ -4183,9 +4179,9 @@ TEST_F(LayerTreeHostImplTopControlsTest, } // Test that the fixed position container delta is appropriately adjusted -// by the top controls showing/hiding and page scale doesn't affect it. -TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +// by the browser controls showing/hiding and page scale doesn't affect it. +TEST_F(LayerTreeHostImplBrowserControlsTest, FixedContainerDelta) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(100, 100), gfx::Size(100, 100), gfx::Size(100, 100)); DrawFrame(); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f); @@ -4204,43 +4200,43 @@ TEST_F(LayerTreeHostImplTopControlsTest, FixedContainerDelta) { InputHandler::TOUCHSCREEN) .thread); - // Scroll down, the top controls hiding should expand the viewport size so + // Scroll down, the browser controls hiding should expand the viewport size so // the delta should be equal to the scroll distance. gfx::Vector2dF top_controls_scroll_delta(0.f, 20.f); - host_impl_->top_controls_manager()->ScrollBegin(); - host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); + host_impl_->browser_controls_manager()->ScrollBegin(); + host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); EXPECT_FLOAT_EQ(top_controls_height_ - top_controls_scroll_delta.y(), - host_impl_->top_controls_manager()->ContentTopOffset()); + host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(), outer_viewport_scroll_layer->FixedContainerSizeDelta().y()); host_impl_->ScrollEnd(EndState().get()); // Scroll past the maximum extent. The delta shouldn't be greater than the - // top controls height. - host_impl_->top_controls_manager()->ScrollBegin(); - host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); - host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); - host_impl_->top_controls_manager()->ScrollBy(top_controls_scroll_delta); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + // browser controls height. + host_impl_->browser_controls_manager()->ScrollBegin(); + host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); + host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); + host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta); + EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height_), outer_viewport_scroll_layer->FixedContainerSizeDelta()); host_impl_->ScrollEnd(EndState().get()); - // Scroll in the direction to make the top controls show. - host_impl_->top_controls_manager()->ScrollBegin(); - host_impl_->top_controls_manager()->ScrollBy(-top_controls_scroll_delta); + // Scroll in the direction to make the browser controls show. + host_impl_->browser_controls_manager()->ScrollBegin(); + host_impl_->browser_controls_manager()->ScrollBy(-top_controls_scroll_delta); EXPECT_EQ(top_controls_scroll_delta.y(), - host_impl_->top_controls_manager()->ContentTopOffset()); + host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_VECTOR_EQ( gfx::Vector2dF(0, top_controls_height_ - top_controls_scroll_delta.y()), outer_viewport_scroll_layer->FixedContainerSizeDelta()); - host_impl_->top_controls_manager()->ScrollEnd(); + host_impl_->browser_controls_manager()->ScrollEnd(); } -// Push a top controls ratio from the main thread that we didn't send as a delta -// and make sure that the ratio is clamped to the [0, 1] range. -TEST_F(LayerTreeHostImplTopControlsTest, TopControlsPushUnsentRatio) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +// Push a browser controls ratio from the main thread that we didn't send as a +// delta and make sure that the ratio is clamped to the [0, 1] range. +TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsPushUnsentRatio) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(10, 50), gfx::Size(10, 50), gfx::Size(10, 100)); DrawFrame(); @@ -4252,28 +4248,30 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsPushUnsentRatio) { host_impl_->active_tree()->OuterViewportScrollLayer(); outer_scroll->SetDrawsContent(true); - host_impl_->active_tree()->PushTopControlsFromMainThread(1); - ASSERT_EQ(1.0f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + host_impl_->active_tree()->PushBrowserControlsFromMainThread(1); + ASSERT_EQ(1.0f, + host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.5f); - ASSERT_EQ(0.5f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.5f); + ASSERT_EQ(0.5f, + host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - host_impl_->active_tree()->PushTopControlsFromMainThread(0); + host_impl_->active_tree()->PushBrowserControlsFromMainThread(0); - ASSERT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + ASSERT_EQ(0, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); } -// Test that if only the top controls are scrolled, we shouldn't request a +// Test that if only the browser controls are scrolled, we shouldn't request a // commit. -TEST_F(LayerTreeHostImplTopControlsTest, TopControlsDontTriggerCommit) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsDontTriggerCommit) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100)); DrawFrame(); - // Show top controls - EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + // Show browser controls + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - // Scroll 25px to hide top controls + // Scroll 25px to hide browser controls gfx::Vector2dF scroll_delta(0.f, 25.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -4285,16 +4283,17 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsDontTriggerCommit) { } // Test that if a scrollable sublayer doesn't consume the scroll, -// top controls should hide when scrolling down. -TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) { +// browser controls should hide when scrolling down. +TEST_F(LayerTreeHostImplBrowserControlsTest, + BrowserControlsScrollableSublayer) { gfx::Size sub_content_size(100, 400); gfx::Size sub_content_layer_size(100, 300); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(100, 50), gfx::Size(100, 100), gfx::Size(100, 100)); DrawFrame(); - // Show top controls - EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + // Show browser controls + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); LayerImpl* outer_viewport_scroll_layer = host_impl_->active_tree()->OuterViewportScrollLayer(); @@ -4319,7 +4318,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) { std::move(child_clip)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); - // Scroll 25px to hide top controls + // Scroll 25px to hide browser controls gfx::Vector2dF scroll_delta(0.f, 25.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -4329,37 +4328,41 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollableSublayer) { host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - // Top controls should be hidden + // Browser controls should be hidden EXPECT_EQ(scroll_delta.y(), top_controls_height_ - - host_impl_->top_controls_manager()->ContentTopOffset()); + host_impl_->browser_controls_manager()->ContentTopOffset()); } -// Ensure setting the top controls position explicitly using the setters on the -// TreeImpl correctly affects the top controls manager and viewport bounds. -TEST_F(LayerTreeHostImplTopControlsTest, PositionTopControlsExplicitly) { +// Ensure setting the browser controls position explicitly using the setters on +// the TreeImpl correctly affects the browser controls manager and viewport +// bounds. +TEST_F(LayerTreeHostImplBrowserControlsTest, + PositionBrowserControlsExplicitly) { settings_ = DefaultSettings(); CreateHostImpl(settings_, CreateCompositorFrameSink()); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f); host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread( 30.f / top_controls_height_); host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive(); - EXPECT_FLOAT_EQ(30.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ(30.f, + host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_FLOAT_EQ(-20.f, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); - EXPECT_FLOAT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f); + EXPECT_FLOAT_EQ(0.f, + host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_FLOAT_EQ(-50.f, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); - host_impl_->DidChangeTopControlsPosition(); + host_impl_->DidChangeBrowserControlsPosition(); - // Now that top controls have moved, expect the clip to resize. + // Now that browser controls have moved, expect the clip to resize. LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() ->test_properties() ->parent->test_properties() @@ -4368,34 +4371,34 @@ TEST_F(LayerTreeHostImplTopControlsTest, PositionTopControlsExplicitly) { } // Test that the top_controls delta and sent delta are appropriately -// applied on sync tree activation. The total top controls offset shouldn't +// applied on sync tree activation. The total browser controls offset shouldn't // change after the activation. -TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) { +TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) { settings_ = DefaultSettings(); CreateHostImpl(settings_, CreateCompositorFrameSink()); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread( 20.f / top_controls_height_); host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive(); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio( + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio( 15.f / top_controls_height_); host_impl_->active_tree() ->top_controls_shown_ratio() ->PullDeltaForMainThread(); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); - host_impl_->sync_tree()->PushTopControlsFromMainThread(15.f / - top_controls_height_); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f); + host_impl_->sync_tree()->PushBrowserControlsFromMainThread( + 15.f / top_controls_height_); - host_impl_->DidChangeTopControlsPosition(); + host_impl_->DidChangeBrowserControlsPosition(); LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() ->test_properties() ->parent->test_properties() ->parent; EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); host_impl_->ActivateSyncTree(); @@ -4403,7 +4406,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) { ->test_properties() ->parent->test_properties() ->parent; - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); EXPECT_FLOAT_EQ( @@ -4415,32 +4418,33 @@ TEST_F(LayerTreeHostImplTopControlsTest, ApplyDeltaOnTreeActivation) { top_controls_height_); } -// Test that changing the top controls layout height is correctly applied to -// the inner viewport container bounds. That is, the top controls layout +// Test that changing the browser controls layout height is correctly applied to +// the inner viewport container bounds. That is, the browser controls layout // height is the amount that the inner viewport container was shrunk outside -// the compositor to accommodate the top controls. -TEST_F(LayerTreeHostImplTopControlsTest, TopControlsLayoutHeightChanged) { +// the compositor to accommodate the browser controls. +TEST_F(LayerTreeHostImplBrowserControlsTest, + BrowserControlsLayoutHeightChanged) { settings_ = DefaultSettings(); CreateHostImpl(settings_, CreateCompositorFrameSink()); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); - host_impl_->sync_tree()->PushTopControlsFromMainThread(1.f); - host_impl_->sync_tree()->set_top_controls_shrink_blink_size(true); + host_impl_->sync_tree()->PushBrowserControlsFromMainThread(1.f); + host_impl_->sync_tree()->set_browser_controls_shrink_blink_size(true); host_impl_->active_tree()->top_controls_shown_ratio()->PushFromMainThread( 1.f); host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive(); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(0.f); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f); - host_impl_->DidChangeTopControlsPosition(); + host_impl_->DidChangeBrowserControlsPosition(); LayerImpl* inner_clip_ptr = host_impl_->InnerViewportScrollLayer() ->test_properties() ->parent->test_properties() ->parent; EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + 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(), @@ -4452,34 +4456,36 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsLayoutHeightChanged) { ->test_properties() ->parent->test_properties() ->parent; - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); + 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 - // top controls offset. + // browser controls offset. EXPECT_EQ(viewport_size_, inner_clip_ptr->bounds()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 50.f), inner_clip_ptr->bounds_delta()); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f); - host_impl_->DidChangeTopControlsPosition(); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); + host_impl_->DidChangeBrowserControlsPosition(); - EXPECT_EQ(1.f, host_impl_->top_controls_manager()->TopControlsShownRatio()); - EXPECT_EQ(50.f, host_impl_->top_controls_manager()->TopControlsHeight()); - EXPECT_EQ(50.f, host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_EQ(1.f, + 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->bounds_delta()); EXPECT_EQ(gfx::Size(viewport_size_.width(), viewport_size_.height() - 50.f), inner_clip_ptr->bounds()); } -// Test that showing/hiding the top controls when the viewport is fully scrolled -// doesn't incorrectly change the viewport offset due to clamping from changing -// viewport bounds. -TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +// Test that showing/hiding the browser controls when the viewport is fully +// scrolled doesn't incorrectly change the viewport offset due to clamping from +// changing viewport bounds. +TEST_F(LayerTreeHostImplBrowserControlsTest, + BrowserControlsViewportOffsetClamping) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); DrawFrame(); - EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); @@ -4492,7 +4498,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { host_impl_->active_tree()->TotalScrollOffset(); EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), viewport_offset); - // Hide the top controls by 25px. + // Hide the browser controls by 25px. gfx::Vector2dF scroll_delta(0.f, 25.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -4501,16 +4507,17 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); - // scrolling down at the max extents no longer hides the top controls - EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + // scrolling down at the max extents no longer hides the browser controls + EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - // forcefully hide the top controls by 25px - host_impl_->top_controls_manager()->ScrollBy(scroll_delta); + // forcefully hide the browser controls by 25px + host_impl_->browser_controls_manager()->ScrollBy(scroll_delta); host_impl_->ScrollEnd(EndState().get()); - EXPECT_FLOAT_EQ(scroll_delta.y(), - top_controls_height_ - - host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ( + scroll_delta.y(), + top_controls_height_ - + host_impl_->browser_controls_manager()->ContentTopOffset()); inner_scroll->ClampScrollToMaxScrollOffset(); outer_scroll->ClampScrollToMaxScrollOffset(); @@ -4521,7 +4528,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { viewport_offset = host_impl_->active_tree()->TotalScrollOffset(); - // Bring the top controls down by 25px. + // Bring the browser controls down by 25px. scroll_delta = gfx::Vector2dF(0.f, -25.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -4542,16 +4549,16 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsViewportOffsetClamping) { host_impl_->active_tree()->TotalScrollOffset()); } -// Test that the top controls coming in and out maintains the same aspect ratio -// between the inner and outer viewports. -TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +// Test that the browser controls coming in and out maintains the same aspect +// ratio between the inner and outer viewports. +TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsAspectRatio) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 2.f); DrawFrame(); EXPECT_FLOAT_EQ(top_controls_height_, - host_impl_->top_controls_manager()->ContentTopOffset()); + host_impl_->browser_controls_manager()->ContentTopOffset()); gfx::Vector2dF scroll_delta(0.f, 25.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -4562,12 +4569,13 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) { host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); host_impl_->ScrollEnd(EndState().get()); - EXPECT_FLOAT_EQ(scroll_delta.y(), - top_controls_height_ - - host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ( + scroll_delta.y(), + top_controls_height_ - + host_impl_->browser_controls_manager()->ContentTopOffset()); - // Top controls were hidden by 25px so the inner viewport should have expanded - // by that much. + // 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 = @@ -4585,17 +4593,18 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsAspectRatio) { host_impl_->InnerViewportScrollLayer()->BoundsForScrolling()); } -// Test that scrolling the outer viewport affects the top controls. -TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { - SetupTopControlsAndScrollLayerWithVirtualViewport( +// Test that scrolling the outer viewport affects the browser controls. +TEST_F(LayerTreeHostImplBrowserControlsTest, + BrowserControlsScrollOuterViewport) { + SetupBrowserControlsAndScrollLayerWithVirtualViewport( gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400)); DrawFrame(); EXPECT_EQ(top_controls_height_, - host_impl_->top_controls_manager()->ContentTopOffset()); + host_impl_->browser_controls_manager()->ContentTopOffset()); // Send a gesture scroll that will scroll the outer viewport, make sure the - // top controls get scrolled. + // browser controls get scrolled. gfx::Vector2dF scroll_delta(0.f, 15.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -4604,13 +4613,14 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); - EXPECT_EQ(host_impl_->InnerViewportScrollLayer(), + EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollEnd(EndState().get()); - EXPECT_FLOAT_EQ(scroll_delta.y(), - top_controls_height_ - - host_impl_->top_controls_manager()->ContentTopOffset()); + EXPECT_FLOAT_EQ( + scroll_delta.y(), + top_controls_height_ - + host_impl_->browser_controls_manager()->ContentTopOffset()); scroll_delta = gfx::Vector2dF(0.f, 50.f); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -4620,8 +4630,8 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { .thread); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset()); - EXPECT_EQ(host_impl_->InnerViewportScrollLayer(), + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset()); + EXPECT_EQ(host_impl_->OuterViewportScrollLayer(), host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollEnd(EndState().get()); @@ -4642,7 +4652,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_EQ(top_controls_height_, - host_impl_->top_controls_manager()->ContentTopOffset()); + host_impl_->browser_controls_manager()->ContentTopOffset()); EXPECT_FLOAT_EQ( inner_viewport_offset.y() + (scroll_delta.y() + top_controls_height_), ScrollDelta(host_impl_->InnerViewportScrollLayer()).y()); @@ -4650,11 +4660,11 @@ TEST_F(LayerTreeHostImplTopControlsTest, TopControlsScrollOuterViewport) { host_impl_->ScrollEnd(EndState().get()); } -TEST_F(LayerTreeHostImplTopControlsTest, - ScrollNonScrollableRootWithTopControls) { +TEST_F(LayerTreeHostImplBrowserControlsTest, + ScrollNonScrollableRootWithBrowserControls) { settings_ = DefaultSettings(); CreateHostImpl(settings_, CreateCompositorFrameSink()); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( layer_size_, layer_size_, layer_size_); DrawFrame(); @@ -4664,11 +4674,11 @@ TEST_F(LayerTreeHostImplTopControlsTest, InputHandler::TOUCHSCREEN) .thread); - host_impl_->top_controls_manager()->ScrollBegin(); - host_impl_->top_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f)); - host_impl_->top_controls_manager()->ScrollEnd(); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ContentTopOffset()); - // Now that top controls have moved, expect the clip to resize. + host_impl_->browser_controls_manager()->ScrollBegin(); + host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f)); + 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() @@ -4684,22 +4694,22 @@ TEST_F(LayerTreeHostImplTopControlsTest, .thread); float scroll_increment_y = -25.f; - host_impl_->top_controls_manager()->ScrollBegin(); - host_impl_->top_controls_manager()->ScrollBy( + host_impl_->browser_controls_manager()->ScrollBegin(); + host_impl_->browser_controls_manager()->ScrollBy( gfx::Vector2dF(0.f, scroll_increment_y)); EXPECT_FLOAT_EQ(-scroll_increment_y, - host_impl_->top_controls_manager()->ContentTopOffset()); - // Now that top controls have moved, expect the clip to resize. + 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()); - host_impl_->top_controls_manager()->ScrollBy( + host_impl_->browser_controls_manager()->ScrollBy( gfx::Vector2dF(0.f, scroll_increment_y)); - host_impl_->top_controls_manager()->ScrollEnd(); + host_impl_->browser_controls_manager()->ScrollEnd(); EXPECT_FLOAT_EQ(-2 * scroll_increment_y, - host_impl_->top_controls_manager()->ContentTopOffset()); - // Now that top controls have moved, expect the clip to resize. + 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()); host_impl_->ScrollEnd(EndState().get()); @@ -4717,29 +4727,31 @@ TEST_F(LayerTreeHostImplTopControlsTest, } // Tests that activating a pending tree while there's a bounds_delta on the -// viewport layers from top controls doesn't cause a scroll jump. This bug was -// occurring because the UpdateViewportContainerSizes was being called before -// the property trees were updated with the bounds_delta. crbug.com/597266. -TEST_F(LayerTreeHostImplTopControlsTest, ViewportBoundsDeltaOnTreeActivation) { +// viewport layers from browser controls doesn't cause a scroll jump. This bug +// was occurring because the UpdateViewportContainerSizes was being called +// before the property trees were updated with the bounds_delta. +// crbug.com/597266. +TEST_F(LayerTreeHostImplBrowserControlsTest, + ViewportBoundsDeltaOnTreeActivation) { const gfx::Size inner_viewport_size(1000, 1000); const gfx::Size outer_viewport_size(1000, 1000); const gfx::Size content_size(2000, 2000); // Initialization { - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( inner_viewport_size, outer_viewport_size, content_size); host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f); - // Start off with the top controls hidden on both main and impl. - host_impl_->active_tree()->set_top_controls_shrink_blink_size(false); - host_impl_->active_tree()->PushTopControlsFromMainThread(0); + // Start off with the browser controls hidden on both main and impl. + host_impl_->active_tree()->set_browser_controls_shrink_blink_size(false); + host_impl_->active_tree()->PushBrowserControlsFromMainThread(0); host_impl_->CreatePendingTree(); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( host_impl_->pending_tree(), inner_viewport_size, outer_viewport_size, content_size); - host_impl_->pending_tree()->set_top_controls_shrink_blink_size(false); + host_impl_->pending_tree()->set_browser_controls_shrink_blink_size(false); // Fully scroll the viewport. host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(), @@ -4752,17 +4764,19 @@ TEST_F(LayerTreeHostImplTopControlsTest, ViewportBoundsDeltaOnTreeActivation) { LayerImpl* outer_scroll = host_impl_->active_tree()->OuterViewportScrollLayer(); - ASSERT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ContentTopOffset()); + ASSERT_FLOAT_EQ(0, + host_impl_->browser_controls_manager()->ContentTopOffset()); ASSERT_EQ(1000, outer_scroll->MaxScrollOffset().y()); ASSERT_EQ(1000, outer_scroll->CurrentScrollOffset().y()); - // Kick off an animation to show the top controls. - host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN, true); + // Kick off an animation to show the browser controls. + host_impl_->browser_controls_manager()->UpdateBrowserControlsState( + BOTH, SHOWN, true); base::TimeTicks start_time = base::TimeTicks::Now(); BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE); - // Pump an animation frame to put some delta in the top controls. + // Pump an animation frame to put some delta in the browser controls. { begin_frame_args.frame_time = start_time + base::TimeDelta::FromMilliseconds(50); @@ -4772,8 +4786,9 @@ TEST_F(LayerTreeHostImplTopControlsTest, ViewportBoundsDeltaOnTreeActivation) { host_impl_->DidFinishImplFrame(); } - // Pull the top controls delta and get it back to the pending tree so that - // when we go to activate the pending tree we cause a change to top controls. + // Pull the browser controls delta and get it back to the pending tree so that + // when we go to activate the pending tree we cause a change to browser + // controls. { float delta = host_impl_->active_tree()->top_controls_shown_ratio()->Delta(); @@ -4786,8 +4801,8 @@ TEST_F(LayerTreeHostImplTopControlsTest, ViewportBoundsDeltaOnTreeActivation) { delta); } - // 200 is the kShowHideMaxDurationMs value from top_controls_manager.cc so the - // top controls should be fully animated in this frame. + // 200 is the kShowHideMaxDurationMs value from browser_controls_manager.cc so + // the browser controls should be fully animated in this frame. { begin_frame_args.frame_time = start_time + base::TimeDelta::FromMilliseconds(200); @@ -4796,7 +4811,7 @@ TEST_F(LayerTreeHostImplTopControlsTest, ViewportBoundsDeltaOnTreeActivation) { host_impl_->UpdateAnimationState(true); host_impl_->DidFinishImplFrame(); - ASSERT_EQ(50, host_impl_->top_controls_manager()->ContentTopOffset()); + ASSERT_EQ(50, host_impl_->browser_controls_manager()->ContentTopOffset()); ASSERT_EQ(1050, outer_scroll->MaxScrollOffset().y()); // NEAR because clip layer bounds are truncated in MaxScrollOffset so we // lose some precision in the intermediate animation steps. @@ -4825,26 +4840,23 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { gfx::Size contents_size(20, 20); std::unique_ptr<LayerImpl> content_layer = - LayerImpl::Create(host_impl_->active_tree(), 1); + LayerImpl::Create(host_impl_->active_tree(), 11); content_layer->SetDrawsContent(true); content_layer->SetPosition(gfx::PointF()); content_layer->SetBounds(contents_size); - std::unique_ptr<LayerImpl> scroll_clip_layer = - LayerImpl::Create(host_impl_->active_tree(), 3); - scroll_clip_layer->SetBounds(surface_size); + LayerImpl* scroll_clip_layer = + CreateBasicVirtualViewportLayers(surface_size, surface_size); std::unique_ptr<LayerImpl> scroll_layer = - LayerImpl::Create(host_impl_->active_tree(), 2); - scroll_layer->SetScrollClipLayer(3); + LayerImpl::Create(host_impl_->active_tree(), 12); + scroll_layer->SetScrollClipLayer(scroll_clip_layer->id()); scroll_layer->SetBounds(contents_size); scroll_layer->SetPosition(gfx::PointF()); scroll_layer->test_properties()->AddChild(std::move(content_layer)); scroll_clip_layer->test_properties()->AddChild(std::move(scroll_layer)); scroll_clip_layer->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting( - std::move(scroll_clip_layer)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(surface_size); @@ -4863,13 +4875,13 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) { TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) { gfx::Size surface_size(10, 10); gfx::Size contents_size(20, 20); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetBounds(surface_size); + + LayerImpl* root = + CreateBasicVirtualViewportLayers(surface_size, surface_size); + root->test_properties()->AddChild( - CreateScrollableLayer(2, contents_size, root.get())); + CreateScrollableLayer(12, contents_size, root)); root->test_properties()->force_render_surface = true; - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(surface_size); @@ -5184,21 +5196,21 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { // parent layer isn't scrolled. gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); - root->SetBounds(surface_size); + + LayerImpl* root = + CreateBasicVirtualViewportLayers(surface_size, surface_size); + root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> grand_child = - CreateScrollableLayer(3, content_size, root.get()); + CreateScrollableLayer(13, content_size, root); std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, content_size, root.get()); + CreateScrollableLayer(12, content_size, root); 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()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); @@ -5230,8 +5242,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) { ->root_layer_for_testing() ->test_properties() ->children[0]; - LayerImpl* grand_child = child->test_properties()->children[0]; - EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child->id(), + EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), grand_child_layer->id(), gfx::Vector2d(0, -5))); // The child should not have scrolled. @@ -5430,17 +5441,26 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { gfx::Size surface_size(10, 10); std::unique_ptr<LayerImpl> root_ptr = LayerImpl::Create(host_impl_->active_tree(), 1); - std::unique_ptr<LayerImpl> root_clip = + std::unique_ptr<LayerImpl> inner_clip = LayerImpl::Create(host_impl_->active_tree(), 2); - std::unique_ptr<LayerImpl> root_scroll = - CreateScrollableLayer(3, surface_size, root_clip.get()); - root_clip->test_properties()->force_render_surface = true; - root_scroll->test_properties()->is_container_for_fixed_position_layers = true; - root_clip->test_properties()->AddChild(std::move(root_scroll)); - root_ptr->test_properties()->AddChild(std::move(root_clip)); + std::unique_ptr<LayerImpl> inner_scroll = + CreateScrollableLayer(3, surface_size, inner_clip.get()); + std::unique_ptr<LayerImpl> outer_clip = + LayerImpl::Create(host_impl_->active_tree(), 7); + std::unique_ptr<LayerImpl> outer_scroll = + CreateScrollableLayer(8, surface_size, outer_clip.get()); + 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)); host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 1, 3, - Layer::INVALID_ID); + 8); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); @@ -5453,19 +5473,27 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) { host_impl_->active_tree()->DetachLayers(); std::unique_ptr<LayerImpl> root_ptr2 = LayerImpl::Create(host_impl_->active_tree(), 4); - std::unique_ptr<LayerImpl> root_clip2 = + std::unique_ptr<LayerImpl> inner_clip2 = LayerImpl::Create(host_impl_->active_tree(), 5); - std::unique_ptr<LayerImpl> root_scroll2 = - CreateScrollableLayer(6, surface_size, root_clip2.get()); - root_scroll2->test_properties()->is_container_for_fixed_position_layers = + std::unique_ptr<LayerImpl> inner_scroll2 = + CreateScrollableLayer(6, surface_size, inner_clip2.get()); + std::unique_ptr<LayerImpl> outer_clip2 = + LayerImpl::Create(host_impl_->active_tree(), 9); + std::unique_ptr<LayerImpl> outer_scroll2 = + CreateScrollableLayer(10, surface_size, outer_clip2.get()); + inner_scroll2->test_properties()->is_container_for_fixed_position_layers = + true; + outer_scroll2->test_properties()->is_container_for_fixed_position_layers = true; - root_clip2->test_properties()->AddChild(std::move(root_scroll2)); - root_clip2->test_properties()->force_render_surface = true; - root_ptr2->test_properties()->AddChild(std::move(root_clip2)); + 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(); host_impl_->active_tree()->SetViewportLayersFromIds(Layer::INVALID_ID, 4, 6, - Layer::INVALID_ID); + 10); host_impl_->active_tree()->DidBecomeActive(); // Scrolling should still work even though we did not draw yet. @@ -6087,7 +6115,6 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) { host_impl_->ScrollEnd(EndState().get()); } - TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { // Scroll child layers beyond their maximum scroll range and make sure root // overscroll does not accumulate. @@ -6108,6 +6135,9 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { LayerImpl* grand_child_layer = grand_child.get(); child->test_properties()->AddChild(std::move(grand_child)); + host_impl_->active_tree()->SetViewportLayersFromIds( + Layer::INVALID_ID, Layer::INVALID_ID, root->id(), Layer::INVALID_ID); + LayerImpl* child_layer = child.get(); root->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root)); @@ -6148,11 +6178,17 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) { .thread); EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), grand_child_layer); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); + host_impl_->ScrollEnd(EndState().get()); + EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, + host_impl_ + ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), + InputHandler::NON_BUBBLING_GESTURE) + .thread); scroll_result = host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); EXPECT_TRUE(scroll_result.did_scroll); EXPECT_FALSE(scroll_result.did_overscroll_root); - EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), child_layer); + EXPECT_EQ(host_impl_->CurrentlyScrollingLayer()->id(), child_layer->id()); EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll()); host_impl_->ScrollEnd(EndState().get()); @@ -6239,7 +6275,13 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) { TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) { InputHandlerScrollResult scroll_result; - SetupScrollAndContentsLayers(gfx::Size(200, 200)); + 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(); DrawFrame(); @@ -6311,10 +6353,15 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) { const gfx::Size viewport_size(50, 50); CreateBasicVirtualViewportLayers(viewport_size, content_size); - LayerImpl* scroll_layer = - host_impl_->active_tree()->InnerViewportScrollLayer(); - scroll_layer->set_main_thread_scrolling_reasons( - MainThreadScrollingReason::kThreadedScrollingDisabled); + host_impl_->active_tree() + ->InnerViewportScrollLayer() + ->set_main_thread_scrolling_reasons( + MainThreadScrollingReason::kThreadedScrollingDisabled); + host_impl_->active_tree() + ->OuterViewportScrollLayer() + ->set_main_thread_scrolling_reasons( + MainThreadScrollingReason::kThreadedScrollingDisabled); + host_impl_->active_tree()->BuildPropertyTreesForTesting(); DrawFrame(); @@ -6338,6 +6385,97 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) { .thread); } +// Test that scrolling the inner viewport directly works, as can happen when the +// scroll chains up to it from an sibling of the outer viewport. +TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) { + const gfx::Size content_size(200, 200); + const gfx::Size viewport_size(100, 100); + + LayerTreeImpl* layer_tree_impl = host_impl_->active_tree(); + + CreateBasicVirtualViewportLayers(viewport_size, viewport_size); + host_impl_->active_tree()->set_top_controls_height(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; + + // 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> clip = LayerImpl::Create(layer_tree_impl, 10); + clip->SetBounds(viewport_size); + clip->SetPosition(gfx::PointF()); + + std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); + scroll->SetBounds(gfx::Size(400, 400)); + scroll->SetScrollClipLayer(clip->id()); + scroll->SetDrawsContent(true); + + scroll_layer = scroll.get(); + + clip->test_properties()->AddChild(std::move(scroll)); + inner_scroll_layer->test_properties()->AddChild(std::move(clip)); + + // Move the outer viewport layer away so that scrolls won't target it. + host_impl_->active_tree()->OuterViewportContainerLayer()->SetPosition( + 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); + } + + // Fully scroll the child. + { + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::TOUCHSCREEN); + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get()); + host_impl_->ScrollEnd(EndState().get()); + + EXPECT_EQ(1.f, + host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(300.f, 300.f), + scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + inner_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + outer_scroll_layer->CurrentScrollOffset()); + } + + // Scrolling on the child now should chain up directly to the inner viewport. + // Scrolling it should cause browser controls to hide. The outer viewport + // should not be affected. + { + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::TOUCHSCREEN); + gfx::Vector2d scroll_delta(0, 10); + host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); + EXPECT_EQ(0.f, + host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + inner_scroll_layer->CurrentScrollOffset()); + + host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); + host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); + + EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 10.f), + inner_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + outer_scroll_layer->CurrentScrollOffset()); + host_impl_->ScrollEnd(EndState().get()); + } +} + // Test that scrolls chain correctly when a child scroller on the page (e.g. a // scrolling div) is set as the outer viewport. This happens in the // rootScroller proposal. @@ -6469,6 +6607,180 @@ 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 +// rootScroller proposal. +TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) { + const gfx::Size content_size(300, 300); + const gfx::Size viewport_size(300, 300); + + 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; + + // 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> clip = LayerImpl::Create(layer_tree_impl, 10); + clip->SetBounds(content_size); + clip->SetPosition(gfx::PointF(100, 100)); + + std::unique_ptr<LayerImpl> scroll = LayerImpl::Create(layer_tree_impl, 11); + scroll->SetBounds(gfx::Size(1200, 1200)); + scroll->SetScrollClipLayer(clip->id()); + scroll->SetDrawsContent(true); + + outer_scroll_layer = scroll.get(); + + clip->test_properties()->AddChild(std::move(scroll)); + content_layer->test_properties()->AddChild(std::move(clip)); + + // Create the non-descendant. + std::unique_ptr<LayerImpl> clip2 = LayerImpl::Create(layer_tree_impl, 14); + clip2->SetBounds(gfx::Size(600, 600)); + clip2->SetPosition(gfx::PointF()); + + std::unique_ptr<LayerImpl> scroll2 = LayerImpl::Create(layer_tree_impl, 15); + scroll2->SetBounds(gfx::Size(1200, 1200)); + scroll2->SetScrollClipLayer(clip2->id()); + scroll2->SetDrawsContent(true); + + sibling_scroll_layer = scroll2.get(); + + clip2->test_properties()->AddChild(std::move(scroll2)); + content_layer->test_properties()->AddChild(std::move(clip2)); + + layer_tree_impl->SetViewportLayersFromIds( + Layer::INVALID_ID, layer_tree_impl->PageScaleLayer()->id(), + inner_scroll_layer->id(), outer_scroll_layer->id()); + layer_tree_impl->BuildPropertyTreesForTesting(); + + ASSERT_EQ(outer_scroll_layer, layer_tree_impl->OuterViewportScrollLayer()); + } + + // Scrolls should target the non-descendant scroller. Chaining should not + // propagate to the outer viewport scroll layer. + { + // This should fully scroll the layer. + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::TOUCHSCREEN); + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get()); + host_impl_->ScrollEnd(EndState().get()); + + EXPECT_VECTOR_EQ(gfx::Vector2dF(600.f, 600.f), + sibling_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + outer_scroll_layer->CurrentScrollOffset()); + + // Scrolling now should chain up but, since the outer viewport is a sibling + // rather than an ancestor, we shouldn't chain to it. + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::TOUCHSCREEN); + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get()); + host_impl_->ScrollEnd(EndState().get()); + + EXPECT_VECTOR_EQ(gfx::Vector2dF(600.f, 600.f), + sibling_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + outer_scroll_layer->CurrentScrollOffset()); + } + + float min_page_scale = 1.f, max_page_scale = 4.f; + float page_scale_factor = 1.f; + host_impl_->active_tree()->PushPageScaleFromMainThread( + page_scale_factor, min_page_scale, max_page_scale); + + gfx::Vector2dF viewport_size_vec(viewport_size.width(), + viewport_size.height()); + + // Reset the scroll offset. + sibling_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset()); + + // Now pinch-zoom in. Anchoring should cause scrolling only on the inner + // viewport layer. + { + // Pinch in to the middle of the screen. The inner viewport should scroll + // to keep the gesture anchored but not the outer or the sibling scroller. + page_scale_factor = 2.f; + gfx::Point anchor(viewport_size.width() / 2, viewport_size.height() / 2); + host_impl_->ScrollBegin(BeginState(anchor).get(), + InputHandler::TOUCHSCREEN); + host_impl_->PinchGestureBegin(); + host_impl_->PinchGestureUpdate(page_scale_factor, anchor); + host_impl_->PinchGestureEnd(); + + EXPECT_VECTOR_EQ(gfx::Vector2dF(anchor.x() / 2, anchor.y() / 2), + inner_scroll_layer->CurrentScrollOffset()); + + host_impl_->ScrollBy(UpdateState(anchor, viewport_size_vec).get()); + + EXPECT_VECTOR_EQ(ScaleVector2d(viewport_size_vec, 1.f / page_scale_factor), + inner_scroll_layer->CurrentScrollOffset()); + // TODO(bokan): This doesn't yet work but we'll probably want to fix this + // at some point. + // EXPECT_VECTOR_EQ( + // gfx::Vector2dF(), + // outer_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + sibling_scroll_layer->CurrentScrollOffset()); + + host_impl_->ScrollEnd(EndState().get()); + } + + // Reset the scroll offsets + sibling_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset()); + inner_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset()); + outer_scroll_layer->SetCurrentScrollOffset(gfx::ScrollOffset()); + + // Scrolls over the sibling while pinched in should scroll the sibling first, + // but then chain up to the inner viewport so that the user can still pan + // around. The outer viewport should be unaffected. + { + // This should fully scroll the sibling but, because we latch to the + // scroller, it shouldn't chain up to the inner viewport yet. + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::TOUCHSCREEN); + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000.f, 2000.f)).get()); + host_impl_->ScrollEnd(EndState().get()); + + EXPECT_VECTOR_EQ(gfx::Vector2dF(600.f, 600.f), + sibling_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + inner_scroll_layer->CurrentScrollOffset()); + + // Scrolling now should chain up to the inner viewport. + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::TOUCHSCREEN); + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000.f, 2000.f)).get()); + host_impl_->ScrollEnd(EndState().get()); + + EXPECT_VECTOR_EQ(ScaleVector2d(viewport_size_vec, 1 / page_scale_factor), + inner_scroll_layer->CurrentScrollOffset()); + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + outer_scroll_layer->CurrentScrollOffset()); + + // No more scrolling should be possible. + host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), + InputHandler::TOUCHSCREEN); + host_impl_->ScrollBy( + UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000.f, 2000.f)).get()); + host_impl_->ScrollEnd(EndState().get()); + + EXPECT_VECTOR_EQ(gfx::Vector2dF(), + outer_scroll_layer->CurrentScrollOffset()); + } +} TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) { InputHandlerScrollResult scroll_result; @@ -7213,7 +7525,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) { std::unique_ptr<LayerTreeHostImpl> layer_tree_host_impl = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, - &shared_bitmap_manager_, NULL, &task_graph_runner_, + &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0); layer_tree_host_impl->SetVisible(true); layer_tree_host_impl->InitializeRenderer(compositor_frame_sink.get()); @@ -7336,15 +7648,14 @@ static std::unique_ptr<LayerTreeHostImpl> SetupLayersForOpacity( bool partial_swap, LayerTreeHostImplClient* client, TaskRunnerProvider* task_runner_provider, - SharedBitmapManager* manager, TaskGraphRunner* task_graph_runner, RenderingStatsInstrumentation* stats_instrumentation, CompositorFrameSink* compositor_frame_sink) { settings.renderer_settings.partial_swap_enabled = partial_swap; std::unique_ptr<LayerTreeHostImpl> my_host_impl = LayerTreeHostImpl::Create( - settings, client, task_runner_provider, stats_instrumentation, manager, - nullptr, task_graph_runner, - AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0); + settings, client, task_runner_provider, stats_instrumentation, + task_graph_runner, AnimationHost::CreateForTesting(ThreadInstance::IMPL), + 0); my_host_impl->SetVisible(true); my_host_impl->InitializeRenderer(compositor_frame_sink); my_host_impl->WillBeginImplFrame( @@ -7407,7 +7718,6 @@ static std::unique_ptr<LayerTreeHostImpl> SetupLayersForOpacity( } TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); provider->BindToCurrentThread(); @@ -7415,9 +7725,8 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { std::unique_ptr<CompositorFrameSink> compositor_frame_sink( FakeCompositorFrameSink::Create3d(provider)); std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( - DefaultSettings(), true, this, &task_runner_provider_, - &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_, - compositor_frame_sink.get()); + DefaultSettings(), true, this, &task_runner_provider_, &task_graph_runner, + &stats_instrumentation_, compositor_frame_sink.get()); { LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame)); @@ -7438,7 +7747,6 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorPartialSwap) { } TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; scoped_refptr<TestContextProvider> provider(TestContextProvider::Create()); provider->BindToCurrentThread(); @@ -7447,8 +7755,7 @@ TEST_F(LayerTreeHostImplTest, ContributingLayerEmptyScissorNoPartialSwap) { FakeCompositorFrameSink::Create3d(provider)); std::unique_ptr<LayerTreeHostImpl> my_host_impl = SetupLayersForOpacity( DefaultSettings(), false, this, &task_runner_provider_, - &shared_bitmap_manager, &task_graph_runner, &stats_instrumentation_, - compositor_frame_sink.get()); + &task_graph_runner, &stats_instrumentation_, compositor_frame_sink.get()); { LayerTreeHostImpl::FrameData frame; EXPECT_EQ(DRAW_SUCCESS, my_host_impl->PrepareToDraw(&frame)); @@ -7715,14 +8022,11 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) { class CompositorFrameMetadataTest : public LayerTreeHostImplTest { public: - CompositorFrameMetadataTest() - : swap_buffers_complete_(0) {} + CompositorFrameMetadataTest() = default; - void DidSwapBuffersCompleteOnImplThread() override { - swap_buffers_complete_++; - } + void DidReceiveCompositorFrameAckOnImplThread() override { acks_received_++; } - int swap_buffers_complete_; + int acks_received_ = 0; }; TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { @@ -7735,8 +8039,8 @@ TEST_F(CompositorFrameMetadataTest, CompositorFrameAckCountsAsSwapComplete) { host_impl_->DidDrawAllLayers(frame); } host_impl_->ReclaimResources(ReturnedResourceArray()); - host_impl_->DidSwapBuffersComplete(); - EXPECT_EQ(swap_buffers_complete_, 1); + host_impl_->DidReceiveCompositorFrameAck(); + EXPECT_EQ(acks_received_, 1); } class CountingSoftwareDevice : public SoftwareOutputDevice { @@ -7821,7 +8125,7 @@ TEST_F(LayerTreeHostImplTest, MemoryLimits) { kSoftwareByteLimit, kSoftwareCutoff, kSoftwareResourceLimit); host_impl_ = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, - &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_, + &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0); // Gpu compositing. @@ -7936,9 +8240,8 @@ TEST_F(LayerTreeHostImplTest, RequireHighResAfterGpuRasterizationToggles) { class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest { public: void SetUp() override { - fake_host_impl_ = - new FakeLayerTreeHostImpl(LayerTreeSettings(), &task_runner_provider_, - &shared_bitmap_manager_, &task_graph_runner_); + fake_host_impl_ = new FakeLayerTreeHostImpl( + LayerTreeSettings(), &task_runner_provider_, &task_graph_runner_); host_impl_.reset(fake_host_impl_); compositor_frame_sink_ = CreateCompositorFrameSink(); host_impl_->SetVisible(true); @@ -8028,18 +8331,39 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) { void ShutdownReleasesContext_Callback( std::unique_ptr<CopyOutputResult> result) {} +class FrameSinkClient : public TestCompositorFrameSinkClient { + public: + explicit FrameSinkClient( + scoped_refptr<ContextProvider> display_context_provider) + : display_context_provider_(std::move(display_context_provider)) {} + + std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + scoped_refptr<ContextProvider> compositor_context_provider) override { + return FakeOutputSurface::Create3d(std::move(display_context_provider_)); + } + + void DisplayReceivedCompositorFrame(const CompositorFrame& frame) override {} + void DisplayWillDrawAndSwap(bool will_draw_and_swap, + const RenderPassList& render_passes) override {} + void DisplayDidDrawAndSwap() override {} + + private: + scoped_refptr<ContextProvider> display_context_provider_; +}; + TEST_F(LayerTreeHostImplTest, ShutdownReleasesContext) { scoped_refptr<TestContextProvider> context_provider = TestContextProvider::Create(); + FrameSinkClient test_client_(context_provider); - CreateHostImpl( - DefaultSettings(), - base::MakeUnique<TestCompositorFrameSink>( - context_provider, TestContextProvider::CreateWorker(), - FakeOutputSurface::Create3d(context_provider), nullptr, nullptr, - RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), - true /* synchronous_composite */, - false /* force_disable_reclaim_resources */)); + auto compositor_frame_sink = base::MakeUnique<TestCompositorFrameSink>( + context_provider, TestContextProvider::CreateWorker(), nullptr, nullptr, + RendererSettings(), base::ThreadTaskRunnerHandle::Get().get(), + true /* synchronous_composite */, + false /* force_disable_reclaim_resources */); + compositor_frame_sink->SetClient(&test_client_); + + CreateHostImpl(DefaultSettings(), std::move(compositor_frame_sink)); SetupRootLayerImpl(LayerImpl::Create(host_impl_->active_tree(), 1)); @@ -8126,26 +8450,25 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { // Scroll a child layer beyond its maximum scroll range and make sure the // the scroll doesn't bubble up to the parent layer. gfx::Size surface_size(10, 10); - std::unique_ptr<LayerImpl> root = - LayerImpl::Create(host_impl_->active_tree(), 1); + LayerImpl* root = + CreateBasicVirtualViewportLayers(surface_size, surface_size); root->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> root_scrolling_owned = - CreateScrollableLayer(2, surface_size, root.get()); + CreateScrollableLayer(12, surface_size, root); auto* root_scrolling = root_scrolling_owned.get(); root->test_properties()->AddChild(std::move(root_scrolling_owned)); std::unique_ptr<LayerImpl> child_owned = - CreateScrollableLayer(3, surface_size, root.get()); + CreateScrollableLayer(13, surface_size, root); auto* child = child_owned.get(); root_scrolling->test_properties()->AddChild(std::move(child_owned)); std::unique_ptr<LayerImpl> grand_child_owned = - CreateScrollableLayer(4, surface_size, root.get()); + CreateScrollableLayer(14, surface_size, root); auto* grand_child = grand_child_owned.get(); child->test_properties()->AddChild(std::move(grand_child_owned)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); @@ -8162,13 +8485,6 @@ TEST_F(LayerTreeHostImplTest, TouchFlingShouldContinueScrollingCurrentLayer) { DrawFrame(); { std::unique_ptr<ScrollAndScaleSet> scroll_info; - LayerImpl* child = host_impl_->active_tree() - ->root_layer_for_testing() - ->test_properties() - ->children[0] - ->test_properties() - ->children[0]; - LayerImpl* grand_child = child->test_properties()->children[0]; gfx::Vector2d scroll_delta(0, -2); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -8225,19 +8541,18 @@ TEST_F(LayerTreeHostImplTest, WheelFlingShouldntBubble) { // When flinging via wheel, we shouldn't bubble. gfx::Size surface_size(10, 10); gfx::Size content_size(20, 20); - std::unique_ptr<LayerImpl> root_clip = - LayerImpl::Create(host_impl_->active_tree(), 3); + LayerImpl* root_clip = + CreateBasicVirtualViewportLayers(surface_size, surface_size); root_clip->test_properties()->force_render_surface = true; std::unique_ptr<LayerImpl> root_scroll = - CreateScrollableLayer(1, content_size, root_clip.get()); + CreateScrollableLayer(11, content_size, root_clip); int root_scroll_id = root_scroll->id(); std::unique_ptr<LayerImpl> child = - CreateScrollableLayer(2, content_size, root_clip.get()); + CreateScrollableLayer(12, content_size, root_clip); root_scroll->test_properties()->AddChild(std::move(child)); root_clip->test_properties()->AddChild(std::move(root_scroll)); - host_impl_->active_tree()->SetRootLayerForTesting(std::move(root_clip)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->active_tree()->DidBecomeActive(); @@ -8345,7 +8660,7 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) { status.main_thread_scrolling_reasons); } -TEST_F(LayerTreeHostImplTest, NotScrollInvisibleScroller) { +TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) { gfx::Size content_size(100, 100); SetupScrollAndContentsLayers(content_size); @@ -8365,110 +8680,8 @@ TEST_F(LayerTreeHostImplTest, NotScrollInvisibleScroller) { DrawFrame(); - // We should not have scrolled |child_scroll| even though we technically "hit" - // it. The reason for this is that if the scrolling the scroll would not move - // any layer that is a drawn RSLL member, then we can ignore the hit. - // - // Why SCROLL_STARTED? In this case, it's because we've bubbled out and - // started scrolling the inner viewport. - EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL) - .thread); - - EXPECT_EQ(2, host_impl_->CurrentlyScrollingLayer()->id()); -} - -TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleDescendent) { - gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); - - LayerImpl* root = host_impl_->active_tree()->LayerById(1); - LayerImpl* root_scroll_layer = host_impl_->active_tree()->LayerById(2); - - std::unique_ptr<LayerImpl> invisible_scroll_layer = - CreateScrollableLayer(7, content_size, root); - invisible_scroll_layer->SetDrawsContent(false); - - std::unique_ptr<LayerImpl> child_layer = - LayerImpl::Create(host_impl_->active_tree(), 8); - child_layer->SetDrawsContent(false); - - std::unique_ptr<LayerImpl> grand_child_layer = - LayerImpl::Create(host_impl_->active_tree(), 9); - grand_child_layer->SetDrawsContent(true); - grand_child_layer->SetBounds(content_size); - // Move the grand child so it's not hit by our test point. - grand_child_layer->SetPosition(gfx::PointF(10.f, 10.f)); - - child_layer->test_properties()->AddChild(std::move(grand_child_layer)); - invisible_scroll_layer->test_properties()->AddChild(std::move(child_layer)); - root_scroll_layer->test_properties()->AddChild( - std::move(invisible_scroll_layer)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - DrawFrame(); - - // We should have scrolled |invisible_scroll_layer| as it was hit and it has - // a descendant which is a drawn RSLL member. - EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, - host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), - InputHandler::WHEEL) - .thread); - - EXPECT_EQ(7, host_impl_->CurrentlyScrollingLayer()->id()); -} - -TEST_F(LayerTreeHostImplTest, ScrollInvisibleScrollerWithVisibleScrollChild) { - // This test case is very similar to the one above with one key difference: - // the invisible scroller has a scroll child that is indeed draw contents. - // If we attempt to initiate a gesture scroll off of the visible scroll child - // we should still start the scroll child. - gfx::Size content_size(100, 100); - SetupScrollAndContentsLayers(content_size); - - LayerImpl* root = host_impl_->active_tree()->LayerById(1); - - int scroll_layer_id = 2; - LayerImpl* scroll_layer = - host_impl_->active_tree()->LayerById(scroll_layer_id); - - int scroll_child_id = 6; - std::unique_ptr<LayerImpl> scroll_child = - LayerImpl::Create(host_impl_->active_tree(), scroll_child_id); - scroll_child->SetDrawsContent(true); - scroll_child->SetBounds(content_size); - // Move the scroll child so it's not hit by our test point. - scroll_child->SetPosition(gfx::PointF(10.f, 10.f)); - - int invisible_scroll_layer_id = 7; - std::unique_ptr<LayerImpl> invisible_scroll = - CreateScrollableLayer(invisible_scroll_layer_id, content_size, root); - invisible_scroll->SetDrawsContent(false); - - int container_id = 8; - std::unique_ptr<LayerImpl> container = - LayerImpl::Create(host_impl_->active_tree(), container_id); - - std::unique_ptr<std::set<LayerImpl*>> scroll_children( - new std::set<LayerImpl*>); - scroll_children->insert(scroll_child.get()); - invisible_scroll->test_properties()->scroll_children.reset( - scroll_children.release()); - - scroll_child->test_properties()->scroll_parent = invisible_scroll.get(); - - container->test_properties()->AddChild(std::move(invisible_scroll)); - container->test_properties()->AddChild(std::move(scroll_child)); - - scroll_layer->test_properties()->AddChild(std::move(container)); - host_impl_->active_tree()->BuildPropertyTreesForTesting(); - - DrawFrame(); - - // We should have scrolled |child_scroll| even though it is invisible. - // The reason for this is that if the scrolling the scroll would move a layer - // that is a drawn RSLL member, then we should accept this hit. + // We should have scrolled |child_scroll| even though it does not move + // any layer that is a drawn RSLL member. EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) @@ -8688,23 +8901,23 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) { } } -class LayerTreeHostImplWithTopControlsTest : public LayerTreeHostImplTest { +class LayerTreeHostImplWithBrowserControlsTest : public LayerTreeHostImplTest { public: void SetUp() override { LayerTreeSettings settings = DefaultSettings(); CreateHostImpl(settings, CreateCompositorFrameSink()); host_impl_->active_tree()->set_top_controls_height(top_controls_height_); host_impl_->sync_tree()->set_top_controls_height(top_controls_height_); - host_impl_->active_tree()->SetCurrentTopControlsShownRatio(1.f); + host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f); } protected: static const int top_controls_height_; }; -const int LayerTreeHostImplWithTopControlsTest::top_controls_height_ = 50; +const int LayerTreeHostImplWithBrowserControlsTest::top_controls_height_ = 50; -TEST_F(LayerTreeHostImplWithTopControlsTest, NoIdleAnimations) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, NoIdleAnimations) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); scroll_layer->layer_tree_impl() ->property_trees() @@ -8718,49 +8931,52 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, NoIdleAnimations) { host_impl_->DidFinishImplFrame(); } -TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsHeightIsCommitted) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + BrowserControlsHeightIsCommitted) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); EXPECT_FALSE(did_request_redraw_); host_impl_->CreatePendingTree(); host_impl_->sync_tree()->set_top_controls_height(100); host_impl_->ActivateSyncTree(); - EXPECT_EQ(100, host_impl_->top_controls_manager()->TopControlsHeight()); + EXPECT_EQ(100, host_impl_->browser_controls_manager()->TopControlsHeight()); } -TEST_F(LayerTreeHostImplWithTopControlsTest, - TopControlsStayFullyVisibleOnHeightChange) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + BrowserControlsStayFullyVisibleOnHeightChange) { SetupScrollAndContentsLayers(gfx::Size(100, 100)); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset()); host_impl_->CreatePendingTree(); host_impl_->sync_tree()->set_top_controls_height(0); host_impl_->ActivateSyncTree(); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset()); host_impl_->CreatePendingTree(); host_impl_->sync_tree()->set_top_controls_height(50); host_impl_->ActivateSyncTree(); - EXPECT_EQ(0.f, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset()); } -TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationScheduling) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + BrowserControlsAnimationScheduling) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 100)); scroll_layer->layer_tree_impl() ->property_trees() ->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->id(), gfx::ScrollOffset(0, 10)); - host_impl_->DidChangeTopControlsPosition(); + host_impl_->DidChangeBrowserControlsPosition(); EXPECT_TRUE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); } -TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + ScrollHandledByBrowserControls) { InputHandlerScrollResult result; LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(gfx::Size(100, 100)); - host_impl_->top_controls_manager()->UpdateTopControlsState( + host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BOTH, SHOWN, false); DrawFrame(); @@ -8769,11 +8985,11 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); - // Scroll just the top controls and verify that the scroll succeeds. + // Scroll just the browser controls and verify that the scroll succeeds. const float residue = 10; float offset = top_controls_height_ - residue; result = host_impl_->ScrollBy( @@ -8781,7 +8997,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0)); EXPECT_TRUE(result.did_scroll); EXPECT_FLOAT_EQ(-offset, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8793,7 +9009,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { EXPECT_TRUE(result.did_scroll); EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0)); EXPECT_EQ(-top_controls_height_, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, content_scroll).ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8804,17 +9020,17 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { EXPECT_TRUE(result.did_scroll); EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0)); EXPECT_EQ(-top_controls_height_, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); - // And scroll the top controls completely into view + // And scroll the browser controls completely into view offset = -top_controls_height_; result = host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get()); EXPECT_TRUE(result.did_scroll); EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0)); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8823,19 +9039,20 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ScrollHandledByTopControls) { UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get()); EXPECT_FALSE(result.did_scroll); EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, -50)); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); host_impl_->ScrollEnd(EndState().get()); } -TEST_F(LayerTreeHostImplWithTopControlsTest, WheelUnhandledByTopControls) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + WheelUnhandledByBrowserControls) { SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->SetViewportSize(gfx::Size(50, 100)); - host_impl_->active_tree()->set_top_controls_shrink_blink_size(true); - host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN, - false); + host_impl_->active_tree()->set_browser_controls_shrink_blink_size(true); + host_impl_->browser_controls_manager()->UpdateBrowserControlsState( + BOTH, SHOWN, false); DrawFrame(); LayerImpl* viewport_layer = host_impl_->InnerViewportScrollLayer(); @@ -8844,17 +9061,18 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, WheelUnhandledByTopControls) { host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL) .thread); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(), viewport_layer->CurrentScrollOffset()); - // Wheel scrolls should not affect the top controls, and should pass + // Wheel scrolls should not affect the browser controls, and should pass // directly through to the viewport. const float delta = top_controls_height_; EXPECT_TRUE( host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, delta)).get()) .did_scroll); - EXPECT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0, + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0, delta), viewport_layer->CurrentScrollOffset()); @@ -8862,17 +9080,19 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, WheelUnhandledByTopControls) { host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, delta)).get()) .did_scroll); - EXPECT_FLOAT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_FLOAT_EQ(0, + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_VECTOR_EQ(gfx::Vector2dF(0, delta * 2), viewport_layer->CurrentScrollOffset()); } -TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + BrowserControlsAnimationAtOrigin) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(gfx::Size(100, 200)); - host_impl_->top_controls_manager()->UpdateTopControlsState( + host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BOTH, SHOWN, false); DrawFrame(); @@ -8881,11 +9101,11 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); - // Scroll the top controls partially. + // Scroll the browser controls partially. const float residue = 35; float offset = top_controls_height_ - residue; EXPECT_TRUE( @@ -8893,7 +9113,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get()) .did_scroll); EXPECT_FLOAT_EQ(-offset, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8903,13 +9123,13 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { // End the scroll while the controls are still offset from their limit. host_impl_->ScrollEnd(EndState().get()); - ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation()); + ASSERT_TRUE(host_impl_->browser_controls_manager()->has_animation()); EXPECT_TRUE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); EXPECT_FALSE(did_request_commit_); - // The top controls should properly animate until finished, despite the scroll - // offset being at the origin. + // The browser controls should properly animate until finished, despite the + // scroll offset being at the origin. BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting( BEGINFRAME_FROM_HERE, base::TimeTicks::Now()); while (did_request_next_frame_) { @@ -8918,7 +9138,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { did_request_commit_ = false; float old_offset = - host_impl_->top_controls_manager()->ControlsTopOffset(); + host_impl_->browser_controls_manager()->ControlsTopOffset(); begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5); host_impl_->WillBeginImplFrame(begin_frame_args); @@ -8927,7 +9147,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { scroll_layer->CurrentScrollOffset().ToString()); float new_offset = - host_impl_->top_controls_manager()->ControlsTopOffset(); + host_impl_->browser_controls_manager()->ControlsTopOffset(); // No commit is needed as the controls are animating the content offset, // not the scroll offset. @@ -8937,20 +9157,21 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAtOrigin) { EXPECT_TRUE(did_request_redraw_); if (new_offset != 0) { - EXPECT_TRUE(host_impl_->top_controls_manager()->has_animation()); + EXPECT_TRUE(host_impl_->browser_controls_manager()->has_animation()); EXPECT_TRUE(did_request_next_frame_); } host_impl_->DidFinishImplFrame(); } - EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation()); + EXPECT_FALSE(host_impl_->browser_controls_manager()->has_animation()); } -TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + BrowserControlsAnimationAfterScroll) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(gfx::Size(100, 100)); - host_impl_->top_controls_manager()->UpdateTopControlsState( + host_impl_->browser_controls_manager()->UpdateBrowserControlsState( BOTH, SHOWN, false); float initial_scroll_offset = 50; scroll_layer->layer_tree_impl() @@ -8964,11 +9185,11 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), scroll_layer->CurrentScrollOffset().ToString()); - // Scroll the top controls partially. + // Scroll the browser controls partially. const float residue = 15; float offset = top_controls_height_ - residue; EXPECT_TRUE( @@ -8976,7 +9197,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get()) .did_scroll); EXPECT_FLOAT_EQ(-offset, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -8986,12 +9207,12 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { // End the scroll while the controls are still offset from the limit. host_impl_->ScrollEnd(EndState().get()); - ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation()); + ASSERT_TRUE(host_impl_->browser_controls_manager()->has_animation()); EXPECT_TRUE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); EXPECT_FALSE(did_request_commit_); - // Animate the top controls to the limit. + // Animate the browser controls to the limit. BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting( BEGINFRAME_FROM_HERE, base::TimeTicks::Now()); while (did_request_next_frame_) { @@ -9000,14 +9221,14 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { did_request_commit_ = false; float old_offset = - host_impl_->top_controls_manager()->ControlsTopOffset(); + host_impl_->browser_controls_manager()->ControlsTopOffset(); begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5); host_impl_->WillBeginImplFrame(begin_frame_args); host_impl_->Animate(); float new_offset = - host_impl_->top_controls_manager()->ControlsTopOffset(); + host_impl_->browser_controls_manager()->ControlsTopOffset(); if (new_offset != old_offset) { EXPECT_TRUE(did_request_redraw_); @@ -9015,19 +9236,19 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, TopControlsAnimationAfterScroll) { } host_impl_->DidFinishImplFrame(); } - EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation()); + EXPECT_FALSE(host_impl_->browser_controls_manager()->has_animation()); EXPECT_EQ(-top_controls_height_, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); } -TEST_F(LayerTreeHostImplWithTopControlsTest, - TopControlsAnimationAfterMainThreadFlingStopped) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + BrowserControlsAnimationAfterMainThreadFlingStopped) { LayerImpl* scroll_layer = SetupScrollAndContentsLayers(gfx::Size(100, 200)); host_impl_->active_tree()->BuildPropertyTreesForTesting(); host_impl_->SetViewportSize(gfx::Size(100, 100)); - host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN, - false); + host_impl_->browser_controls_manager()->UpdateBrowserControlsState( + BOTH, SHOWN, false); float initial_scroll_offset = 50; scroll_layer->layer_tree_impl() ->property_trees() @@ -9040,11 +9261,11 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), scroll_layer->CurrentScrollOffset().ToString()); - // Scroll the top controls partially. + // Scroll the browser controls partially. const float residue = 15; float offset = top_controls_height_ - residue; EXPECT_TRUE( @@ -9052,7 +9273,7 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get()) .did_scroll); EXPECT_FLOAT_EQ(-offset, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -9062,12 +9283,12 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, // End the fling while the controls are still offset from the limit. host_impl_->MainThreadHasStoppedFlinging(); - ASSERT_TRUE(host_impl_->top_controls_manager()->has_animation()); + ASSERT_TRUE(host_impl_->browser_controls_manager()->has_animation()); EXPECT_TRUE(did_request_next_frame_); EXPECT_TRUE(did_request_redraw_); EXPECT_FALSE(did_request_commit_); - // Animate the top controls to the limit. + // Animate the browser controls to the limit. BeginFrameArgs begin_frame_args = CreateBeginFrameArgsForTesting( BEGINFRAME_FROM_HERE, base::TimeTicks::Now()); while (did_request_next_frame_) { @@ -9075,13 +9296,15 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, did_request_next_frame_ = false; did_request_commit_ = false; - float old_offset = host_impl_->top_controls_manager()->ControlsTopOffset(); + float old_offset = + host_impl_->browser_controls_manager()->ControlsTopOffset(); begin_frame_args.frame_time += base::TimeDelta::FromMilliseconds(5); host_impl_->WillBeginImplFrame(begin_frame_args); host_impl_->Animate(); - float new_offset = host_impl_->top_controls_manager()->ControlsTopOffset(); + float new_offset = + host_impl_->browser_controls_manager()->ControlsTopOffset(); if (new_offset != old_offset) { EXPECT_TRUE(did_request_redraw_); @@ -9089,21 +9312,21 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, } host_impl_->DidFinishImplFrame(); } - EXPECT_FALSE(host_impl_->top_controls_manager()->has_animation()); + EXPECT_FALSE(host_impl_->browser_controls_manager()->has_animation()); EXPECT_EQ(-top_controls_height_, - host_impl_->top_controls_manager()->ControlsTopOffset()); + host_impl_->browser_controls_manager()->ControlsTopOffset()); } -TEST_F(LayerTreeHostImplWithTopControlsTest, - TopControlsScrollDeltaInOverScroll) { +TEST_F(LayerTreeHostImplWithBrowserControlsTest, + BrowserControlsScrollDeltaInOverScroll) { // Verifies that the overscroll delta should not have accumulated in - // the top controls if we do a hide and show without releasing finger. + // 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(); host_impl_->SetViewportSize(gfx::Size(100, 100)); - host_impl_->top_controls_manager()->UpdateTopControlsState(BOTH, SHOWN, - false); + host_impl_->browser_controls_manager()->UpdateBrowserControlsState( + BOTH, SHOWN, false); DrawFrame(); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, @@ -9111,14 +9334,15 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); float offset = 50; EXPECT_TRUE( host_impl_->ScrollBy( UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get()) .did_scroll); - EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(-offset, + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_EQ(gfx::Vector2dF().ToString(), scroll_layer->CurrentScrollOffset().ToString()); @@ -9157,7 +9381,8 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, .did_scroll); EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(), scroll_layer->CurrentScrollOffset().ToString()); - EXPECT_EQ(-offset, host_impl_->top_controls_manager()->ControlsTopOffset()); + EXPECT_EQ(-offset, + host_impl_->browser_controls_manager()->ControlsTopOffset()); EXPECT_TRUE( host_impl_->ScrollBy( @@ -9166,21 +9391,21 @@ TEST_F(LayerTreeHostImplWithTopControlsTest, EXPECT_EQ(gfx::Vector2dF(0, 0).ToString(), scroll_layer->CurrentScrollOffset().ToString()); - // Top controls should be fully visible - EXPECT_EQ(0, host_impl_->top_controls_manager()->ControlsTopOffset()); + // Browser controls should be fully visible + EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset()); host_impl_->ScrollEnd(EndState().get()); } // Tests that when we set a child scroller (e.g. a scrolling div) as the outer -// viewport, scrolling it controls the top controls. -TEST_F(LayerTreeHostImplTopControlsTest, - ReplacedOuterViewportScrollsTopControls) { +// viewport, scrolling it controls the browser controls. +TEST_F(LayerTreeHostImplBrowserControlsTest, + ReplacedOuterViewportScrollsBrowserControls) { const gfx::Size scroll_content_size(400, 400); const gfx::Size root_layer_size(200, 200); const gfx::Size viewport_size(100, 100); - SetupTopControlsAndScrollLayerWithVirtualViewport( + SetupBrowserControlsAndScrollLayerWithVirtualViewport( viewport_size, viewport_size, root_layer_size); LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); @@ -9212,9 +9437,9 @@ TEST_F(LayerTreeHostImplTopControlsTest, DrawFrame(); } - ASSERT_EQ(1.f, host_impl_->active_tree()->CurrentTopControlsShownRatio()); + ASSERT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); - // Scrolling should scroll the child content and the top controls. The + // Scrolling should scroll the child content and the browser controls. The // original outer viewport should get no scroll. { host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), @@ -9226,7 +9451,8 @@ TEST_F(LayerTreeHostImplTopControlsTest, 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()->CurrentTopControlsShownRatio()); + EXPECT_EQ(0.f, + host_impl_->active_tree()->CurrentBrowserControlsShownRatio()); } } @@ -9356,16 +9582,16 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) { ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); + EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->FlingScrollBegin().thread); - EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); + EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer()); gfx::Vector2d scroll_delta(inner_viewport.width() / 2.f, inner_viewport.height() / 2.f); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); - EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); + EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollEnd(EndState().get()); EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer()); @@ -9379,18 +9605,18 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, FlingScrollBubblesToInner) { ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); + EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_->FlingScrollBegin().thread); - EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); + EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); inner_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); - EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); + EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get()); outer_expected += gfx::Vector2dF(scroll_delta.x(), scroll_delta.y()); - EXPECT_EQ(inner_scroll, host_impl_->CurrentlyScrollingLayer()); + EXPECT_EQ(outer_scroll, host_impl_->CurrentlyScrollingLayer()); host_impl_->ScrollEnd(EndState().get()); EXPECT_EQ(nullptr, host_impl_->CurrentlyScrollingLayer()); @@ -9536,7 +9762,6 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, SetupVirtualViewportLayers(content_size, outer_viewport, inner_viewport); LayerImpl* outer_scroll = host_impl_->OuterViewportScrollLayer(); - LayerImpl* inner_scroll = host_impl_->InnerViewportScrollLayer(); std::unique_ptr<LayerImpl> child = CreateScrollableLayer(10, outer_viewport, outer_scroll); @@ -9552,7 +9777,8 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, ->RootScrollBegin(BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN) .thread); - EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), inner_scroll); + EXPECT_EQ(host_impl_->CurrentlyScrollingLayer(), + host_impl_->ViewportMainScrollLayer()); host_impl_->ScrollEnd(EndState().get()); EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, host_impl_ @@ -9901,9 +10127,9 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { host_impl_->SetViewportSize(gfx::Size(50, 50)); host_impl_->active_tree()->UpdateDrawProperties(update_lcd_text); - TransformNode* node = - host_impl_->active_tree()->property_trees()->transform_tree.Node( - test_layer->transform_tree_index()); + EffectNode* node = + host_impl_->active_tree()->property_trees()->effect_tree.Node( + test_layer->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f)); gfx::Transform external_transform; @@ -9917,8 +10143,8 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { // Transform node's sublayer scale should include the device transform scale. host_impl_->OnDraw(external_transform, external_viewport, resourceless_software_draw); - node = host_impl_->active_tree()->property_trees()->transform_tree.Node( - test_layer->transform_tree_index()); + node = host_impl_->active_tree()->property_trees()->effect_tree.Node( + test_layer->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); // Clear the external transform. @@ -9928,8 +10154,8 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) { host_impl_->OnDraw(external_transform, external_viewport, resourceless_software_draw); - node = host_impl_->active_tree()->property_trees()->transform_tree.Node( - test_layer->transform_tree_index()); + node = host_impl_->active_tree()->property_trees()->effect_tree.Node( + test_layer->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f)); } @@ -10143,7 +10369,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_TRUE(host_impl_->animation_host()->HasAnyAnimationTargetingProperty( + EXPECT_TRUE(GetImplAnimationHost()->HasAnyAnimationTargetingProperty( scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET)); EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); @@ -10176,7 +10402,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) { // The instant scroll should have marked the smooth scroll animation as // aborted. - EXPECT_FALSE(host_impl_->animation_host()->HasActiveAnimationForTesting( + EXPECT_FALSE(GetImplAnimationHost()->HasActiveAnimationForTesting( scrolling_layer->element_id())); EXPECT_VECTOR2DF_EQ(gfx::ScrollOffset(0, y + 50), @@ -10214,7 +10440,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, host_impl_->Animate(); host_impl_->UpdateAnimationState(true); - EXPECT_TRUE(host_impl_->animation_host()->HasAnyAnimationTargetingProperty( + EXPECT_TRUE(GetImplAnimationHost()->HasAnyAnimationTargetingProperty( scrolling_layer->element_id(), TargetProperty::SCROLL_OFFSET)); EXPECT_EQ(gfx::ScrollOffset(), scrolling_layer->CurrentScrollOffset()); @@ -10230,12 +10456,12 @@ TEST_F(LayerTreeHostImplTimelinesTest, EXPECT_TRUE(y > 1 && y < 49); // Abort animation. - host_impl_->animation_host()->ScrollAnimationAbort(true /*needs_completion*/); + GetImplAnimationHost()->ScrollAnimationAbort(true /*needs_completion*/); host_impl_->UpdateAnimationState(true); // Aborting with the needs completion param should have marked the smooth // scroll animation as finished. - EXPECT_FALSE(host_impl_->animation_host()->HasActiveAnimationForTesting( + EXPECT_FALSE(GetImplAnimationHost()->HasActiveAnimationForTesting( scrolling_layer->element_id())); EXPECT_TRUE(y > 1 && y < 49); EXPECT_EQ(NULL, host_impl_->CurrentlyScrollingLayer()); @@ -10906,38 +11132,104 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) { EXPECT_FALSE(controller.did_draw_frame()); } -TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) { +// Tests that SetHasGpuRasterizationTrigger behaves as expected. +TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusTrigger) { + // Set initial state, before varying GPU rasterization trigger. + host_impl_->SetHasGpuRasterizationTrigger(false); + host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, + host_impl_->gpu_rasterization_status()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + // Toggle the trigger on. host_impl_->SetHasGpuRasterizationTrigger(true); - host_impl_->SetContentIsSuitableForGpuRasterization(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + // And off. host_impl_->SetHasGpuRasterizationTrigger(false); - host_impl_->SetContentIsSuitableForGpuRasterization(true); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_VIEWPORT, host_impl_->gpu_rasterization_status()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); +} +// Tests that SetContentIsSuitableForGpuRasterization behaves as expected. +TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSuitability) { + // Set initial state, before varying GPU rasterization suitability. host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentIsSuitableForGpuRasterization(false); host_impl_->CommitComplete(); EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, host_impl_->gpu_rasterization_status()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + + // Toggle suitability on. + host_impl_->SetContentIsSuitableForGpuRasterization(true); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_FALSE(host_impl_->use_msaa()); + // And off. + host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_FALSE(host_impl_->use_msaa()); +} + +// Tests that SetDeviceScaleFactor correctly impacts GPU rasterization. +TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) { + // Create a host impl with MSAA support. std::unique_ptr<TestWebGraphicsContext3D> context_with_msaa = TestWebGraphicsContext3D::Create(); - context_with_msaa->SetMaxSamples(8); + context_with_msaa->SetMaxSamples(4); + LayerTreeSettings msaaSettings = GpuRasterizationEnabledSettings(); + msaaSettings.gpu_rasterization_msaa_sample_count = -1; + EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeCompositorFrameSink::Create3d( + std::move(context_with_msaa)))); + + // Set initial state, before varying scale factor. + host_impl_->SetHasGpuRasterizationTrigger(true); + host_impl_->SetContentIsSuitableForGpuRasterization(false); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + + // Set device scale factor to 2, which lowers the required MSAA samples from + // 8 to 4. + host_impl_->active_tree()->SetDeviceScaleFactor(2.0f); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_TRUE(host_impl_->use_gpu_rasterization()); + EXPECT_TRUE(host_impl_->use_msaa()); + + // Set device scale factor back to 1. + host_impl_->active_tree()->SetDeviceScaleFactor(1.0f); + host_impl_->CommitComplete(); + EXPECT_EQ(GpuRasterizationStatus::OFF_CONTENT, + host_impl_->gpu_rasterization_status()); + EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + EXPECT_FALSE(host_impl_->use_msaa()); +} +// Tests that explicit MSAA sample count correctly impacts GPU rasterization. +TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusExplicitMSAACount) { + // Create a host impl with MSAA support and a forced sample count of 4. + std::unique_ptr<TestWebGraphicsContext3D> context_with_msaa = + TestWebGraphicsContext3D::Create(); + context_with_msaa->SetMaxSamples(4); LayerTreeSettings msaaSettings = GpuRasterizationEnabledSettings(); msaaSettings.gpu_rasterization_msaa_sample_count = 4; EXPECT_TRUE(CreateHostImpl(msaaSettings, FakeCompositorFrameSink::Create3d( std::move(context_with_msaa)))); + host_impl_->SetHasGpuRasterizationTrigger(true); host_impl_->SetContentIsSuitableForGpuRasterization(false); host_impl_->CommitComplete(); @@ -10945,7 +11237,11 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) { host_impl_->gpu_rasterization_status()); EXPECT_TRUE(host_impl_->use_gpu_rasterization()); EXPECT_TRUE(host_impl_->use_msaa()); +} +// Tests that GPU rasterization overrides work as expected. +TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusOverrides) { + // GPU rasterization explicitly disabled. LayerTreeSettings settings = DefaultSettings(); settings.gpu_rasterization_enabled = false; EXPECT_TRUE(CreateHostImpl(settings, FakeCompositorFrameSink::Create3d())); @@ -10956,6 +11252,7 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusModes) { host_impl_->gpu_rasterization_status()); EXPECT_FALSE(host_impl_->use_gpu_rasterization()); + // GPU rasterization explicitly forced. settings.gpu_rasterization_forced = true; EXPECT_TRUE(CreateHostImpl(settings, FakeCompositorFrameSink::Create3d())); @@ -11090,9 +11387,9 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { DrawFrame(); - TransformNode* node = - host_impl_->active_tree()->property_trees()->transform_tree.Node( - in_subtree_of_page_scale_layer->transform_tree_index()); + EffectNode* node = + host_impl_->active_tree()->property_trees()->effect_tree.Node( + in_subtree_of_page_scale_layer->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f)); host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f); @@ -11100,8 +11397,8 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) { DrawFrame(); in_subtree_of_page_scale_layer = host_impl_->active_tree()->LayerById(100); - node = host_impl_->active_tree()->property_trees()->transform_tree.Node( - in_subtree_of_page_scale_layer->transform_tree_index()); + node = host_impl_->active_tree()->property_trees()->effect_tree.Node( + in_subtree_of_page_scale_layer->effect_tree_index()); EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f)); } @@ -11141,7 +11438,7 @@ TEST_F(LayerTreeHostImplTest, JitterTest) { 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()->LastScrolledLayerId()); + 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: @@ -11187,7 +11484,7 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnCompositorFrameSinkChange) { host_impl_ = LayerTreeHostImpl::Create( settings, this, &task_runner_provider_, &stats_instrumentation_, - &shared_bitmap_manager_, &gpu_memory_buffer_manager_, &task_graph_runner_, + &task_graph_runner_, AnimationHost::CreateForTesting(ThreadInstance::IMPL), 0); host_impl_->SetVisible(true); @@ -11203,5 +11500,130 @@ TEST_F(LayerTreeHostImplTest, RecomputeGpuRasterOnCompositorFrameSinkChange) { EXPECT_FALSE(host_impl_->use_gpu_rasterization()); } +TEST_F(LayerTreeHostImplTest, LayerTreeHostImplTestScrollbarStates) { + LayerTreeSettings settings = DefaultSettings(); + settings.scrollbar_fade_delay = base::TimeDelta::FromMilliseconds(500); + settings.scrollbar_fade_duration = base::TimeDelta::FromMilliseconds(300); + settings.scrollbar_animator = LayerTreeSettings::THINNING; + + gfx::Size viewport_size(300, 200); + gfx::Size content_size(1000, 1000); + gfx::Size child_layer_size(250, 150); + 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_clip_id = 12; + const int child_scroll_id = 13; + + CreateHostImpl(settings, CreateCompositorFrameSink()); + host_impl_->active_tree()->SetDeviceScaleFactor(1); + host_impl_->SetViewportSize(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(); + + // scrollbar_1 on root scroll. + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_1 = + SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), + scrollbar_1_id, VERTICAL, 5, 5, true, + true); + scrollbar_1->SetScrollLayerId(root_scroll->id()); + scrollbar_1->SetDrawsContent(true); + scrollbar_1->SetBounds(scrollbar_size_1); + scrollbar_1->SetTouchEventHandlerRegion(gfx::Rect(scrollbar_size_1)); + host_impl_->active_tree() + ->InnerViewportContainerLayer() + ->test_properties() + ->AddChild(std::move(scrollbar_1)); + + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + host_impl_->active_tree()->DidBecomeActive(); + + DrawFrame(); + host_impl_->active_tree()->UpdateDrawProperties(false); + + ScrollbarAnimationControllerThinning* scrollbar_1_animation_controller = + static_cast<ScrollbarAnimationControllerThinning*>( + host_impl_->ScrollbarAnimationControllerForId(root_scroll->id())); + EXPECT_TRUE(scrollbar_1_animation_controller); + scrollbar_1_animation_controller->set_mouse_move_distance_for_test(40.f); + + // Mouse moves close to the scrollbar, goes over the scrollbar, and + // moves back to where it was. + host_impl_->MouseMoveAt(gfx::Point(100, 150)); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(40, 150)); + EXPECT_TRUE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(10, 150)); + EXPECT_TRUE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_TRUE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(40, 150)); + EXPECT_TRUE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(100, 150)); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + + // scrollbar_2 on child. + std::unique_ptr<SolidColorScrollbarLayerImpl> scrollbar_2 = + SolidColorScrollbarLayerImpl::Create(host_impl_->active_tree(), + scrollbar_2_id, VERTICAL, 5, 5, true, + true); + std::unique_ptr<LayerImpl> child_clip = + LayerImpl::Create(host_impl_->active_tree(), child_clip_id); + std::unique_ptr<LayerImpl> child = + LayerImpl::Create(host_impl_->active_tree(), child_scroll_id); + child->SetPosition(gfx::PointF(50, 50)); + child->SetBounds(child_layer_size); + child->SetDrawsContent(true); + child->SetScrollClipLayer(child_clip_id); + + scrollbar_2->SetScrollLayerId(child_scroll_id); + scrollbar_2->SetDrawsContent(true); + scrollbar_2->SetBounds(scrollbar_size_2); + + child->test_properties()->AddChild(std::move(scrollbar_2)); + child_clip->test_properties()->AddChild(std::move(child)); + root_scroll->test_properties()->AddChild(std::move(child_clip)); + + host_impl_->active_tree()->BuildPropertyTreesForTesting(); + host_impl_->active_tree()->DidBecomeActive(); + + ScrollbarAnimationControllerThinning* scrollbar_2_animation_controller = + static_cast<ScrollbarAnimationControllerThinning*>( + host_impl_->ScrollbarAnimationControllerForId(child_scroll_id)); + EXPECT_TRUE(scrollbar_2_animation_controller); + scrollbar_2_animation_controller->set_mouse_move_distance_for_test(40.f); + + // Mouse goes over scrollbar_2, moves close to scrollbar_2, moves close to + // scrollbar_1, goes over scrollbar_1. + host_impl_->MouseMoveAt(gfx::Point(60, 150)); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + EXPECT_TRUE(scrollbar_2_animation_controller->mouse_is_near_scrollbar()); + EXPECT_TRUE(scrollbar_2_animation_controller->mouse_is_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(100, 150)); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + EXPECT_TRUE(scrollbar_2_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_2_animation_controller->mouse_is_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(40, 150)); + EXPECT_TRUE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + EXPECT_FALSE(scrollbar_2_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_2_animation_controller->mouse_is_over_scrollbar()); + host_impl_->MouseMoveAt(gfx::Point(10, 150)); + EXPECT_TRUE(scrollbar_1_animation_controller->mouse_is_near_scrollbar()); + EXPECT_TRUE(scrollbar_1_animation_controller->mouse_is_over_scrollbar()); + EXPECT_FALSE(scrollbar_2_animation_controller->mouse_is_near_scrollbar()); + EXPECT_FALSE(scrollbar_2_animation_controller->mouse_is_over_scrollbar()); +} + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_in_process.cc b/chromium/cc/trees/layer_tree_host_in_process.cc index 57e2ea414e8..6280097b16a 100644 --- a/chromium/cc/trees/layer_tree_host_in_process.cc +++ b/chromium/cc/trees/layer_tree_host_in_process.cc @@ -26,8 +26,6 @@ #include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" -#include "cc/animation/animation_events.h" -#include "cc/animation/animation_host.h" #include "cc/base/math_util.h" #include "cc/blimp/client_picture_cache.h" #include "cc/blimp/engine_picture_cache.h" @@ -43,20 +41,16 @@ #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/layers/layer.h" #include "cc/layers/layer_iterator.h" -#include "cc/layers/layer_proto_converter.h" #include "cc/layers/painted_scrollbar_layer.h" -#include "cc/proto/gfx_conversions.h" -#include "cc/proto/layer_tree.pb.h" -#include "cc/proto/layer_tree_host.pb.h" #include "cc/resources/ui_resource_manager.h" #include "cc/trees/draw_property_utils.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/remote_channel_impl.h" #include "cc/trees/single_thread_proxy.h" #include "cc/trees/swap_promise_manager.h" #include "cc/trees/tree_synchronizer.h" @@ -68,60 +62,6 @@ static base::StaticAtomicSequenceNumber s_layer_tree_host_sequence_number; } namespace cc { -namespace { - -std::unique_ptr<base::trace_event::TracedValue> -ComputeLayerTreeHostProtoSizeSplitAsValue(proto::LayerTreeHost* proto) { - std::unique_ptr<base::trace_event::TracedValue> value( - new base::trace_event::TracedValue()); - base::CheckedNumeric<int> base_layer_properties_size = 0; - base::CheckedNumeric<int> picture_layer_properties_size = 0; - base::CheckedNumeric<int> display_item_list_size = 0; - base::CheckedNumeric<int> drawing_display_items_size = 0; - - const proto::LayerUpdate& layer_update_proto = proto->layer_updates(); - for (int i = 0; i < layer_update_proto.layers_size(); ++i) { - const proto::LayerProperties layer_properties_proto = - layer_update_proto.layers(i); - base_layer_properties_size += layer_properties_proto.base().ByteSize(); - - if (layer_properties_proto.has_picture()) { - const proto::PictureLayerProperties& picture_proto = - layer_properties_proto.picture(); - picture_layer_properties_size += picture_proto.ByteSize(); - - const proto::DisplayItemList& display_list_proto = - picture_proto.display_list(); - display_item_list_size += display_list_proto.ByteSize(); - - for (int j = 0; j < display_list_proto.items_size(); ++j) { - const proto::DisplayItem& display_item = display_list_proto.items(j); - if (display_item.type() == proto::DisplayItem::Type_Drawing) - drawing_display_items_size += display_item.ByteSize(); - } - } - } - - value->SetInteger("TotalLayerTreeHostProtoSize", proto->ByteSize()); - value->SetInteger("LayerTreeHierarchySize", - proto->layer_tree().root_layer().ByteSize()); - value->SetInteger("LayerUpdatesSize", proto->layer_updates().ByteSize()); - value->SetInteger("PropertyTreesSize", - proto->layer_tree().property_trees().ByteSize()); - - // LayerUpdate size breakdown. - value->SetInteger("TotalBasePropertiesSize", - base_layer_properties_size.ValueOrDefault(-1)); - value->SetInteger("PictureLayerPropertiesSize", - picture_layer_properties_size.ValueOrDefault(-1)); - value->SetInteger("DisplayItemListSize", - display_item_list_size.ValueOrDefault(-1)); - value->SetInteger("DrawingDisplayItemsSize", - drawing_display_items_size.ValueOrDefault(-1)); - return value; -} - -} // namespace LayerTreeHostInProcess::InitParams::InitParams() {} @@ -152,48 +92,12 @@ LayerTreeHostInProcess::CreateSingleThreaded( return layer_tree_host; } -std::unique_ptr<LayerTreeHostInProcess> -LayerTreeHostInProcess::CreateRemoteServer( - RemoteProtoChannel* remote_proto_channel, - InitParams* params) { - DCHECK(params->main_task_runner.get()); - DCHECK(params->settings); - DCHECK(remote_proto_channel); - TRACE_EVENT0("cc.remote", "LayerTreeHostInProcess::CreateRemoteServer"); - - DCHECK(params->image_serialization_processor); - - std::unique_ptr<LayerTreeHostInProcess> layer_tree_host( - new LayerTreeHostInProcess(params, CompositorMode::REMOTE)); - layer_tree_host->InitializeRemoteServer(remote_proto_channel, - params->main_task_runner); - return layer_tree_host; -} - -std::unique_ptr<LayerTreeHostInProcess> -LayerTreeHostInProcess::CreateRemoteClient( - RemoteProtoChannel* remote_proto_channel, - scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, - InitParams* params) { - DCHECK(params->main_task_runner.get()); - DCHECK(params->settings); - DCHECK(remote_proto_channel); - DCHECK(params->image_serialization_processor); - - std::unique_ptr<LayerTreeHostInProcess> layer_tree_host( - new LayerTreeHostInProcess(params, CompositorMode::REMOTE)); - layer_tree_host->InitializeRemoteClient( - remote_proto_channel, params->main_task_runner, impl_task_runner); - return layer_tree_host; -} - LayerTreeHostInProcess::LayerTreeHostInProcess(InitParams* params, CompositorMode mode) : LayerTreeHostInProcess( params, mode, - base::MakeUnique<LayerTree>(std::move(params->animation_host), - this)) {} + base::MakeUnique<LayerTree>(params->mutator_host, this)) {} LayerTreeHostInProcess::LayerTreeHostInProcess( InitParams* params, @@ -214,12 +118,11 @@ LayerTreeHostInProcess::LayerTreeHostInProcess( gpu_rasterization_histogram_recorded_(false), did_complete_scale_animation_(false), id_(s_layer_tree_host_sequence_number.GetNext() + 1), - shared_bitmap_manager_(params->shared_bitmap_manager), - gpu_memory_buffer_manager_(params->gpu_memory_buffer_manager), task_graph_runner_(params->task_graph_runner), image_serialization_processor_(params->image_serialization_processor) { DCHECK(task_graph_runner_); DCHECK(layer_tree_); + DCHECK_NE(compositor_mode_, CompositorMode::REMOTE); rendering_stats_instrumentation_->set_record_rendering_stats( debug_state_.RecordRenderingStats()); @@ -243,43 +146,6 @@ void LayerTreeHostInProcess::InitializeSingleThreaded( task_runner_provider_.get())); } -void LayerTreeHostInProcess::InitializeRemoteServer( - RemoteProtoChannel* remote_proto_channel, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner) { - task_runner_provider_ = TaskRunnerProvider::Create(main_task_runner, nullptr); - - if (image_serialization_processor_) { - engine_picture_cache_ = - image_serialization_processor_->CreateEnginePictureCache(); - layer_tree_->set_engine_picture_cache(engine_picture_cache_.get()); - } - InitializeProxy(ProxyMain::CreateRemote(remote_proto_channel, this, - task_runner_provider_.get())); -} - -void LayerTreeHostInProcess::InitializeRemoteClient( - RemoteProtoChannel* remote_proto_channel, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner) { - task_runner_provider_ = - TaskRunnerProvider::Create(main_task_runner, impl_task_runner); - - if (image_serialization_processor_) { - client_picture_cache_ = - image_serialization_processor_->CreateClientPictureCache(); - layer_tree_->set_client_picture_cache(client_picture_cache_.get()); - } - - // For the remote mode, the RemoteChannelImpl implements the Proxy, which is - // owned by the LayerTreeHostInProcess. The RemoteChannelImpl pipes requests - // which need to handled locally, for instance the Output Surface creation to - // the LayerTreeHostInProcess on the client, while the other requests are sent - // to the RemoteChannelMain on the server which directs them to ProxyMain and - // the remote server LayerTreeHostInProcess. - InitializeProxy(base::MakeUnique<RemoteChannelImpl>( - this, remote_proto_channel, task_runner_provider_.get())); -} - void LayerTreeHostInProcess::InitializeForTesting( std::unique_ptr<TaskRunnerProvider> task_runner_provider, std::unique_ptr<Proxy> proxy_for_testing) { @@ -322,7 +188,7 @@ void LayerTreeHostInProcess::InitializeProxy(std::unique_ptr<Proxy> proxy) { proxy_ = std::move(proxy); proxy_->Start(); - layer_tree_->animation_host()->SetSupportsScrollAnimations( + layer_tree_->mutator_host()->SetSupportsScrollAnimations( proxy_->SupportsImplScrolling()); } @@ -421,11 +287,9 @@ void LayerTreeHostInProcess::RequestMainFrameUpdate() { // this function, keep in mind that the function *runs* on the impl thread! Any // code that is logically a main thread operation, e.g. deletion of a Layer, // should be delayed until the LayerTreeHostInProcess::CommitComplete, which -// will run -// after the commit, but on the main thread. +// will run after the commit, but on the main thread. void LayerTreeHostInProcess::FinishCommitOnImplThread( LayerTreeHostImpl* host_impl) { - DCHECK(!IsRemoteServer()); DCHECK(task_runner_provider_->IsImplThread()); bool is_new_trace; @@ -453,7 +317,10 @@ void LayerTreeHostInProcess::FinishCommitOnImplThread( if (layer_tree_->needs_full_tree_sync()) TreeSynchronizer::SynchronizeTrees(layer_tree_->root_layer(), sync_tree); - layer_tree_->PushPropertiesTo(sync_tree); + float page_scale_delta = 1.f; + if (reflected_main_frame_state_) + page_scale_delta = reflected_main_frame_state_->page_scale_delta; + layer_tree_->PushPropertiesTo(sync_tree, page_scale_delta); sync_tree->PassSwapPromises(swap_promise_manager_.TakeSwapPromises()); @@ -463,10 +330,6 @@ void LayerTreeHostInProcess::FinishCommitOnImplThread( RecordGpuRasterizationHistogram(); host_impl->SetViewportSize(layer_tree_->device_viewport_size()); - // TODO(senorblanco): Move this to LayerTree::PushPropertiesTo so that it - // happens before GPU rasterization properties are set, since those trigger an - // update of GPU rasterization status, which depends on the device scale - // factor. (crbug.com/535700) sync_tree->SetDeviceScaleFactor(layer_tree_->device_scale_factor()); host_impl->SetDebugState(debug_state_); @@ -478,6 +341,23 @@ void LayerTreeHostInProcess::FinishCommitOnImplThread( TreeSynchronizer::PushLayerProperties(layer_tree_.get(), sync_tree); + if (reflected_main_frame_state_) { + for (const auto& scroll_update : reflected_main_frame_state_->scrolls) { + int layer_id = scroll_update.layer_id; + gfx::Vector2dF scroll_delta = scroll_update.scroll_delta; + + PropertyTrees* property_trees = layer_tree_->property_trees(); + property_trees->scroll_tree.SetScrollOffset( + layer_id, gfx::ScrollOffsetWithDelta( + layer_tree_->LayerById(layer_id)->scroll_offset(), + scroll_delta)); + } + } + + // This must happen after synchronizing property trees and after pushing + // properties, which updates the clobber_active_value flag. + sync_tree->UpdatePropertyTreeScrollOffset(layer_tree_->property_trees()); + // This must happen after synchronizing property trees and after push // properties, which updates property tree indices, but before animation // host pushes properties as animation host push properties can change @@ -486,17 +366,13 @@ void LayerTreeHostInProcess::FinishCommitOnImplThread( sync_tree->UpdatePropertyTreeScrollingAndAnimationFromMainThread(); TRACE_EVENT0("cc", "LayerTreeHostInProcess::AnimationHost::PushProperties"); - DCHECK(host_impl->animation_host()); - layer_tree_->animation_host()->PushPropertiesTo( - host_impl->animation_host()); + DCHECK(host_impl->mutator_host()); + layer_tree_->mutator_host()->PushPropertiesTo(host_impl->mutator_host()); } - // This must happen after synchronizing property trees and after pushing - // properties, which updates the clobber_active_value flag. - sync_tree->UpdatePropertyTreeScrollOffset(layer_tree_->property_trees()); - micro_benchmark_controller_.ScheduleImplBenchmarks(host_impl); layer_tree_->property_trees()->ResetAllChangeTracking(); + reflected_main_frame_state_ = nullptr; } void LayerTreeHostInProcess::WillCommit() { @@ -557,24 +433,19 @@ void LayerTreeHostInProcess::DidFailToInitializeCompositorFrameSink() { std::unique_ptr<LayerTreeHostImpl> LayerTreeHostInProcess::CreateLayerTreeHostImpl( LayerTreeHostImplClient* client) { - DCHECK(!IsRemoteServer()); DCHECK(task_runner_provider_->IsImplThread()); const bool supports_impl_scrolling = task_runner_provider_->HasImplThread(); - std::unique_ptr<AnimationHost> animation_host_impl = - layer_tree_->animation_host()->CreateImplInstance( - supports_impl_scrolling); + std::unique_ptr<MutatorHost> mutator_host_impl = + layer_tree_->mutator_host()->CreateImplInstance(supports_impl_scrolling); std::unique_ptr<LayerTreeHostImpl> host_impl = LayerTreeHostImpl::Create( settings_, client, task_runner_provider_.get(), - rendering_stats_instrumentation_.get(), shared_bitmap_manager_, - gpu_memory_buffer_manager_, task_graph_runner_, - std::move(animation_host_impl), id_); + rendering_stats_instrumentation_.get(), task_graph_runner_, + std::move(mutator_host_impl), id_); host_impl->SetHasGpuRasterizationTrigger(has_gpu_rasterization_trigger_); host_impl->SetContentIsSuitableForGpuRasterization( content_is_suitable_for_gpu_rasterization_); - shared_bitmap_manager_ = NULL; - gpu_memory_buffer_manager_ = NULL; task_graph_runner_ = NULL; input_handler_weak_ptr_ = host_impl->AsWeakPtr(); return host_impl; @@ -612,10 +483,6 @@ void LayerTreeHostInProcess::SetNeedsRecalculateRasterScales() { proxy_->SetNeedsCommit(); } -void LayerTreeHostInProcess::SetNeedsRedraw() { - SetNeedsRedrawRect(gfx::Rect(layer_tree_->device_viewport_size())); -} - void LayerTreeHostInProcess::SetNeedsRedrawRect(const gfx::Rect& damage_rect) { proxy_->SetNeedsRedraw(damage_rect); } @@ -638,9 +505,9 @@ void LayerTreeHostInProcess::SetNextCommitForcesRedraw() { } void LayerTreeHostInProcess::SetAnimationEvents( - std::unique_ptr<AnimationEvents> events) { + std::unique_ptr<MutatorEvents> events) { DCHECK(task_runner_provider_->IsMainThread()); - layer_tree_->animation_host()->SetAnimationEvents(std::move(events)); + layer_tree_->mutator_host()->SetAnimationEvents(std::move(events)); } void LayerTreeHostInProcess::SetDebugState( @@ -810,8 +677,7 @@ bool LayerTreeHostInProcess::DoUpdateLayers(Layer* root_layer) { draw_property_utils::UpdatePropertyTrees(property_trees, can_render_to_separate_surface); draw_property_utils::FindLayersThatNeedUpdates( - layer_tree_.get(), property_trees->transform_tree, - property_trees->effect_tree, &update_layer_list); + layer_tree_.get(), property_trees, &update_layer_list); } for (const auto& layer : update_layer_list) @@ -883,6 +749,12 @@ void LayerTreeHostInProcess::ApplyScrollAndScale(ScrollAndScaleSet* info) { layer->scroll_offset(), info->scrolls[i].scroll_delta)); SetNeedsUpdateLayers(); } + for (size_t i = 0; i < info->scrollbars.size(); ++i) { + Layer* layer = layer_tree_->LayerById(info->scrollbars[i].layer_id); + if (!layer) + continue; + layer->SetScrollbarsHiddenFromImplSide(info->scrollbars[i].hidden); + } } // This needs to happen after scroll deltas have been sent to prevent top @@ -891,28 +763,36 @@ void LayerTreeHostInProcess::ApplyScrollAndScale(ScrollAndScaleSet* info) { ApplyViewportDeltas(info); } +void LayerTreeHostInProcess::SetReflectedMainFrameState( + std::unique_ptr<ReflectedMainFrameState> reflected_main_frame_state) { + DCHECK(IsThreaded()); + + reflected_main_frame_state_ = std::move(reflected_main_frame_state); + SetNeedsCommit(); +} + const base::WeakPtr<InputHandler>& LayerTreeHostInProcess::GetInputHandler() const { return input_handler_weak_ptr_; } -void LayerTreeHostInProcess::UpdateTopControlsState( - TopControlsState constraints, - TopControlsState current, +void LayerTreeHostInProcess::UpdateBrowserControlsState( + BrowserControlsState constraints, + BrowserControlsState current, bool animate) { - // Top controls are only used in threaded or remote mode. - DCHECK(IsThreaded() || IsRemoteServer()); - proxy_->UpdateTopControlsState(constraints, current, animate); + // Browser controls are only used in threaded mode. + DCHECK(IsThreaded()); + proxy_->UpdateBrowserControlsState(constraints, current, animate); } void LayerTreeHostInProcess::AnimateLayers(base::TimeTicks monotonic_time) { - AnimationHost* animation_host = layer_tree_->animation_host(); - std::unique_ptr<AnimationEvents> events = animation_host->CreateEvents(); + MutatorHost* mutator_host = layer_tree_->mutator_host(); + std::unique_ptr<MutatorEvents> events = mutator_host->CreateEvents(); - if (animation_host->AnimateLayers(monotonic_time)) - animation_host->UpdateAnimationState(true, events.get()); + if (mutator_host->AnimateLayers(monotonic_time)) + mutator_host->UpdateAnimationState(true, events.get()); - if (!events->events_.empty()) + if (!events->IsEmpty()) layer_tree_->property_trees()->needs_rebuild = true; } @@ -947,101 +827,4 @@ bool LayerTreeHostInProcess::IsThreaded() const { return compositor_mode_ == CompositorMode::THREADED; } -bool LayerTreeHostInProcess::IsRemoteServer() const { - // The LayerTreeHostInProcess on the server does not have an impl task runner. - return compositor_mode_ == CompositorMode::REMOTE && - !task_runner_provider_->HasImplThread(); -} - -bool LayerTreeHostInProcess::IsRemoteClient() const { - return compositor_mode_ == CompositorMode::REMOTE && - task_runner_provider_->HasImplThread(); -} - -void LayerTreeHostInProcess::ToProtobufForCommit( - proto::LayerTreeHost* proto, - std::vector<std::unique_ptr<SwapPromise>>* swap_promises) { - DCHECK(engine_picture_cache_); - // Not all fields are serialized, as they are either not needed for a commit, - // or implementation isn't ready yet. - // Unsupported items: - // - animations - // - UI resources - // - instrumentation of stats - // - histograms - // Skipped items: - // - SwapPromise as they are mostly used for perf measurements. - // - The bitmap and GPU memory related items. - // Other notes: - // - The output surfaces are only valid on the client-side so they are - // therefore not serialized. - // - LayerTreeSettings are needed only during construction of the - // LayerTreeHostInProcess, so they are serialized outside of the - // LayerTreeHostInProcess - // serialization. - // - The |visible_| flag will be controlled from the client separately and - // will need special handling outside of the serialization of the - // LayerTreeHostInProcess. - // TODO(nyquist): Figure out how to support animations. See crbug.com/570376. - TRACE_EVENT0("cc.remote", "LayerTreeHostInProcess::ToProtobufForCommit"); - *swap_promises = swap_promise_manager_.TakeSwapPromises(); - - proto->set_source_frame_number(source_frame_number_); - - // Serialize the LayerTree before serializing the properties. During layer - // property serialization, we clear the list |layer_that_should_properties_| - // from the LayerTree. - // The serialization code here need to serialize the complete state, including - // the result of the main frame update. - const bool inputs_only = false; - layer_tree_->ToProtobuf(proto->mutable_layer_tree(), inputs_only); - - LayerProtoConverter::SerializeLayerProperties(this, - proto->mutable_layer_updates()); - - std::vector<PictureData> pictures = - engine_picture_cache_->CalculateCacheUpdateAndFlush(); - proto::PictureDataVectorToSkPicturesProto(pictures, - proto->mutable_pictures()); - - debug_state_.ToProtobuf(proto->mutable_debug_state()); - proto->set_has_gpu_rasterization_trigger(has_gpu_rasterization_trigger_); - proto->set_content_is_suitable_for_gpu_rasterization( - content_is_suitable_for_gpu_rasterization_); - proto->set_id(id_); - proto->set_next_commit_forces_redraw(next_commit_forces_redraw_); - - TRACE_EVENT_OBJECT_SNAPSHOT_WITH_ID( - "cc.remote", "LayerTreeHostProto", source_frame_number_, - ComputeLayerTreeHostProtoSizeSplitAsValue(proto)); -} - -void LayerTreeHostInProcess::FromProtobufForCommit( - const proto::LayerTreeHost& proto) { - DCHECK(client_picture_cache_); - source_frame_number_ = proto.source_frame_number(); - - layer_tree_->FromProtobuf(proto.layer_tree()); - - // Ensure ClientPictureCache contains all the necessary SkPictures before - // deserializing the properties. - proto::SkPictures proto_pictures = proto.pictures(); - std::vector<PictureData> pictures = - SkPicturesProtoToPictureDataVector(proto_pictures); - client_picture_cache_->ApplyCacheUpdate(pictures); - - LayerProtoConverter::DeserializeLayerProperties(layer_tree_->root_layer(), - proto.layer_updates()); - - // The deserialization is finished, so now clear the cache. - client_picture_cache_->Flush(); - - debug_state_.FromProtobuf(proto.debug_state()); - has_gpu_rasterization_trigger_ = proto.has_gpu_rasterization_trigger(); - content_is_suitable_for_gpu_rasterization_ = - proto.content_is_suitable_for_gpu_rasterization(); - id_ = proto.id(); - next_commit_forces_redraw_ = proto.next_commit_forces_redraw(); -} - } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_in_process.h b/chromium/cc/trees/layer_tree_host_in_process.h index 17983f40b6d..eec439482d6 100644 --- a/chromium/cc/trees/layer_tree_host_in_process.h +++ b/chromium/cc/trees/layer_tree_host_in_process.h @@ -20,15 +20,14 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" -#include "cc/animation/target_property.h" #include "cc/base/cc_export.h" #include "cc/debug/micro_benchmark.h" #include "cc/debug/micro_benchmark_controller.h" +#include "cc/input/browser_controls_state.h" #include "cc/input/event_listener_properties.h" #include "cc/input/input_handler.h" #include "cc/input/layer_selection_bound.h" #include "cc/input/scrollbar.h" -#include "cc/input/top_controls_state.h" #include "cc/layers/layer_collections.h" #include "cc/layers/layer_list_iterator.h" #include "cc/output/compositor_frame_sink.h" @@ -42,20 +41,14 @@ #include "cc/trees/layer_tree_settings.h" #include "cc/trees/proxy.h" #include "cc/trees/swap_promise_manager.h" +#include "cc/trees/target_property.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/geometry/rect.h" -namespace gpu { -class GpuMemoryBufferManager; -} // namespace gpu - namespace cc { -class AnimationHost; -class AnimationEvents; -class BeginFrameSource; +class MutatorEvents; class ClientPictureCache; class EnginePictureCache; -class HeadsUpDisplayLayer; class ImageSerializationProcessor; class Layer; class LayerTreeHostClient; @@ -63,42 +56,30 @@ class LayerTreeHostImpl; class LayerTreeHostImplClient; class LayerTreeHostSingleThreadClient; class LayerTreeMutator; +class MutatorHost; class PropertyTrees; -class Region; -class RemoteProtoChannel; class RenderingStatsInstrumentation; -class ResourceProvider; -class ResourceUpdateQueue; -class SharedBitmapManager; class TaskGraphRunner; -class TopControlsManager; -struct PendingPageScaleAnimation; +struct ReflectedMainFrameState; struct RenderingStats; struct ScrollAndScaleSet; -namespace proto { -class LayerTreeHost; -} - class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { public: // TODO(sad): InitParams should be a movable type so that it can be // std::move()d to the Create* functions. struct CC_EXPORT InitParams { LayerTreeHostClient* client = nullptr; - SharedBitmapManager* shared_bitmap_manager = nullptr; - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = nullptr; TaskGraphRunner* task_graph_runner = nullptr; LayerTreeSettings const* settings = nullptr; scoped_refptr<base::SingleThreadTaskRunner> main_task_runner; ImageSerializationProcessor* image_serialization_processor = nullptr; - std::unique_ptr<AnimationHost> animation_host; + MutatorHost* mutator_host; InitParams(); ~InitParams(); }; - // The SharedBitmapManager will be used on the compositor thread. static std::unique_ptr<LayerTreeHostInProcess> CreateThreaded( scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, InitParams* params); @@ -107,21 +88,6 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { LayerTreeHostSingleThreadClient* single_thread_client, InitParams* params); - static std::unique_ptr<LayerTreeHostInProcess> CreateRemoteServer( - RemoteProtoChannel* remote_proto_channel, - InitParams* params); - - // The lifetime of this LayerTreeHostInProcess is tied to the lifetime of the - // remote server LayerTreeHostInProcess. It should be created on receiving - // CompositorMessageToImpl::InitializeImpl message and destroyed on receiving - // a CompositorMessageToImpl::CloseImpl message from the server. This ensures - // that the client will not send any compositor messages once the - // LayerTreeHostInProcess on the server is destroyed. - static std::unique_ptr<LayerTreeHostInProcess> CreateRemoteClient( - RemoteProtoChannel* remote_proto_channel, - scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner, - InitParams* params); - ~LayerTreeHostInProcess() override; // LayerTreeHost implementation. @@ -151,13 +117,12 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { void SetDeferCommits(bool defer_commits) override; void LayoutAndUpdateLayers() override; void Composite(base::TimeTicks frame_begin_time) override; - void SetNeedsRedraw() override; void SetNeedsRedrawRect(const gfx::Rect& damage_rect) override; void SetNextCommitForcesRedraw() override; void NotifyInputThrottledUntilCommit() override; - void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) override; + void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) override; const base::WeakPtr<InputHandler>& GetInputHandler() const override; void DidStopFlinging() override; void SetDebugState(const LayerTreeDebugState& debug_state) override; @@ -189,12 +154,21 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { LayerTreeHostImplClient* client); void DidLoseCompositorFrameSink(); void DidCommitAndDrawFrame() { client_->DidCommitAndDrawFrame(); } - void DidCompleteSwapBuffers() { client_->DidCompleteSwapBuffers(); } + void DidReceiveCompositorFrameAck() { + client_->DidReceiveCompositorFrameAck(); + } bool UpdateLayers(); // Called when the compositor completed page scale animation. void DidCompletePageScaleAnimation(); void ApplyScrollAndScale(ScrollAndScaleSet* info); + void SetReflectedMainFrameState( + std::unique_ptr<ReflectedMainFrameState> reflected_main_frame_state); + const ReflectedMainFrameState* reflected_main_frame_state_for_testing() + const { + return reflected_main_frame_state_.get(); + } + LayerTreeHostClient* client() { return client_; } bool gpu_rasterization_histogram_recorded() const { @@ -207,7 +181,7 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { return rendering_stats_instrumentation_.get(); } - void SetAnimationEvents(std::unique_ptr<AnimationEvents> events); + void SetAnimationEvents(std::unique_ptr<MutatorEvents> events); bool has_gpu_rasterization_trigger() const { return has_gpu_rasterization_trigger_; @@ -215,24 +189,8 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { Proxy* proxy() const { return proxy_.get(); } - // Serializes the parts of this LayerTreeHostInProcess that is needed for a - // commit to a protobuf message. Not all members are serialized as they are - // not helpful for remote usage. - // The |swap_promise_list_| is transferred to the serializer in - // |swap_promises|. - void ToProtobufForCommit( - proto::LayerTreeHost* proto, - std::vector<std::unique_ptr<SwapPromise>>* swap_promises); - - // Deserializes the protobuf into this LayerTreeHostInProcess before a commit. - // The expected input is a serialized remote LayerTreeHost. After - // deserializing the protobuf, the normal commit-flow should continue. - void FromProtobufForCommit(const proto::LayerTreeHost& proto); - bool IsSingleThreaded() const; bool IsThreaded() const; - bool IsRemoteServer() const; - bool IsRemoteClient() const; ImageSerializationProcessor* image_serialization_processor() const { return image_serialization_processor_; @@ -259,13 +217,6 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { void InitializeSingleThreaded( LayerTreeHostSingleThreadClient* single_thread_client, scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); - void InitializeRemoteServer( - RemoteProtoChannel* remote_proto_channel, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner); - void InitializeRemoteClient( - RemoteProtoChannel* remote_proto_channel, - scoped_refptr<base::SingleThreadTaskRunner> main_task_runner, - scoped_refptr<base::SingleThreadTaskRunner> impl_task_runner); void InitializeForTesting( std::unique_ptr<TaskRunnerProvider> task_runner_provider, std::unique_ptr<Proxy> proxy_for_testing); @@ -275,15 +226,8 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { void SetUIResourceManagerForTesting( std::unique_ptr<UIResourceManager> ui_resource_manager); - // shared_bitmap_manager(), gpu_memory_buffer_manager(), and - // task_graph_runner() return valid values only until the LayerTreeHostImpl is - // created in CreateLayerTreeHostImpl(). - SharedBitmapManager* shared_bitmap_manager() const { - return shared_bitmap_manager_; - } - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager() const { - return gpu_memory_buffer_manager_; - } + // task_graph_runner() returns a valid value only until the LayerTreeHostImpl + // is created in CreateLayerTreeHostImpl(). TaskGraphRunner* task_graph_runner() const { return task_graph_runner_; } void OnCommitForSwapPromises(); @@ -355,8 +299,6 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { bool next_commit_forces_redraw_ = false; bool next_commit_forces_recalculate_raster_scales_ = false; - SharedBitmapManager* shared_bitmap_manager_; - gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager_; TaskGraphRunner* task_graph_runner_; ImageSerializationProcessor* image_serialization_processor_; @@ -366,6 +308,15 @@ class CC_EXPORT LayerTreeHostInProcess : public LayerTreeHost { SurfaceSequenceGenerator surface_sequence_generator_; uint32_t num_consecutive_frames_suitable_for_gpu_ = 0; + // The state that was expected to be reflected from the main thread during + // BeginMainFrame, but could not be done. The client provides these deltas + // to use during the commit instead of applying them at that point because + // its necessary for these deltas to be applied *after* PropertyTrees are + // built/updated on the main thread. + // TODO(khushalsagar): Investigate removing this after SPV2, since then we + // should get these PropertyTrees directly from blink? + std::unique_ptr<ReflectedMainFrameState> reflected_main_frame_state_; + DISALLOW_COPY_AND_ASSIGN(LayerTreeHostInProcess); }; diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc index 723c6d95724..a4386cbd58d 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc @@ -7,6 +7,7 @@ #include "build/build_config.h" #include "cc/layers/picture_layer.h" #include "cc/layers/solid_color_layer.h" +#include "cc/test/fake_content_layer_client.h" #include "cc/test/layer_tree_pixel_test.h" #include "cc/test/pixel_comparator.h" #include "cc/test/solid_color_content_layer_client.h" @@ -754,6 +755,58 @@ TEST_F(RotatedDropShadowFilterTest, RotatedDropShadowFilterTest_Software) { base::FilePath(FILE_PATH_LITERAL("rotated_drop_shadow_filter_sw.png"))); } +class TranslatedFilterTest : public LayerTreeHostFiltersPixelTest { + protected: + void RunPixelTestType(PixelTestType test_type, base::FilePath image_name) { + scoped_refptr<Layer> clip = Layer::Create(); + clip->SetBounds(gfx::Size(300, 300)); + clip->SetMasksToBounds(true); + + scoped_refptr<Layer> parent = Layer::Create(); + parent->SetPosition(gfx::PointF(30.f, 30.f)); + + gfx::Rect child_rect(100, 100); + // Use two colors to bypass solid color detection, so we get a tile quad. + // This is intended to test render pass removal optimizations. + FakeContentLayerClient client; + client.set_bounds(child_rect.size()); + SkPaint paint; + paint.setColor(SK_ColorGREEN); + client.add_draw_rect(child_rect, paint); + paint.setColor(SK_ColorBLUE); + client.add_draw_rect(gfx::Rect(100, 50), paint); + scoped_refptr<PictureLayer> child = PictureLayer::Create(&client); + child->SetBounds(child_rect.size()); + child->SetIsDrawable(true); + FilterOperations filters; + filters.Append(FilterOperation::CreateOpacityFilter(0.5f)); + child->SetFilters(filters); + + // This layer will be clipped by |clip|, so the RenderPass created for + // |child| will only have one visible quad. + scoped_refptr<SolidColorLayer> grand_child = + CreateSolidColorLayer(gfx::Rect(-300, -300, 100, 100), SK_ColorRED); + + child->AddChild(grand_child); + parent->AddChild(child); + clip->AddChild(parent); + + RunPixelTest(test_type, clip, image_name); + } +}; + +TEST_F(TranslatedFilterTest, GL) { + RunPixelTestType( + PIXEL_TEST_GL, + base::FilePath(FILE_PATH_LITERAL("translated_blue_green_alpha_gl.png"))); +} + +TEST_F(TranslatedFilterTest, Software) { + RunPixelTestType( + PIXEL_TEST_SOFTWARE, + base::FilePath(FILE_PATH_LITERAL("translated_blue_green_alpha_sw.png"))); +} + class EnlargedTextureWithAlphaThresholdFilter : public LayerTreeHostFiltersPixelTest { protected: diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc index 67342e21151..9a649dcece9 100644 --- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc +++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc @@ -11,7 +11,6 @@ #include "cc/playback/display_item_list_settings.h" #include "cc/playback/drawing_display_item.h" #include "cc/test/layer_tree_pixel_test.h" -#include "cc/test/test_gpu_memory_buffer_manager.h" #include "third_party/skia/include/core/SkCanvas.h" #include "third_party/skia/include/core/SkPictureRecorder.h" diff --git a/chromium/cc/trees/layer_tree_host_single_thread_client.h b/chromium/cc/trees/layer_tree_host_single_thread_client.h index 3d078920735..00cc3dbaec8 100644 --- a/chromium/cc/trees/layer_tree_host_single_thread_client.h +++ b/chromium/cc/trees/layer_tree_host_single_thread_client.h @@ -15,14 +15,17 @@ class LayerTreeHostSingleThreadClient { // delay for potential future frame. virtual void RequestScheduleAnimation() {} - // Called whenever the compositor posts a SwapBuffers (either full or - // partial). After DidPostSwapBuffers(), exactly one of - // DidCompleteSwapBuffers() or DidAbortSwapBuffers() will be called, thus - // these functions can be used to keep track of pending swap buffers calls for - // rate limiting. - virtual void DidPostSwapBuffers() = 0; - virtual void DidCompleteSwapBuffers() = 0; - virtual void DidAbortSwapBuffers() = 0; + // Called whenever the compositor submits a CompositorFrame. Afterward, + // LayerTreeHostClient::DidReceiveCompositorFrameAck() will be called once the + // display compositor/ finishes processing the frame. So these functions can + // be used to keep track of pending submitted CompositorFrames for rate + // limiting. + virtual void DidSubmitCompositorFrame() = 0; + + // Called when the active CompositorFrameSink is lost and needs to be + // replaced. This allows the embedder to schedule a composite which will + // run the machinery to acquire a new CompositorFrameSink. + virtual void DidLoseCompositorFrameSink() = 0; protected: virtual ~LayerTreeHostSingleThreadClient() {} diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc index 5f168bc16df..ae40cad1835 100644 --- a/chromium/cc/trees/layer_tree_host_unittest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest.cc @@ -47,10 +47,11 @@ #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_internals_for_test.h" #include "cc/test/layer_tree_test.h" +#include "cc/test/push_properties_counting_layer.h" +#include "cc/test/push_properties_counting_layer_impl.h" #include "cc/test/render_pass_test_utils.h" #include "cc/test/skia_common.h" #include "cc/test/test_compositor_frame_sink.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_web_graphics_context_3d.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host_common.h" @@ -81,25 +82,25 @@ class LayerTreeHostTest : public LayerTreeTest {}; class LayerTreeHostTestHasImplThreadTest : public LayerTreeHostTest { public: - LayerTreeHostTestHasImplThreadTest() : threaded_(false) {} + LayerTreeHostTestHasImplThreadTest() : single_threaded_(false) {} void RunTest(CompositorMode mode) override { - threaded_ = mode == CompositorMode::THREADED; + single_threaded_ = mode == CompositorMode::SINGLE_THREADED; LayerTreeHostTest::RunTest(mode); } void BeginTest() override { - EXPECT_EQ(threaded_, HasImplThread()); + EXPECT_EQ(single_threaded_, !HasImplThread()); EndTest(); } - void AfterTest() override { EXPECT_EQ(threaded_, HasImplThread()); } + void AfterTest() override { EXPECT_EQ(single_threaded_, !HasImplThread()); } private: - bool threaded_; + bool single_threaded_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestHasImplThreadTest); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestHasImplThreadTest); class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest { protected: @@ -118,7 +119,7 @@ class LayerTreeHostTestSetNeedsCommitInsideLayout : public LayerTreeHostTest { void AfterTest() override {} }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommitInsideLayout); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestSetNeedsCommitInsideLayout); class LayerTreeHostTestFrameOrdering : public LayerTreeHostTest { protected: @@ -193,7 +194,7 @@ class LayerTreeHostTestFrameOrdering : public LayerTreeHostTest { ImplOrder impl_ = IMPL_START; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameOrdering); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestFrameOrdering); class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest { protected: @@ -212,7 +213,7 @@ class LayerTreeHostTestSetNeedsUpdateInsideLayout : public LayerTreeHostTest { void AfterTest() override {} }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsUpdateInsideLayout); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestSetNeedsUpdateInsideLayout); // Test if the LTHI receives ReadyToActivate notifications from the TileManager // when no raster tasks get scheduled. @@ -256,7 +257,7 @@ class LayerTreeHostTestReadyToActivateEmpty : public LayerTreeHostTest { size_t required_for_activation_count_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateEmpty); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestReadyToActivateEmpty); // Test if the LTHI receives ReadyToActivate notifications from the TileManager // when some raster tasks flagged as REQUIRED_FOR_ACTIVATION got scheduled. @@ -285,9 +286,9 @@ class LayerTreeHostTestReadyToActivateNonEmpty FakeContentLayerClient client_; }; -// Multi-thread only because in single thread the commit goes directly to the -// active tree, so notify ready to activate is skipped. -MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty); +// No single thread test because the commit goes directly to the active tree in +// single thread mode, so notify ready to activate is skipped. +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToActivateNonEmpty); // Test if the LTHI receives ReadyToDraw notifications from the TileManager when // no raster tasks get scheduled. @@ -327,7 +328,7 @@ class LayerTreeHostTestReadyToDrawEmpty : public LayerTreeHostTest { size_t required_for_draw_count_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestReadyToDrawEmpty); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestReadyToDrawEmpty); // Test if the LTHI receives ReadyToDraw notifications from the TileManager when // some raster tasks flagged as REQUIRED_FOR_DRAW got scheduled. @@ -434,6 +435,8 @@ class LayerTreeHostTestReadyToDrawVisibility : public LayerTreeHostTest { // single threaded mode. SINGLE_THREAD_TEST_F(LayerTreeHostTestReadyToDrawVisibility); +// Since the LayerTreeHostContextCacheTests exclusively tests the behavior of +// LayerTreeHostImpl, they don't need to run for the remote mode. class LayerTreeHostContextCacheTest : public LayerTreeHostTest { public: std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( @@ -573,35 +576,36 @@ class LayerTreeHostFreeContextResourcesOnDestroy SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostFreeContextResourcesOnDestroy); // Test if the LTH successfully frees and stops freeing context resources -// when the OutputSurface is lost and recreated. -class LayerTreeHostCacheBehaviorOnOutputSurfaceRecreated +// when the CompositorFrameSink is lost and recreated. +class LayerTreeHostCacheBehaviorOnCompositorFrameSinkRecreated : public LayerTreeHostContextCacheTest { public: void WillBeginImplFrameOnThread(LayerTreeHostImpl* host_impl, const BeginFrameArgs& args) override { - // This code is run once, to trigger recreation of our OutputSurface. - if (has_recreated_) + // This code is run once, to trigger recreation of our CompositorFrameSink. + if (test_state_ != TestState::INIT) return; // Ensure that our initialization expectations have completed. Mock::VerifyAndClearExpectations(mock_main_context_support_); Mock::VerifyAndClearExpectations(mock_worker_context_support_); - // Output surface lost expectations. + // CompositorFrameSink lost expectations. EXPECT_CALL(*mock_worker_context_support_, SetAggressivelyFreeResources(true)); EXPECT_CALL(*mock_main_context_support_, SetAggressivelyFreeResources(true)); host_impl->DidLoseCompositorFrameSink(); - has_recreated_ = true; + test_state_ = TestState::RECREATED; } - void DidInitializeCompositorFrameSink() override { - // This is run after we have recreated our OutputSurface. - if (!has_recreated_) + void InitializedRendererOnThread(LayerTreeHostImpl* host_impl, + bool success) override { + // This is run after we have recreated our CompositorFrameSink. + if (test_state_ != TestState::RECREATED) return; - // Ensure that our initialization expectations have completed. + // Ensure that our expectations have completed. Mock::VerifyAndClearExpectations(mock_main_context_support_); Mock::VerifyAndClearExpectations(mock_worker_context_support_); @@ -611,14 +615,16 @@ class LayerTreeHostCacheBehaviorOnOutputSurfaceRecreated EXPECT_CALL(*mock_main_context_support_, SetAggressivelyFreeResources(true)); EndTest(); + test_state_ = TestState::DONE; } private: - bool has_recreated_ = false; + enum class TestState { INIT, RECREATED, DONE }; + TestState test_state_ = TestState::INIT; }; SINGLE_AND_MULTI_THREAD_TEST_F( - LayerTreeHostCacheBehaviorOnOutputSurfaceRecreated); + LayerTreeHostCacheBehaviorOnCompositorFrameSinkRecreated); // Two setNeedsCommits in a row should lead to at least 1 commit and at least 1 // draw with frame 0. @@ -651,7 +657,7 @@ class LayerTreeHostTestSetNeedsCommit1 : public LayerTreeHostTest { int num_draws_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit1); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestSetNeedsCommit1); // A SetNeedsCommit should lead to 1 commit. Issuing a second commit after that // first committed frame draws should lead to another commit. @@ -687,7 +693,7 @@ class LayerTreeHostTestSetNeedsCommit2 : public LayerTreeHostTest { int num_draws_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsCommit2); // Verify that we pass property values in PushPropertiesTo. class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { @@ -782,7 +788,7 @@ class LayerTreeHostTestPushPropertiesTo : public LayerTreeHostTest { int index_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesTo); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestPushPropertiesTo); class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest { protected: @@ -904,6 +910,11 @@ class LayerTreeHostTestPushNodeOwnerToNodeIdMap : public LayerTreeHostTest { scoped_refptr<Layer> child_; }; +// This test compares the value of tree indexes from Layers on the engine to the +// resulting PropertyTrees copied to the pending tree after the commit on the +// client. This will result in a failure for LTH remote test since while the +// client side Layers would have the correct values for these indexes, but the +// engine will never build PropertyTrees in LTH remote. See crbug.com/655795. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushNodeOwnerToNodeIdMap); class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest { @@ -985,6 +996,12 @@ class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest { scoped_refptr<Layer> grand_child_; }; +// This test changes properties on the Layer and ensures that the subtree damage +// is tracked correctly on the resulting RenderSurfaceImpl for the corresponding +// LayerImpl. Since the remote code path currently synchronizes the hierarchy +// between the engine and client for every frame, all Layers on the client end +// up being marked as damaged. +// Enable this when crbug.com/605170 is fixed. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage); // Verify damage status of property trees is preserved after commit. @@ -1196,6 +1213,9 @@ class LayerTreeHostTestEffectTreeSync : public LayerTreeHostTest { FilterOperations sepia_filter_; }; +// This test verifies that correct values are retained on the impl thread in +// cases where they are animated on that thread. Since remote mode doesn't +// support threaded animations, we don't need to run this in remote mode. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestEffectTreeSync); class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest { @@ -1273,6 +1293,9 @@ class LayerTreeHostTestTransformTreeSync : public LayerTreeHostTest { scoped_refptr<Layer> root_; }; +// This test verifies that correct values are retained on the impl thread in +// cases where they are animated on that thread. Since remote mode doesn't +// support threaded animations, we don't need to run this in remote mode. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTransformTreeSync); // Verify damage status is updated even when the transform tree doesn't need @@ -1347,6 +1370,9 @@ class LayerTreeHostTestTransformTreeDamageIsUpdated : public LayerTreeHostTest { scoped_refptr<Layer> grand_child_; }; +// This test verifies that correct values are retained on the impl thread in +// cases where they are animated on that thread. Since remote mode doesn't +// support threaded animations, we don't need to run this in remote mode. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTransformTreeDamageIsUpdated); // Test that when mask layers switches layers, this gets pushed onto impl. @@ -1417,6 +1443,12 @@ class LayerTreeHostTestSwitchMaskLayer : public LayerTreeHostTest { int index_; }; +// This test also verifies that the Layers updated in a main frame correspond +// only to the Layers that need updates computed using +// draw_property_utils::FindLayersThatNeedUpdates. Since LayerTreeHostRemote +// currently updates all Layers during the main frame, the test fails for remote +// mode. +// TODO(xingliu): Revisit enabling this when crbug.com/650885 is resolved. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSwitchMaskLayer); // 1 setNeedsRedraw after the first commit has completed should lead to 1 @@ -1453,7 +1485,7 @@ class LayerTreeHostTestSetNeedsRedraw : public LayerTreeHostTest { int num_draws_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedraw); // After setNeedsRedrawRect(invalid_rect) the final damage_rect // must contain invalid_rect. @@ -1511,7 +1543,7 @@ class LayerTreeHostTestSetNeedsRedrawRect : public LayerTreeHostTest { scoped_refptr<FakePictureLayer> root_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetNeedsRedrawRect); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestSetNeedsRedrawRect); // Ensure the texture size of the pending and active trees are identical when a // layer is not in the viewport and a resize happens on the viewport @@ -1590,7 +1622,7 @@ class LayerTreeHostTestGpuRasterDeviceSizeChanged : public LayerTreeHostTest { // As there's no pending tree in single-threaded case, this test should run // only for multi-threaded case. -MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterDeviceSizeChanged); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterDeviceSizeChanged); class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { public: @@ -1640,7 +1672,7 @@ class LayerTreeHostTestNoExtraCommitFromInvalidate : public LayerTreeHostTest { scoped_refptr<Layer> scaled_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestNoExtraCommitFromInvalidate); class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate : public LayerTreeHostTest { @@ -1697,6 +1729,8 @@ class LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate scoped_refptr<FakePaintedScrollbarLayer> scrollbar_; }; +// No remote test here because PaintedScrollbarLayer is not supported by LTH +// remote. SINGLE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestNoExtraCommitFromScrollbarInvalidate); @@ -1764,7 +1798,7 @@ class LayerTreeHostTestDeviceScaleFactorChange : public LayerTreeHostTest { scoped_refptr<Layer> child_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorChange); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestDeviceScaleFactorChange); class LayerTreeHostTestDeviceColorSpaceChange : public LayerTreeHostTest { public: @@ -1887,6 +1921,9 @@ class LayerTreeHostTestDeviceColorSpaceChange : public LayerTreeHostTest { scoped_refptr<Layer> child_layer_; }; +// No remote test because LTH remote doesn't serialize device_color_space, so +// LTH in process will always use the default color space here. +// see crbug/658786. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceColorSpaceChange); class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { @@ -1977,6 +2014,7 @@ class LayerTreeHostTestSetNextCommitForcesRedraw : public LayerTreeHostTest { // This test blocks activation which is not supported for single thread mode. MULTI_THREAD_BLOCKNOTIFY_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw); +REMOTE_TEST_F(LayerTreeHostTestSetNextCommitForcesRedraw); // Tests that if a layer is not drawn because of some reason in the parent then // its damage is preserved until the next time it is drawn. @@ -2073,7 +2111,7 @@ class LayerTreeHostTestUndrawnLayersDamageLater : public LayerTreeHostTest { scoped_refptr<FakePictureLayer> child_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestUndrawnLayersDamageLater); // Tests that if a layer is not drawn because of some reason in the parent then // its damage is preserved until the next time it is drawn. @@ -2178,7 +2216,7 @@ class LayerTreeHostTestDamageWithScale : public LayerTreeHostTest { scoped_refptr<Layer> child_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDamageWithScale); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestDamageWithScale); // This test verifies that properties on the layer tree host are commited // to the impl side. @@ -2222,7 +2260,7 @@ class LayerTreeHostTestCommit : public LayerTreeHostTest { void AfterTest() override {} }; -MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestCommit); // This test verifies that LayerTreeHostImpl's current frame time gets // updated in consecutive frames when it doesn't draw due to tree @@ -2280,6 +2318,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterActivationFails // This test blocks activation which is not supported for single thread mode. MULTI_THREAD_BLOCKNOTIFY_TEST_F( LayerTreeHostTestFrameTimeUpdatesAfterActivationFails); +REMOTE_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterActivationFails); // This test verifies that LayerTreeHostImpl's current frame time gets // updated in consecutive frames when it draws in each frame. @@ -2328,7 +2367,7 @@ class LayerTreeHostTestFrameTimeUpdatesAfterDraw : public LayerTreeHostTest { base::TimeTicks first_frame_time_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestFrameTimeUpdatesAfterDraw); // Verifies that StartPageScaleAnimation events propagate correctly // from LayerTreeHost to LayerTreeHostImpl in the MT compositor. @@ -2406,6 +2445,7 @@ class LayerTreeHostTestStartPageScaleAnimation : public LayerTreeHostTest { }; // Single thread proxy does not support impl-side page scale changes. +// Remote test does not support page scale animation. MULTI_THREAD_TEST_F(LayerTreeHostTestStartPageScaleAnimation); class LayerTreeHostTestSetVisible : public LayerTreeHostTest { @@ -2436,7 +2476,7 @@ class LayerTreeHostTestSetVisible : public LayerTreeHostTest { int num_draws_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetVisible); class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers : public LayerTreeHostTest { @@ -2538,7 +2578,8 @@ class LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers scoped_refptr<FakePictureLayer> child_layer_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); +REMOTE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostTestDeviceScaleFactorScalesViewportAndLayers); class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { public: @@ -2588,7 +2629,7 @@ class LayerTreeHostTestContinuousInvalidate : public LayerTreeHostTest { int num_draw_layers_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestContinuousInvalidate); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestContinuousInvalidate); class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { public: @@ -2646,7 +2687,7 @@ class LayerTreeHostTestDeferCommits : public LayerTreeHostTest { int num_send_begin_main_frame_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestDeferCommits); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestDeferCommits); class LayerTreeHostTestCompositeImmediatelyStateTransitions : public LayerTreeHostTest { @@ -2805,7 +2846,7 @@ class LayerTreeHostTestLCDChange : public LayerTreeHostTest { int num_tiles_rastered_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestLCDChange); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestLCDChange); class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled : public LayerTreeHostTest { @@ -2827,6 +2868,8 @@ class LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled void AfterTest() override {} }; +// No remote test since synchronous renderer compositor is not supported for LTH +// remote. MULTI_THREAD_TEST_F( LayerTreeHostTestBeginFrameNotificationShutdownWhileEnabled); @@ -2880,7 +2923,6 @@ class OnDrawCompositorFrameSink : public TestCompositorFrameSink { explicit OnDrawCompositorFrameSink( scoped_refptr<ContextProvider> compositor_context_provider, scoped_refptr<ContextProvider> worker_context_provider, - std::unique_ptr<OutputSurface> display_output_surface, SharedBitmapManager* shared_bitmap_manager, gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager, const RendererSettings& renderer_settings, @@ -2890,7 +2932,6 @@ class OnDrawCompositorFrameSink : public TestCompositorFrameSink { base::Closure invalidate_callback) : TestCompositorFrameSink(std::move(compositor_context_provider), std::move(worker_context_provider), - std::move(display_output_surface), shared_bitmap_manager, gpu_memory_buffer_manager, renderer_settings, @@ -2927,16 +2968,15 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor &LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor:: CallOnDraw, base::Unretained(this)); - auto output_surface = base::MakeUnique<OnDrawCompositorFrameSink>( + auto frame_sink = base::MakeUnique<OnDrawCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), - CreateDisplayOutputSurface(compositor_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, ImplThreadTaskRunner(), false /* synchronous_composite */, false /* force_disable_reclaim_resources */, std::move(on_draw_callback)); - output_surface_ = output_surface.get(); - return std::move(output_surface); + compositor_frame_sink_ = frame_sink.get(); + return std::move(frame_sink); } void CallOnDraw() { @@ -2946,14 +2986,16 @@ class LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor bool resourceless_software_draw = false; ImplThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&OnDrawCompositorFrameSink::OnDraw, - base::Unretained(output_surface_), + base::Unretained(compositor_frame_sink_), resourceless_software_draw)); } } - OnDrawCompositorFrameSink* output_surface_ = nullptr; + OnDrawCompositorFrameSink* compositor_frame_sink_ = nullptr; }; +// No remote test since synchronous renderer compositor is not supported for LTH +// remote. MULTI_THREAD_TEST_F( LayerTreeHostTestAbortedCommitDoesntStallSynchronousCompositor); @@ -2981,7 +3023,7 @@ class LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation FakeContentLayerClient client_; }; -SINGLE_AND_MULTI_THREAD_TEST_F( +SINGLE_MULTI_AND_REMOTE_TEST_F( LayerTreeHostTestUninvertibleTransformDoesNotBlockActivation); class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { @@ -3001,12 +3043,13 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { case 2: // Round 2 done. EXPECT_EQ(1, frame_); - layer_tree_host()->SetNeedsRedraw(); + layer_tree_host()->SetNeedsRedrawRect( + gfx::Rect(layer_tree()->device_viewport_size())); break; } } - void DidCompleteSwapBuffers() override { + void DidReceiveCompositorFrameAck() override { int commit = layer_tree_host()->SourceFrameNumber(); ++frame_; switch (frame_) { @@ -3029,7 +3072,7 @@ class LayerTreeHostTestNumFramesPending : public LayerTreeHostTest { int frame_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestNumFramesPending); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestNumFramesPending); class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { protected: @@ -3065,16 +3108,15 @@ class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { auto on_draw_callback = base::Bind(&LayerTreeHostTestResourcelessSoftwareDraw::CallOnDraw, base::Unretained(this)); - auto output_surface = base::MakeUnique<OnDrawCompositorFrameSink>( + auto frame_sink = base::MakeUnique<OnDrawCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), - CreateDisplayOutputSurface(compositor_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, ImplThreadTaskRunner(), false /* synchronous_composite */, false /* force_disable_reclaim_resources */, std::move(on_draw_callback)); - output_surface_ = output_surface.get(); - return std::move(output_surface); + compositor_frame_sink_ = frame_sink.get(); + return std::move(frame_sink); } void BeginTest() override { PostSetNeedsCommitToMainThread(); } @@ -3086,7 +3128,7 @@ class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { bool resourceless_software_draw = true; ImplThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&OnDrawCompositorFrameSink::OnDraw, - base::Unretained(output_surface_), + base::Unretained(compositor_frame_sink_), resourceless_software_draw)); } } @@ -3127,7 +3169,7 @@ class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { void AfterTest() override {} private: - OnDrawCompositorFrameSink* output_surface_ = nullptr; + OnDrawCompositorFrameSink* compositor_frame_sink_ = nullptr; FakeContentLayerClient client_; scoped_refptr<Layer> root_layer_; scoped_refptr<Layer> parent_layer_; @@ -3136,6 +3178,8 @@ class LayerTreeHostTestResourcelessSoftwareDraw : public LayerTreeHostTest { }; // Resourceless is not used for SingleThreadProxy, so it is unimplemented. +// No remote test since synchronous renderer compositor is not supported for LTH +// remote. MULTI_THREAD_TEST_F(LayerTreeHostTestResourcelessSoftwareDraw); // Test for UI Resource management. @@ -3232,85 +3276,10 @@ class LayerTreeHostTestUIResource : public LayerTreeHostTest { int num_ui_resources_; }; +// No remote test since LTH remote does not support UIResourceLayers and +// PaintedScrollbarLayers, which uses UIResourceManager. MULTI_THREAD_TEST_F(LayerTreeHostTestUIResource); -class PushPropertiesCountingLayerImpl : public LayerImpl { - public: - static std::unique_ptr<PushPropertiesCountingLayerImpl> Create( - LayerTreeImpl* tree_impl, - int id) { - return base::WrapUnique(new PushPropertiesCountingLayerImpl(tree_impl, id)); - } - - ~PushPropertiesCountingLayerImpl() override {} - - void PushPropertiesTo(LayerImpl* layer) override { - LayerImpl::PushPropertiesTo(layer); - push_properties_count_++; - // Push state to the active tree because we can only access it from there. - static_cast<PushPropertiesCountingLayerImpl*>(layer) - ->push_properties_count_ = push_properties_count_; - } - - std::unique_ptr<LayerImpl> CreateLayerImpl( - LayerTreeImpl* tree_impl) override { - return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); - } - - size_t push_properties_count() const { return push_properties_count_; } - void reset_push_properties_count() { push_properties_count_ = 0; } - - private: - size_t push_properties_count_; - - PushPropertiesCountingLayerImpl(LayerTreeImpl* tree_impl, int id) - : LayerImpl(tree_impl, id), push_properties_count_(0) { - SetBounds(gfx::Size(1, 1)); - } -}; - -class PushPropertiesCountingLayer : public Layer { - public: - static scoped_refptr<PushPropertiesCountingLayer> Create() { - return new PushPropertiesCountingLayer(); - } - - void PushPropertiesTo(LayerImpl* layer) override { - Layer::PushPropertiesTo(layer); - push_properties_count_++; - if (persist_needs_push_properties_) { - GetLayerTree()->AddLayerShouldPushProperties(this); - } - } - - // Something to make this layer push properties, but no other layer. - void MakePushProperties() { SetContentsOpaque(!contents_opaque()); } - - std::unique_ptr<LayerImpl> CreateLayerImpl( - LayerTreeImpl* tree_impl) override { - return PushPropertiesCountingLayerImpl::Create(tree_impl, id()); - } - - void SetDrawsContent(bool draws_content) { SetIsDrawable(draws_content); } - - size_t push_properties_count() const { return push_properties_count_; } - void reset_push_properties_count() { push_properties_count_ = 0; } - - void set_persist_needs_push_properties(bool persist) { - persist_needs_push_properties_ = persist; - } - - private: - PushPropertiesCountingLayer() - : push_properties_count_(0), persist_needs_push_properties_(false) { - SetBounds(gfx::Size(1, 1)); - } - ~PushPropertiesCountingLayer() override {} - - size_t push_properties_count_; - bool persist_needs_push_properties_; -}; - class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { protected: void BeginTest() override { @@ -3511,6 +3480,9 @@ class LayerTreeHostTestLayersPushProperties : public LayerTreeHostTest { size_t expected_push_properties_leaf_layer_; }; +// No remote test because LTH remote does not build property trees, so layers +// to push properties are different between engine and client. +// See crbug/655795. MULTI_THREAD_TEST_F(LayerTreeHostTestLayersPushProperties); class LayerTreeHostTestImplLayersPushProperties @@ -3707,7 +3679,9 @@ class LayerTreeHostTestImplLayersPushProperties size_t expected_push_properties_grandchild2_impl_; }; -// In single thread there's no pending tree to push properties from. +// No remote test because LTH remote does not build property trees, so layers +// to push properties are different between engine and client. +// See crbug/655795. MULTI_THREAD_TEST_F(LayerTreeHostTestImplLayersPushProperties); class LayerTreeHostTestPropertyChangesDuringUpdateArePushed @@ -3765,6 +3739,7 @@ class LayerTreeHostTestPropertyChangesDuringUpdateArePushed scoped_refptr<FakePaintedScrollbarLayer> scrollbar_layer_; }; +// No remote test since remote LTH does not support PaintedScrollbarLayer. MULTI_THREAD_TEST_F(LayerTreeHostTestPropertyChangesDuringUpdateArePushed); class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { @@ -3796,7 +3771,7 @@ class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { EXPECT_EQ(0, root_->NumDescendantsThatDrawContent()); root_->reset_push_properties_count(); child_->reset_push_properties_count(); - child_->SetDrawsContent(true); + child_->SetIsDrawable(true); EXPECT_EQ(1, root_->NumDescendantsThatDrawContent()); EXPECT_EQ(0u, root_->push_properties_count()); EXPECT_EQ(0u, child_->push_properties_count()); @@ -3825,7 +3800,7 @@ class LayerTreeHostTestSetDrawableCausesCommit : public LayerTreeHostTest { scoped_refptr<PushPropertiesCountingLayer> child_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSetDrawableCausesCommit); class LayerTreeHostTestCasePushPropertiesThreeGrandChildren : public LayerTreeHostTest { @@ -3898,7 +3873,8 @@ class LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush } }; -MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush); +REMOTE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostTestPushPropertiesAddingToTreeRequiresPush); class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { @@ -3981,7 +3957,8 @@ class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion } }; -MULTI_THREAD_TEST_F(LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion); +REMOTE_AND_MULTI_THREAD_TEST_F( + LayerTreeHostTestPushPropertiesRemovingChildStopsRecursion); class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence : public LayerTreeHostTestCasePushPropertiesThreeGrandChildren { @@ -4029,7 +4006,7 @@ class LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence } }; -MULTI_THREAD_TEST_F( +REMOTE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestPushPropertiesRemovingChildStopsRecursionWithPersistence); class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree @@ -4098,7 +4075,7 @@ class LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree } }; -MULTI_THREAD_TEST_F( +REMOTE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestPushPropertiesSetPropertiesWhileOutsideTree); class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild @@ -4163,7 +4140,7 @@ class LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild } }; -MULTI_THREAD_TEST_F( +REMOTE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestPushPropertiesSetPropertyInParentThenChild); class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent @@ -4228,7 +4205,7 @@ class LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent } }; -MULTI_THREAD_TEST_F( +REMOTE_AND_MULTI_THREAD_TEST_F( LayerTreeHostTestPushPropertiesSetPropertyInChildThenParent); // This test verifies that the tree activation callback is invoked correctly. @@ -4287,7 +4264,7 @@ class LayerTreeHostTestTreeActivationCallback : public LayerTreeHostTest { int callback_count_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestTreeActivationCallback); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestTreeActivationCallback); class LayerInvalidateCausesDraw : public LayerTreeHostTest { public: @@ -4350,6 +4327,7 @@ class LayerTreeHostTestVideoLayerInvalidate : public LayerInvalidateCausesDraw { FakeVideoFrameProvider provider_; }; +// LTH remote does not support VideoLayer. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestVideoLayerInvalidate); class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { @@ -4417,7 +4395,7 @@ class LayerTreeHostTestPushHiddenLayer : public LayerTreeHostTest { scoped_refptr<SolidColorLayer> child_layer_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestPushHiddenLayer); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeHostTestPushHiddenLayer); class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { protected: @@ -4450,7 +4428,7 @@ class LayerTreeHostTestUpdateLayerInEmptyViewport : public LayerTreeHostTest { scoped_refptr<FakePictureLayer> root_layer_; }; -MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestUpdateLayerInEmptyViewport); class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { public: @@ -4545,6 +4523,7 @@ class LayerTreeHostTestElasticOverscroll : public LayerTreeHostTest { int num_draws_; }; +// Remote test does not support enable_elastic_overscroll. MULTI_THREAD_TEST_F(LayerTreeHostTestElasticOverscroll); struct TestSwapPromiseResult { @@ -4649,6 +4628,9 @@ class PinnedLayerTreeSwapPromise : public LayerTreeHostTest { TestSwapPromiseResult pinned_active_swap_promise_result_; }; +// No remote test because this test compares the swap promises result between +// LTH in process and LTH impl. LTH remote runs its own swap promise, and we +// don't send swap promises to the client. MULTI_THREAD_TEST_F(PinnedLayerTreeSwapPromise); class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { @@ -4746,6 +4728,8 @@ class LayerTreeHostTestBreakSwapPromise : public LayerTreeHostTest { TestSwapPromiseResult swap_promise_result_[3]; }; +// No remote test because LTH remote runs its own swap promises, and we +// don't send swap promises to the LTH in process on the client side. MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromise); class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest { @@ -4837,6 +4821,8 @@ class LayerTreeHostTestKeepSwapPromise : public LayerTreeHostTest { TestSwapPromiseResult swap_promise_result_; }; +// No remote test because LTH remote runs its own swap promises, and we +// don't send swap promises to the LTH in process on the client side. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromise); class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest { @@ -4951,6 +4937,8 @@ class LayerTreeHostTestKeepSwapPromiseMFBA : public LayerTreeHostTest { TestSwapPromiseResult swap_promise_result_; }; +// No remote test because LTH remote runs its own swap promises, and we +// don't send swap promises to the LTH in process on the client side. MULTI_THREAD_TEST_F(LayerTreeHostTestKeepSwapPromiseMFBA); class LayerTreeHostTestBreakSwapPromiseForVisibility @@ -4993,6 +4981,8 @@ class LayerTreeHostTestBreakSwapPromiseForVisibility TestSwapPromiseResult swap_promise_result_; }; +// No remote test because LTH remote runs its own swap promises, and we +// don't send swap promises to the LTH in process on the client side. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestBreakSwapPromiseForVisibility); class SimpleSwapPromiseMonitor : public SwapPromiseMonitor { @@ -5076,6 +5066,8 @@ class LayerTreeHostTestSimpleSwapPromiseMonitor : public LayerTreeHostTest { void AfterTest() override {} }; +// No remote test because LTH remote runs its own swap promises, and we +// don't send swap promises to the LTH in process on the client side. SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSimpleSwapPromiseMonitor); class LayerTreeHostTestHighResRequiredAfterEvictingUIResources @@ -5297,6 +5289,8 @@ class LayerTreeHostTestGpuRasterizationEnabled : public LayerTreeHostTest { FakeRecordingSource* recording_source_; }; +// No remote test since we does not send gpu rasterization flag to the client. +// See crbug/650431. MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabled); class LayerTreeHostTestGpuRasterizationReenabled : public LayerTreeHostTest { @@ -5640,7 +5634,6 @@ class LayerTreeHostTestSynchronousCompositeSwapPromise bool force_disable_reclaim_resources = !reclaim_resources_; return base::MakeUnique<TestCompositorFrameSink>( compositor_context_provider, std::move(worker_context_provider), - CreateDisplayOutputSurface(compositor_context_provider), shared_bitmap_manager(), gpu_memory_buffer_manager(), layer_tree_host()->GetSettings().renderer_settings, ImplThreadTaskRunner(), synchronous_composite, @@ -5942,14 +5935,14 @@ class LayerTreeHostTestCrispUpAfterPinchEnds : public LayerTreeHostTest { // On frame 3, we will have a lower res tile complete for the pinch-out // gesture even though it's not displayed. We wait for it here to prevent // flakiness. - EXPECT_EQ(0.75f, tile->contents_scale()); + EXPECT_EQ(0.75f, tile->contents_scale_key()); PostNextAfterDraw(host_impl); } // On frame_ == 4, we are preventing texture uploads from completing, // so this verifies they are not completing before frame_ == 5. // Flaky failures here indicate we're failing to prevent uploads from // completing. - EXPECT_NE(4, frame_) << tile->contents_scale(); + EXPECT_NE(4, frame_) << tile->contents_scale_key(); } void AfterTest() override {} @@ -5967,7 +5960,7 @@ MULTI_THREAD_TEST_F(LayerTreeHostTestCrispUpAfterPinchEnds); class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy : public LayerTreeHostTestCrispUpAfterPinchEnds { protected: - std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( scoped_refptr<ContextProvider> compositor_context_provider) override { scoped_refptr<TestContextProvider> display_context_provider = TestContextProvider::Create(); @@ -5977,7 +5970,8 @@ class LayerTreeHostTestCrispUpAfterPinchEndsWithOneCopy #if defined(OS_MACOSX) context3d->set_support_texture_rectangle(true); #endif - return LayerTreeTest::CreateDisplayOutputSurface( + display_context_provider->BindToCurrentThread(); + return LayerTreeTest::CreateDisplayOutputSurfaceOnThread( std::move(display_context_provider)); } }; @@ -6730,7 +6724,7 @@ class LayerTreeTestMaskLayerWithDifferentBounds : public LayerTreeTest { FakeContentLayerClient client_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeTestMaskLayerWithDifferentBounds); class LayerTreeTestPageScaleFlags : public LayerTreeTest { protected: @@ -6801,7 +6795,7 @@ class LayerTreeTestPageScaleFlags : public LayerTreeTest { std::vector<int> not_affected_by_page_scale_; }; -SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeTestPageScaleFlags); +SINGLE_MULTI_AND_REMOTE_TEST_F(LayerTreeTestPageScaleFlags); class LayerTreeHostTestDestroyWhileInitializingOutputSurface : public LayerTreeHostTest { diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc index 44f7d83f7b6..b6c4053e7b9 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc @@ -44,14 +44,14 @@ class LayerTreeHostAnimationTest : public LayerTreeTest { } void AttachPlayersToTimeline() { - layer_tree()->animation_host()->AddAnimationTimeline(timeline_.get()); + animation_host()->AddAnimationTimeline(timeline_.get()); layer_tree()->SetElementIdsForTesting(); timeline_->AttachPlayer(player_.get()); timeline_->AttachPlayer(player_child_.get()); } void GetImplTimelineAndPlayerByID(const LayerTreeHostImpl& host_impl) { - AnimationHost* animation_host_impl = host_impl.animation_host(); + AnimationHost* animation_host_impl = GetImplAnimationHost(&host_impl); timeline_impl_ = animation_host_impl->GetTimelineById(timeline_id_); EXPECT_TRUE(timeline_impl_); player_impl_ = timeline_impl_->GetPlayerById(player_id_); @@ -60,6 +60,11 @@ class LayerTreeHostAnimationTest : public LayerTreeTest { EXPECT_TRUE(player_child_impl_); } + AnimationHost* GetImplAnimationHost( + const LayerTreeHostImpl* host_impl) const { + return static_cast<AnimationHost*>(host_impl->mutator_host()); + } + protected: scoped_refptr<AnimationTimeline> timeline_; scoped_refptr<AnimationPlayer> player_; @@ -245,7 +250,7 @@ class LayerTreeHostAnimationTestAnimationsGetDeleted void AnimateLayers(LayerTreeHostImpl* host_impl, base::TimeTicks monotonic_time) override { - bool have_animations = !host_impl->animation_host() + bool have_animations = !GetImplAnimationHost(host_impl) ->active_element_animations_for_testing() .empty(); if (!started_animating_ && have_animations) { @@ -304,7 +309,7 @@ class LayerTreeHostAnimationTestAddAnimationWithTimingFunction return; scoped_refptr<AnimationTimeline> timeline_impl = - host_impl->animation_host()->GetTimelineById(timeline_id_); + GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); scoped_refptr<AnimationPlayer> player_child_impl = timeline_impl->GetPlayerById(player_child_id_); @@ -369,7 +374,7 @@ class LayerTreeHostAnimationTestSynchronizeAnimationStartTimes void UpdateAnimationState(LayerTreeHostImpl* impl_host, bool has_unfinished_animation) override { scoped_refptr<AnimationTimeline> timeline_impl = - impl_host->animation_host()->GetTimelineById(timeline_id_); + GetImplAnimationHost(impl_host)->GetTimelineById(timeline_id_); scoped_refptr<AnimationPlayer> player_child_impl = timeline_impl->GetPlayerById(player_child_id_); @@ -446,7 +451,7 @@ class LayerTreeHostAnimationTestDoNotSkipLayersWithAnimatedOpacity void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { scoped_refptr<AnimationTimeline> timeline_impl = - host_impl->animation_host()->GetTimelineById(timeline_id_); + GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); scoped_refptr<AnimationPlayer> player_impl = timeline_impl->GetPlayerById(player_id_); @@ -795,20 +800,16 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover if (layer_tree_host()->SourceFrameNumber() == 1) { // Add an update after the first commit to trigger the animation takeover // path. - layer_tree() - ->animation_host() - ->scroll_offset_animations() - .AddTakeoverUpdate(scroll_layer_->element_id()); - EXPECT_TRUE(layer_tree() - ->animation_host() - ->scroll_offset_animations() - .HasUpdatesForTesting()); + animation_host()->scroll_offset_animations().AddTakeoverUpdate( + scroll_layer_->element_id()); + EXPECT_TRUE( + animation_host()->scroll_offset_animations().HasUpdatesForTesting()); } } void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->sync_tree()->source_frame_number() == 0) { - host_impl->animation_host()->ImplOnlyScrollAnimationCreate( + GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate( scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f), gfx::ScrollOffset(10, 20), base::TimeDelta()); } @@ -854,14 +855,11 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted const LayerTreeHostImpl& host_impl, scoped_refptr<FakePictureLayer> layer) const { scoped_refptr<ElementAnimations> element_animations = - host_impl.animation_host()->GetElementAnimationsForElementId( - layer->element_id()); + GetImplAnimationHost(&host_impl) + ->GetElementAnimationsForElementId(layer->element_id()); DCHECK(element_animations); DCHECK(element_animations->players_list().might_have_observers()); - - ElementAnimations::PlayersList::Iterator it( - &element_animations->players_list()); - AnimationPlayer* player = it.GetNext(); + AnimationPlayer* player = &*element_animations->players_list().begin(); DCHECK(player); return *player; } @@ -872,21 +870,14 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted if (layer_tree_host()->SourceFrameNumber() == 1) { // Add an update after the first commit to trigger the animation update // path. - layer_tree() - ->animation_host() - ->scroll_offset_animations() - .AddAdjustmentUpdate(scroll_layer_->element_id(), - gfx::Vector2dF(100.f, 100.f)); - EXPECT_TRUE(layer_tree() - ->animation_host() - ->scroll_offset_animations() - .HasUpdatesForTesting()); + animation_host()->scroll_offset_animations().AddAdjustmentUpdate( + scroll_layer_->element_id(), gfx::Vector2dF(100.f, 100.f)); + EXPECT_TRUE( + animation_host()->scroll_offset_animations().HasUpdatesForTesting()); } else if (layer_tree_host()->SourceFrameNumber() == 2) { // Verify that the update queue is cleared after the update is applied. - EXPECT_FALSE(layer_tree() - ->animation_host() - ->scroll_offset_animations() - .HasUpdatesForTesting()); + EXPECT_FALSE( + animation_host()->scroll_offset_animations().HasUpdatesForTesting()); } } @@ -914,7 +905,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationAdjusted void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { if (host_impl->sync_tree()->source_frame_number() == 0) { - host_impl->animation_host()->ImplOnlyScrollAnimationCreate( + GetImplAnimationHost(host_impl)->ImplOnlyScrollAnimationCreate( scroll_layer_->element_id(), gfx::ScrollOffset(650.f, 750.f), gfx::ScrollOffset(10, 20), base::TimeDelta()); } @@ -1040,7 +1031,7 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval return false; scoped_refptr<AnimationTimeline> timeline_impl = - host_impl->animation_host()->GetTimelineById(timeline_id_); + GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); scoped_refptr<AnimationPlayer> player_impl = timeline_impl->GetPlayerById(player_child_id_); @@ -1130,7 +1121,7 @@ class LayerTreeHostAnimationTestAnimationsAddedToNewAndExistingLayers void UpdateAnimationState(LayerTreeHostImpl* host_impl, bool has_unfinished_animation) override { scoped_refptr<AnimationTimeline> timeline_impl = - host_impl->animation_host()->GetTimelineById(timeline_id_); + GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); scoped_refptr<AnimationPlayer> player_impl = timeline_impl->GetPlayerById(player_id_); scoped_refptr<AnimationPlayer> player_child_impl = @@ -1208,7 +1199,7 @@ class LayerTreeHostAnimationTestPendingTreeAnimatesFirstCommit return; scoped_refptr<AnimationTimeline> timeline_impl = - host_impl->animation_host()->GetTimelineById(timeline_id_); + GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); scoped_refptr<AnimationPlayer> player_impl = timeline_impl->GetPlayerById(player_id_); @@ -1252,7 +1243,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded layer_tree()->SetElementIdsForTesting(); - layer_tree()->animation_host()->AddAnimationTimeline(timeline_.get()); + animation_host()->AddAnimationTimeline(timeline_.get()); timeline_->AttachPlayer(player_.get()); player_->AttachElement(layer_->element_id()); DCHECK(player_->element_animations()); @@ -1269,7 +1260,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded player_->element_animations()->has_element_in_active_list()); EXPECT_FALSE( player_->element_animations()->has_element_in_pending_list()); - EXPECT_TRUE(layer_tree()->animation_host()->NeedsAnimateLayers()); + EXPECT_TRUE(animation_host()->NeedsAnimateLayers()); break; case 1: layer_->RemoveFromParent(); @@ -1277,7 +1268,7 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded player_->element_animations()->has_element_in_active_list()); EXPECT_FALSE( player_->element_animations()->has_element_in_pending_list()); - EXPECT_FALSE(layer_tree()->animation_host()->NeedsAnimateLayers()); + EXPECT_FALSE(animation_host()->NeedsAnimateLayers()); break; case 2: layer_tree()->root_layer()->AddChild(layer_); @@ -1285,14 +1276,14 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded player_->element_animations()->has_element_in_active_list()); EXPECT_FALSE( player_->element_animations()->has_element_in_pending_list()); - EXPECT_TRUE(layer_tree()->animation_host()->NeedsAnimateLayers()); + EXPECT_TRUE(animation_host()->NeedsAnimateLayers()); break; } } void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { scoped_refptr<AnimationTimeline> timeline_impl = - host_impl->animation_host()->GetTimelineById(timeline_id_); + GetImplAnimationHost(host_impl)->GetTimelineById(timeline_id_); scoped_refptr<AnimationPlayer> player_impl = timeline_impl->GetPlayerById(player_id_); @@ -1300,17 +1291,17 @@ class LayerTreeHostAnimationTestAnimatedLayerRemovedAndAdded case 0: EXPECT_TRUE( player_impl->element_animations()->has_element_in_active_list()); - EXPECT_TRUE(host_impl->animation_host()->NeedsAnimateLayers()); + EXPECT_TRUE(GetImplAnimationHost(host_impl)->NeedsAnimateLayers()); break; case 1: EXPECT_FALSE( player_impl->element_animations()->has_element_in_active_list()); - EXPECT_FALSE(host_impl->animation_host()->NeedsAnimateLayers()); + EXPECT_FALSE(GetImplAnimationHost(host_impl)->NeedsAnimateLayers()); break; case 2: EXPECT_TRUE( player_impl->element_animations()->has_element_in_active_list()); - EXPECT_TRUE(host_impl->animation_host()->NeedsAnimateLayers()); + EXPECT_TRUE(GetImplAnimationHost(host_impl)->NeedsAnimateLayers()); EndTest(); break; } @@ -1375,7 +1366,7 @@ class LayerTreeHostAnimationTestAddAnimationAfterAnimating void CheckAnimations(LayerTreeHostImpl* host_impl) { GetImplTimelineAndPlayerByID(*host_impl); - EXPECT_EQ(2u, host_impl->animation_host() + EXPECT_EQ(2u, GetImplAnimationHost(host_impl) ->active_element_animations_for_testing() .size()); diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc index ef0c1fbbc5a..25fe1ec2f2b 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc @@ -129,7 +129,7 @@ class LayerTreeHostCopyRequestTestMultipleRequests void AfterTest() override { EXPECT_EQ(4u, callbacks_.size()); } - std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( scoped_refptr<ContextProvider> compositor_context_provider) override { if (!use_gl_renderer_) { return FakeOutputSurface::CreateSoftware( @@ -140,6 +140,7 @@ class LayerTreeHostCopyRequestTestMultipleRequests TestContextProvider::Create(); TestContextSupport* context_support = display_context_provider->support(); context_support->set_out_of_order_callbacks(out_of_order_callbacks_); + display_context_provider->BindToCurrentThread(); return FakeOutputSurface::Create3d(std::move(display_context_provider)); } @@ -466,11 +467,11 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest std::unique_ptr<TestCompositorFrameSink> CreateCompositorFrameSink( scoped_refptr<ContextProvider> compositor_context_provider, scoped_refptr<ContextProvider> worker_context_provider) override { - auto surface = LayerTreeHostCopyRequestTest::CreateCompositorFrameSink( + auto frame_sink = LayerTreeHostCopyRequestTest::CreateCompositorFrameSink( std::move(compositor_context_provider), std::move(worker_context_provider)); - display_ = surface->display(); - return surface; + frame_sink_ = frame_sink.get(); + return frame_sink; } void BeginTest() override { @@ -507,7 +508,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest } void DisplayDidDrawAndSwapOnThread() override { - DirectRenderer* renderer = display_->renderer_for_testing(); + DirectRenderer* renderer = frame_sink_->display()->renderer_for_testing(); // |parent| owns a surface, but it was hidden and not part of the copy // request so it should not allocate any resource. @@ -533,7 +534,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest RenderPassId parent_render_pass_id; RenderPassId copy_layer_render_pass_id; - Display* display_ = nullptr; + TestCompositorFrameSink* frame_sink_ = nullptr; bool did_swap_ = false; FakeContentLayerClient client_; scoped_refptr<FakePictureLayer> root_; @@ -731,9 +732,10 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestAsyncTwoReadbacksWithoutDraw); class LayerTreeHostCopyRequestTestDeleteTexture : public LayerTreeHostCopyRequestTest { protected: - std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( scoped_refptr<ContextProvider> compositor_context_provider) override { display_context_provider_ = TestContextProvider::Create(); + display_context_provider_->BindToCurrentThread(); return FakeOutputSurface::Create3d(display_context_provider_); } @@ -789,6 +791,9 @@ class LayerTreeHostCopyRequestTestDeleteTexture // to be destroyed by the compositor, so we should have 1 less by now. EXPECT_EQ(num_textures_after_readback_ - 1, display_context_provider_->TestContext3d()->NumTextures()); + + // Drop the reference to the context provider on the compositor thread. + display_context_provider_ = nullptr; EndTest(); } @@ -847,7 +852,7 @@ class LayerTreeHostCopyRequestTestCountTextures settings->renderer_settings.texture_id_allocation_chunk_size = 1; } - std::unique_ptr<OutputSurface> CreateDisplayOutputSurface( + std::unique_ptr<OutputSurface> CreateDisplayOutputSurfaceOnThread( scoped_refptr<ContextProvider> compositor_context_provider) override { // These tests expect the LayerTreeHostImpl to share a context with // the Display so that sync points are not needed and the texture counts diff --git a/chromium/cc/trees/layer_tree_host_unittest_damage.cc b/chromium/cc/trees/layer_tree_host_unittest_damage.cc index 561a92a0896..33ff66f3e7a 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_damage.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_damage.cc @@ -43,7 +43,8 @@ class LayerTreeHostDamageTestSetNeedsRedraw void DidCommitAndDrawFrame() override { switch (layer_tree_host()->SourceFrameNumber()) { case 1: - layer_tree_host()->SetNeedsRedraw(); + layer_tree_host()->SetNeedsRedrawRect( + gfx::Rect(layer_tree()->device_viewport_size())); break; } } diff --git a/chromium/cc/trees/layer_tree_host_unittest_picture.cc b/chromium/cc/trees/layer_tree_host_unittest_picture.cc index bb13a32b06e..f7d4fadceeb 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_picture.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_picture.cc @@ -458,19 +458,19 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale case 0: // On 1st commit the pending layer has tilings. ASSERT_EQ(1u, picture->tilings()->num_tilings()); - EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale_key()); break; case 1: // On 2nd commit, the pending layer is transparent, so has a stale // value. ASSERT_EQ(1u, picture->tilings()->num_tilings()); - EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(1.f, picture->tilings()->tiling_at(0)->contents_scale_key()); break; case 2: // On 3rd commit, the pending layer is visible again, so has tilings and // is updated for the pinch. ASSERT_EQ(1u, picture->tilings()->num_tilings()); - EXPECT_EQ(2.f, picture->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(2.f, picture->tilings()->tiling_at(0)->contents_scale_key()); } } @@ -488,7 +488,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale if (draws_in_frame_ == 1) { // On 1st commit the layer has tilings. EXPECT_GT(picture->tilings()->num_tilings(), 0u); - EXPECT_EQ(1.f, picture->HighResTiling()->contents_scale()); + EXPECT_EQ(1.f, picture->HighResTiling()->contents_scale_key()); // Pinch zoom in to change the scale on the active tree. impl->PinchGestureBegin(); @@ -498,7 +498,7 @@ class LayerTreeHostPictureTestRSLLMembershipWithScale // If the pinch gesture caused a commit we could get here with a // pending tree. EXPECT_FALSE(impl->pending_tree()); - EXPECT_EQ(2.f, picture->HighResTiling()->contents_scale()); + EXPECT_EQ(2.f, picture->HighResTiling()->contents_scale_key()); // Need to wait for ready to draw here so that the pinch is // entirely complete, otherwise another draw might come in before @@ -616,10 +616,12 @@ class LayerTreeHostPictureTestForceRecalculateScales case 0: // On first commit, both layers are at the default scale. ASSERT_EQ(1u, will_change_layer->tilings()->num_tilings()); - EXPECT_EQ(1.f, - will_change_layer->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ( + 1.f, + will_change_layer->tilings()->tiling_at(0)->contents_scale_key()); ASSERT_EQ(1u, normal_layer->tilings()->num_tilings()); - EXPECT_EQ(1.f, normal_layer->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(1.f, + normal_layer->tilings()->tiling_at(0)->contents_scale_key()); MainThreadTaskRunner()->PostTask( FROM_HERE, @@ -631,10 +633,12 @@ class LayerTreeHostPictureTestForceRecalculateScales // On 2nd commit after scaling up to 2, the normal layer will adjust its // scale and the will change layer should not (as it is will change. ASSERT_EQ(1u, will_change_layer->tilings()->num_tilings()); - EXPECT_EQ(1.f, - will_change_layer->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ( + 1.f, + will_change_layer->tilings()->tiling_at(0)->contents_scale_key()); ASSERT_EQ(1u, normal_layer->tilings()->num_tilings()); - EXPECT_EQ(2.f, normal_layer->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(2.f, + normal_layer->tilings()->tiling_at(0)->contents_scale_key()); MainThreadTaskRunner()->PostTask( FROM_HERE, @@ -646,10 +650,12 @@ class LayerTreeHostPictureTestForceRecalculateScales // On 3rd commit, both layers should adjust scales due to forced // recalculating. ASSERT_EQ(1u, will_change_layer->tilings()->num_tilings()); - EXPECT_EQ(4.f, - will_change_layer->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ( + 4.f, + will_change_layer->tilings()->tiling_at(0)->contents_scale_key()); ASSERT_EQ(1u, normal_layer->tilings()->num_tilings()); - EXPECT_EQ(4.f, normal_layer->tilings()->tiling_at(0)->contents_scale()); + EXPECT_EQ(4.f, + normal_layer->tilings()->tiling_at(0)->contents_scale_key()); EndTest(); break; } diff --git a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc index e82cd26d5ff..94ca4cb55c0 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_proxy.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_proxy.cc @@ -25,7 +25,7 @@ class LayerTreeHostProxyTest : public LayerTreeTest { return update_check_layer_.get(); } - ProxyMain* GetProxyMain() const { + ProxyMain* GetProxyMain() { DCHECK(HasImplThread()); return static_cast<ProxyMain*>(proxy()); } diff --git a/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.cc b/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.cc index a9b1993bd2e..bb64f2ac81e 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_record_gpu_histogram.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 "cc/animation/animation_host.h" #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_layer_tree_host_client.h" #include "cc/test/test_task_graph_runner.h" @@ -15,9 +16,10 @@ TEST(LayerTreeHostRecordGpuHistogramTest, SingleThreaded) { FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings; - std::unique_ptr<FakeLayerTreeHost> host = - FakeLayerTreeHost::Create(&host_client, &task_graph_runner, settings, - CompositorMode::SINGLE_THREADED); + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( + &host_client, &task_graph_runner, animation_host.get(), settings, + CompositorMode::SINGLE_THREADED); host->RecordGpuRasterizationHistogram(); EXPECT_FALSE(host->gpu_rasterization_histogram_recorded()); } @@ -26,8 +28,10 @@ TEST(LayerTreeHostRecordGpuHistogramTest, Threaded) { FakeLayerTreeHostClient host_client; TestTaskGraphRunner task_graph_runner; LayerTreeSettings settings; + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); std::unique_ptr<FakeLayerTreeHost> host = FakeLayerTreeHost::Create( - &host_client, &task_graph_runner, settings, CompositorMode::THREADED); + &host_client, &task_graph_runner, animation_host.get(), settings, + CompositorMode::THREADED); host->RecordGpuRasterizationHistogram(); EXPECT_TRUE(host->gpu_rasterization_histogram_recorded()); } diff --git a/chromium/cc/trees/layer_tree_host_unittest_remote_server.cc b/chromium/cc/trees/layer_tree_host_unittest_remote_server.cc deleted file mode 100644 index 8a41fb9c2db..00000000000 --- a/chromium/cc/trees/layer_tree_host_unittest_remote_server.cc +++ /dev/null @@ -1,105 +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 <memory> - -#include "base/memory/ptr_util.h" -#include "base/threading/thread_task_runner_handle.h" -#include "cc/animation/animation_host.h" -#include "cc/test/fake_image_serialization_processor.h" -#include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree_host_client.h" -#include "cc/trees/layer_tree_host_in_process.h" -#include "cc/trees/proxy_common.h" -#include "cc/trees/proxy_main.h" -#include "cc/trees/remote_proto_channel.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -class LayerTreeHostTestRemoteServer : public testing::Test, - public RemoteProtoChannel, - public LayerTreeHostClient { - public: - LayerTreeHostTestRemoteServer() - : calls_received_(0), - image_serialization_processor_( - base::WrapUnique(new FakeImageSerializationProcessor)) { - LayerTreeHostInProcess::InitParams params; - params.client = this; - params.task_graph_runner = &task_graph_runner_; - params.settings = &settings_; - params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); - params.image_serialization_processor = image_serialization_processor_.get(); - params.animation_host = - AnimationHost::CreateForTesting(ThreadInstance::MAIN); - layer_tree_host_ = - LayerTreeHostInProcess::CreateRemoteServer(this, ¶ms); - } - - ~LayerTreeHostTestRemoteServer() override {} - - // LayerTreeHostClient implementation - void WillBeginMainFrame() override {} - void BeginMainFrame(const BeginFrameArgs& args) override {} - void BeginMainFrameNotExpectedSoon() override {} - void DidBeginMainFrame() override {} - void UpdateLayerTreeHost() override {} - void ApplyViewportDeltas(const gfx::Vector2dF& inner_delta, - const gfx::Vector2dF& outer_delta, - const gfx::Vector2dF& elastic_overscroll_delta, - float page_scale, - float top_controls_delta) override {} - void RequestNewCompositorFrameSink() override { NOTREACHED(); } - void DidInitializeCompositorFrameSink() override { NOTREACHED(); } - void DidFailToInitializeCompositorFrameSink() override { NOTREACHED(); } - void WillCommit() override {} - void DidCommit() override {} - void DidCommitAndDrawFrame() override {} - void DidCompleteSwapBuffers() override {} - void DidCompletePageScaleAnimation() override {} - - // RemoteProtoChannel implementation - void SetProtoReceiver(RemoteProtoChannel::ProtoReceiver* receiver) override { - receiver_ = receiver; - } - void SendCompositorProto(const proto::CompositorMessage& proto) override {} - - int calls_received_; - TestTaskGraphRunner task_graph_runner_; - LayerTreeSettings settings_; - std::unique_ptr<LayerTreeHostInProcess> layer_tree_host_; - RemoteProtoChannel::ProtoReceiver* receiver_; - std::unique_ptr<FakeImageSerializationProcessor> - image_serialization_processor_; - - private: - DISALLOW_COPY_AND_ASSIGN(LayerTreeHostTestRemoteServer); -}; - -class LayerTreeHostTestRemoteServerBeginMainFrame - : public LayerTreeHostTestRemoteServer { - protected: - void BeginMainFrame(const BeginFrameArgs& args) override { - calls_received_++; - } -}; - -// Makes sure that the BeginMainFrame call is not aborted on the server. -// See crbug.com/577301. -TEST_F(LayerTreeHostTestRemoteServerBeginMainFrame, BeginMainFrameNotAborted) { - layer_tree_host_->SetVisible(true); - - std::unique_ptr<BeginMainFrameAndCommitState> begin_frame_state; - begin_frame_state.reset(new BeginMainFrameAndCommitState()); - begin_frame_state->scroll_info.reset(new ScrollAndScaleSet()); - - static_cast<ProxyMain*>(layer_tree_host_->proxy()) - ->BeginMainFrame(std::move(begin_frame_state)); - EXPECT_EQ(calls_received_, 1); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc index 7af261ed77f..473d5285e43 100644 --- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc +++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc @@ -21,10 +21,11 @@ #include "cc/test/fake_picture_layer_impl.h" #include "cc/test/geometry_test_utils.h" #include "cc/test/layer_tree_test.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.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" #include "testing/gmock/include/gmock/gmock.h" #include "ui/gfx/geometry/point_conversions.h" #include "ui/gfx/geometry/size_conversions.h" @@ -155,7 +156,7 @@ class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest { int outer_viewport_container_layer_id_; }; -MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple); +REMOTE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestScrollSimple); class LayerTreeHostScrollTestScrollMultipleRedraw : public LayerTreeHostScrollTest { @@ -1306,16 +1307,16 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { LayerTreeSettings settings; StubLayerTreeHostClient layer_tree_host_client; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; + auto animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + LayerTreeHostInProcess::InitParams params; params.client = &layer_tree_host_client; - params.shared_bitmap_manager = &shared_bitmap_manager; params.task_graph_runner = &task_graph_runner; params.settings = &settings; params.main_task_runner = base::ThreadTaskRunnerHandle::Get(); - params.animation_host = AnimationHost::CreateForTesting(ThreadInstance::MAIN); + params.mutator_host = animation_host.get(); std::unique_ptr<LayerTreeHostInProcess> layer_tree_host = LayerTreeHostInProcess::CreateThreaded(impl_thread.task_runner(), ¶ms); @@ -1328,7 +1329,11 @@ TEST(LayerTreeHostFlingTest, DidStopFlingingThread) { base::Unretained(&input_handler_client))); layer_tree_host->DidStopFlinging(); + + animation_host->SetMutatorHostClient(nullptr); layer_tree_host = nullptr; + animation_host = nullptr; + impl_thread.Stop(); EXPECT_TRUE(received_stop_flinging); } @@ -1977,5 +1982,258 @@ class LayerTreeHostScrollTestElasticOverscroll MULTI_THREAD_TEST_F(LayerTreeHostScrollTestElasticOverscroll); +class LayerTreeHostScrollTestPropertyTreeUpdate + : public LayerTreeHostScrollTest { + public: + LayerTreeHostScrollTestPropertyTreeUpdate() + : initial_scroll_(10, 20), second_scroll_(0, 0) {} + + void BeginTest() override { + layer_tree()->inner_viewport_scroll_layer()->SetScrollOffset( + initial_scroll_); + layer_tree()->inner_viewport_scroll_layer()->SetBounds(gfx::Size(100, 100)); + PostSetNeedsCommitToMainThread(); + } + + void UpdateLayerTreeHost() override { + Layer* scroll_layer = layer_tree()->inner_viewport_scroll_layer(); + if (layer_tree_host()->SourceFrameNumber() == 0) { + EXPECT_VECTOR_EQ(initial_scroll_, scroll_layer->scroll_offset()); + } else { + EXPECT_VECTOR_EQ( + gfx::ScrollOffsetWithDelta(initial_scroll_, scroll_amount_), + scroll_layer->scroll_offset()); + scroll_layer->SetScrollOffset(second_scroll_); + scroll_layer->SetOpacity(0.5f); + } + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* impl) override { + LayerImpl* scroll_layer = impl->InnerViewportScrollLayer(); + + switch (impl->active_tree()->source_frame_number()) { + case 0: + EXPECT_VECTOR_EQ(initial_scroll_, ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting( + scroll_layer->id())); + EXPECT_VECTOR_EQ( + initial_scroll_, + scroll_layer->layer_tree_impl() + ->property_trees() + ->transform_tree.Node(scroll_layer->transform_tree_index()) + ->scroll_offset); + PostSetNeedsCommitToMainThread(); + break; + case 1: + EXPECT_VECTOR_EQ(second_scroll_, ScrollTreeForLayer(scroll_layer) + ->GetScrollOffsetBaseForTesting( + scroll_layer->id())); + EXPECT_VECTOR_EQ( + second_scroll_, + scroll_layer->layer_tree_impl() + ->property_trees() + ->transform_tree.Node(scroll_layer->transform_tree_index()) + ->scroll_offset); + EndTest(); + break; + } + } + + void AfterTest() override {} + + private: + gfx::ScrollOffset initial_scroll_; + gfx::ScrollOffset second_scroll_; + gfx::Vector2dF scroll_amount_; +}; + +SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestPropertyTreeUpdate); + +class LayerTreeHostScrollTestAppliesReflectedDeltas + : public LayerTreeHostScrollTest { + public: + void BeginTest() override { PostSetNeedsCommitToMainThread(); } + + void SetupTree() override { + LayerTreeHostScrollTest::SetupTree(); + + gfx::Size scroll_layer_bounds(200, 200); + layer_tree()->outer_viewport_scroll_layer()->SetBounds(scroll_layer_bounds); + layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset( + initial_offset_); + layer_tree()->outer_viewport_scroll_layer()->set_did_scroll_callback( + base::Bind(&LayerTreeHostScrollTestAppliesReflectedDeltas:: + DidScrollOuterViewport, + base::Unretained(this))); + + layer_tree()->SetPageScaleFactorAndLimits(initial_page_scale_, 0.f, 1.f); + } + + void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override { + LayerImpl* outer_viewport_layer = host_impl->OuterViewportScrollLayer(); + + switch (host_impl->active_tree()->source_frame_number()) { + case 0: { + // We have the first tree, so let's scroll the outer viewport layer and + // change the page scale. + outer_viewport_layer->ScrollBy(outer_viewport_offset_deltas_[0]); + last_active_offset_ = outer_viewport_layer->CurrentScrollOffset(); + + host_impl->active_tree()->page_scale_factor()->SetCurrent( + initial_page_scale_ * page_scale_update_); + last_page_scale_ = + host_impl->active_tree()->current_page_scale_factor(); + + PostSetNeedsCommitToMainThread(); + } break; + case 1: + // The scroll offset on the active tree should remain unchanged. + EXPECT_EQ(last_active_offset_, + outer_viewport_layer->CurrentScrollOffset()); + EXPECT_EQ(last_page_scale_, + host_impl->active_tree()->current_page_scale_factor()); + + // Scroll again to make sure that only the delta applied in this frame + // is reported to the main thread. + outer_viewport_layer->ScrollBy(outer_viewport_offset_deltas_[1]); + last_active_offset_ = outer_viewport_layer->CurrentScrollOffset(); + + PostSetNeedsCommitToMainThread(); + break; + case 2: + // The scroll offset on the active tree should remain unchanged. + EXPECT_EQ(last_active_offset_, + outer_viewport_layer->CurrentScrollOffset()); + EXPECT_EQ(last_page_scale_, + host_impl->active_tree()->current_page_scale_factor()); + + // One last frame to make sure we reach consistent state. + PostSetNeedsCommitToMainThread(); + break; + case 3: + // The scroll offset on the active tree should remain unchanged. + EXPECT_EQ(last_active_offset_, + outer_viewport_layer->CurrentScrollOffset()); + EXPECT_EQ(last_page_scale_, + host_impl->active_tree()->current_page_scale_factor()); + + EndTest(); + break; + } + } + + void WillCommitCompleteOnThread(LayerTreeHostImpl* host_impl) override { + LayerTreeImpl* sync_tree = host_impl->sync_tree(); + LayerImpl* outer_viewport_layer = sync_tree->OuterViewportScrollLayer(); + TransformNode* node = sync_tree->property_trees()->transform_tree.Node( + outer_viewport_layer->transform_tree_index()); + + switch (host_impl->sync_tree()->source_frame_number()) { + case 1: + case 2: + // Pushing page scale/scroll offset from the main thread should have + // resulted in a request to update draw properties. This is necessary + // to ensure that the draw properties are recomputed on the pending + // tree post-commit, since the property trees update on the main thread + // did not include the additionally reflected delta. + EXPECT_TRUE(host_impl->sync_tree()->needs_update_draw_properties()); + EXPECT_TRUE(node->needs_local_transform_update); + break; + } + } + + void BeginMainFrame(const BeginFrameArgs& args) override { + switch (layer_tree_host()->SourceFrameNumber()) { + case 1: + // Pretend that we could not apply the deltas this frame and send them + // back to the impl thread. + layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset( + initial_offset_); + layer_tree()->SetPageScaleFactorAndLimits(initial_page_scale_, 0.f, + 1.f); + + SendReflectedMainFrameState(0); + break; + case 2: + // Pretend that the previous delta was handled and now reflect back the + // new delta. + layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset( + gfx::ScrollOffsetWithDelta(initial_offset_, + outer_viewport_offset_deltas_[0])); + layer_tree()->SetPageScaleFactorAndLimits( + initial_page_scale_ * page_scale_update_, 0.f, 1.f); + + SendReflectedMainFrameState(1); + break; + case 3: + // Reflect all the deltas on the tree during the main frame itself. + gfx::ScrollOffset scroll_offset = + layer_tree()->outer_viewport_scroll_layer()->scroll_offset(); + layer_tree()->outer_viewport_scroll_layer()->SetScrollOffset( + gfx::ScrollOffsetWithDelta(scroll_offset, + outer_viewport_offset_deltas_[1])); + break; + } + } + + void DidScrollOuterViewport() { + Layer* outer_viewport_layer = layer_tree()->outer_viewport_scroll_layer(); + gfx::ScrollOffset expected_offset; + switch (layer_tree_host()->SourceFrameNumber()) { + case 0: + NOTREACHED(); + case 1: + expected_offset = gfx::ScrollOffsetWithDelta( + initial_offset_, outer_viewport_offset_deltas_[0]); + EXPECT_EQ(outer_viewport_layer->scroll_offset(), expected_offset); + break; + case 2: + // Since the first delta was reflected back and not applied on the main + // thread, the value here should only include the delta from the second + // update. + expected_offset = gfx::ScrollOffsetWithDelta( + initial_offset_, outer_viewport_offset_deltas_[1]); + EXPECT_EQ(outer_viewport_layer->scroll_offset(), expected_offset); + break; + default: + NOTREACHED(); + } + } + + void AfterTest() override {} + + private: + void SendReflectedMainFrameState(int delta_to_reflect) { + std::unique_ptr<ReflectedMainFrameState> reflected_main_frame_state = + base::MakeUnique<ReflectedMainFrameState>(); + + ReflectedMainFrameState::ScrollUpdate scroll_update; + scroll_update.layer_id = layer_tree()->outer_viewport_scroll_layer()->id(); + scroll_update.scroll_delta = + outer_viewport_offset_deltas_[delta_to_reflect]; + reflected_main_frame_state->scrolls.push_back(scroll_update); + + if (delta_to_reflect == 0) + reflected_main_frame_state->page_scale_delta = page_scale_update_; + + layer_tree_host_in_process()->SetReflectedMainFrameState( + std::move(reflected_main_frame_state)); + } + + // Accessed on the impl thread. + gfx::ScrollOffset last_active_offset_; + float last_page_scale_ = 0.f; + + const gfx::ScrollOffset initial_offset_ = gfx::ScrollOffset(2, 3); + const gfx::Vector2dF outer_viewport_offset_deltas_[2] = { + gfx::Vector2dF(10, 3), gfx::Vector2dF(5, 3)}; + + const float initial_page_scale_ = 0.5f; + const float page_scale_update_ = 0.2f; +}; + +// The reflected deltas are supported in threaded mode only. +MULTI_THREAD_TEST_F(LayerTreeHostScrollTestAppliesReflectedDeltas); + } // namespace } // namespace cc diff --git a/chromium/cc/trees/layer_tree_host_unittest_serialization.cc b/chromium/cc/trees/layer_tree_host_unittest_serialization.cc deleted file mode 100644 index 7cab9ba0ca4..00000000000 --- a/chromium/cc/trees/layer_tree_host_unittest_serialization.cc +++ /dev/null @@ -1,446 +0,0 @@ -// Copyright 2015 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.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "cc/layers/empty_content_layer_client.h" -#include "cc/layers/heads_up_display_layer.h" -#include "cc/layers/layer.h" -#include "cc/proto/layer.pb.h" -#include "cc/proto/layer_tree_host.pb.h" -#include "cc/test/fake_image_serialization_processor.h" -#include "cc/test/fake_layer_tree_host.h" -#include "cc/test/fake_layer_tree_host_client.h" -#include "cc/test/fake_picture_layer.h" -#include "cc/test/fake_recording_source.h" -#include "cc/test/layer_tree_test.h" -#include "cc/test/skia_common.h" -#include "cc/test/test_task_graph_runner.h" -#include "cc/trees/layer_tree.h" -#include "cc/trees/layer_tree_host_common.h" -#include "cc/trees/layer_tree_settings.h" -#include "testing/gtest/include/gtest/gtest.h" -#include "third_party/skia/include/core/SkColor.h" -#include "ui/gfx/geometry/point.h" -#include "ui/gfx/geometry/size.h" -#include "ui/gfx/geometry/vector2d_f.h" - -namespace cc { - -namespace { -std::unique_ptr<FakeRecordingSource> CreateRecordingSource( - const gfx::Rect& viewport) { - gfx::Rect layer_rect(viewport.right(), viewport.bottom()); - std::unique_ptr<FakeRecordingSource> recording_source = - FakeRecordingSource::CreateRecordingSource(viewport, layer_rect.size()); - return recording_source; -} - -scoped_refptr<FakePictureLayer> CreatePictureLayer() { - gfx::Rect recorded_viewport(0, 0, 256, 256); - - std::unique_ptr<FakeRecordingSource> recording_source = - CreateRecordingSource(recorded_viewport); - recording_source->SetDisplayListUsesCachedPicture(false); - - SkPaint simple_paint; - simple_paint.setColor(SkColorSetARGB(255, 12, 23, 34)); - recording_source->add_draw_rect_with_paint(gfx::Rect(0, 0, 256, 256), - simple_paint); - recording_source->SetGenerateDiscardableImagesMetadata(true); - recording_source->Rerecord(); - - ContentLayerClient* client = EmptyContentLayerClient::GetInstance(); - return FakePictureLayer::CreateWithRecordingSource( - client, std::move(recording_source)); -} -} // namespace - -class LayerTreeHostSerializationTest : public testing::Test { - public: - LayerTreeHostSerializationTest() - : image_serialization_processor_( - base::MakeUnique<FakeImageSerializationProcessor>()) {} - - protected: - void SetUp() override { - LayerTreeSettings settings; - layer_tree_host_src_ = FakeLayerTreeHost::Create( - &client_src_, &task_graph_runner_src_, settings, - CompositorMode::SINGLE_THREADED, image_serialization_processor_.get()); - layer_tree_host_dst_ = FakeLayerTreeHost::Create( - &client_dst_, &task_graph_runner_dst_, settings, - CompositorMode::SINGLE_THREADED, image_serialization_processor_.get()); - layer_tree_host_src_->InitializePictureCacheForTesting(); - layer_tree_host_dst_->InitializePictureCacheForTesting(); - } - - void TearDown() override { - // Need to reset |in_paint_layer_contents_| to tear down. - - layer_tree_host_src_->GetLayerTree()->in_paint_layer_contents_ = false; - layer_tree_host_dst_->GetLayerTree()->in_paint_layer_contents_ = false; - - // Need to reset LayerTreeHost pointers before tear down. - layer_tree_host_src_ = nullptr; - layer_tree_host_dst_ = nullptr; - } - - void VerifyHostHasAllExpectedLayersInTree(Layer* root_layer) { - LayerTreeHostCommon::CallFunctionForEveryLayer( - root_layer->GetLayerTree(), [root_layer](Layer* layer) { - DCHECK(layer->GetLayerTreeHostForTesting()); - EXPECT_EQ(layer, layer->GetLayerTree()->LayerById(layer->id())); - }); - } - - void VerifySerializationAndDeserialization() { - proto::LayerTreeHost proto; - LayerTree* layer_tree_src = layer_tree_host_src_->GetLayerTree(); - LayerTree* layer_tree_dst = layer_tree_host_dst_->GetLayerTree(); - - std::unordered_set<Layer*> layers_that_should_push_properties_src = - layer_tree_src->LayersThatShouldPushProperties(); - std::vector<std::unique_ptr<SwapPromise>> swap_promises; - layer_tree_host_src_->ToProtobufForCommit(&proto, &swap_promises); - layer_tree_host_dst_->FromProtobufForCommit(proto); - - EXPECT_EQ(layer_tree_src->needs_full_tree_sync_, - layer_tree_dst->needs_full_tree_sync_); - EXPECT_EQ(layer_tree_src->needs_meta_info_recomputation_, - layer_tree_dst->needs_meta_info_recomputation_); - EXPECT_EQ(layer_tree_host_src_->source_frame_number_, - layer_tree_host_dst_->source_frame_number_); - EXPECT_EQ(layer_tree_host_src_->root_layer()->id(), - layer_tree_host_dst_->root_layer()->id()); - EXPECT_EQ(layer_tree_host_dst_.get(), - layer_tree_dst->inputs_.root_layer->GetLayerTreeHostForTesting()); - EXPECT_EQ(layer_tree_src->inputs_.root_layer->double_sided(), - layer_tree_dst->inputs_.root_layer->double_sided()); - EXPECT_EQ(layer_tree_src->inputs_.device_viewport_size, - layer_tree_dst->inputs_.device_viewport_size); - EXPECT_EQ(layer_tree_src->inputs_.device_scale_factor, - layer_tree_dst->inputs_.device_scale_factor); - EXPECT_EQ(layer_tree_src->inputs_.painted_device_scale_factor, - layer_tree_dst->inputs_.painted_device_scale_factor); - EXPECT_EQ(layer_tree_src->inputs_.page_scale_factor, - layer_tree_dst->inputs_.page_scale_factor); - EXPECT_EQ(layer_tree_src->inputs_.min_page_scale_factor, - layer_tree_dst->inputs_.min_page_scale_factor); - EXPECT_EQ(layer_tree_src->inputs_.max_page_scale_factor, - layer_tree_dst->inputs_.max_page_scale_factor); - EXPECT_EQ(layer_tree_src->elastic_overscroll_, - layer_tree_dst->elastic_overscroll_); - EXPECT_EQ(layer_tree_host_src_->has_gpu_rasterization_trigger_, - layer_tree_host_dst_->has_gpu_rasterization_trigger_); - EXPECT_EQ(layer_tree_host_src_->content_is_suitable_for_gpu_rasterization_, - layer_tree_host_dst_->content_is_suitable_for_gpu_rasterization_); - EXPECT_EQ(layer_tree_src->inputs_.background_color, - layer_tree_dst->inputs_.background_color); - EXPECT_EQ(layer_tree_src->inputs_.has_transparent_background, - layer_tree_dst->inputs_.has_transparent_background); - EXPECT_EQ(layer_tree_src->in_paint_layer_contents(), - layer_tree_dst->in_paint_layer_contents()); - EXPECT_EQ(layer_tree_host_src_->id_, layer_tree_host_dst_->id_); - EXPECT_EQ(layer_tree_host_src_->next_commit_forces_redraw_, - layer_tree_host_dst_->next_commit_forces_redraw_); - for (auto* layer : layers_that_should_push_properties_src) { - EXPECT_TRUE(layer_tree_dst->LayerNeedsPushPropertiesForTesting( - layer_tree_dst->LayerById(layer->id()))); - } - - if (layer_tree_src->hud_layer_) { - EXPECT_EQ(layer_tree_src->hud_layer_->id(), - layer_tree_dst->hud_layer_->id()); - // The HUD layer member is a HeadsUpDisplayLayer instead of Layer, so - // inspect the proto to see if it contains the the right layer type. - bool found_hud_layer_type = false; - for (int i = 0; i < proto.layer_tree().root_layer().children_size(); - ++i) { - if (proto.layer_tree().root_layer().children(i).id() == - layer_tree_src->hud_layer_->id()) { - EXPECT_EQ(proto::LayerNode::HEADS_UP_DISPLAY_LAYER, - proto.layer_tree().root_layer().children(i).type()); - found_hud_layer_type = true; - break; - } - } - EXPECT_TRUE(found_hud_layer_type); - } else { - EXPECT_FALSE(layer_tree_dst->hud_layer_); - } - if (layer_tree_src->overscroll_elasticity_layer()) { - EXPECT_EQ(layer_tree_src->overscroll_elasticity_layer()->id(), - layer_tree_dst->overscroll_elasticity_layer()->id()); - } else { - EXPECT_FALSE(layer_tree_dst->overscroll_elasticity_layer()); - } - if (layer_tree_src->page_scale_layer()) { - EXPECT_EQ(layer_tree_src->page_scale_layer()->id(), - layer_tree_dst->page_scale_layer()->id()); - } else { - EXPECT_FALSE(layer_tree_dst->page_scale_layer()); - } - if (layer_tree_src->inner_viewport_scroll_layer()) { - EXPECT_EQ(layer_tree_src->inner_viewport_scroll_layer()->id(), - layer_tree_dst->inner_viewport_scroll_layer()->id()); - } else { - EXPECT_FALSE(layer_tree_dst->inner_viewport_scroll_layer()); - } - if (layer_tree_src->outer_viewport_scroll_layer()) { - EXPECT_EQ(layer_tree_src->outer_viewport_scroll_layer()->id(), - layer_tree_dst->outer_viewport_scroll_layer()->id()); - } else { - EXPECT_FALSE(layer_tree_dst->outer_viewport_scroll_layer()); - } - EXPECT_EQ(layer_tree_src->inputs_.selection, - layer_tree_dst->inputs_.selection); - EXPECT_EQ(layer_tree_src->property_trees_, layer_tree_dst->property_trees_); - - // All layers must have a property tree index that matches PropertyTrees. - if (layer_tree_dst->property_trees_.sequence_number) { - int seq_num = layer_tree_dst->property_trees_.sequence_number; - LayerTreeHostCommon::CallFunctionForEveryLayer( - layer_tree_host_dst_->GetLayerTree(), [seq_num](Layer* layer) { - EXPECT_EQ(seq_num, layer->property_tree_sequence_number()); - }); - } - } - - void RunAllMembersChangedTest() { - LayerTree* layer_tree_src = layer_tree_host_src_->GetLayerTree(); - - layer_tree_src->needs_full_tree_sync_ = - !layer_tree_src->needs_full_tree_sync_; - layer_tree_src->needs_meta_info_recomputation_ = - !layer_tree_src->needs_meta_info_recomputation_; - layer_tree_host_src_->source_frame_number_ *= 3; - - // Just fake setup a layer for both source and dest. - scoped_refptr<Layer> root_layer_src = Layer::Create(); - layer_tree_host_src_->SetRootLayer(root_layer_src); - layer_tree_host_dst_->SetRootLayer(Layer::Create()); - root_layer_src->SetDoubleSided(!root_layer_src->double_sided()); - - layer_tree_src->inputs_.device_viewport_size = gfx::Size(3, 14); - layer_tree_src->inputs_.device_scale_factor = - layer_tree_src->inputs_.device_scale_factor * 3 + 1; - layer_tree_src->inputs_.painted_device_scale_factor = - layer_tree_src->inputs_.painted_device_scale_factor * 3 + 1; - layer_tree_src->inputs_.page_scale_factor = - layer_tree_src->inputs_.page_scale_factor * 3 + 1; - layer_tree_src->inputs_.min_page_scale_factor = - layer_tree_src->inputs_.min_page_scale_factor * 3 + 1; - layer_tree_src->inputs_.max_page_scale_factor = - layer_tree_src->inputs_.max_page_scale_factor * 3 + 1; - layer_tree_src->elastic_overscroll_ = gfx::Vector2dF(3, 14); - layer_tree_host_src_->has_gpu_rasterization_trigger_ = - !layer_tree_host_src_->has_gpu_rasterization_trigger_; - layer_tree_host_src_->content_is_suitable_for_gpu_rasterization_ = - !layer_tree_host_src_->content_is_suitable_for_gpu_rasterization_; - layer_tree_src->inputs_.background_color = SK_ColorMAGENTA; - layer_tree_src->inputs_.has_transparent_background = - !layer_tree_src->inputs_.has_transparent_background; - layer_tree_host_src_->id_ = layer_tree_host_src_->id_ * 3 + 1; - layer_tree_host_src_->next_commit_forces_redraw_ = - !layer_tree_host_src_->next_commit_forces_redraw_; - - layer_tree_src->hud_layer_ = HeadsUpDisplayLayer::Create(); - root_layer_src->AddChild(layer_tree_src->hud_layer_); - - scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); - scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create(); - - root_layer_src->AddChild(overscroll_elasticity_layer); - root_layer_src->AddChild(page_scale_layer); - root_layer_src->AddChild(inner_viewport_scroll_layer); - root_layer_src->AddChild(outer_viewport_scroll_layer); - - layer_tree_src->RegisterViewportLayers( - overscroll_elasticity_layer, page_scale_layer, - inner_viewport_scroll_layer, outer_viewport_scroll_layer); - - // Set in_paint_layer_contents_ only after all calls to AddChild() have - // finished to ensure it's allowed to do so at that time. - layer_tree_src->in_paint_layer_contents_ = - !layer_tree_src->in_paint_layer_contents(); - - LayerSelectionBound sel_bound; - sel_bound.edge_top = gfx::Point(14, 3); - LayerSelection selection; - selection.start = sel_bound; - layer_tree_src->inputs_.selection = selection; - - layer_tree_src->property_trees_.sequence_number = - layer_tree_src->property_trees_.sequence_number * 3 + 1; - - VerifySerializationAndDeserialization(); - } - - void RunLayersChangedTest() { - // Just fake setup a layer for both source and dest. - scoped_refptr<Layer> root_layer_src = Layer::Create(); - layer_tree_host_src_->SetRootLayer(root_layer_src); - layer_tree_host_dst_->SetRootLayer(Layer::Create()); - root_layer_src->SetDoubleSided(!root_layer_src->double_sided()); - - // No HUD layer or |overscroll_elasticity_layer_|, or the inner/outer - // viewport scroll layers. - scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); - layer_tree_host_src_->GetLayerTree()->inputs_.overscroll_elasticity_layer = - overscroll_elasticity_layer; - root_layer_src->AddChild(overscroll_elasticity_layer); - - VerifySerializationAndDeserialization(); - } - - void RunLayersChangedMultipleSerializations() { - // Just fake setup a layer for both source and dest. - scoped_refptr<Layer> root_layer_src = Layer::Create(); - layer_tree_host_src_->SetRootLayer(root_layer_src); - layer_tree_host_dst_->SetRootLayer(Layer::Create()); - root_layer_src->SetDoubleSided(!root_layer_src->double_sided()); - - LayerTree* layer_tree_src = layer_tree_host_src_->GetLayerTree(); - - // Ensure that all the layers work correctly for multiple rounds of - // serialization and deserialization. - layer_tree_src->hud_layer_ = HeadsUpDisplayLayer::Create(); - root_layer_src->AddChild(layer_tree_src->hud_layer_); - - scoped_refptr<Layer> overscroll_elasticity_layer = Layer::Create(); - scoped_refptr<Layer> page_scale_layer = Layer::Create(); - scoped_refptr<Layer> inner_viewport_scroll_layer = Layer::Create(); - scoped_refptr<Layer> outer_viewport_scroll_layer = Layer::Create(); - - root_layer_src->AddChild(overscroll_elasticity_layer); - root_layer_src->AddChild(page_scale_layer); - root_layer_src->AddChild(inner_viewport_scroll_layer); - root_layer_src->AddChild(outer_viewport_scroll_layer); - layer_tree_host_src_->GetLayerTree()->RegisterViewportLayers( - overscroll_elasticity_layer, page_scale_layer, - inner_viewport_scroll_layer, outer_viewport_scroll_layer); - - VerifySerializationAndDeserialization(); - VerifySerializationAndDeserialization(); - - layer_tree_src->hud_layer_ = nullptr; - VerifySerializationAndDeserialization(); - layer_tree_host_src_->GetLayerTree()->inputs_.overscroll_elasticity_layer = - nullptr; - VerifySerializationAndDeserialization(); - layer_tree_host_src_->GetLayerTree()->inputs_.page_scale_layer = nullptr; - VerifySerializationAndDeserialization(); - layer_tree_host_src_->GetLayerTree()->inputs_.inner_viewport_scroll_layer = - nullptr; - VerifySerializationAndDeserialization(); - layer_tree_host_src_->GetLayerTree()->inputs_.outer_viewport_scroll_layer = - nullptr; - VerifySerializationAndDeserialization(); - } - - void RunPictureLayerMultipleSerializationsTest() { - // Just fake setup a layer for both source and dest. - scoped_refptr<Layer> root_layer_src = Layer::Create(); - layer_tree_host_src_->SetRootLayer(root_layer_src); - layer_tree_host_dst_->SetRootLayer(Layer::Create()); - - // Ensure that a PictureLayer work correctly for multiple rounds of - // serialization and deserialization. - scoped_refptr<FakePictureLayer> picture_layer_src = CreatePictureLayer(); - root_layer_src->AddChild(picture_layer_src); - picture_layer_src->SetBounds(gfx::Size(10, 10)); - picture_layer_src->SetIsDrawable(true); - picture_layer_src->SavePaintProperties(); - picture_layer_src->Update(); - picture_layer_src->SavePaintProperties(); - VerifySerializationAndDeserialization(); - ASSERT_EQ(1U, layer_tree_host_dst_->root_layer()->children().size()); - PictureLayer* picture_layer_dst = reinterpret_cast<PictureLayer*>( - layer_tree_host_dst_->root_layer()->child_at(0)); - - RecordingSource* recording_source_src = - picture_layer_src->GetRecordingSourceForTesting(); - RecordingSource* recording_source_dst = - picture_layer_dst->GetRecordingSourceForTesting(); - EXPECT_EQ(recording_source_src->GetSize(), recording_source_dst->GetSize()); - EXPECT_TRUE(AreDisplayListDrawingResultsSame( - gfx::Rect(recording_source_src->GetSize()), - picture_layer_src->GetDisplayItemList(), - picture_layer_dst->GetDisplayItemList())); - - VerifySerializationAndDeserialization(); - } - - void RunAddAndRemoveNodeFromLayerTree() { - /* Testing serialization when the tree hierarchy changes like this: - root root - / \ / \ - a b => a c - \ \ - c d - */ - scoped_refptr<Layer> layer_src_root = Layer::Create(); - layer_tree_host_src_->SetRootLayer(layer_src_root); - - scoped_refptr<Layer> layer_src_a = Layer::Create(); - scoped_refptr<Layer> layer_src_b = Layer::Create(); - scoped_refptr<Layer> layer_src_c = Layer::Create(); - scoped_refptr<Layer> layer_src_d = Layer::Create(); - - layer_src_root->AddChild(layer_src_a); - layer_src_root->AddChild(layer_src_b); - layer_src_b->AddChild(layer_src_c); - - VerifySerializationAndDeserialization(); - VerifyHostHasAllExpectedLayersInTree(layer_tree_host_dst_->root_layer()); - - // Now change the Layer Hierarchy - layer_src_c->RemoveFromParent(); - layer_src_b->RemoveFromParent(); - layer_src_root->AddChild(layer_src_c); - layer_src_c->AddChild(layer_src_d); - - VerifySerializationAndDeserialization(); - VerifyHostHasAllExpectedLayersInTree(layer_tree_host_dst_->root_layer()); - } - - private: - std::unique_ptr<ImageSerializationProcessor> image_serialization_processor_; - - TestTaskGraphRunner task_graph_runner_src_; - FakeLayerTreeHostClient client_src_; - std::unique_ptr<FakeLayerTreeHost> layer_tree_host_src_; - - TestTaskGraphRunner task_graph_runner_dst_; - FakeLayerTreeHostClient client_dst_; - std::unique_ptr<FakeLayerTreeHost> layer_tree_host_dst_; -}; - -TEST_F(LayerTreeHostSerializationTest, AllMembersChanged) { - RunAllMembersChangedTest(); -} - -TEST_F(LayerTreeHostSerializationTest, LayersChanged) { - RunLayersChangedTest(); -} - -TEST_F(LayerTreeHostSerializationTest, LayersChangedMultipleSerializations) { - RunLayersChangedMultipleSerializations(); -} - -TEST_F(LayerTreeHostSerializationTest, AddAndRemoveNodeFromLayerTree) { - RunAddAndRemoveNodeFromLayerTree(); -} - -TEST_F(LayerTreeHostSerializationTest, PictureLayerMultipleSerializations) { - RunPictureLayerMultipleSerializationsTest(); -} - -} // namespace cc diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc index 2909ece1ab0..edfd5b0aeee 100644 --- a/chromium/cc/trees/layer_tree_impl.cc +++ b/chromium/cc/trees/layer_tree_impl.cc @@ -17,7 +17,6 @@ #include "base/timer/elapsed_timer.h" #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" -#include "cc/animation/animation_host.h" #include "cc/base/histograms.h" #include "cc/base/math_util.h" #include "cc/base/synced_property.h" @@ -40,6 +39,7 @@ #include "cc/trees/effect_node.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" @@ -56,7 +56,7 @@ namespace cc { LayerTreeImpl::LayerTreeImpl( LayerTreeHostImpl* layer_tree_host_impl, scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, - scoped_refptr<SyncedTopControls> top_controls_shown_ratio, + scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll) : layer_tree_host_impl_(layer_tree_host_impl), source_frame_number_(-1), @@ -84,7 +84,7 @@ LayerTreeImpl::LayerTreeImpl( has_ever_been_drawn_(false), have_scroll_event_handlers_(false), event_listener_properties_(), - top_controls_shrink_blink_size_(false), + browser_controls_shrink_blink_size_(false), top_controls_height_(0), bottom_controls_height_(0), top_controls_shown_ratio_(top_controls_shown_ratio) { @@ -426,7 +426,7 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { // This needs to be called early so that we don't clamp with incorrect max // offsets when UpdateViewportContainerSizes is called from e.g. - // PushTopControls + // PushBrowserControls target_tree->UpdatePropertyTreesForBoundsDelta(); if (next_activation_forces_redraw_) { @@ -437,11 +437,11 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) { target_tree->PassSwapPromises(std::move(swap_promise_list_)); swap_promise_list_.clear(); - target_tree->set_top_controls_shrink_blink_size( - top_controls_shrink_blink_size_); + target_tree->set_browser_controls_shrink_blink_size( + browser_controls_shrink_blink_size_); target_tree->set_top_controls_height(top_controls_height_); target_tree->set_bottom_controls_height(bottom_controls_height_); - target_tree->PushTopControls(nullptr); + target_tree->PushBrowserControls(nullptr); // Active tree already shares the page_scale_factor object with pending // tree so only the limits need to be provided. @@ -548,7 +548,7 @@ void LayerTreeImpl::AddToElementMap(LayerImpl* layer) { element_layers_map_[layer->element_id()] = layer->id(); - layer_tree_host_impl_->animation_host()->RegisterElement( + layer_tree_host_impl_->mutator_host()->RegisterElement( layer->element_id(), IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING); } @@ -562,7 +562,7 @@ void LayerTreeImpl::RemoveFromElementMap(LayerImpl* layer) { layer->element_id().AsValue().release(), "layer_id", layer->id()); - layer_tree_host_impl_->animation_host()->UnregisterElement( + layer_tree_host_impl_->mutator_host()->UnregisterElement( layer->element_id(), IsActiveTree() ? ElementListType::ACTIVE : ElementListType::PENDING); @@ -776,11 +776,11 @@ void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor, } } -void LayerTreeImpl::set_top_controls_shrink_blink_size(bool shrink) { - if (top_controls_shrink_blink_size_ == shrink) +void LayerTreeImpl::set_browser_controls_shrink_blink_size(bool shrink) { + if (browser_controls_shrink_blink_size_ == shrink) return; - top_controls_shrink_blink_size_ = shrink; + browser_controls_shrink_blink_size_ = shrink; if (IsActiveTree()) layer_tree_host_impl_->UpdateViewportContainerSizes(); } @@ -803,25 +803,25 @@ void LayerTreeImpl::set_bottom_controls_height(float bottom_controls_height) { layer_tree_host_impl_->UpdateViewportContainerSizes(); } -bool LayerTreeImpl::ClampTopControlsShownRatio() { +bool LayerTreeImpl::ClampBrowserControlsShownRatio() { float ratio = top_controls_shown_ratio_->Current(true); ratio = std::max(ratio, 0.f); ratio = std::min(ratio, 1.f); return top_controls_shown_ratio_->SetCurrent(ratio); } -bool LayerTreeImpl::SetCurrentTopControlsShownRatio(float ratio) { +bool LayerTreeImpl::SetCurrentBrowserControlsShownRatio(float ratio) { bool changed = top_controls_shown_ratio_->SetCurrent(ratio); - changed |= ClampTopControlsShownRatio(); + changed |= ClampBrowserControlsShownRatio(); return changed; } -void LayerTreeImpl::PushTopControlsFromMainThread( +void LayerTreeImpl::PushBrowserControlsFromMainThread( float top_controls_shown_ratio) { - PushTopControls(&top_controls_shown_ratio); + PushBrowserControls(&top_controls_shown_ratio); } -void LayerTreeImpl::PushTopControls(const float* top_controls_shown_ratio) { +void LayerTreeImpl::PushBrowserControls(const float* top_controls_shown_ratio) { DCHECK(top_controls_shown_ratio || IsActiveTree()); if (top_controls_shown_ratio) { @@ -830,9 +830,9 @@ void LayerTreeImpl::PushTopControls(const float* top_controls_shown_ratio) { } if (IsActiveTree()) { bool changed_active = top_controls_shown_ratio_->PushPendingToActive(); - changed_active |= ClampTopControlsShownRatio(); + changed_active |= ClampBrowserControlsShownRatio(); if (changed_active) - layer_tree_host_impl_->DidChangeTopControlsPosition(); + layer_tree_host_impl_->DidChangeBrowserControlsPosition(); } } @@ -865,6 +865,7 @@ void LayerTreeImpl::SetDeviceScaleFactor(float device_scale_factor) { set_needs_update_draw_properties(); if (IsActiveTree()) layer_tree_host_impl_->SetFullViewportDamage(); + layer_tree_host_impl_->SetNeedUpdateGpuRasterizationStatus(); } void LayerTreeImpl::SetDeviceColorSpace( @@ -992,7 +993,6 @@ bool LayerTreeImpl::UpdateDrawProperties( settings().layer_transforms_should_scale_layer_contents, settings().verify_clip_tree_calculations, verify_visible_rect_calculations, - settings().verify_transform_tree_calculations, &render_surface_layer_list_, &property_trees_); LayerTreeHostCommon::CalculateDrawProperties(&inputs); if (const char* client_name = GetClientNameForMetrics()) { @@ -1037,14 +1037,9 @@ bool LayerTreeImpl::UpdateDrawProperties( // We are calculating transform between two render surfaces. So, we // need to apply the surface contents scale at target and remove the // surface contents scale at source. - property_trees()->ComputeTransformToTarget( + property_trees()->GetToTarget( it->render_surface()->TransformTreeIndex(), occlusion_surface->EffectTreeIndex(), &draw_transform); - const EffectNode* occlusion_effect_node = - property_trees()->effect_tree.Node( - occlusion_surface->EffectTreeIndex()); - draw_property_utils::PostConcatSurfaceContentsScale( - occlusion_effect_node, &draw_transform); const EffectNode* effect_node = property_trees()->effect_tree.Node( it->render_surface()->EffectTreeIndex()); draw_property_utils::ConcatInverseSurfaceContentsScale( @@ -1362,24 +1357,23 @@ const gfx::Rect LayerTreeImpl::ViewportRectForTilePriority() const { std::unique_ptr<ScrollbarAnimationController> LayerTreeImpl::CreateScrollbarAnimationController(int scroll_layer_id) { - DCHECK(settings().scrollbar_fade_delay_ms); - DCHECK(settings().scrollbar_fade_duration_ms); - base::TimeDelta delay = - base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_delay_ms); - base::TimeDelta resize_delay = base::TimeDelta::FromMilliseconds( - settings().scrollbar_fade_resize_delay_ms); - base::TimeDelta duration = - base::TimeDelta::FromMilliseconds(settings().scrollbar_fade_duration_ms); + DCHECK(!settings().scrollbar_fade_delay.is_zero()); + DCHECK(!settings().scrollbar_fade_duration.is_zero()); + base::TimeDelta delay = settings().scrollbar_fade_delay; + base::TimeDelta resize_delay = settings().scrollbar_fade_resize_delay; + base::TimeDelta fade_duration = settings().scrollbar_fade_duration; switch (settings().scrollbar_animator) { case LayerTreeSettings::LINEAR_FADE: { return ScrollbarAnimationControllerLinearFade::Create( scroll_layer_id, layer_tree_host_impl_, delay, resize_delay, - duration); + fade_duration); } case LayerTreeSettings::THINNING: { + base::TimeDelta thinning_duration = + settings().scrollbar_thinning_duration; return ScrollbarAnimationControllerThinning::Create( scroll_layer_id, layer_tree_host_impl_, delay, resize_delay, - duration); + fade_duration, thinning_duration); } case LayerTreeSettings::NO_ANIMATOR: NOTREACHED(); @@ -1785,7 +1779,7 @@ static bool PointIsClippedByAncestorClipNode( for (const ClipNode* clip_node = clip_tree.Node(layer->clip_tree_index()); clip_node->id > 1; clip_node = clip_tree.parent(clip_node)) { - if (clip_node->applies_local_clip) { + if (clip_node->clip_type == ClipNode::ClipType::APPLIES_LOCAL_CLIP) { const TransformNode* transform_node = transform_tree.Node(clip_node->target_transform_id); gfx::Rect combined_clip_in_target_space = @@ -1893,16 +1887,15 @@ static void FindClosestMatchingLayer(const gfx::PointF& screen_space_point, } } -static bool ScrollsOrScrollbarAnyDrawnRenderSurfaceLayerListMember( - LayerImpl* layer) { - return layer->scrolls_drawn_descendant() || +static bool IsScrollableOrDrawnScrollbarLayer(LayerImpl* layer) { + return layer->scrollable() || (layer->ToScrollbarLayer() && layer->is_drawn_render_surface_layer_list_member()); } struct FindScrollingLayerOrScrollbarLayerFunctor { bool operator()(LayerImpl* layer) const { - return ScrollsOrScrollbarAnyDrawnRenderSurfaceLayerListMember(layer); + return IsScrollableOrDrawnScrollbarLayer(layer); } }; @@ -1919,7 +1912,7 @@ LayerTreeImpl::FindFirstScrollingLayerOrScrollbarLayerThatIsHitByPoint( struct HitTestVisibleScrollableOrTouchableFunctor { bool operator()(LayerImpl* layer) const { return layer->is_drawn_render_surface_layer_list_member() || - ScrollsOrScrollbarAnyDrawnRenderSurfaceLayerListMember(layer) || + IsScrollableOrDrawnScrollbarLayer(layer) || !layer->touch_event_handler_region().IsEmpty(); } }; @@ -2074,8 +2067,7 @@ LayerTreeImpl::TakePendingPageScaleAnimation() { } void LayerTreeImpl::ScrollAnimationAbort(bool needs_completion) { - layer_tree_host_impl_->animation_host()->ScrollAnimationAbort( - needs_completion); + layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort(needs_completion); } void LayerTreeImpl::ResetAllChangeTracking() { diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h index 85473a43251..ad4edc336f2 100644 --- a/chromium/cc/trees/layer_tree_impl.h +++ b/chromium/cc/trees/layer_tree_impl.h @@ -38,12 +38,10 @@ class DebugRectHistory; class FrameRateCounter; class HeadsUpDisplayLayerImpl; class ImageDecodeController; -class LayerExternalScrollOffsetListener; class LayerTreeDebugState; class LayerTreeImpl; class LayerTreeSettings; class MemoryHistory; -class PageScaleAnimation; class PictureLayerImpl; class TaskRunnerProvider; class ResourceProvider; @@ -53,7 +51,7 @@ class VideoFrameControllerClient; struct PendingPageScaleAnimation; typedef std::vector<UIResourceRequest> UIResourceRequestQueue; -typedef SyncedProperty<AdditionGroup<float>> SyncedTopControls; +typedef SyncedProperty<AdditionGroup<float>> SyncedBrowserControls; typedef SyncedProperty<AdditionGroup<gfx::Vector2dF>> SyncedElasticOverscroll; class CC_EXPORT LayerTreeImpl { @@ -63,7 +61,7 @@ class CC_EXPORT LayerTreeImpl { enum : int { kFixedPointHitsThreshold = 3 }; LayerTreeImpl(LayerTreeHostImpl* layer_tree_host_impl, scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor, - scoped_refptr<SyncedTopControls> top_controls_shown_ratio, + scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio, scoped_refptr<SyncedElasticOverscroll> elastic_overscroll); virtual ~LayerTreeImpl(); @@ -105,8 +103,8 @@ class CC_EXPORT LayerTreeImpl { bool RequiresHighResToDraw() const; bool SmoothnessTakesPriority() const; VideoFrameControllerClient* GetVideoFrameControllerClient() const; - AnimationHost* animation_host() const { - return layer_tree_host_impl_->animation_host(); + MutatorHost* mutator_host() const { + return layer_tree_host_impl_->mutator_host(); } // Tree specific methods exposed to layer-impl tree. @@ -246,10 +244,10 @@ class CC_EXPORT LayerTreeImpl { return elastic_overscroll_.get(); } - SyncedTopControls* top_controls_shown_ratio() { + SyncedBrowserControls* top_controls_shown_ratio() { return top_controls_shown_ratio_.get(); } - const SyncedTopControls* top_controls_shown_ratio() const { + const SyncedBrowserControls* top_controls_shown_ratio() const { return top_controls_shown_ratio_.get(); } @@ -411,17 +409,17 @@ class CC_EXPORT LayerTreeImpl { // the viewport. void GetViewportSelection(Selection<gfx::SelectionBound>* selection); - void set_top_controls_shrink_blink_size(bool shrink); - bool top_controls_shrink_blink_size() const { - return top_controls_shrink_blink_size_; + void set_browser_controls_shrink_blink_size(bool shrink); + bool browser_controls_shrink_blink_size() const { + return browser_controls_shrink_blink_size_; } - bool SetCurrentTopControlsShownRatio(float ratio); - float CurrentTopControlsShownRatio() const { + bool SetCurrentBrowserControlsShownRatio(float ratio); + float CurrentBrowserControlsShownRatio() const { return top_controls_shown_ratio_->Current(IsActiveTree()); } void set_top_controls_height(float top_controls_height); float top_controls_height() const { return top_controls_height_; } - void PushTopControlsFromMainThread(float top_controls_shown_ratio); + void PushBrowserControlsFromMainThread(float top_controls_shown_ratio); void set_bottom_controls_height(float bottom_controls_height); float bottom_controls_height() const { return bottom_controls_height_; } @@ -469,8 +467,8 @@ class CC_EXPORT LayerTreeImpl { bool IsViewportLayerId(int id) const; void UpdateScrollbars(int scroll_layer_id, int clip_layer_id); void DidUpdatePageScale(); - void PushTopControls(const float* top_controls_shown_ratio); - bool ClampTopControlsShownRatio(); + void PushBrowserControls(const float* top_controls_shown_ratio); + bool ClampBrowserControlsShownRatio(); LayerTreeHostImpl* layer_tree_host_impl_; int source_frame_number_; @@ -553,13 +551,13 @@ class CC_EXPORT LayerTreeImpl { // Whether or not Blink's viewport size was shrunk by the height of the top // controls at the time of the last layout. - bool top_controls_shrink_blink_size_; + bool browser_controls_shrink_blink_size_; float top_controls_height_; float bottom_controls_height_; - // The amount that the top controls are shown from 0 (hidden) to 1 (fully + // The amount that the browser controls are shown from 0 (hidden) to 1 (fully // shown). - scoped_refptr<SyncedTopControls> top_controls_shown_ratio_; + scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio_; std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_; diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc index 47d4435117e..213d9d2106f 100644 --- a/chromium/cc/trees/layer_tree_impl_unittest.cc +++ b/chromium/cc/trees/layer_tree_impl_unittest.cc @@ -5,7 +5,6 @@ #include "cc/trees/layer_tree_impl.h" #include "base/macros.h" -#include "cc/animation/mutable_properties.h" #include "cc/layers/heads_up_display_layer_impl.h" #include "cc/test/fake_layer_tree_host_impl.h" #include "cc/test/geometry_test_utils.h" @@ -15,6 +14,7 @@ #include "cc/trees/draw_property_utils.h" #include "cc/trees/layer_tree_host_common.h" #include "cc/trees/layer_tree_host_impl.h" +#include "cc/trees/mutable_properties.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" diff --git a/chromium/cc/animation/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h index ef2f9ba2bcb..9233ca2eec9 100644 --- a/chromium/cc/animation/layer_tree_mutator.h +++ b/chromium/cc/trees/layer_tree_mutator.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_ANIMATION_LAYER_TREE_MUTATOR_H_ -#define CC_ANIMATION_LAYER_TREE_MUTATOR_H_ +#ifndef CC_TREES_LAYER_TREE_MUTATOR_H_ +#define CC_TREES_LAYER_TREE_MUTATOR_H_ #include "base/callback_forward.h" #include "base/time/time.h" @@ -37,4 +37,4 @@ class CC_EXPORT LayerTreeMutator { } // namespace cc -#endif // CC_ANIMATION_LAYER_TREE_MUTATOR_H_ +#endif // CC_TREES_LAYER_TREE_MUTATOR_H_ diff --git a/chromium/cc/trees/layer_tree_settings.cc b/chromium/cc/trees/layer_tree_settings.cc index 7a2d0a93f38..faebb4209da 100644 --- a/chromium/cc/trees/layer_tree_settings.cc +++ b/chromium/cc/trees/layer_tree_settings.cc @@ -40,10 +40,9 @@ bool LayerTreeSettings::operator==(const LayerTreeSettings& other) const { other.gpu_rasterization_msaa_sample_count && create_low_res_tiling == other.create_low_res_tiling && scrollbar_animator == other.scrollbar_animator && - scrollbar_fade_delay_ms == other.scrollbar_fade_delay_ms && - scrollbar_fade_resize_delay_ms == - other.scrollbar_fade_resize_delay_ms && - scrollbar_fade_duration_ms == other.scrollbar_fade_duration_ms && + scrollbar_fade_delay == other.scrollbar_fade_delay && + scrollbar_fade_resize_delay == other.scrollbar_fade_resize_delay && + scrollbar_fade_duration == other.scrollbar_fade_duration && solid_color_scrollbar_color == other.solid_color_scrollbar_color && timeout_and_draw_when_animation_checkerboards == other.timeout_and_draw_when_animation_checkerboards && @@ -75,8 +74,6 @@ bool LayerTreeSettings::operator==(const LayerTreeSettings& other) const { use_occlusion_for_tile_prioritization == other.use_occlusion_for_tile_prioritization && verify_clip_tree_calculations == other.verify_clip_tree_calculations && - verify_transform_tree_calculations == - other.verify_transform_tree_calculations && image_decode_tasks_enabled == other.image_decode_tasks_enabled && max_staging_buffer_usage_in_bytes == other.max_staging_buffer_usage_in_bytes && diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h index 22275d88e4e..28f129a01ae 100644 --- a/chromium/cc/trees/layer_tree_settings.h +++ b/chromium/cc/trees/layer_tree_settings.h @@ -9,6 +9,7 @@ #include <vector> +#include "base/time/time.h" #include "cc/base/cc_export.h" #include "cc/debug/layer_tree_debug_state.h" #include "cc/output/managed_memory_policy.h" @@ -56,9 +57,10 @@ class CC_EXPORT LayerTreeSettings { THINNING, }; ScrollbarAnimator scrollbar_animator = NO_ANIMATOR; - int scrollbar_fade_delay_ms = 0; - int scrollbar_fade_resize_delay_ms = 0; - int scrollbar_fade_duration_ms = 0; + base::TimeDelta scrollbar_fade_delay; + base::TimeDelta scrollbar_fade_resize_delay; + base::TimeDelta scrollbar_fade_duration; + base::TimeDelta scrollbar_thinning_duration; SkColor solid_color_scrollbar_color = SK_ColorWHITE; bool timeout_and_draw_when_animation_checkerboards = true; bool layer_transforms_should_scale_layer_contents = false; @@ -86,7 +88,6 @@ class CC_EXPORT LayerTreeSettings { size_t scheduled_raster_task_limit = 32; bool use_occlusion_for_tile_prioritization = false; bool verify_clip_tree_calculations = false; - bool verify_transform_tree_calculations = false; bool image_decode_tasks_enabled = false; bool abort_commit_before_compositor_frame_sink_creation = true; bool use_layer_lists = false; diff --git a/chromium/cc/animation/mutable_properties.h b/chromium/cc/trees/mutable_properties.h index 1938313a757..ef68c5ad274 100644 --- a/chromium/cc/animation/mutable_properties.h +++ b/chromium/cc/trees/mutable_properties.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_ANIMATION_MUTABLE_PROPERTIES_H_ -#define CC_ANIMATION_MUTABLE_PROPERTIES_H_ +#ifndef CC_TREES_MUTABLE_PROPERTIES_H_ +#define CC_TREES_MUTABLE_PROPERTIES_H_ #include <stdint.h> @@ -22,4 +22,4 @@ struct MutableProperty { } // namespace cc -#endif // CC_ANIMATION_MUTABLE_PROPERTIES_H_ +#endif // CC_TREES_MUTABLE_PROPERTIES_H_ diff --git a/chromium/cc/trees/mutator_host.h b/chromium/cc/trees/mutator_host.h new file mode 100644 index 00000000000..bd3ed1d88a4 --- /dev/null +++ b/chromium/cc/trees/mutator_host.h @@ -0,0 +1,138 @@ +// 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_TREES_MUTATOR_HOST_H_ +#define CC_TREES_MUTATOR_HOST_H_ + +#include <memory> + +#include "base/memory/ptr_util.h" +#include "base/time/time.h" +#include "cc/trees/element_id.h" +#include "cc/trees/mutator_host_client.h" +#include "ui/gfx/geometry/box_f.h" +#include "ui/gfx/geometry/vector2d_f.h" + +namespace gfx { +class ScrollOffset; +} + +namespace cc { + +class MutatorEvents; +class MutatorHostClient; + +// A MutatorHost owns all the animation and mutation effects. +// There is just one MutatorHost for LayerTreeHost on main renderer thread +// and just one MutatorHost for LayerTreeHostImpl on the impl thread. +// We synchronize them during the commit in a one-way data-flow process +// (PushPropertiesTo). +// A MutatorHost talks to its correspondent LayerTreeHost via +// MutatorHostClient interface. +class MutatorHost { + public: + virtual ~MutatorHost() {} + + virtual std::unique_ptr<MutatorHost> CreateImplInstance( + bool supports_impl_scrolling) const = 0; + + virtual void ClearMutators() = 0; + + virtual void RegisterElement(ElementId element_id, + ElementListType list_type) = 0; + virtual void UnregisterElement(ElementId element_id, + ElementListType list_type) = 0; + + virtual void SetMutatorHostClient(MutatorHostClient* client) = 0; + + virtual void PushPropertiesTo(MutatorHost* host_impl) = 0; + + virtual void SetSupportsScrollAnimations(bool supports_scroll_animations) = 0; + virtual bool NeedsAnimateLayers() const = 0; + + virtual bool ActivateAnimations() = 0; + virtual bool AnimateLayers(base::TimeTicks monotonic_time) = 0; + virtual bool UpdateAnimationState(bool start_ready_animations, + MutatorEvents* events) = 0; + + virtual std::unique_ptr<MutatorEvents> CreateEvents() = 0; + virtual void SetAnimationEvents(std::unique_ptr<MutatorEvents> events) = 0; + + virtual bool ScrollOffsetAnimationWasInterrupted( + ElementId element_id) const = 0; + + virtual bool IsAnimatingFilterProperty(ElementId element_id, + ElementListType list_type) const = 0; + virtual bool IsAnimatingOpacityProperty(ElementId element_id, + ElementListType list_type) const = 0; + virtual bool IsAnimatingTransformProperty( + ElementId element_id, + ElementListType list_type) const = 0; + + virtual bool HasPotentiallyRunningFilterAnimation( + ElementId element_id, + ElementListType list_type) const = 0; + virtual bool HasPotentiallyRunningOpacityAnimation( + ElementId element_id, + ElementListType list_type) const = 0; + virtual bool HasPotentiallyRunningTransformAnimation( + ElementId element_id, + ElementListType list_type) const = 0; + + virtual bool HasAnyAnimationTargetingProperty( + ElementId element_id, + TargetProperty::Type property) const = 0; + + virtual bool HasFilterAnimationThatInflatesBounds( + ElementId element_id) const = 0; + virtual bool HasTransformAnimationThatInflatesBounds( + ElementId element_id) const = 0; + virtual bool HasAnimationThatInflatesBounds(ElementId element_id) const = 0; + + virtual bool FilterAnimationBoundsForBox(ElementId element_id, + const gfx::BoxF& box, + gfx::BoxF* bounds) const = 0; + virtual bool TransformAnimationBoundsForBox(ElementId element_id, + const gfx::BoxF& box, + gfx::BoxF* bounds) const = 0; + + virtual bool HasOnlyTranslationTransforms( + ElementId element_id, + ElementListType list_type) const = 0; + virtual bool AnimationsPreserveAxisAlignment(ElementId element_id) const = 0; + + virtual bool MaximumTargetScale(ElementId element_id, + ElementListType list_type, + float* max_scale) const = 0; + virtual bool AnimationStartScale(ElementId element_id, + ElementListType list_type, + float* start_scale) const = 0; + + virtual bool HasAnyAnimation(ElementId element_id) const = 0; + virtual bool HasActiveAnimationForTesting(ElementId element_id) const = 0; + + virtual void ImplOnlyScrollAnimationCreate( + ElementId element_id, + const gfx::ScrollOffset& target_offset, + const gfx::ScrollOffset& current_offset, + base::TimeDelta delayed_by) = 0; + virtual bool ImplOnlyScrollAnimationUpdateTarget( + ElementId element_id, + const gfx::Vector2dF& scroll_delta, + const gfx::ScrollOffset& max_scroll_offset, + base::TimeTicks frame_monotonic_time, + base::TimeDelta delayed_by) = 0; + + virtual void ScrollAnimationAbort(bool needs_completion) = 0; +}; + +class MutatorEvents { + public: + virtual ~MutatorEvents() {} + virtual bool IsEmpty() const = 0; +}; + +} // namespace cc + +#endif // CC_TREES_MUTATOR_HOST_H_ diff --git a/chromium/cc/trees/mutator_host_client.h b/chromium/cc/trees/mutator_host_client.h index 0dca15b7fbc..d3a3e0e7683 100644 --- a/chromium/cc/trees/mutator_host_client.h +++ b/chromium/cc/trees/mutator_host_client.h @@ -5,10 +5,9 @@ #ifndef CC_TREES_MUTATOR_HOST_CLIENT_H_ #define CC_TREES_MUTATOR_HOST_CLIENT_H_ -// TODO(loyso) Move these headers out of cc/animation. -#include "cc/animation/element_id.h" -#include "cc/animation/property_animation_state.h" -#include "cc/animation/target_property.h" +#include "cc/trees/element_id.h" +#include "cc/trees/property_animation_state.h" +#include "cc/trees/target_property.h" namespace gfx { class Transform; diff --git a/chromium/cc/trees/occlusion_tracker_unittest.cc b/chromium/cc/trees/occlusion_tracker_unittest.cc index 7f8ee8460b1..d99d41eb419 100644 --- a/chromium/cc/trees/occlusion_tracker_unittest.cc +++ b/chromium/cc/trees/occlusion_tracker_unittest.cc @@ -6,6 +6,7 @@ #include <stddef.h> +#include "cc/animation/animation_host.h" #include "cc/base/math_util.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" @@ -87,7 +88,10 @@ class OcclusionTrackerTest : public testing::Test { protected: explicit OcclusionTrackerTest(bool opaque_layers) : opaque_layers_(opaque_layers), - host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)), + animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)), + host_(FakeLayerTreeHost::Create(&client_, + &task_graph_runner_, + animation_host_.get())), next_layer_impl_id_(1) {} virtual void RunMyTest() = 0; @@ -290,6 +294,7 @@ class OcclusionTrackerTest : public testing::Test { bool opaque_layers_; FakeLayerTreeHostClient client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> host_; // These hold ownership of the layers for the duration of the test. LayerImplList render_surface_layer_list_impl_; diff --git a/chromium/cc/animation/property_animation_state.cc b/chromium/cc/trees/property_animation_state.cc index bda251c6b8f..92f4b99d851 100644 --- a/chromium/cc/animation/property_animation_state.cc +++ b/chromium/cc/trees/property_animation_state.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/animation/property_animation_state.h" +#include "cc/trees/property_animation_state.h" #include "base/logging.h" diff --git a/chromium/cc/animation/property_animation_state.h b/chromium/cc/trees/property_animation_state.h index 642576364e1..173ea921da2 100644 --- a/chromium/cc/animation/property_animation_state.h +++ b/chromium/cc/trees/property_animation_state.h @@ -2,11 +2,11 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_ANIMATION_PROPERTY_ANIMATION_STATE_H_ -#define CC_ANIMATION_PROPERTY_ANIMATION_STATE_H_ +#ifndef CC_TREES_PROPERTY_ANIMATION_STATE_H_ +#define CC_TREES_PROPERTY_ANIMATION_STATE_H_ -#include "cc/animation/target_property.h" #include "cc/base/cc_export.h" +#include "cc/trees/target_property.h" namespace cc { @@ -35,4 +35,4 @@ PropertyAnimationState operator^(const PropertyAnimationState& lhs, } // namespace cc -#endif // CC_ANIMATION_PROPERTY_ANIMATION_STATE_H_ +#endif // CC_TREES_PROPERTY_ANIMATION_STATE_H_ diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc index dc1a210c0c1..3e67f101ae2 100644 --- a/chromium/cc/trees/property_tree.cc +++ b/chromium/cc/trees/property_tree.cc @@ -10,20 +10,19 @@ #include "base/logging.h" #include "base/memory/ptr_util.h" #include "base/trace_event/trace_event_argument.h" -#include "cc/animation/animation_host.h" #include "cc/layers/layer_impl.h" #include "cc/output/copy_output_request.h" #include "cc/proto/gfx_conversions.h" -#include "cc/proto/property_tree.pb.h" -#include "cc/proto/synced_property_conversions.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/mutator_host.h" #include "cc/trees/property_tree.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" #include "ui/gfx/geometry/vector2d_conversions.h" + namespace cc { template <typename T> @@ -85,37 +84,6 @@ bool PropertyTree<T>::operator==(const PropertyTree<T>& other) const { } template <typename T> -void PropertyTree<T>::ToProtobuf(proto::PropertyTree* proto) const { - DCHECK_EQ(0, proto->nodes_size()); - for (const auto& node : nodes_) - node.ToProtobuf(proto->add_nodes()); - proto->set_needs_update(needs_update_); -} - -template <typename T> -void PropertyTree<T>::FromProtobuf( - const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map) { - // Verify that the property tree is empty. - DCHECK_EQ(static_cast<int>(nodes_.size()), 1); - DCHECK_EQ(back()->id, kRootNodeId); - DCHECK_EQ(back()->parent_id, kInvalidNodeId); - - // Add the first node. - DCHECK_GT(proto.nodes_size(), 0); - nodes_.back().FromProtobuf(proto.nodes(0)); - - DCHECK(!node_id_to_index_map || (*node_id_to_index_map).empty()); - for (int i = 1; i < proto.nodes_size(); ++i) { - nodes_.push_back(T()); - nodes_.back().FromProtobuf(proto.nodes(i)); - (*node_id_to_index_map)[nodes_.back().owner_id] = nodes_.back().id; - } - - needs_update_ = proto.needs_update(); -} - -template <typename T> void PropertyTree<T>::AsValueInto(base::trace_event::TracedValue* value) const { value->BeginArray("nodes"); for (const auto& node : nodes_) { @@ -131,20 +99,6 @@ template class PropertyTree<ClipNode>; template class PropertyTree<EffectNode>; template class PropertyTree<ScrollNode>; -void StickyPositionNodeData::ToProtobuf( - proto::StickyPositionNodeData* proto) const { - proto->set_scroll_ancestor(scroll_ancestor); - constraints.ToProtobuf(proto->mutable_constraints()); - Vector2dFToProto(main_thread_offset, proto->mutable_main_thread_offset()); -} - -void StickyPositionNodeData::FromProtobuf( - const proto::StickyPositionNodeData& proto) { - scroll_ancestor = proto.scroll_ancestor(); - constraints.FromProtobuf(proto.constraints()); - main_thread_offset = ProtoToVector2dF(proto.main_thread_offset()); -} - int TransformTree::Insert(const TransformNode& tree_node, int parent_id) { int node_id = PropertyTree<TransformNode>::Insert(tree_node, parent_id); DCHECK_EQ(node_id, static_cast<int>(cached_data_.size())); @@ -174,20 +128,10 @@ void TransformTree::clear() { #endif } -bool TransformTree::ComputeTransform(int source_id, - int dest_id, - gfx::Transform* transform) const { - transform->MakeIdentity(); - - if (source_id == dest_id) - return true; - - if (source_id > dest_id) { - CombineTransformsBetween(source_id, dest_id, transform); - return true; - } - - return CombineInversesBetween(source_id, dest_id, transform); +void TransformTree::set_needs_update(bool needs_update) { + if (needs_update && !needs_update_) + property_trees()->UpdateCachedNumber(); + needs_update_ = needs_update; } bool TransformTree::ComputeTranslation(int source_id, @@ -262,9 +206,9 @@ void TransformTree::ResetChangeTracking() { void TransformTree::UpdateTransforms(int id) { TransformNode* node = Node(id); TransformNode* parent_node = parent(node); + DCHECK(parent_node); TransformNode* target_node = Node(TargetId(id)); TransformNode* source_node = Node(node->source_node_id); - property_trees()->UpdateCachedNumber(); // TODO(flackr): Only dirty when scroll offset changes. if (node->sticky_position_constraint_id >= 0 || node->needs_local_transform_update || NeedsSourceToParentUpdate(node)) { @@ -273,10 +217,8 @@ void TransformTree::UpdateTransforms(int id) { UndoSnapping(node); } UpdateScreenSpaceTransform(node, parent_node, target_node); - UpdateSurfaceContentsScale(node); UpdateAnimationProperties(node, parent_node); UpdateSnapping(node); - UpdateTargetSpaceTransform(node, target_node); UpdateNodeAndAncestorsHaveIntegerTranslations(node, parent_node); UpdateTransformChanged(node, parent_node, source_node); UpdateNodeAndAncestorsAreAnimatedOrInvertible(node, parent_node); @@ -328,30 +270,11 @@ void TransformTree::CombineTransformsBetween(int source_id, std::vector<int> source_to_destination; source_to_destination.push_back(current->id); current = parent(current); - bool destination_has_non_zero_surface_contents_scale = - dest->surface_contents_scale.x() != 0.f && - dest->surface_contents_scale.y() != 0.f; - DCHECK(destination_has_non_zero_surface_contents_scale || - !dest->ancestors_are_invertible); - for (; current && current->id > dest_id; current = parent(current)) { - if (destination_has_non_zero_surface_contents_scale && - TargetId(current->id) == dest_id && - ContentTargetId(current->id) == dest_id) - break; + for (; current && current->id > dest_id; current = parent(current)) source_to_destination.push_back(current->id); - } gfx::Transform combined_transform; - if (current->id > dest_id) { - // TODO(sunxd): Instead of using target space transform, only use to_parent - // here when we fully implement computing draw transforms on demand. - combined_transform = ToTarget(current->id, kInvalidNodeId); - // The stored target space transform has surface contents scale baked in, - // but we need the unscaled transform. - combined_transform.matrix().postScale( - 1.0f / dest->surface_contents_scale.x(), - 1.0f / dest->surface_contents_scale.y(), 1.0f); - } else if (current->id < dest_id) { + if (current->id < dest_id) { // We have reached the lowest common ancestor of the source and destination // nodes. This case can occur when we are transforming between a node // corresponding to a fixed-position layer (or its descendant) and the node @@ -428,9 +351,20 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { gfx::ScrollOffset scroll_offset = tree->property_trees()->scroll_tree.current_scroll_offset( scroll_node->owner_id); - - gfx::RectF clip(gfx::PointF(scroll_offset.x(), scroll_offset.y()), - gfx::SizeF(scroll_node->scroll_clip_layer_bounds)); + gfx::PointF scroll_position(scroll_offset.x(), scroll_offset.y()); + TransformNode* scroll_ancestor_transform_node = + tree->Node(scroll_node->transform_id); + if (scroll_ancestor_transform_node->scrolls) { + // The scroll position does not include snapping which shifts the scroll + // offset to align to a pixel boundary, we need to manually include it here. + // In this case, snapping is caused by a scroll. + scroll_position -= scroll_ancestor_transform_node->snap_amount; + } + + gfx::RectF clip( + scroll_position, + gfx::SizeF(tree->property_trees()->scroll_tree.scroll_clip_layer_bounds( + scroll_node->id))); gfx::Vector2dF sticky_offset( constraint.scroll_container_relative_sticky_box_rect.OffsetFromOrigin()); gfx::Vector2dF layer_offset(sticky_data->main_thread_offset); @@ -492,7 +426,7 @@ gfx::Vector2dF StickyPositionOffset(TransformTree* tree, TransformNode* node) { top_delta = available_space; sticky_offset.set_y(sticky_offset.y() + top_delta); } - return sticky_offset - layer_offset - + return sticky_offset - layer_offset - node->source_to_parent - constraint.scroll_container_relative_sticky_box_rect .OffsetFromOrigin(); } @@ -505,14 +439,20 @@ void TransformTree::UpdateLocalTransform(TransformNode* node) { gfx::Vector2dF unsnapping; TransformNode* current; TransformNode* parent_node; + // Since we are calculating the adjustment for fixed position node or a + // scroll child, we need to unsnap only if the snap was caused by a scroll. for (current = Node(node->source_node_id); current->id > node->parent_id; current = parent(current)) { - unsnapping.Subtract(current->scroll_snap); + DCHECK(current->scrolls || current->snap_amount.IsZero()); + if (current->scrolls) + unsnapping.Subtract(current->snap_amount); } for (parent_node = Node(node->parent_id); parent_node->id > node->source_node_id; parent_node = parent(parent_node)) { - unsnapping.Add(parent_node->scroll_snap); + DCHECK(parent_node->scrolls || parent_node->snap_amount.IsZero()); + if (parent_node->scrolls) + unsnapping.Add(parent_node->snap_amount); } // If a node NeedsSourceToParentUpdate, the node is either a fixed position // node or a scroll child. @@ -532,14 +472,14 @@ void TransformTree::UpdateLocalTransform(TransformNode* node) { property_trees()->inner_viewport_container_bounds_delta(); gfx::Vector2dF outer_viewport_bounds_delta = property_trees()->outer_viewport_container_bounds_delta(); - if (node->affected_by_inner_viewport_bounds_delta_x) + if (node->moved_by_inner_viewport_bounds_delta_x) fixed_position_adjustment.set_x(inner_viewport_bounds_delta.x()); - else if (node->affected_by_outer_viewport_bounds_delta_x) + else if (node->moved_by_outer_viewport_bounds_delta_x) fixed_position_adjustment.set_x(outer_viewport_bounds_delta.x()); - if (node->affected_by_inner_viewport_bounds_delta_y) + if (node->moved_by_inner_viewport_bounds_delta_y) fixed_position_adjustment.set_y(inner_viewport_bounds_delta.y()); - else if (node->affected_by_outer_viewport_bounds_delta_y) + else if (node->moved_by_outer_viewport_bounds_delta_y) fixed_position_adjustment.set_y(outer_viewport_bounds_delta.y()); transform.Translate(node->source_to_parent.x() - node->scroll_offset.x() + @@ -557,21 +497,15 @@ void TransformTree::UpdateLocalTransform(TransformNode* node) { void TransformTree::UpdateScreenSpaceTransform(TransformNode* node, TransformNode* parent_node, TransformNode* target_node) { - if (!parent_node) { - SetToScreen(node->id, node->to_parent); - node->ancestors_are_invertible = true; - node->to_screen_is_potentially_animated = false; - node->node_and_ancestors_are_flat = node->to_parent.IsFlat(); - } else { - gfx::Transform to_screen_space_transform = ToScreen(parent_node->id); - if (node->flattens_inherited_transform) - to_screen_space_transform.FlattenTo2d(); - to_screen_space_transform.PreconcatTransform(node->to_parent); - node->ancestors_are_invertible = parent_node->ancestors_are_invertible; - node->node_and_ancestors_are_flat = - parent_node->node_and_ancestors_are_flat && node->to_parent.IsFlat(); - SetToScreen(node->id, to_screen_space_transform); - } + DCHECK(parent_node); + gfx::Transform to_screen_space_transform = ToScreen(parent_node->id); + if (node->flattens_inherited_transform) + to_screen_space_transform.FlattenTo2d(); + to_screen_space_transform.PreconcatTransform(node->to_parent); + node->ancestors_are_invertible = parent_node->ancestors_are_invertible; + node->node_and_ancestors_are_flat = + parent_node->node_and_ancestors_are_flat && node->to_parent.IsFlat(); + SetToScreen(node->id, to_screen_space_transform); gfx::Transform from_screen; if (!ToScreen(node->id).GetInverse(&from_screen)) @@ -579,75 +513,37 @@ void TransformTree::UpdateScreenSpaceTransform(TransformNode* node, SetFromScreen(node->id, from_screen); } -void TransformTree::UpdateSurfaceContentsScale(TransformNode* node) { - // The surface contents scale depends on the screen space transform, so update - // it too. - if (!node->needs_surface_contents_scale) { - node->surface_contents_scale = gfx::Vector2dF(1.0f, 1.0f); - return; - } - - float layer_scale_factor = - device_scale_factor_ * device_transform_scale_factor_; - if (node->in_subtree_of_page_scale_layer) - layer_scale_factor *= page_scale_factor_; - node->surface_contents_scale = MathUtil::ComputeTransform2dScaleComponents( - ToScreen(node->id), layer_scale_factor); -} - -void TransformTree::UpdateTargetSpaceTransform(TransformNode* node, - TransformNode* target_node) { - gfx::Transform target_space_transform; - if (node->needs_surface_contents_scale) { - target_space_transform.MakeIdentity(); - target_space_transform.Scale(node->surface_contents_scale.x(), - node->surface_contents_scale.y()); - } else { - // In order to include the root transform for the root surface, we walk up - // to the root of the transform tree in ComputeTransform. - int target_id = target_node->id; - ComputeTransform(node->id, target_id, &target_space_transform); - target_space_transform.matrix().postScale( - target_node->surface_contents_scale.x(), - target_node->surface_contents_scale.y(), 1.f); - } - - gfx::Transform from_target; - if (!target_space_transform.GetInverse(&from_target)) - node->ancestors_are_invertible = false; - SetToTarget(node->id, target_space_transform); - SetFromTarget(node->id, from_target); -} - void TransformTree::UpdateAnimationProperties(TransformNode* node, TransformNode* parent_node) { + DCHECK(parent_node); bool ancestor_is_animating = false; - if (parent_node) - ancestor_is_animating = parent_node->to_screen_is_potentially_animated; + ancestor_is_animating = parent_node->to_screen_is_potentially_animated; node->to_screen_is_potentially_animated = node->has_potential_animation || ancestor_is_animating; } void TransformTree::UndoSnapping(TransformNode* node) { - // to_parent transform has the scroll snap from previous frame baked in. + // to_parent transform has snapping from previous frame baked in. // We need to undo it and use the un-snapped transform to compute current // target and screen space transforms. - node->to_parent.Translate(-node->scroll_snap.x(), -node->scroll_snap.y()); + node->to_parent.Translate(-node->snap_amount.x(), -node->snap_amount.y()); } void TransformTree::UpdateSnapping(TransformNode* node) { - if (!node->scrolls || node->to_screen_is_potentially_animated || + if (!node->should_be_snapped || node->to_screen_is_potentially_animated || !ToScreen(node->id).IsScaleOrTranslation() || !node->ancestors_are_invertible) { return; } - // Scroll snapping must be done in screen space (the pixels we care about). - // This means we effectively snap the screen space transform. If ST is the + // Snapping must be done in target space (the pixels we care about) and then + // the render pass should also be snapped if necessary. But, we do it in + // screen space because it is easier and works most of the time if there is + // no intermediate render pass with a snap-destrying transform. If ST is the // screen space transform and ST' is ST with its translation components // rounded, then what we're after is the scroll delta X, where ST * X = ST'. - // I.e., we want a transform that will realize our scroll snap. It follows - // that X = ST^-1 * ST'. We cache ST and ST^-1 to make this more efficient. + // I.e., we want a transform that will realize our snap. It follows that + // X = ST^-1 * ST'. We cache ST and ST^-1 to make this more efficient. gfx::Transform rounded = ToScreen(node->id); rounded.RoundTranslationComponents(); gfx::Transform delta = FromScreen(node->id); @@ -658,20 +554,21 @@ void TransformTree::UpdateSnapping(TransformNode* node) { gfx::Vector2dF translation = delta.To2dTranslation(); - // Now that we have our scroll delta, we must apply it to each of our - // combined, to/from matrices. + // Now that we have our delta, we must apply it to each of our combined, + // to/from matrices. SetToScreen(node->id, rounded); node->to_parent.Translate(translation.x(), translation.y()); gfx::Transform from_screen = FromScreen(node->id); from_screen.matrix().postTranslate(-translation.x(), -translation.y(), 0); SetFromScreen(node->id, from_screen); - node->scroll_snap = translation; + node->snap_amount = translation; } void TransformTree::UpdateTransformChanged(TransformNode* node, TransformNode* parent_node, TransformNode* source_node) { - if (parent_node && parent_node->transform_changed) { + DCHECK(parent_node); + if (parent_node->transform_changed) { node->transform_changed = true; return; } @@ -684,11 +581,7 @@ void TransformTree::UpdateTransformChanged(TransformNode* node, void TransformTree::UpdateNodeAndAncestorsAreAnimatedOrInvertible( TransformNode* node, TransformNode* parent_node) { - if (!parent_node) { - node->node_and_ancestors_are_animated_or_invertible = - node->has_potential_animation || node->is_invertible; - return; - } + DCHECK(parent_node); if (!parent_node->node_and_ancestors_are_animated_or_invertible) { node->node_and_ancestors_are_animated_or_invertible = false; return; @@ -738,10 +631,7 @@ void TransformTree::SetRootTransformsAndScales( gfx::Transform root_from_screen; bool invertible = root_to_screen.GetInverse(&root_from_screen); DCHECK(invertible); - TransformNode* root_node = Node(kRootNodeId); - if (root_node->surface_contents_scale != screen_space_scale) { - root_node->needs_surface_contents_scale = true; - root_node->surface_contents_scale = screen_space_scale; + if (root_to_screen != ToScreen(kRootNodeId)) { SetToScreen(kRootNodeId, root_to_screen); SetFromScreen(kRootNodeId, root_from_screen); set_needs_update(true); @@ -790,44 +680,6 @@ bool TransformTree::HasNodesAffectedByOuterViewportBoundsDelta() const { return !nodes_affected_by_outer_viewport_bounds_delta_.empty(); } -const gfx::Transform& TransformTree::FromTarget(int node_id, - int effect_id) const { - DCHECK(static_cast<int>(cached_data_.size()) > node_id); - if (effect_id != kInvalidNodeId && - property_trees()->verify_transform_tree_calculations) { - const gfx::Transform& transform = - property_trees()->GetDrawTransforms(node_id, effect_id).from_target; - CHECK(transform.ApproximatelyEqual(cached_data_[node_id].from_target)); - } - return cached_data_[node_id].from_target; -} - -void TransformTree::SetFromTarget(int node_id, - const gfx::Transform& transform) { - DCHECK(static_cast<int>(cached_data_.size()) > node_id); - cached_data_[node_id].from_target = transform; -} - -const gfx::Transform& TransformTree::ToTarget(int node_id, - int effect_id) const { - DCHECK(static_cast<int>(cached_data_.size()) > node_id); - if (effect_id != kInvalidNodeId && - property_trees()->verify_transform_tree_calculations) { - const gfx::Transform& transform = - property_trees()->GetDrawTransforms(node_id, effect_id).to_target; - if (property_trees()->non_root_surfaces_enabled) - CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_target)); - else - CHECK(transform.ApproximatelyEqual(cached_data_[node_id].to_screen)); - } - return cached_data_[node_id].to_target; -} - -void TransformTree::SetToTarget(int node_id, const gfx::Transform& transform) { - DCHECK(static_cast<int>(cached_data_.size()) > node_id); - cached_data_[node_id].to_target = transform; -} - const gfx::Transform& TransformTree::FromScreen(int node_id) const { DCHECK(static_cast<int>(cached_data_.size()) > node_id); return cached_data_[node_id].from_screen; @@ -847,6 +699,7 @@ const gfx::Transform& TransformTree::ToScreen(int node_id) const { void TransformTree::SetToScreen(int node_id, const gfx::Transform& transform) { DCHECK(static_cast<int>(cached_data_.size()) > node_id); cached_data_[node_id].to_screen = transform; + cached_data_[node_id].is_showing_backface = transform.IsBackFaceVisible(); } int TransformTree::TargetId(int node_id) const { @@ -893,73 +746,6 @@ StickyPositionNodeData* TransformTree::StickyPositionData(int node_id) { return &sticky_position_data_[node->sticky_position_constraint_id]; } -void TransformTree::ToProtobuf(proto::PropertyTree* proto) const { - DCHECK(!proto->has_property_type()); - proto->set_property_type(proto::PropertyTree::Transform); - - PropertyTree::ToProtobuf(proto); - proto::TransformTreeData* data = proto->mutable_transform_tree_data(); - - data->set_source_to_parent_updates_allowed(source_to_parent_updates_allowed_); - data->set_page_scale_factor(page_scale_factor_); - data->set_device_scale_factor(device_scale_factor_); - data->set_device_transform_scale_factor(device_transform_scale_factor_); - - for (auto i : nodes_affected_by_inner_viewport_bounds_delta_) - data->add_nodes_affected_by_inner_viewport_bounds_delta(i); - - for (auto i : nodes_affected_by_outer_viewport_bounds_delta_) - data->add_nodes_affected_by_outer_viewport_bounds_delta(i); - - for (int i = 0; i < static_cast<int>(cached_data_.size()); ++i) - cached_data_[i].ToProtobuf(data->add_cached_data()); - - for (int i = 0; i < static_cast<int>(sticky_position_data_.size()); ++i) - sticky_position_data_[i].ToProtobuf(data->add_sticky_position_data()); -} - -void TransformTree::FromProtobuf( - const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map) { - DCHECK(proto.has_property_type()); - DCHECK_EQ(proto.property_type(), proto::PropertyTree::Transform); - - PropertyTree::FromProtobuf(proto, node_id_to_index_map); - const proto::TransformTreeData& data = proto.transform_tree_data(); - - source_to_parent_updates_allowed_ = data.source_to_parent_updates_allowed(); - page_scale_factor_ = data.page_scale_factor(); - device_scale_factor_ = data.device_scale_factor(); - device_transform_scale_factor_ = data.device_transform_scale_factor(); - - DCHECK(nodes_affected_by_inner_viewport_bounds_delta_.empty()); - for (int i = 0; i < data.nodes_affected_by_inner_viewport_bounds_delta_size(); - ++i) { - nodes_affected_by_inner_viewport_bounds_delta_.push_back( - data.nodes_affected_by_inner_viewport_bounds_delta(i)); - } - - DCHECK(nodes_affected_by_outer_viewport_bounds_delta_.empty()); - for (int i = 0; i < data.nodes_affected_by_outer_viewport_bounds_delta_size(); - ++i) { - nodes_affected_by_outer_viewport_bounds_delta_.push_back( - data.nodes_affected_by_outer_viewport_bounds_delta(i)); - } - - DCHECK_EQ(static_cast<int>(cached_data_.size()), 1); - cached_data_.back().FromProtobuf(data.cached_data(0)); - for (int i = 1; i < data.cached_data_size(); ++i) { - cached_data_.push_back(TransformCachedNodeData()); - cached_data_.back().FromProtobuf(data.cached_data(i)); - } - - DCHECK(static_cast<int>(sticky_position_data_.empty())); - for (int i = 0; i < data.sticky_position_data_size(); ++i) { - sticky_position_data_.push_back(StickyPositionNodeData()); - sticky_position_data_.back().FromProtobuf(data.sticky_position_data(i)); - } -} - EffectTree::EffectTree() {} EffectTree::~EffectTree() {} @@ -1015,40 +801,17 @@ void EffectTree::UpdateEffectChanged(EffectNode* node, void EffectTree::UpdateBackfaceVisibility(EffectNode* node, EffectNode* parent_node) { - if (!parent_node) { - node->hidden_by_backface_visibility = false; - return; - } - if (parent_node->hidden_by_backface_visibility) { + if (parent_node && parent_node->hidden_by_backface_visibility) { node->hidden_by_backface_visibility = true; return; + } else if (node->double_sided) { + node->hidden_by_backface_visibility = false; + return; } - - TransformTree& transform_tree = property_trees()->transform_tree; - if (node->has_render_surface && !node->double_sided) { - TransformNode* transform_node = transform_tree.Node(node->transform_id); - if (transform_node->is_invertible && - transform_node->ancestors_are_invertible) { - if (transform_node->sorting_context_id) { - const TransformNode* parent_transform_node = - transform_tree.parent(transform_node); - if (parent_transform_node && - parent_transform_node->sorting_context_id == - transform_node->sorting_context_id) { - gfx::Transform surface_draw_transform; - property_trees()->ComputeTransformToTarget( - transform_node->id, node->target_id, &surface_draw_transform); - node->hidden_by_backface_visibility = - surface_draw_transform.IsBackFaceVisible(); - } else { - node->hidden_by_backface_visibility = - transform_node->local.IsBackFaceVisible(); - } - return; - } - } - } - node->hidden_by_backface_visibility = false; + node->hidden_by_backface_visibility = + property_trees() + ->transform_tree.cached_data()[node->transform_id] + .is_showing_backface; } void EffectTree::UpdateSurfaceContentsScale(EffectNode* effect_node) { @@ -1170,10 +933,7 @@ void EffectTree::TakeCopyRequestsAndTransformToSurface( source_id = TransformTree::kContentsRootNodeId; } gfx::Transform transform; - property_trees()->transform_tree.ComputeTransform(source_id, destination_id, - &transform); - transform.matrix().postScale(effect_node->surface_contents_scale.x(), - effect_node->surface_contents_scale.y(), 1.f); + property_trees()->GetToTarget(source_id, node_id, &transform); it->set_area(MathUtil::MapEnclosingClippedRect(transform, it->area())); } } @@ -1233,12 +993,10 @@ void EffectTree::ResetChangeTracking() { void TransformTree::UpdateNodeAndAncestorsHaveIntegerTranslations( TransformNode* node, TransformNode* parent_node) { + DCHECK(parent_node); node->node_and_ancestors_have_only_integer_translation = - node->to_parent.IsIdentityOrIntegerTranslation(); - if (parent_node) - node->node_and_ancestors_have_only_integer_translation = - node->node_and_ancestors_have_only_integer_translation && - parent_node->node_and_ancestors_have_only_integer_translation; + node->to_parent.IsIdentityOrIntegerTranslation() && + parent_node->node_and_ancestors_have_only_integer_translation; } void ClipTree::SetViewportClip(gfx::RectF viewport_rect) { @@ -1261,22 +1019,6 @@ bool ClipTree::operator==(const ClipTree& other) const { return PropertyTree::operator==(other); } -void ClipTree::ToProtobuf(proto::PropertyTree* proto) const { - DCHECK(!proto->has_property_type()); - proto->set_property_type(proto::PropertyTree::Clip); - - PropertyTree::ToProtobuf(proto); -} - -void ClipTree::FromProtobuf( - const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map) { - DCHECK(proto.has_property_type()); - DCHECK_EQ(proto.property_type(), proto::PropertyTree::Clip); - - PropertyTree::FromProtobuf(proto, node_id_to_index_map); -} - EffectTree& EffectTree::operator=(const EffectTree& from) { PropertyTree::operator=(from); mask_layer_ids_ = from.mask_layer_ids_; @@ -1290,32 +1032,6 @@ bool EffectTree::operator==(const EffectTree& other) const { mask_layer_ids_ == other.mask_layer_ids_; } -void EffectTree::ToProtobuf(proto::PropertyTree* proto) const { - DCHECK(!proto->has_property_type()); - proto->set_property_type(proto::PropertyTree::Effect); - - PropertyTree::ToProtobuf(proto); - proto::EffectTreeData* data = proto->mutable_effect_tree_data(); - - for (auto i : mask_layer_ids_) - data->add_mask_layer_ids(i); -} - -void EffectTree::FromProtobuf( - const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map) { - DCHECK(proto.has_property_type()); - DCHECK_EQ(proto.property_type(), proto::PropertyTree::Effect); - - PropertyTree::FromProtobuf(proto, node_id_to_index_map); - const proto::EffectTreeData& data = proto.effect_tree_data(); - - DCHECK(mask_layer_ids_.empty()); - for (int i = 0; i < data.mask_layer_ids_size(); ++i) { - mask_layer_ids_.push_back(data.mask_layer_ids(i)); - } -} - ScrollTree::ScrollTree() : currently_scrolling_node_id_(kInvalidNodeId), layer_id_to_scroll_offset_map_(ScrollTree::ScrollOffsetMap()) {} @@ -1354,48 +1070,6 @@ bool ScrollTree::operator==(const ScrollTree& other) const { return PropertyTree::operator==(other) && is_currently_scrolling_node_equal; } -void ScrollTree::ToProtobuf(proto::PropertyTree* proto) const { - DCHECK(!proto->has_property_type()); - proto->set_property_type(proto::PropertyTree::Scroll); - - PropertyTree::ToProtobuf(proto); - proto::ScrollTreeData* data = proto->mutable_scroll_tree_data(); - - data->set_currently_scrolling_node_id(currently_scrolling_node_id_); - for (auto i : layer_id_to_scroll_offset_map_) { - data->add_layer_id_to_scroll_offset_map(); - proto::ScrollOffsetMapEntry* entry = - data->mutable_layer_id_to_scroll_offset_map( - data->layer_id_to_scroll_offset_map_size() - 1); - entry->set_layer_id(i.first); - SyncedScrollOffsetToProto(*i.second.get(), entry->mutable_scroll_offset()); - } -} - -void ScrollTree::FromProtobuf( - const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map) { - DCHECK(proto.has_property_type()); - DCHECK_EQ(proto.property_type(), proto::PropertyTree::Scroll); - - PropertyTree::FromProtobuf(proto, node_id_to_index_map); - const proto::ScrollTreeData& data = proto.scroll_tree_data(); - - currently_scrolling_node_id_ = data.currently_scrolling_node_id(); - - // TODO(khushalsagar): This should probably be removed if the copy constructor - // for ScrollTree copies the |layer_id_to_scroll_offset_map_| as well. - layer_id_to_scroll_offset_map_.clear(); - for (int i = 0; i < data.layer_id_to_scroll_offset_map_size(); ++i) { - const proto::ScrollOffsetMapEntry entry = - data.layer_id_to_scroll_offset_map(i); - layer_id_to_scroll_offset_map_[entry.layer_id()] = new SyncedScrollOffset(); - ProtoToSyncedScrollOffset( - entry.scroll_offset(), - layer_id_to_scroll_offset_map_[entry.layer_id()].get()); - } -} - void ScrollTree::clear() { PropertyTree<ScrollNode>::clear(); @@ -1772,8 +1446,7 @@ PropertyTrees::PropertyTrees() full_tree_damaged(false), sequence_number(0), is_main_thread(true), - is_active(false), - verify_transform_tree_calculations(false) { + is_active(false) { transform_tree.SetPropertyTrees(this); effect_tree.SetPropertyTrees(this); clip_tree.SetPropertyTrees(this); @@ -1818,7 +1491,6 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) { sequence_number = from.sequence_number; is_main_thread = from.is_main_thread; is_active = from.is_active; - verify_transform_tree_calculations = from.verify_transform_tree_calculations; inner_viewport_container_bounds_delta_ = from.inner_viewport_container_bounds_delta(); outer_viewport_container_bounds_delta_ = @@ -1833,56 +1505,6 @@ PropertyTrees& PropertyTrees::operator=(const PropertyTrees& from) { return *this; } -void PropertyTrees::ToProtobuf(proto::PropertyTrees* proto) const { - // TODO(khushalsagar): Add support for sending diffs when serializaing - // property trees. See crbug/555370. - transform_tree.ToProtobuf(proto->mutable_transform_tree()); - effect_tree.ToProtobuf(proto->mutable_effect_tree()); - clip_tree.ToProtobuf(proto->mutable_clip_tree()); - scroll_tree.ToProtobuf(proto->mutable_scroll_tree()); - proto->set_needs_rebuild(needs_rebuild); - proto->set_changed(changed); - proto->set_full_tree_damaged(full_tree_damaged); - proto->set_non_root_surfaces_enabled(non_root_surfaces_enabled); - proto->set_is_main_thread(is_main_thread); - proto->set_is_active(is_active); - proto->set_verify_transform_tree_calculations( - verify_transform_tree_calculations); - - // TODO(khushalsagar): Consider using the sequence number to decide if - // property trees need to be serialized again for a commit. See crbug/555370. - proto->set_sequence_number(sequence_number); - - for (auto i : always_use_active_tree_opacity_effect_ids) - proto->add_always_use_active_tree_opacity_effect_ids(i); -} - -// static -void PropertyTrees::FromProtobuf(const proto::PropertyTrees& proto) { - transform_tree.FromProtobuf(proto.transform_tree(), - &transform_id_to_index_map); - effect_tree.FromProtobuf(proto.effect_tree(), &effect_id_to_index_map); - clip_tree.FromProtobuf(proto.clip_tree(), &clip_id_to_index_map); - scroll_tree.FromProtobuf(proto.scroll_tree(), &scroll_id_to_index_map); - - needs_rebuild = proto.needs_rebuild(); - changed = proto.changed(); - full_tree_damaged = proto.full_tree_damaged(); - non_root_surfaces_enabled = proto.non_root_surfaces_enabled(); - sequence_number = proto.sequence_number(); - is_main_thread = proto.is_main_thread(); - is_active = proto.is_active(); - verify_transform_tree_calculations = - proto.verify_transform_tree_calculations(); - - transform_tree.SetPropertyTrees(this); - effect_tree.SetPropertyTrees(this); - clip_tree.SetPropertyTrees(this); - scroll_tree.SetPropertyTrees(this); - for (auto i : proto.always_use_active_tree_opacity_effect_ids()) - always_use_active_tree_opacity_effect_ids.push_back(i); -} - void PropertyTrees::clear() { transform_tree.clear(); clip_tree.clear(); @@ -2101,8 +1723,7 @@ CombinedAnimationScale PropertyTrees::GetAnimationScales( // Computing maximum animated scale in the presence of non-scale/translation // transforms isn't supported. bool failed_for_non_scale_or_translation = - !transform_tree.Node(transform_node_id) - ->to_parent.IsScaleOrTranslation(); + !node->to_parent.IsScaleOrTranslation(); // We don't attempt to accumulate animation scale from multiple nodes with // scale animations, because of the risk of significant overestimation. For @@ -2144,11 +1765,11 @@ CombinedAnimationScale PropertyTrees::GetAnimationScales( // TODO(sunxd): make LayerTreeImpl::MaximumTargetScale take layer id as // parameter. LayerImpl* layer_impl = layer_tree_impl->LayerById(node->owner_id); - layer_impl->GetAnimationHost()->MaximumTargetScale( + layer_impl->GetMutatorHost()->MaximumTargetScale( layer_impl->element_id(), layer_impl->GetElementTypeForAnimation(), &cached_data_.animation_scales[transform_node_id] .local_maximum_animation_target_scale); - layer_impl->GetAnimationHost()->AnimationStartScale( + layer_impl->GetMutatorHost()->AnimationStartScale( layer_impl->element_id(), layer_impl->GetElementTypeForAnimation(), &cached_data_.animation_scales[transform_node_id] .local_starting_animation_scale); @@ -2207,95 +1828,123 @@ void PropertyTrees::SetAnimationScalesForTesting( cached_data_.property_tree_update_number; } -const DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, - int effect_id) const { - if (cached_data_.draw_transforms[effect_id][transform_id].update_number != - cached_data_.property_tree_update_number) { - gfx::Transform target_space_transform; - gfx::Transform from_target; - const TransformNode* transform_node = transform_tree.Node(transform_id); - const EffectNode* effect_node = effect_tree.Node(effect_id); - const TransformNode* dest_node = - transform_tree.Node(effect_node->transform_id); - DCHECK(effect_id == effect_tree.kRootNodeId || - effect_node->has_render_surface); - bool already_computed_inverse = false; - if (transform_id == effect_node->transform_id) { - target_space_transform.Scale(effect_node->surface_contents_scale.x(), - effect_node->surface_contents_scale.y()); - } else if (!dest_node || (dest_node->ancestors_are_invertible && - dest_node->node_and_ancestors_are_flat)) { - // Compute transform from transform_id to effect_node->transform using - // screen space transforms. - target_space_transform.ConcatTransform( - transform_tree.ToScreen(transform_id)); - if (dest_node) - target_space_transform.ConcatTransform( - transform_tree.FromScreen(dest_node->id)); - if (dest_node->needs_surface_contents_scale) - target_space_transform.matrix().postScale( - dest_node->surface_contents_scale.x(), - dest_node->surface_contents_scale.y(), 1.f); - } else if (transform_node->id > dest_node->id) { - target_space_transform = - GetDrawTransforms(transform_node->parent_id, effect_id).to_target; - if (transform_node->flattens_inherited_transform) - target_space_transform.FlattenTo2d(); - target_space_transform.PreconcatTransform(transform_node->to_parent); - } else { - const TransformNode* current = dest_node; - std::vector<int> source_to_destination; - source_to_destination.push_back(current->id); - current = transform_tree.parent(current); - for (; current && current->id > transform_node->id; - current = transform_tree.parent(current)) { - source_to_destination.push_back(current->id); - } - DCHECK_EQ(current, transform_node); - gfx::Transform combined_transform; - size_t source_to_destination_size = source_to_destination.size(); - for (size_t i = 0; i < source_to_destination_size; ++i) { - size_t index = source_to_destination_size - 1 - i; - const TransformNode* node = - transform_tree.Node(source_to_destination[index]); - if (node->flattens_inherited_transform) - combined_transform.FlattenTo2d(); - combined_transform.PreconcatTransform(node->to_parent); - } - if (effect_node->surface_contents_scale.x() != 0.f && - effect_node->surface_contents_scale.y() != 0.f) - combined_transform.Scale( - 1.0f / effect_node->surface_contents_scale.x(), - 1.0f / effect_node->surface_contents_scale.y()); - cached_data_.draw_transforms[effect_id][transform_id] - .transforms.invertible = - combined_transform.GetInverse(&target_space_transform); - from_target = combined_transform; - already_computed_inverse = true; - } - if (!already_computed_inverse) { - cached_data_.draw_transforms[effect_id][transform_id] - .transforms.invertible = - target_space_transform.GetInverse(&from_target); +bool PropertyTrees::GetToTarget(int transform_id, + int effect_id, + gfx::Transform* to_target) const { + DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id); + if (transforms.to_valid) { + *to_target = transforms.to_target; + return true; + } else if (!transforms.might_be_invertible) { + return false; + } else { + transforms.might_be_invertible = + transforms.from_target.GetInverse(to_target); + transforms.to_valid = transforms.might_be_invertible; + transforms.to_target = *to_target; + return transforms.to_valid; + } +} + +bool PropertyTrees::GetFromTarget(int transform_id, + int effect_id, + gfx::Transform* from_target) const { + DrawTransforms& transforms = GetDrawTransforms(transform_id, effect_id); + if (transforms.from_valid) { + *from_target = transforms.from_target; + return true; + } else if (!transforms.might_be_invertible) { + return false; + } else { + transforms.might_be_invertible = + transforms.to_target.GetInverse(from_target); + transforms.from_valid = transforms.might_be_invertible; + transforms.from_target = *from_target; + return transforms.from_valid; + } +} + +DrawTransformData& PropertyTrees::FetchDrawTransformsDataFromCache( + int transform_id, + int dest_id) const { + for (auto& transform_data : cached_data_.draw_transforms[transform_id]) { + // We initialize draw_transforms with 1 element vectors when + // ResetCachedData, so if we hit a -1 target id, it means it's the first + // time we compute draw transforms after reset. + if (transform_data.target_id == dest_id || transform_data.target_id == -1) { + return transform_data; } - cached_data_.draw_transforms[effect_id][transform_id].update_number = - cached_data_.property_tree_update_number; - cached_data_.draw_transforms[effect_id][transform_id] - .transforms.from_target = from_target; - cached_data_.draw_transforms[effect_id][transform_id].transforms.to_target = - target_space_transform; } - return cached_data_.draw_transforms[effect_id][transform_id].transforms; + // Add an entry to the cache. + cached_data_.draw_transforms[transform_id].push_back(DrawTransformData()); + DrawTransformData& data = cached_data_.draw_transforms[transform_id].back(); + data.update_number = -1; + data.target_id = dest_id; + return data; +} + +DrawTransforms& PropertyTrees::GetDrawTransforms(int transform_id, + int effect_id) const { + const EffectNode* effect_node = effect_tree.Node(effect_id); + int dest_id = effect_node->transform_id; + + DrawTransformData& data = + FetchDrawTransformsDataFromCache(transform_id, dest_id); + + DCHECK(data.update_number != cached_data_.property_tree_update_number || + data.target_id != -1); + if (data.update_number == cached_data_.property_tree_update_number) + return data.transforms; + + // Cache miss. + gfx::Transform target_space_transform; + gfx::Transform from_target; + bool already_computed_inverse = false; + if (transform_id == dest_id) { + target_space_transform.Scale(effect_node->surface_contents_scale.x(), + effect_node->surface_contents_scale.y()); + data.transforms.to_valid = true; + data.transforms.from_valid = false; + } else if (transform_id > dest_id) { + transform_tree.CombineTransformsBetween(transform_id, dest_id, + &target_space_transform); + target_space_transform.matrix().postScale( + effect_node->surface_contents_scale.x(), + effect_node->surface_contents_scale.y(), 1.f); + data.transforms.to_valid = true; + data.transforms.from_valid = false; + data.transforms.might_be_invertible = true; + } else { + gfx::Transform combined_transform; + transform_tree.CombineTransformsBetween(dest_id, transform_id, + &combined_transform); + if (effect_node->surface_contents_scale.x() != 0.f && + effect_node->surface_contents_scale.y() != 0.f) + combined_transform.Scale(1.0f / effect_node->surface_contents_scale.x(), + 1.0f / effect_node->surface_contents_scale.y()); + bool invertible = combined_transform.GetInverse(&target_space_transform); + data.transforms.might_be_invertible = invertible; + data.transforms.to_valid = invertible; + data.transforms.from_valid = true; + from_target = combined_transform; + already_computed_inverse = true; + } + + if (!already_computed_inverse) + data.transforms.to_valid = true; + data.update_number = cached_data_.property_tree_update_number; + data.target_id = dest_id; + data.transforms.from_target = from_target; + data.transforms.to_target = target_space_transform; + return data.transforms; } void PropertyTrees::ResetCachedData() { cached_data_.property_tree_update_number = 0; cached_data_.animation_scales = std::vector<AnimationScaleData>( transform_tree.nodes().size(), AnimationScaleData()); - cached_data_.draw_transforms = - std::vector<std::unordered_map<int, DrawTransformData>>( - effect_tree.nodes().size(), - std::unordered_map<int, DrawTransformData>()); + cached_data_.draw_transforms = std::vector<std::vector<DrawTransformData>>( + transform_tree.nodes().size(), std::vector<DrawTransformData>(1)); } void PropertyTrees::UpdateCachedNumber() { @@ -2319,76 +1968,19 @@ gfx::Transform PropertyTrees::ToScreenSpaceTransformWithoutSurfaceContentsScale( return screen_space_transform; } -bool PropertyTrees::ComputeTransformToTarget(int transform_id, - int effect_id, - gfx::Transform* transform) const { - transform->MakeIdentity(); - - if (transform_id == TransformTree::kInvalidNodeId) - return true; - - int target_transform_id; - const EffectNode* effect_node = effect_tree.Node(effect_id); - if (effect_id == EffectTree::kInvalidNodeId) { - // This can happen when PaintArtifactCompositor builds property trees as - // it doesn't set effect ids on clip nodes. We want to compute transform - // to the root in this case. - target_transform_id = TransformTree::kRootNodeId; - } else { - DCHECK(effect_node->has_render_surface || - effect_node->id == EffectTree::kRootNodeId); - target_transform_id = effect_node->transform_id; - } - - bool success = transform_tree.ComputeTransform( - transform_id, target_transform_id, transform); - if (verify_transform_tree_calculations) { - gfx::Transform to_target; - to_target.ConcatTransform( - GetDrawTransforms(transform_id, effect_id).to_target); - if (effect_node->surface_contents_scale.x() != 0.f && - effect_node->surface_contents_scale.y() != 0.f) - to_target.matrix().postScale( - 1.0f / effect_node->surface_contents_scale.x(), - 1.0f / effect_node->surface_contents_scale.y(), 1.0f); - DCHECK(to_target.ApproximatelyEqual(*transform)); - } - return success; -} - bool PropertyTrees::ComputeTransformFromTarget( int transform_id, int effect_id, gfx::Transform* transform) const { transform->MakeIdentity(); - if (transform_id == TransformTree::kInvalidNodeId) return true; - int target_transform_id; const EffectNode* effect_node = effect_tree.Node(effect_id); - if (effect_id == EffectTree::kInvalidNodeId) { - // This can happen when PaintArtifactCompositor builds property trees as - // it doesn't set effect ids on clip nodes. We want to compute transform - // to the root in this case. - target_transform_id = TransformTree::kRootNodeId; - } else { - DCHECK(effect_node->has_render_surface || - effect_node->id == EffectTree::kRootNodeId); - target_transform_id = effect_node->transform_id; - } - bool success = transform_tree.ComputeTransform(target_transform_id, - transform_id, transform); - if (verify_transform_tree_calculations) { - auto draw_transforms = GetDrawTransforms(transform_id, effect_id); - gfx::Transform from_target; - from_target.ConcatTransform(draw_transforms.from_target); - from_target.Scale(effect_node->surface_contents_scale.x(), - effect_node->surface_contents_scale.y()); - DCHECK(from_target.ApproximatelyEqual(*transform) || - !draw_transforms.invertible); - } + bool success = GetFromTarget(transform_id, effect_id, transform); + transform->Scale(effect_node->surface_contents_scale.x(), + effect_node->surface_contents_scale.y()); return success; } diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h index 28dfee36bab..85a8d47a825 100644 --- a/chromium/cc/trees/property_tree.h +++ b/chromium/cc/trees/property_tree.h @@ -11,11 +11,11 @@ #include <unordered_map> #include <vector> -#include "cc/animation/element_id.h" #include "cc/base/cc_export.h" #include "cc/base/synced_property.h" #include "cc/layers/layer_sticky_position_constraint.h" #include "cc/output/filter_operations.h" +#include "cc/trees/element_id.h" #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/scroll_offset.h" #include "ui/gfx/transform.h" @@ -28,14 +28,6 @@ class TracedValue; namespace cc { -namespace proto { -class PropertyTree; -class PropertyTrees; -class ScrollNodeData; -class StickyPositionNodeData; -class TreeNode; -} // namespace proto - class CopyOutputRequest; class LayerTreeImpl; class ScrollState; @@ -46,13 +38,6 @@ struct ScrollNode; struct TransformNode; struct TransformCachedNodeData; -// ------------------------------*IMPORTANT*--------------------------------- -// Each class declared here has a corresponding proto defined in -// cc/proto/property_tree.proto. When making any changes to a class structure -// including addition/deletion/updation of a field, please also make the -// change to its proto and the ToProtobuf and FromProtobuf methods for that -// class. - typedef SyncedProperty<AdditionGroup<gfx::ScrollOffset>> SyncedScrollOffset; class PropertyTrees; @@ -106,10 +91,6 @@ class CC_EXPORT PropertyTree { int next_available_id() const { return static_cast<int>(size()); } - void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map); - void SetPropertyTrees(PropertyTrees* property_trees) { property_trees_ = property_trees; } @@ -120,6 +101,7 @@ class CC_EXPORT PropertyTree { private: std::vector<T> nodes_; + friend class TransformTree; bool needs_update_; PropertyTrees* property_trees_; }; @@ -134,8 +116,6 @@ struct StickyPositionNodeData { gfx::Vector2dF main_thread_offset; StickyPositionNodeData() : scroll_ancestor(-1) {} - void ToProtobuf(proto::StickyPositionNodeData* proto) const; - void FromProtobuf(const proto::StickyPositionNodeData& proto); }; class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { @@ -158,19 +138,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { void clear(); - // Computes the change of basis transform from node |source_id| to |dest_id|. - // The function returns false iff the inverse of a singular transform was - // used (and the result should, therefore, not be trusted). Transforms may - // be computed between any pair of nodes that have an ancestor/descendant - // relationship. Transforms between other pairs of nodes may only be computed - // if the following condition holds: let id1 the larger id and let id2 be the - // other id; then the nearest ancestor of node id1 whose id is smaller than - // id2 is the lowest common ancestor of the pair of nodes, and the transform - // from this lowest common ancestor to node id2 is only a 2d translation. - bool ComputeTransform(int source_id, - int dest_id, - gfx::Transform* transform) const; - void OnTransformAnimated(const gfx::Transform& transform, int id, LayerTreeImpl* layer_tree_impl); @@ -194,6 +161,8 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { TransformNode* node, TransformNode* parent_node); + void set_needs_update(bool needs_update); + // A TransformNode's source_to_parent value is used to account for the fact // that fixed-position layers are positioned by Blink wrt to their layer tree // parent (their "source"), but are parented in the transform tree by their @@ -225,7 +194,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { float page_scale_factor_for_root, const gfx::Transform& device_transform, gfx::PointF root_position); - float device_transform_scale_factor() const { return device_transform_scale_factor_; } @@ -249,14 +217,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { return nodes_affected_by_outer_viewport_bounds_delta_; } - const gfx::Transform& FromTarget(int node_id, int effect) const; - void SetFromTarget(int node_id, const gfx::Transform& transform); - - // TODO(sunxd): Remove target space transforms in cached data when we - // completely implement computing draw transforms on demand. - const gfx::Transform& ToTarget(int node_id, int effect_id) const; - void SetToTarget(int node_id, const gfx::Transform& transform); - const gfx::Transform& FromScreen(int node_id) const; void SetFromScreen(int node_id, const gfx::Transform& transform); @@ -275,10 +235,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { StickyPositionNodeData* StickyPositionData(int node_id); - void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map); - // Computes the combined transform between |source_id| and |dest_id|. These // two nodes must be on the same ancestor chain. void CombineTransformsBetween(int source_id, @@ -301,9 +257,6 @@ class CC_EXPORT TransformTree final : public PropertyTree<TransformNode> { void UpdateScreenSpaceTransform(TransformNode* node, TransformNode* parent_node, TransformNode* target_node); - void UpdateSurfaceContentsScale(TransformNode* node); - void UpdateTargetSpaceTransform(TransformNode* node, - TransformNode* target_node); void UpdateAnimationProperties(TransformNode* node, TransformNode* parent_node); void UndoSnapping(TransformNode* node); @@ -334,10 +287,6 @@ class CC_EXPORT ClipTree final : public PropertyTree<ClipNode> { void SetViewportClip(gfx::RectF viewport_rect); gfx::RectF ViewportClip() const; - - void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map); }; class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { @@ -382,10 +331,6 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> { void ResetChangeTracking(); - void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map); - private: void UpdateOpacities(EffectNode* node, EffectNode* parent_node); void UpdateIsDrawn(EffectNode* node, EffectNode* parent_node); @@ -407,14 +352,11 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { ScrollTree& operator=(const ScrollTree& from); bool operator==(const ScrollTree& other) const; - void ToProtobuf(proto::PropertyTree* proto) const; - void FromProtobuf(const proto::PropertyTree& proto, - std::unordered_map<int, int>* node_id_to_index_map); - void clear(); typedef std::unordered_map<int, scoped_refptr<SyncedScrollOffset>> ScrollOffsetMap; + typedef std::unordered_map<int, bool> ScrollbarsEnabledMap; gfx::ScrollOffset MaxScrollOffset(int scroll_node_id) const; void OnScrollOffsetAnimated(int layer_id, @@ -463,6 +405,7 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> { private: int currently_scrolling_node_id_; ScrollOffsetMap layer_id_to_scroll_offset_map_; + ScrollbarsEnabledMap layer_id_to_scrollbars_enabled_map_; SyncedScrollOffset* synced_scroll_offset(int layer_id); const SyncedScrollOffset* synced_scroll_offset(int layer_id) const; @@ -519,33 +462,48 @@ struct CombinedAnimationScale { }; struct DrawTransforms { - bool invertible; + // We compute invertibility of a draw transforms lazily. + // Might_be_invertible is true if we have not computed the inverse of either + // to_target or from_target, or to_target / from_target is invertible. + bool might_be_invertible; + // From_valid is true if the from_target is already computed directly or + // computed by inverting an invertible to_target. + bool from_valid; + // To_valid is true if to_target stores a valid result, similar to from_valid. + bool to_valid; gfx::Transform from_target; gfx::Transform to_target; DrawTransforms(gfx::Transform from, gfx::Transform to) - : invertible(true), from_target(from), to_target(to) {} + : might_be_invertible(true), + from_valid(false), + to_valid(false), + from_target(from), + to_target(to) {} bool operator==(const DrawTransforms& other) const { - return invertible == other.invertible && from_target == other.from_target && - to_target == other.to_target; + return from_valid == other.from_valid && to_valid == other.to_valid && + from_target == other.from_target && to_target == other.to_target; } }; struct DrawTransformData { int update_number; + int target_id; + DrawTransforms transforms; // TODO(sunxd): Move screen space transforms here if it can improve // performance. DrawTransformData() - : update_number(-1), transforms(gfx::Transform(), gfx::Transform()) {} + : update_number(-1), + target_id(-1), + transforms(gfx::Transform(), gfx::Transform()) {} }; struct PropertyTreesCachedData { int property_tree_update_number; std::vector<AnimationScaleData> animation_scales; - mutable std::vector<std::unordered_map<int, DrawTransformData>> - draw_transforms; + mutable std::vector<std::vector<DrawTransformData>> draw_transforms; PropertyTreesCachedData(); ~PropertyTreesCachedData(); @@ -560,9 +518,6 @@ class CC_EXPORT PropertyTrees final { bool operator==(const PropertyTrees& other) const; PropertyTrees& operator=(const PropertyTrees& from); - void ToProtobuf(proto::PropertyTrees* proto) const; - void FromProtobuf(const proto::PropertyTrees& proto); - std::unordered_map<int, int> transform_id_to_index_map; std::unordered_map<int, int> effect_id_to_index_map; std::unordered_map<int, int> clip_id_to_index_map; @@ -590,7 +545,6 @@ class CC_EXPORT PropertyTrees final { int sequence_number; bool is_main_thread; bool is_active; - bool verify_transform_tree_calculations; void clear(); @@ -624,18 +578,18 @@ class CC_EXPORT PropertyTrees final { float maximum_animation_scale, float starting_animation_scale); - // GetDrawTransforms may change the value of cached_data_. - const DrawTransforms& GetDrawTransforms(int transform_id, - int effect_id) const; + bool GetToTarget(int transform_id, + int effect_id, + gfx::Transform* to_target) const; + bool GetFromTarget(int transform_id, + int effect_id, + gfx::Transform* from_target) const; void ResetCachedData(); void UpdateCachedNumber(); gfx::Transform ToScreenSpaceTransformWithoutSurfaceContentsScale( int transform_id, int effect_id) const; - bool ComputeTransformToTarget(int transform_id, - int effect_id, - gfx::Transform* transform) const; bool ComputeTransformFromTarget(int transform_id, int effect_id, @@ -646,6 +600,11 @@ class CC_EXPORT PropertyTrees final { 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; + DrawTransformData& FetchDrawTransformsDataFromCache(int transform_id, + int effect_id) const; + PropertyTreesCachedData cached_data_; }; diff --git a/chromium/cc/trees/property_tree_builder.cc b/chromium/cc/trees/property_tree_builder.cc index 5bab434b848..6a0a0899f98 100644 --- a/chromium/cc/trees/property_tree_builder.cc +++ b/chromium/cc/trees/property_tree_builder.cc @@ -9,8 +9,6 @@ #include <map> #include <set> -#include "cc/animation/animation_host.h" -#include "cc/animation/mutable_properties.h" #include "cc/base/math_util.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" @@ -20,6 +18,8 @@ #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_impl.h" #include "cc/trees/layer_tree_settings.h" +#include "cc/trees/mutable_properties.h" +#include "cc/trees/mutator_host.h" #include "cc/trees/scroll_node.h" #include "cc/trees/transform_node.h" #include "ui/gfx/geometry/point_f.h" @@ -244,56 +244,56 @@ static const gfx::Transform& Transform(LayerImpl* layer) { // Methods to query state from the AnimationHost ---------------------- template <typename LayerType> bool OpacityIsAnimating(LayerType* layer) { - return layer->GetAnimationHost()->IsAnimatingOpacityProperty( + return layer->GetMutatorHost()->IsAnimatingOpacityProperty( layer->element_id(), layer->GetElementTypeForAnimation()); } template <typename LayerType> bool HasPotentiallyRunningOpacityAnimation(LayerType* layer) { - return layer->GetAnimationHost()->HasPotentiallyRunningOpacityAnimation( + return layer->GetMutatorHost()->HasPotentiallyRunningOpacityAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } template <typename LayerType> bool FilterIsAnimating(LayerType* layer) { - return layer->GetAnimationHost()->IsAnimatingFilterProperty( + return layer->GetMutatorHost()->IsAnimatingFilterProperty( layer->element_id(), layer->GetElementTypeForAnimation()); } template <typename LayerType> bool HasPotentiallyRunningFilterAnimation(LayerType* layer) { - return layer->GetAnimationHost()->HasPotentiallyRunningFilterAnimation( + return layer->GetMutatorHost()->HasPotentiallyRunningFilterAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } template <typename LayerType> bool TransformIsAnimating(LayerType* layer) { - return layer->GetAnimationHost()->IsAnimatingTransformProperty( + return layer->GetMutatorHost()->IsAnimatingTransformProperty( layer->element_id(), layer->GetElementTypeForAnimation()); } template <typename LayerType> bool HasPotentiallyRunningTransformAnimation(LayerType* layer) { - return layer->GetAnimationHost()->HasPotentiallyRunningTransformAnimation( + return layer->GetMutatorHost()->HasPotentiallyRunningTransformAnimation( layer->element_id(), layer->GetElementTypeForAnimation()); } template <typename LayerType> bool HasOnlyTranslationTransforms(LayerType* layer) { - return layer->GetAnimationHost()->HasOnlyTranslationTransforms( + return layer->GetMutatorHost()->HasOnlyTranslationTransforms( layer->element_id(), layer->GetElementTypeForAnimation()); } template <typename LayerType> bool AnimationsPreserveAxisAlignment(LayerType* layer) { - return layer->GetAnimationHost()->AnimationsPreserveAxisAlignment( + return layer->GetMutatorHost()->AnimationsPreserveAxisAlignment( layer->element_id()); } template <typename LayerType> bool HasAnyAnimationTargetingProperty(LayerType* layer, TargetProperty::Type property) { - return layer->GetAnimationHost()->HasAnyAnimationTargetingProperty( + return layer->GetMutatorHost()->HasAnyAnimationTargetingProperty( layer->element_id(), property); } @@ -369,7 +369,7 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, // of its own, but clips from ancestor nodes don't need to be considered // when computing clip rects or visibility. has_unclipped_surface = true; - DCHECK(!parent->applies_local_clip); + DCHECK_NE(parent->clip_type, ClipNode::ClipType::APPLIES_LOCAL_CLIP); } // A surface with unclipped descendants cannot be clipped by its ancestor // clip at draw time since the unclipped descendants aren't affected by the @@ -429,7 +429,10 @@ void AddClipNodeIfNeeded(const DataForRecursion<LayerType>& data_from_ancestor, node.layer_clipping_uses_only_local_clip = false; } - node.applies_local_clip = layer_clips_subtree; + if (layer_clips_subtree) + node.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; + else + node.clip_type = ClipNode::ClipType::NONE; node.resets_clip = has_unclipped_surface; node.target_is_clipped = data_for_children->target_is_clipped; node.layers_are_clipped = layers_are_clipped; @@ -490,6 +493,7 @@ bool AddTransformNodeIfNeeded( const bool is_scrollable = layer->scrollable(); const bool is_fixed = PositionConstraint(layer).is_fixed_position(); const bool is_sticky = StickyPositionConstraint(layer).is_sticky; + const bool is_snapped = layer->IsSnapped(); const bool has_significant_transform = !Transform(layer).IsIdentityOr2DTranslation(); @@ -520,7 +524,8 @@ bool AddTransformNodeIfNeeded( const bool is_at_boundary_of_3d_rendering_context = IsAtBoundaryOf3dRenderingContext(layer); - bool requires_node = is_root || is_scrollable || has_significant_transform || + DCHECK(!is_scrollable || is_snapped); + bool requires_node = is_root || is_snapped || has_significant_transform || has_any_transform_animation || has_surface || is_fixed || is_page_scale_layer || is_overscroll_elasticity_layer || has_proxied_transform_related_property || @@ -596,6 +601,7 @@ bool AddTransformNodeIfNeeded( node->id; node->scrolls = is_scrollable; + node->should_be_snapped = is_snapped; node->flattens_inherited_transform = data_for_children->should_flatten; node->sorting_context_id = layer->sorting_context_id(); @@ -638,9 +644,6 @@ bool AddTransformNodeIfNeeded( data_from_ancestor.page_scale_factor); } - if (has_surface && !is_root) - node->needs_surface_contents_scale = true; - node->source_node_id = source_index; node->post_local_scale_factor = post_local_scale_factor; if (is_root) { @@ -668,22 +671,22 @@ bool AddTransformNodeIfNeeded( if (is_fixed) { if (data_from_ancestor.affected_by_inner_viewport_bounds_delta) { - node->affected_by_inner_viewport_bounds_delta_x = + node->moved_by_inner_viewport_bounds_delta_x = PositionConstraint(layer).is_fixed_to_right_edge(); - node->affected_by_inner_viewport_bounds_delta_y = + node->moved_by_inner_viewport_bounds_delta_y = PositionConstraint(layer).is_fixed_to_bottom_edge(); - if (node->affected_by_inner_viewport_bounds_delta_x || - node->affected_by_inner_viewport_bounds_delta_y) { + if (node->moved_by_inner_viewport_bounds_delta_x || + node->moved_by_inner_viewport_bounds_delta_y) { data_for_children->property_trees->transform_tree .AddNodeAffectedByInnerViewportBoundsDelta(node->id); } } else if (data_from_ancestor.affected_by_outer_viewport_bounds_delta) { - node->affected_by_outer_viewport_bounds_delta_x = + node->moved_by_outer_viewport_bounds_delta_x = PositionConstraint(layer).is_fixed_to_right_edge(); - node->affected_by_outer_viewport_bounds_delta_y = + node->moved_by_outer_viewport_bounds_delta_y = PositionConstraint(layer).is_fixed_to_bottom_edge(); - if (node->affected_by_outer_viewport_bounds_delta_x || - node->affected_by_outer_viewport_bounds_delta_y) { + if (node->moved_by_outer_viewport_bounds_delta_x || + node->moved_by_outer_viewport_bounds_delta_y) { data_for_children->property_trees->transform_tree .AddNodeAffectedByOuterViewportBoundsDelta(node->id); } @@ -699,9 +702,26 @@ bool AddTransformNodeIfNeeded( node->id); sticky_data->constraints = StickyPositionConstraint(layer); sticky_data->scroll_ancestor = GetScrollParentId(data_from_ancestor, layer); + ScrollNode* scroll_ancestor = + data_for_children->property_trees->scroll_tree.Node( + sticky_data->scroll_ancestor); + if (sticky_data->constraints.is_anchored_right || + sticky_data->constraints.is_anchored_bottom) { + // Sticky nodes whose ancestor scroller is the inner / outer viewport + // need to have their local transform updated when the inner / outer + // viewport bounds change, but do not unconditionally move by that delta + // like fixed position nodes. + if (scroll_ancestor->is_inner_viewport_scroll_layer) { + data_for_children->property_trees->transform_tree + .AddNodeAffectedByInnerViewportBoundsDelta(node->id); + } else if (scroll_ancestor->is_outer_viewport_scroll_layer) { + data_for_children->property_trees->transform_tree + .AddNodeAffectedByOuterViewportBoundsDelta(node->id); + } + } sticky_data->main_thread_offset = layer->position().OffsetFromOrigin() - - sticky_data->constraints.scroll_container_relative_sticky_box_rect + sticky_data->constraints.parent_relative_sticky_box_offset .OffsetFromOrigin(); } @@ -1386,7 +1406,7 @@ void BuildPropertyTreesTopLevelInternal( ClipNode root_clip; root_clip.resets_clip = true; - root_clip.applies_local_clip = true; + root_clip.clip_type = ClipNode::ClipType::APPLIES_LOCAL_CLIP; root_clip.clip = gfx::RectF(viewport); root_clip.transform_id = kRootPropertyTreeNodeId; root_clip.target_transform_id = kRootPropertyTreeNodeId; @@ -1442,10 +1462,6 @@ void PropertyTreeBuilder::BuildPropertyTrees( PropertyTrees* property_trees) { property_trees->is_main_thread = true; property_trees->is_active = false; - property_trees->verify_transform_tree_calculations = - root_layer->GetLayerTree() - ->GetSettings() - .verify_transform_tree_calculations; SkColor color = root_layer->GetLayerTree()->background_color(); if (SkColorGetA(color) != 255) color = SkColorSetA(color, 255); @@ -1475,10 +1491,6 @@ void PropertyTreeBuilder::BuildPropertyTrees( PropertyTrees* property_trees) { property_trees->is_main_thread = false; property_trees->is_active = root_layer->IsActive(); - property_trees->verify_transform_tree_calculations = - root_layer->layer_tree_impl() - ->settings() - .verify_transform_tree_calculations; SkColor color = root_layer->layer_tree_impl()->background_color(); if (SkColorGetA(color) != 255) color = SkColorSetA(color, 255); diff --git a/chromium/cc/trees/property_tree_unittest.cc b/chromium/cc/trees/property_tree_unittest.cc index b2f5a78d414..66840c4ad1c 100644 --- a/chromium/cc/trees/property_tree_unittest.cc +++ b/chromium/cc/trees/property_tree_unittest.cc @@ -5,7 +5,6 @@ #include "cc/trees/property_tree.h" #include "cc/input/main_thread_scrolling_reason.h" -#include "cc/proto/property_tree.pb.h" #include "cc/test/geometry_test_utils.h" #include "cc/trees/clip_node.h" #include "cc/trees/draw_property_utils.h" @@ -17,420 +16,37 @@ namespace cc { namespace { -TEST(PropertyTreeSerializationTest, TransformNodeSerialization) { - TransformNode original; - original.id = 3; - original.parent_id = 2; - original.owner_id = 4; - original.pre_local.Translate3d(1.f, 2.f, 3.f); - original.local.Translate3d(3.f, 1.f, 5.f); - original.post_local.Translate3d(1.f, 8.f, 3.f); - original.to_parent.Translate3d(3.2f, 2.f, 3.f); - original.source_node_id = 5; - original.needs_local_transform_update = false; - original.is_invertible = false; - original.ancestors_are_invertible = false; - original.has_potential_animation = false; - original.to_screen_is_potentially_animated = false; - original.has_only_translation_animations = false; - original.flattens_inherited_transform = false; - original.node_and_ancestors_are_flat = false; - original.node_and_ancestors_have_only_integer_translation = false; - original.scrolls = false; - original.needs_surface_contents_scale = false; - original.affected_by_inner_viewport_bounds_delta_x = false; - original.affected_by_inner_viewport_bounds_delta_y = false; - original.affected_by_outer_viewport_bounds_delta_x = false; - original.affected_by_outer_viewport_bounds_delta_y = false; - original.in_subtree_of_page_scale_layer = false; - original.post_local_scale_factor = 0.5f; - original.surface_contents_scale = gfx::Vector2dF(0.5f, 0.5f); - original.scroll_offset = gfx::ScrollOffset(1.5f, 1.5f); - original.scroll_snap = gfx::Vector2dF(0.4f, 0.4f); - original.source_offset = gfx::Vector2dF(2.5f, 2.4f); - original.source_to_parent = gfx::Vector2dF(3.2f, 3.2f); - - proto::TreeNode proto; - original.ToProtobuf(&proto); - TransformNode result; - result.FromProtobuf(proto); - - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, TransformTreeSerialization) { +TEST(PropertyTreeTest, ComputeTransformRoot) { PropertyTrees property_trees; - TransformTree& original = property_trees.transform_tree; - TransformNode& root = *original.Node(0); - root.id = 0; - root.owner_id = 1; - original.SetTargetId(root.id, 3); - original.SetContentTargetId(root.id, 4); - TransformNode second; - second.owner_id = 2; - second.local.Translate3d(2.f, 2.f, 0.f); - second.source_node_id = 0; - second.id = original.Insert(second, 0); - original.SetTargetId(second.id, 0); - TransformNode third; - third.owner_id = 3; - third.scrolls = true; - third.source_node_id = 1; - third.id = original.Insert(third, 1); - original.SetTargetId(third.id, 0); - - original.set_needs_update(true); - - original.set_page_scale_factor(0.5f); - original.set_device_scale_factor(0.6f); - gfx::Transform transform = - gfx::Transform(1.05f, 2.15f, 3.14f, 4.13f, 5.12f, 6.11f, 7.1f, 8.9f, 9.8f, - 10.7f, 11.6f, 12.5f, 13.4f, 14.3f, 15.2f, 16.1f); - original.SetRootTransformsAndScales(0.6f, 1.f, transform, gfx::PointF()); - original.AddNodeAffectedByInnerViewportBoundsDelta(0); - original.AddNodeAffectedByOuterViewportBoundsDelta(1); - - proto::PropertyTree proto; - original.ToProtobuf(&proto); - TransformTree result; - std::unordered_map<int, int> transform_id_to_index_map; - result.FromProtobuf(proto, &transform_id_to_index_map); - - EXPECT_EQ(transform_id_to_index_map[1], 0); - EXPECT_EQ(transform_id_to_index_map[2], 1); - EXPECT_EQ(transform_id_to_index_map[3], 2); - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, ClipNodeSerialization) { - ClipNode original; - original.id = 3; - original.parent_id = 2; - original.owner_id = 4; - original.clip = gfx::RectF(0.5f, 0.5f); - original.combined_clip_in_target_space = gfx::RectF(0.6f, 0.6f); - original.clip_in_target_space = gfx::RectF(0.7f, 0.7f); - original.transform_id = 2; - original.target_transform_id = 3; - original.target_effect_id = 4; - original.applies_local_clip = false; - original.layer_clipping_uses_only_local_clip = false; - original.target_is_clipped = false; - original.layers_are_clipped = false; - original.layers_are_clipped_when_surfaces_disabled = false; - original.resets_clip = false; - - proto::TreeNode proto; - original.ToProtobuf(&proto); - ClipNode result; - result.FromProtobuf(proto); - - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, ClipTreeSerialization) { - ClipTree original; - ClipNode& root = *original.Node(0); - root.owner_id = 1; - root.transform_id = 2; - root.target_transform_id = 1; - root.target_effect_id = 1; - ClipNode second; - second.owner_id = 2; - second.transform_id = 4; - second.applies_local_clip = true; - ClipNode third; - third.owner_id = 3; - third.target_transform_id = 3; - third.target_effect_id = 2; - third.target_is_clipped = false; - - original.Insert(second, 0); - original.Insert(third, 1); - original.set_needs_update(true); - - proto::PropertyTree proto; - original.ToProtobuf(&proto); - ClipTree result; - std::unordered_map<int, int> clip_id_to_index_map; - result.FromProtobuf(proto, &clip_id_to_index_map); - - EXPECT_EQ(clip_id_to_index_map[1], 0); - EXPECT_EQ(clip_id_to_index_map[2], 1); - EXPECT_EQ(clip_id_to_index_map[3], 2); - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, EffectNodeSerialization) { - EffectNode original; - original.id = 3; - original.parent_id = 2; - original.owner_id = 4; - original.opacity = 0.5f; - original.screen_space_opacity = 0.6f; - original.has_render_surface = false; - original.transform_id = 2; - original.clip_id = 3; - original.mask_layer_id = 6; - original.surface_contents_scale = gfx::Vector2dF(0.5f, 0.5f); - - proto::TreeNode proto; - original.ToProtobuf(&proto); - EffectNode result; - result.FromProtobuf(proto); - - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, EffectTreeSerialization) { - EffectTree original; - EffectNode& root = *original.Node(0); - root.owner_id = 5; - root.transform_id = 2; - root.clip_id = 1; - EffectNode second; - second.owner_id = 6; - second.transform_id = 4; - second.opacity = true; - second.mask_layer_id = 32; - EffectNode third; - third.owner_id = 7; - third.clip_id = 3; - third.has_render_surface = false; - - original.Insert(second, 0); - original.Insert(third, 1); - original.AddMaskLayerId(32); - original.set_needs_update(true); - - proto::PropertyTree proto; - original.ToProtobuf(&proto); - EffectTree result; - std::unordered_map<int, int> effect_id_to_index_map; - result.FromProtobuf(proto, &effect_id_to_index_map); - - EXPECT_EQ(effect_id_to_index_map[5], 0); - EXPECT_EQ(effect_id_to_index_map[6], 1); - EXPECT_EQ(effect_id_to_index_map[7], 2); - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, ScrollNodeSerialization) { - ScrollNode original; - original.id = 3; - original.parent_id = 2; - original.owner_id = 4; - original.scrollable = true; - original.main_thread_scrolling_reasons = - MainThreadScrollingReason::kScrollbarScrolling; - original.contains_non_fast_scrollable_region = false; - original.scroll_clip_layer_bounds = gfx::Size(10, 10); - original.bounds = gfx::Size(15, 15); - original.max_scroll_offset_affected_by_page_scale = true; - original.is_inner_viewport_scroll_layer = true; - original.is_outer_viewport_scroll_layer = false; - - proto::TreeNode proto; - original.ToProtobuf(&proto); - ScrollNode result; - result.FromProtobuf(proto); - - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, ScrollTreeSerialization) { - PropertyTrees property_trees; - property_trees.is_main_thread = true; - ScrollTree& original = property_trees.scroll_tree; - ScrollNode second; - second.owner_id = 10; - second.scrollable = true; - second.bounds = gfx::Size(15, 15); - ScrollNode third; - third.owner_id = 20; - third.contains_non_fast_scrollable_region = true; - - original.Insert(second, 0); - original.Insert(third, 1); - - original.set_currently_scrolling_node(1); - original.SetScrollOffset(1, gfx::ScrollOffset(1, 2)); - - proto::PropertyTree proto; - original.ToProtobuf(&proto); - ScrollTree result; - std::unordered_map<int, int> scroll_id_to_index_map; - result.FromProtobuf(proto, &scroll_id_to_index_map); - - EXPECT_EQ(original, result); - EXPECT_EQ(scroll_id_to_index_map[10], 1); - EXPECT_EQ(scroll_id_to_index_map[20], 2); - - original.clear(); - original.set_currently_scrolling_node(0); - original.SetScrollOffset(2, gfx::ScrollOffset(1, 2)); - - proto::PropertyTree proto2; - original.ToProtobuf(&proto2); - result = ScrollTree(); - scroll_id_to_index_map.clear(); - result.FromProtobuf(proto2, &scroll_id_to_index_map); - - EXPECT_EQ(original, result); -} - -TEST(PropertyTreeSerializationTest, PropertyTrees) { - PropertyTrees original; - TransformNode transform_node1 = TransformNode(); - transform_node1.owner_id = 10; - transform_node1.id = original.transform_tree.Insert(transform_node1, 0); - TransformNode transform_node2 = TransformNode(); - transform_node2.owner_id = 20; - transform_node2.id = original.transform_tree.Insert(transform_node2, 1); - original.transform_id_to_index_map[10] = 1; - original.transform_id_to_index_map[20] = 2; - - ClipNode clip_node1 = ClipNode(); - clip_node1.owner_id = 10; - clip_node1.id = original.clip_tree.Insert(clip_node1, 0); - ClipNode clip_node2 = ClipNode(); - clip_node2.owner_id = 22; - clip_node2.id = original.clip_tree.Insert(clip_node2, 1); - original.clip_id_to_index_map[10] = 1; - original.clip_id_to_index_map[22] = 2; - - EffectNode effect_node1 = EffectNode(); - effect_node1.owner_id = 11; - effect_node1.id = original.effect_tree.Insert(effect_node1, 0); - EffectNode effect_node2 = EffectNode(); - effect_node2.owner_id = 23; - effect_node2.id = original.effect_tree.Insert(effect_node2, 1); - original.effect_id_to_index_map[11] = 1; - original.effect_id_to_index_map[23] = 2; - - ScrollNode scroll_node1 = ScrollNode(); - scroll_node1.owner_id = 10; - scroll_node1.id = original.scroll_tree.Insert(scroll_node1, 0); - ScrollNode scroll_node2 = ScrollNode(); - scroll_node2.owner_id = 20; - scroll_node2.id = original.scroll_tree.Insert(scroll_node2, 1); - original.scroll_id_to_index_map[10] = 1; - original.scroll_id_to_index_map[20] = 2; - - original.needs_rebuild = false; - original.non_root_surfaces_enabled = false; - original.sequence_number = 3; - - proto::PropertyTrees proto; - original.ToProtobuf(&proto); - PropertyTrees result; - result.FromProtobuf(proto); - - EXPECT_EQ(original, result); -} - -class PropertyTreeTest : public testing::Test { - public: - PropertyTreeTest() : test_serialization_(false) {} - - protected: - void RunTest(bool test_serialization) { - test_serialization_ = test_serialization; - StartTest(); - } - - virtual void StartTest() = 0; - - void SetupTransformTreeForTest(TransformTree* transform_tree) { - if (!test_serialization_) - return; - - TransformTree new_tree; - proto::PropertyTree proto; - transform_tree->ToProtobuf(&proto); - std::unordered_map<int, int> transform_id_to_index_map; - new_tree.FromProtobuf(proto, &transform_id_to_index_map); - EXPECT_EQ(*transform_tree, new_tree); - - PropertyTrees* property_trees = transform_tree->property_trees(); - *transform_tree = new_tree; - transform_tree->SetPropertyTrees(property_trees); - } - - void SetupEffectTreeForTest(EffectTree* effect_tree) { - if (!test_serialization_) - return; - - EffectTree new_tree; - proto::PropertyTree proto; - effect_tree->ToProtobuf(&proto); - std::unordered_map<int, int> effect_id_to_index_map; - new_tree.FromProtobuf(proto, &effect_id_to_index_map); - - EXPECT_EQ(*effect_tree, new_tree); - *effect_tree = new_tree; - } - - private: - bool test_serialization_; -}; - -#define DIRECT_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME) \ - TEST_F(TEST_FIXTURE_NAME, RunDirect) { RunTest(false); } - -#define SERIALIZED_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME) \ - TEST_F(TEST_FIXTURE_NAME, RunSerialized) { RunTest(true); } - -#define DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME) \ - DIRECT_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME); \ - SERIALIZED_PROPERTY_TREE_TEST_F(TEST_FIXTURE_NAME) - -class PropertyTreeTestComputeTransformRoot : public PropertyTreeTest { - protected: - void StartTest() override { - PropertyTrees property_trees; - TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - root.id = 0; - root.local.Translate(2, 2); - tree.SetTargetId(root.id, 0); - SetupTransformTreeForTest(&tree); - tree.UpdateTransforms(0); - - gfx::Transform expected; - gfx::Transform transform; - bool success = tree.ComputeTransform(0, 0, &transform); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); - - transform.MakeIdentity(); - expected.Translate(2, 2); - success = tree.ComputeTransform(0, -1, &transform); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); - - transform.MakeIdentity(); - expected.MakeIdentity(); - expected.Translate(-2, -2); - success = tree.ComputeTransform(-1, 0, &transform); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); + TransformTree& tree = property_trees.transform_tree; + TransformNode contents_root; + contents_root.local.Translate(2, 2); + contents_root.source_node_id = 0; + contents_root.id = tree.Insert(contents_root, 0); + tree.SetTargetId(contents_root.id, 0); + tree.UpdateTransforms(1); + + gfx::Transform expected; + gfx::Transform transform; + expected.Translate(2, 2); + tree.CombineTransformsBetween(1, 0, &transform); + EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); + + transform.MakeIdentity(); + expected.MakeIdentity(); + expected.Translate(-2, -2); + bool success = tree.CombineInversesBetween(0, 1, &transform); + EXPECT_TRUE(success); + EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); } -}; - -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestComputeTransformRoot); -class PropertyTreeTestSetNeedsUpdate : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, SetNeedsUpdate) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; TransformNode contents_root; contents_root.source_node_id = 0; contents_root.id = tree.Insert(contents_root, 0); tree.SetTargetId(contents_root.id, 0); - SetupTransformTreeForTest(&tree); EXPECT_FALSE(tree.needs_update()); tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform(), gfx::PointF()); @@ -439,114 +55,94 @@ class PropertyTreeTestSetNeedsUpdate : public PropertyTreeTest { tree.SetRootTransformsAndScales(0.6f, 1.f, gfx::Transform(), gfx::PointF()); EXPECT_FALSE(tree.needs_update()); } -}; -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(PropertyTreeTestSetNeedsUpdate); - -class PropertyTreeTestComputeTransformChild : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, ComputeTransformChild) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - root.local.Translate(2, 2); - tree.SetTargetId(root.id, 0); - tree.UpdateTransforms(0); + TransformNode contents_root; + contents_root.local.Translate(2, 2); + contents_root.source_node_id = 0; + contents_root.id = tree.Insert(contents_root, 0); + tree.SetTargetId(contents_root.id, 0); + tree.UpdateTransforms(contents_root.id); TransformNode child; child.local.Translate(3, 3); - child.source_node_id = 0; - child.id = tree.Insert(child, 0); + child.source_node_id = 1; + child.id = tree.Insert(child, contents_root.id); tree.SetTargetId(child.id, 0); - SetupTransformTreeForTest(&tree); - tree.UpdateTransforms(1); + tree.UpdateTransforms(child.id); gfx::Transform expected; gfx::Transform transform; expected.Translate(3, 3); - bool success = tree.ComputeTransform(1, 0, &transform); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(2, 1, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); transform.MakeIdentity(); expected.MakeIdentity(); expected.Translate(-3, -3); - success = tree.ComputeTransform(0, 1, &transform); + bool success = tree.CombineInversesBetween(1, 2, &transform); EXPECT_TRUE(success); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); transform.MakeIdentity(); expected.MakeIdentity(); expected.Translate(5, 5); - success = tree.ComputeTransform(1, -1, &transform); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(2, 0, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); transform.MakeIdentity(); expected.MakeIdentity(); expected.Translate(-5, -5); - success = tree.ComputeTransform(-1, 1, &transform); + success = tree.CombineInversesBetween(0, 2, &transform); EXPECT_TRUE(success); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); } -}; -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestComputeTransformChild); - -class PropertyTreeTestComputeTransformSibling : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, ComputeTransformSibling) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - root.local.Translate(2, 2); - tree.SetTargetId(root.id, 0); - tree.UpdateTransforms(0); + TransformNode contents_root; + contents_root.source_node_id = 0; + contents_root.local.Translate(2, 2); + contents_root.id = tree.Insert(contents_root, 0); + tree.SetTargetId(contents_root.id, 0); + tree.UpdateTransforms(1); TransformNode child; child.local.Translate(3, 3); - child.source_node_id = 0; - child.id = tree.Insert(child, 0); + child.source_node_id = 1; + child.id = tree.Insert(child, 1); tree.SetTargetId(child.id, 0); TransformNode sibling; sibling.local.Translate(7, 7); - sibling.source_node_id = 0; - sibling.id = tree.Insert(sibling, 0); + sibling.source_node_id = 1; + sibling.id = tree.Insert(sibling, 1); tree.SetTargetId(sibling.id, 0); - SetupTransformTreeForTest(&tree); - - tree.UpdateTransforms(1); tree.UpdateTransforms(2); + tree.UpdateTransforms(3); gfx::Transform expected; gfx::Transform transform; expected.Translate(4, 4); - bool success = tree.ComputeTransform(2, 1, &transform); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(3, 2, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); transform.MakeIdentity(); expected.MakeIdentity(); expected.Translate(-4, -4); - success = tree.ComputeTransform(1, 2, &transform); + bool success = tree.CombineInversesBetween(2, 3, &transform); EXPECT_TRUE(success); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); } -}; -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestComputeTransformSibling); - -class PropertyTreeTestComputeTransformSiblingSingularAncestor - : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, ComputeTransformSiblingSingularAncestor) { // In this test, we have the following tree: // root // + singular @@ -558,60 +154,52 @@ class PropertyTreeTestComputeTransformSiblingSingularAncestor // transforms between these nodes. PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - root.local.Translate(2, 2); - tree.SetTargetId(root.id, 0); - tree.UpdateTransforms(0); + TransformNode contents_root; + contents_root.local.Translate(2, 2); + contents_root.source_node_id = 0; + contents_root.id = tree.Insert(contents_root, 0); + tree.SetTargetId(contents_root.id, 0); + tree.UpdateTransforms(1); TransformNode singular; singular.local.matrix().set(2, 2, 0.0); - singular.source_node_id = 0; - singular.id = tree.Insert(singular, 0); + singular.source_node_id = 1; + singular.id = tree.Insert(singular, 1); tree.SetTargetId(singular.id, 0); TransformNode child; child.local.Translate(3, 3); - child.source_node_id = 1; - child.id = tree.Insert(child, 1); + child.source_node_id = 2; + child.id = tree.Insert(child, 2); tree.SetTargetId(child.id, 0); TransformNode sibling; sibling.local.Translate(7, 7); - sibling.source_node_id = 1; - sibling.id = tree.Insert(sibling, 1); + sibling.source_node_id = 2; + sibling.id = tree.Insert(sibling, 2); tree.SetTargetId(sibling.id, 0); - SetupTransformTreeForTest(&tree); - - tree.UpdateTransforms(1); tree.UpdateTransforms(2); tree.UpdateTransforms(3); + tree.UpdateTransforms(4); gfx::Transform expected; gfx::Transform transform; expected.Translate(4, 4); - bool success = tree.ComputeTransform(3, 2, &transform); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(4, 3, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); transform.MakeIdentity(); expected.MakeIdentity(); expected.Translate(-4, -4); - success = tree.ComputeTransform(2, 3, &transform); + bool success = tree.CombineInversesBetween(3, 4, &transform); EXPECT_TRUE(success); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); } -}; -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestComputeTransformSiblingSingularAncestor); - -class PropertyTreeTestTransformsWithFlattening : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, TransformsWithFlattening) { PropertyTrees property_trees; - property_trees.verify_transform_tree_calculations = true; TransformTree& tree = property_trees.transform_tree; EffectTree& effect_tree = property_trees.effect_tree; @@ -634,7 +222,6 @@ class PropertyTreeTestTransformsWithFlattening : public PropertyTreeTest { effect_tree.Node(effect_parent)->has_render_surface = true; effect_tree.Node(effect_parent)->surface_contents_scale = gfx::Vector2dF(1.f, 1.f); - tree.Node(parent)->needs_surface_contents_scale = true; tree.SetTargetId(parent, grand_parent); tree.SetContentTargetId(parent, parent); tree.Node(parent)->source_node_id = grand_parent; @@ -655,22 +242,22 @@ class PropertyTreeTestTransformsWithFlattening : public PropertyTreeTest { tree.Node(grand_child)->local = rotation_about_x; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); property_trees.ResetCachedData(); gfx::Transform flattened_rotation_about_x = rotation_about_x; flattened_rotation_about_x.FlattenTo2d(); - EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, - tree.ToTarget(child, effect_parent)); + gfx::Transform to_target; + property_trees.GetToTarget(child, effect_parent, &to_target); + EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, to_target); EXPECT_TRANSFORMATION_MATRIX_EQ( flattened_rotation_about_x * rotation_about_x, tree.ToScreen(child)); + property_trees.GetToTarget(grand_child, effect_parent, &to_target); EXPECT_TRANSFORMATION_MATRIX_EQ( - flattened_rotation_about_x * rotation_about_x, - tree.ToTarget(grand_child, effect_parent)); + flattened_rotation_about_x * rotation_about_x, to_target); EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x * flattened_rotation_about_x * @@ -678,51 +265,44 @@ class PropertyTreeTestTransformsWithFlattening : public PropertyTreeTest { tree.ToScreen(grand_child)); gfx::Transform grand_child_to_child; - bool success = - tree.ComputeTransform(grand_child, child, &grand_child_to_child); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(grand_child, child, &grand_child_to_child); EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, grand_child_to_child); // Remove flattening at grand_child, and recompute transforms. tree.Node(grand_child)->flattens_inherited_transform = false; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); + property_trees.GetToTarget(grand_child, effect_parent, &to_target); EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x * rotation_about_x, - tree.ToTarget(grand_child, effect_parent)); + to_target); EXPECT_TRANSFORMATION_MATRIX_EQ( flattened_rotation_about_x * rotation_about_x * rotation_about_x, tree.ToScreen(grand_child)); - success = tree.ComputeTransform(grand_child, child, &grand_child_to_child); - EXPECT_TRUE(success); + grand_child_to_child.MakeIdentity(); + tree.CombineTransformsBetween(grand_child, child, &grand_child_to_child); EXPECT_TRANSFORMATION_MATRIX_EQ(rotation_about_x, grand_child_to_child); } -}; - -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestTransformsWithFlattening); -class PropertyTreeTestMultiplicationOrder : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, MultiplicationOrder) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - root.local.Translate(2, 2); - tree.SetTargetId(root.id, 0); - tree.UpdateTransforms(0); + TransformNode contents_root; + contents_root.local.Translate(2, 2); + contents_root.source_node_id = 0; + contents_root.id = tree.Insert(contents_root, 0); + tree.SetTargetId(contents_root.id, 0); + tree.UpdateTransforms(1); TransformNode child; child.local.Scale(2, 2); - child.source_node_id = 0; - child.id = tree.Insert(child, 0); + child.source_node_id = 1; + child.id = tree.Insert(child, 1); tree.SetTargetId(child.id, 0); - SetupTransformTreeForTest(&tree); - tree.UpdateTransforms(1); + tree.UpdateTransforms(2); gfx::Transform expected; expected.Translate(2, 2); @@ -731,39 +311,33 @@ class PropertyTreeTestMultiplicationOrder : public PropertyTreeTest { gfx::Transform transform; gfx::Transform inverse; - bool success = tree.ComputeTransform(1, -1, &transform); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(2, 0, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); - success = tree.ComputeTransform(-1, 1, &inverse); + bool success = tree.CombineInversesBetween(0, 2, &inverse); EXPECT_TRUE(success); transform = transform * inverse; expected.MakeIdentity(); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); } -}; -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F(PropertyTreeTestMultiplicationOrder); - -class PropertyTreeTestComputeTransformWithUninvertibleTransform - : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, ComputeTransformWithUninvertibleTransform) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - tree.SetTargetId(root.id, 0); - tree.UpdateTransforms(0); + TransformNode contents_root; + contents_root.source_node_id = 0; + contents_root.id = tree.Insert(contents_root, 0); + tree.SetTargetId(contents_root.id, 0); + tree.UpdateTransforms(1); TransformNode child; child.local.Scale(0, 0); - child.source_node_id = 0; - child.id = tree.Insert(child, 0); + child.source_node_id = 1; + child.id = tree.Insert(child, 1); tree.SetTargetId(child.id, 0); - SetupTransformTreeForTest(&tree); - tree.UpdateTransforms(1); + tree.UpdateTransforms(2); gfx::Transform expected; expected.Scale(0, 0); @@ -771,175 +345,28 @@ class PropertyTreeTestComputeTransformWithUninvertibleTransform gfx::Transform transform; gfx::Transform inverse; - bool success = tree.ComputeTransform(1, 0, &transform); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(2, 1, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected, transform); // To compute this would require inverting the 0 matrix, so we cannot // succeed. - success = tree.ComputeTransform(0, 1, &inverse); + bool success = tree.CombineInversesBetween(1, 2, &inverse); EXPECT_FALSE(success); } -}; - -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestComputeTransformWithUninvertibleTransform); - -class PropertyTreeTestComputeTransformWithSurfaceContentsScale - : public PropertyTreeTest { - protected: - void StartTest() override { - PropertyTrees property_trees; - TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - root.id = 0; - tree.SetTargetId(root.id, 0); - tree.UpdateTransforms(0); - - TransformNode grand_parent; - grand_parent.local.Scale(2.f, 2.f); - grand_parent.source_node_id = 0; - grand_parent.needs_surface_contents_scale = true; - int grand_parent_id = tree.Insert(grand_parent, 0); - tree.SetTargetId(grand_parent_id, 0); - tree.UpdateTransforms(grand_parent_id); - - TransformNode parent; - parent.local.Translate(15.f, 15.f); - parent.source_node_id = grand_parent_id; - int parent_id = tree.Insert(parent, grand_parent_id); - tree.SetTargetId(parent_id, grand_parent_id); - tree.UpdateTransforms(parent_id); - - TransformNode child; - child.local.Scale(3.f, 3.f); - child.source_node_id = parent_id; - int child_id = tree.Insert(child, parent_id); - tree.SetTargetId(child_id, grand_parent_id); - tree.UpdateTransforms(child_id); - - TransformNode grand_child; - grand_child.local.Scale(5.f, 5.f); - grand_child.source_node_id = child_id; - grand_child.needs_surface_contents_scale = true; - int grand_child_id = tree.Insert(grand_child, child_id); - tree.SetTargetId(grand_child_id, grand_parent_id); - SetupTransformTreeForTest(&tree); - tree.UpdateTransforms(grand_child_id); - - EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), - tree.Node(grand_parent_id)->surface_contents_scale); - EXPECT_EQ(gfx::Vector2dF(30.f, 30.f), - tree.Node(grand_child_id)->surface_contents_scale); - - // Compute transform from grand_parent to grand_child. - gfx::Transform expected_transform_without_surface_contents_scale; - expected_transform_without_surface_contents_scale.Scale(1.f / 15.f, - 1.f / 15.f); - expected_transform_without_surface_contents_scale.Translate(-15.f, -15.f); - - gfx::Transform expected_transform_with_dest_surface_contents_scale; - expected_transform_with_dest_surface_contents_scale.Scale(30.f, 30.f); - expected_transform_with_dest_surface_contents_scale.Scale(1.f / 15.f, - 1.f / 15.f); - expected_transform_with_dest_surface_contents_scale.Translate(-15.f, -15.f); - - gfx::Transform expected_transform_with_source_surface_contents_scale; - expected_transform_with_source_surface_contents_scale.Scale(1.f / 15.f, - 1.f / 15.f); - expected_transform_with_source_surface_contents_scale.Translate(-15.f, - -15.f); - expected_transform_with_source_surface_contents_scale.Scale(0.5f, 0.5f); - - gfx::Transform transform; - bool success = - tree.ComputeTransform(grand_parent_id, grand_child_id, &transform); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_transform_without_surface_contents_scale, transform); - - success = - tree.ComputeTransform(grand_parent_id, grand_child_id, &transform); - const TransformNode* grand_child_node = tree.Node(grand_child_id); - transform.matrix().postScale(grand_child_node->surface_contents_scale.x(), - grand_child_node->surface_contents_scale.y(), - 1.f); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_transform_with_dest_surface_contents_scale, transform); - - success = - tree.ComputeTransform(grand_parent_id, grand_child_id, &transform); - const TransformNode* grand_parent_node = tree.Node(grand_parent_id); - EXPECT_NE(grand_parent_node->surface_contents_scale.x(), 0.f); - EXPECT_NE(grand_parent_node->surface_contents_scale.y(), 0.f); - transform.Scale(1.0 / grand_parent_node->surface_contents_scale.x(), - 1.0 / grand_parent_node->surface_contents_scale.y()); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_transform_with_source_surface_contents_scale, transform); - - // Now compute transform from grand_child to grand_parent. - expected_transform_without_surface_contents_scale.MakeIdentity(); - expected_transform_without_surface_contents_scale.Translate(15.f, 15.f); - expected_transform_without_surface_contents_scale.Scale(15.f, 15.f); - - expected_transform_with_dest_surface_contents_scale.MakeIdentity(); - expected_transform_with_dest_surface_contents_scale.Scale(2.f, 2.f); - expected_transform_with_dest_surface_contents_scale.Translate(15.f, 15.f); - expected_transform_with_dest_surface_contents_scale.Scale(15.f, 15.f); - - expected_transform_with_source_surface_contents_scale.MakeIdentity(); - expected_transform_with_source_surface_contents_scale.Translate(15.f, 15.f); - expected_transform_with_source_surface_contents_scale.Scale(15.f, 15.f); - expected_transform_with_source_surface_contents_scale.Scale(1.f / 30.f, - 1.f / 30.f); - - success = - tree.ComputeTransform(grand_child_id, grand_parent_id, &transform); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_transform_without_surface_contents_scale, transform); - - success = - tree.ComputeTransform(grand_child_id, grand_parent_id, &transform); - transform.matrix().postScale(grand_parent_node->surface_contents_scale.x(), - grand_parent_node->surface_contents_scale.y(), - 1.f); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_transform_with_dest_surface_contents_scale, transform); - - success = - tree.ComputeTransform(grand_child_id, grand_parent_id, &transform); - EXPECT_NE(grand_child_node->surface_contents_scale.x(), 0.f); - EXPECT_NE(grand_child_node->surface_contents_scale.y(), 0.f); - transform.Scale(1.0 / grand_child_node->surface_contents_scale.x(), - 1.0 / grand_child_node->surface_contents_scale.y()); - EXPECT_TRUE(success); - EXPECT_TRANSFORMATION_MATRIX_EQ( - expected_transform_with_source_surface_contents_scale, transform); - } -}; - -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestComputeTransformWithSurfaceContentsScale); -class PropertyTreeTestComputeTransformToTargetWithZeroSurfaceContentsScale - : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, ComputeTransformToTargetWithZeroSurfaceContentsScale) { PropertyTrees property_trees; TransformTree& tree = property_trees.transform_tree; - TransformNode& root = *tree.Node(0); - tree.SetTargetId(root.id, 0); - tree.UpdateTransforms(0); + TransformNode contents_root; + contents_root.source_node_id = 0; + contents_root.id = tree.Insert(contents_root, 0); + tree.SetTargetId(contents_root.id, 0); + tree.UpdateTransforms(1); TransformNode grand_parent; grand_parent.local.Scale(2.f, 0.f); - grand_parent.source_node_id = 0; - grand_parent.needs_surface_contents_scale = true; - int grand_parent_id = tree.Insert(grand_parent, 0); + grand_parent.source_node_id = 1; + int grand_parent_id = tree.Insert(grand_parent, 1); tree.SetTargetId(grand_parent_id, 0); tree.SetContentTargetId(grand_parent_id, grand_parent_id); tree.UpdateTransforms(grand_parent_id); @@ -958,50 +385,39 @@ class PropertyTreeTestComputeTransformToTargetWithZeroSurfaceContentsScale int child_id = tree.Insert(child, parent_id); tree.SetTargetId(child_id, grand_parent_id); tree.SetContentTargetId(child_id, grand_parent_id); - SetupTransformTreeForTest(&tree); tree.UpdateTransforms(child_id); gfx::Transform expected_transform; expected_transform.Translate(4.f, 5.f); gfx::Transform transform; - bool success = tree.ComputeTransform(child_id, grand_parent_id, &transform); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(child_id, grand_parent_id, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform); tree.Node(grand_parent_id)->local.MakeIdentity(); tree.Node(grand_parent_id)->local.Scale(0.f, 2.f); tree.Node(grand_parent_id)->needs_local_transform_update = true; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); - success = tree.ComputeTransform(child_id, grand_parent_id, &transform); - EXPECT_TRUE(success); + transform.MakeIdentity(); + tree.CombineTransformsBetween(child_id, grand_parent_id, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform); tree.Node(grand_parent_id)->local.MakeIdentity(); tree.Node(grand_parent_id)->local.Scale(0.f, 0.f); tree.Node(grand_parent_id)->needs_local_transform_update = true; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); - success = tree.ComputeTransform(child_id, grand_parent_id, &transform); - EXPECT_TRUE(success); + transform.MakeIdentity(); + tree.CombineTransformsBetween(child_id, grand_parent_id, &transform); EXPECT_TRANSFORMATION_MATRIX_EQ(expected_transform, transform); } -}; -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestComputeTransformToTargetWithZeroSurfaceContentsScale); - -class PropertyTreeTestFlatteningWhenDestinationHasOnlyFlatAncestors - : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, FlatteningWhenDestinationHasOnlyFlatAncestors) { // This tests that flattening is performed correctly when // destination and its ancestors are flat, but there are 3d transforms // and flattening between the source and destination. @@ -1030,56 +446,39 @@ class PropertyTreeTestFlatteningWhenDestinationHasOnlyFlatAncestors tree.Node(grand_child)->flattens_inherited_transform = true; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); gfx::Transform flattened_rotation_about_x = rotation_about_x; flattened_rotation_about_x.FlattenTo2d(); gfx::Transform grand_child_to_parent; - bool success = - tree.ComputeTransform(grand_child, parent, &grand_child_to_parent); - EXPECT_TRUE(success); + tree.CombineTransformsBetween(grand_child, parent, &grand_child_to_parent); EXPECT_TRANSFORMATION_MATRIX_EQ(flattened_rotation_about_x, grand_child_to_parent); } -}; - -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestFlatteningWhenDestinationHasOnlyFlatAncestors); -class PropertyTreeTestScreenSpaceOpacityUpdateTest : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, ScreenSpaceOpacityUpdateTest) { // This tests that screen space opacity is updated for the subtree when // opacity of a node changes. - EffectTree tree; + PropertyTrees property_trees; + EffectTree& tree = property_trees.effect_tree; int parent = tree.Insert(EffectNode(), 0); int child = tree.Insert(EffectNode(), parent); - SetupEffectTreeForTest(&tree); EXPECT_EQ(tree.Node(child)->screen_space_opacity, 1.f); tree.Node(parent)->opacity = 0.5f; tree.set_needs_update(true); - SetupEffectTreeForTest(&tree); draw_property_utils::ComputeEffects(&tree); EXPECT_EQ(tree.Node(child)->screen_space_opacity, 0.5f); tree.Node(child)->opacity = 0.5f; tree.set_needs_update(true); - SetupEffectTreeForTest(&tree); draw_property_utils::ComputeEffects(&tree); EXPECT_EQ(tree.Node(child)->screen_space_opacity, 0.25f); } -}; - -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestScreenSpaceOpacityUpdateTest); -class PropertyTreeTestNonIntegerTranslationTest : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, NonIntegerTranslationTest) { // This tests that when a node has non-integer translation, the information // is propagated to the subtree. PropertyTrees property_trees; @@ -1095,7 +494,6 @@ class PropertyTreeTestNonIntegerTranslationTest : public PropertyTreeTest { tree.Node(child)->local.Translate(1, 1); tree.Node(child)->source_node_id = parent; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); EXPECT_FALSE( tree.Node(parent)->node_and_ancestors_have_only_integer_translation); @@ -1107,7 +505,6 @@ class PropertyTreeTestNonIntegerTranslationTest : public PropertyTreeTest { tree.Node(parent)->needs_local_transform_update = true; tree.Node(child)->needs_local_transform_update = true; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); EXPECT_TRUE( tree.Node(parent)->node_and_ancestors_have_only_integer_translation); @@ -1118,25 +515,17 @@ class PropertyTreeTestNonIntegerTranslationTest : public PropertyTreeTest { tree.Node(child)->needs_local_transform_update = true; tree.SetTargetId(child, child); tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); EXPECT_TRUE( tree.Node(parent)->node_and_ancestors_have_only_integer_translation); EXPECT_TRUE( tree.Node(child)->node_and_ancestors_have_only_integer_translation); } -}; -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestNonIntegerTranslationTest); - -class PropertyTreeTestSingularTransformSnapTest : public PropertyTreeTest { - protected: - void StartTest() override { + TEST(PropertyTreeTest, SingularTransformSnapTest) { // This tests that to_target transform is not snapped when it has a singular // transform. PropertyTrees property_trees; - property_trees.verify_transform_tree_calculations = true; TransformTree& tree = property_trees.transform_tree; EffectTree& effect_tree = property_trees.effect_tree; @@ -1145,7 +534,6 @@ class PropertyTreeTestSingularTransformSnapTest : public PropertyTreeTest { effect_tree.Node(effect_parent)->has_render_surface = true; effect_tree.Node(effect_parent)->surface_contents_scale = gfx::Vector2dF(1.f, 1.f); - tree.SetTargetId(parent, parent); tree.Node(parent)->scrolls = true; tree.Node(parent)->source_node_id = 0; @@ -1159,32 +547,28 @@ class PropertyTreeTestSingularTransformSnapTest : public PropertyTreeTest { child_node->source_node_id = parent; tree.set_needs_update(true); - SetupTransformTreeForTest(&tree); draw_property_utils::ComputeTransforms(&tree); property_trees.ResetCachedData(); gfx::Transform from_target; - EXPECT_FALSE(tree.ToTarget(child, effect_parent).GetInverse(&from_target)); + gfx::Transform to_target; + property_trees.GetToTarget(child, effect_parent, &to_target); + EXPECT_FALSE(to_target.GetInverse(&from_target)); // The following checks are to ensure that snapping is skipped because of // singular transform (and not because of other reasons which also cause // snapping to be skipped). EXPECT_TRUE(child_node->scrolls); - EXPECT_TRUE(tree.ToTarget(child, effect_parent).IsScaleOrTranslation()); + property_trees.GetToTarget(child, effect_parent, &to_target); + EXPECT_TRUE(to_target.IsScaleOrTranslation()); EXPECT_FALSE(child_node->to_screen_is_potentially_animated); EXPECT_FALSE(child_node->ancestors_are_invertible); - gfx::Transform rounded = tree.ToTarget(child, effect_parent); + gfx::Transform rounded; + property_trees.GetToTarget(child, effect_parent, &rounded); rounded.RoundTranslationComponents(); - EXPECT_NE(tree.ToTarget(child, effect_parent), rounded); + property_trees.GetToTarget(child, effect_parent, &to_target); + EXPECT_NE(to_target, rounded); } -}; - -DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F( - PropertyTreeTestSingularTransformSnapTest); - -#undef DIRECT_AND_SERIALIZED_PROPERTY_TREE_TEST_F -#undef SERIALIZED_PROPERTY_TREE_TEST_F -#undef DIRECT_PROPERTY_TREE_TEST_F } // namespace } // namespace cc diff --git a/chromium/cc/trees/proxy.h b/chromium/cc/trees/proxy.h index 53381d9dfe7..e49dc774b77 100644 --- a/chromium/cc/trees/proxy.h +++ b/chromium/cc/trees/proxy.h @@ -14,18 +14,15 @@ #include "base/time/time.h" #include "base/values.h" #include "cc/base/cc_export.h" -#include "cc/input/top_controls_state.h" +#include "cc/input/browser_controls_state.h" #include "cc/scheduler/begin_frame_source.h" #include "cc/trees/task_runner_provider.h" namespace gfx { class Rect; -class Vector2d; } namespace cc { -class BeginFrameSource; -class LayerTreeDebugState; class LayerTreeMutator; class CompositorFrameSink; @@ -73,9 +70,9 @@ class CC_EXPORT Proxy { virtual bool SupportsImplScrolling() const = 0; - virtual void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) = 0; + virtual void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) = 0; // Testing hooks virtual bool MainFrameWillHappenForTesting() = 0; diff --git a/chromium/cc/trees/proxy_common.cc b/chromium/cc/trees/proxy_common.cc index be80dd52733..ab9c87be5b6 100644 --- a/chromium/cc/trees/proxy_common.cc +++ b/chromium/cc/trees/proxy_common.cc @@ -4,7 +4,6 @@ #include "cc/trees/proxy_common.h" -#include "cc/proto/begin_main_frame_and_commit_state.pb.h" #include "cc/trees/layer_tree_host.h" namespace cc { @@ -13,23 +12,4 @@ BeginMainFrameAndCommitState::BeginMainFrameAndCommitState() {} BeginMainFrameAndCommitState::~BeginMainFrameAndCommitState() {} -void BeginMainFrameAndCommitState::ToProtobuf( - proto::BeginMainFrameAndCommitState* proto) const { - proto->set_begin_frame_id(begin_frame_id); - begin_frame_args.ToProtobuf(proto->mutable_begin_frame_args()); - scroll_info->ToProtobuf(proto->mutable_scroll_info()); - proto->set_memory_allocation_limit_bytes(memory_allocation_limit_bytes); - proto->set_evicted_ui_resources(evicted_ui_resources); -} - -void BeginMainFrameAndCommitState::FromProtobuf( - const proto::BeginMainFrameAndCommitState& proto) { - begin_frame_id = proto.begin_frame_id(); - begin_frame_args.FromProtobuf(proto.begin_frame_args()); - scroll_info.reset(new ScrollAndScaleSet()); - scroll_info->FromProtobuf(proto.scroll_info()); - memory_allocation_limit_bytes = proto.memory_allocation_limit_bytes(); - evicted_ui_resources = proto.evicted_ui_resources(); -} - } // namespace cc diff --git a/chromium/cc/trees/proxy_common.h b/chromium/cc/trees/proxy_common.h index 42156f7ec05..69ffcfda262 100644 --- a/chromium/cc/trees/proxy_common.h +++ b/chromium/cc/trees/proxy_common.h @@ -14,12 +14,6 @@ namespace cc { -namespace proto { -class BeginMainFrameAndCommitState; -} - -class LayerTreeHost; - using BeginFrameCallbackList = std::vector<base::Closure>; struct CC_EXPORT BeginMainFrameAndCommitState { @@ -32,9 +26,6 @@ struct CC_EXPORT BeginMainFrameAndCommitState { std::unique_ptr<ScrollAndScaleSet> scroll_info; size_t memory_allocation_limit_bytes = 0; bool evicted_ui_resources = false; - - void ToProtobuf(proto::BeginMainFrameAndCommitState* proto) const; - void FromProtobuf(const proto::BeginMainFrameAndCommitState& proto); }; } // namespace cc diff --git a/chromium/cc/trees/proxy_common_unittest.cc b/chromium/cc/trees/proxy_common_unittest.cc deleted file mode 100644 index 3b47eb87a7c..00000000000 --- a/chromium/cc/trees/proxy_common_unittest.cc +++ /dev/null @@ -1,58 +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/trees/proxy_common.h" - -#include "cc/proto/begin_main_frame_and_commit_state.pb.h" -#include "cc/test/begin_frame_args_test.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace cc { -namespace { - -TEST(ProxyCommonUnittest, SerializeBeginMainFrameAndCommitState) { - BeginMainFrameAndCommitState begin_main_frame_state; - begin_main_frame_state.begin_frame_id = 5; - - begin_main_frame_state.begin_frame_args = BeginFrameArgs::Create( - BEGINFRAME_FROM_HERE, base::TimeTicks::FromInternalValue(4), - base::TimeTicks::FromInternalValue(7), - base::TimeDelta::FromInternalValue(9), BeginFrameArgs::NORMAL); - begin_main_frame_state.begin_frame_args.on_critical_path = false; - - LayerTreeHostCommon::ScrollUpdateInfo scroll1; - scroll1.layer_id = 1; - scroll1.scroll_delta = gfx::Vector2d(5, 10); - LayerTreeHostCommon::ScrollUpdateInfo scroll2; - scroll2.layer_id = 2; - scroll2.scroll_delta = gfx::Vector2d(1, 5); - begin_main_frame_state.scroll_info.reset(new ScrollAndScaleSet()); - begin_main_frame_state.scroll_info->scrolls.push_back(scroll1); - begin_main_frame_state.scroll_info->scrolls.push_back(scroll2); - - begin_main_frame_state.scroll_info->page_scale_delta = 0.3f; - begin_main_frame_state.scroll_info->elastic_overscroll_delta = - gfx::Vector2dF(0.5f, 0.6f); - begin_main_frame_state.scroll_info->top_controls_delta = 0.9f; - - begin_main_frame_state.evicted_ui_resources = false; - - proto::BeginMainFrameAndCommitState proto; - begin_main_frame_state.ToProtobuf(&proto); - - BeginMainFrameAndCommitState new_begin_main_frame_state; - new_begin_main_frame_state.FromProtobuf(proto); - - EXPECT_EQ(new_begin_main_frame_state.begin_frame_id, - begin_main_frame_state.begin_frame_id); - EXPECT_EQ(new_begin_main_frame_state.begin_frame_args, - begin_main_frame_state.begin_frame_args); - EXPECT_TRUE(begin_main_frame_state.scroll_info->EqualsForTesting( - *new_begin_main_frame_state.scroll_info.get())); - EXPECT_EQ(new_begin_main_frame_state.evicted_ui_resources, - begin_main_frame_state.evicted_ui_resources); -} - -} // namespace -} // namespace cc diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc index fcefcec6594..710a80b1dd7 100644 --- a/chromium/cc/trees/proxy_impl.cc +++ b/chromium/cc/trees/proxy_impl.cc @@ -12,16 +12,16 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "base/trace_event/trace_event_synthetic_delay.h" -#include "cc/animation/animation_events.h" #include "cc/debug/benchmark_instrumentation.h" #include "cc/debug/devtools_instrumentation.h" -#include "cc/input/top_controls_manager.h" +#include "cc/input/browser_controls_offset_manager.h" #include "cc/output/compositor_frame_sink.h" #include "cc/output/context_provider.h" #include "cc/scheduler/compositor_timing_history.h" #include "cc/scheduler/delay_based_time_source.h" #include "cc/trees/layer_tree_host_in_process.h" #include "cc/trees/layer_tree_impl.h" +#include "cc/trees/mutator_host.h" #include "cc/trees/task_runner_provider.h" #include "gpu/command_buffer/client/gles2_interface.h" @@ -90,11 +90,12 @@ ProxyImpl::~ProxyImpl() { DCHECK(IsImplThread()); DCHECK(IsMainThreadBlocked()); + // Prevent the scheduler from performing actions while we're in an + // inconsistent state. + scheduler_->Stop(); // Take away the CompositorFrameSink before destroying things so it doesn't // try to call into its client mid-shutdown. - scheduler_->DidLoseCompositorFrameSink(); layer_tree_host_impl_->ReleaseCompositorFrameSink(); - scheduler_ = nullptr; layer_tree_host_impl_ = nullptr; // We need to explicitly shutdown the notifier to destroy any weakptrs it is @@ -110,11 +111,12 @@ void ProxyImpl::InitializeMutatorOnImpl( layer_tree_host_impl_->SetLayerTreeMutator(std::move(mutator)); } -void ProxyImpl::UpdateTopControlsStateOnImpl(TopControlsState constraints, - TopControlsState current, - bool animate) { +void ProxyImpl::UpdateBrowserControlsStateOnImpl( + BrowserControlsState constraints, + BrowserControlsState current, + bool animate) { DCHECK(IsImplThread()); - layer_tree_host_impl_->top_controls_manager()->UpdateTopControlsState( + layer_tree_host_impl_->browser_controls_manager()->UpdateBrowserControlsState( constraints, current, animate); } @@ -267,11 +269,12 @@ void ProxyImpl::SetBeginFrameSource(BeginFrameSource* source) { } } -void ProxyImpl::DidSwapBuffersCompleteOnImplThread() { - TRACE_EVENT0("cc,benchmark", "ProxyImpl::DidSwapBuffersCompleteOnImplThread"); +void ProxyImpl::DidReceiveCompositorFrameAckOnImplThread() { + TRACE_EVENT0("cc,benchmark", + "ProxyImpl::DidReceiveCompositorFrameAckOnImplThread"); DCHECK(IsImplThread()); - scheduler_->DidSwapBuffersComplete(); - channel_impl_->DidCompleteSwapBuffers(); + scheduler_->DidReceiveCompositorFrameAck(); + channel_impl_->DidReceiveCompositorFrameAck(); } void ProxyImpl::OnCanDrawStateChanged(bool can_draw) { @@ -325,7 +328,7 @@ void ProxyImpl::SetVideoNeedsBeginFrames(bool needs_begin_frames) { } void ProxyImpl::PostAnimationEventsToMainThreadOnImplThread( - std::unique_ptr<AnimationEvents> events) { + std::unique_ptr<MutatorEvents> events) { TRACE_EVENT0("cc", "ProxyImpl::PostAnimationEventsToMainThreadOnImplThread"); DCHECK(IsImplThread()); channel_impl_->SetAnimationEvents(std::move(events)); @@ -447,24 +450,22 @@ void ProxyImpl::ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) { devtools_instrumentation::DidRequestMainThreadFrame(layer_tree_host_id_); } -DrawResult ProxyImpl::ScheduledActionDrawAndSwapIfPossible() { - TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionDrawAndSwap"); +DrawResult ProxyImpl::ScheduledActionDrawIfPossible() { + TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionDraw"); DCHECK(IsImplThread()); - // SchedulerStateMachine::DidDrawIfPossibleCompleted isn't set up to - // handle DRAW_ABORTED_CANT_DRAW. Moreover, the scheduler should - // never generate this call when it can't draw. + // The scheduler should never generate this call when it can't draw. DCHECK(layer_tree_host_impl_->CanDraw()); bool forced_draw = false; - return DrawAndSwapInternal(forced_draw); + return DrawInternal(forced_draw); } -DrawResult ProxyImpl::ScheduledActionDrawAndSwapForced() { - TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionDrawAndSwapForced"); +DrawResult ProxyImpl::ScheduledActionDrawForced() { + TRACE_EVENT0("cc", "ProxyImpl::ScheduledActionDrawForced"); DCHECK(IsImplThread()); bool forced_draw = true; - return DrawAndSwapInternal(forced_draw); + return DrawInternal(forced_draw); } void ProxyImpl::ScheduledActionCommit() { @@ -537,8 +538,8 @@ void ProxyImpl::SendBeginMainFrameNotExpectedSoon() { channel_impl_->BeginMainFrameNotExpectedSoon(); } -DrawResult ProxyImpl::DrawAndSwapInternal(bool forced_draw) { - TRACE_EVENT_SYNTHETIC_DELAY("cc.DrawAndSwap"); +DrawResult ProxyImpl::DrawInternal(bool forced_draw) { + TRACE_EVENT_SYNTHETIC_DELAY("cc.Draw"); DCHECK(IsImplThread()); DCHECK(layer_tree_host_impl_.get()); @@ -575,7 +576,8 @@ DrawResult ProxyImpl::DrawAndSwapInternal(bool forced_draw) { if (draw_frame) { if (layer_tree_host_impl_->DrawLayers(&frame)) - scheduler_->DidSwapBuffers(); + // Drawing implies we submitted a frame to the CompositorFrameSink. + scheduler_->DidSubmitCompositorFrame(); result = DRAW_SUCCESS; } else { DCHECK_NE(DRAW_SUCCESS, result); diff --git a/chromium/cc/trees/proxy_impl.h b/chromium/cc/trees/proxy_impl.h index ed1e10edf0b..d6c20c10db8 100644 --- a/chromium/cc/trees/proxy_impl.h +++ b/chromium/cc/trees/proxy_impl.h @@ -10,7 +10,7 @@ #include "base/macros.h" #include "cc/base/completion_event.h" #include "cc/base/delayed_unique_notifier.h" -#include "cc/input/top_controls_state.h" +#include "cc/input/browser_controls_state.h" #include "cc/scheduler/scheduler.h" #include "cc/trees/channel_impl.h" #include "cc/trees/layer_tree_host_impl.h" @@ -30,9 +30,9 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), ~ProxyImpl() override; // Virtual for testing. - void UpdateTopControlsStateOnImpl(TopControlsState constraints, - TopControlsState current, - bool animate); + void UpdateBrowserControlsStateOnImpl(BrowserControlsState constraints, + BrowserControlsState current, + bool animate); void InitializeCompositorFrameSinkOnImpl( CompositorFrameSink* compositor_frame_sink); void InitializeMutatorOnImpl(std::unique_ptr<LayerTreeMutator> mutator); @@ -68,7 +68,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), // LayerTreeHostImplClient implementation void DidLoseCompositorFrameSinkOnImplThread() override; void SetBeginFrameSource(BeginFrameSource* source) override; - void DidSwapBuffersCompleteOnImplThread() override; + void DidReceiveCompositorFrameAckOnImplThread() override; void OnCanDrawStateChanged(bool can_draw) override; void NotifyReadyToActivate() override; void NotifyReadyToDraw() override; @@ -80,7 +80,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void SetNeedsCommitOnImplThread() override; void SetVideoNeedsBeginFrames(bool needs_begin_frames) override; void PostAnimationEventsToMainThreadOnImplThread( - std::unique_ptr<AnimationEvents> events) override; + std::unique_ptr<MutatorEvents> events) override; bool IsInsideDraw() override; void RenewTreePriority() override; void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -95,8 +95,8 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void WillBeginImplFrame(const BeginFrameArgs& args) override; void DidFinishImplFrame() override; void ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) override; - DrawResult ScheduledActionDrawAndSwapIfPossible() override; - DrawResult ScheduledActionDrawAndSwapForced() override; + DrawResult ScheduledActionDrawIfPossible() override; + DrawResult ScheduledActionDrawForced() override; void ScheduledActionCommit() override; void ScheduledActionActivateSyncTree() override; void ScheduledActionBeginCompositorFrameSinkCreation() override; @@ -104,7 +104,7 @@ class CC_EXPORT ProxyImpl : public NON_EXPORTED_BASE(LayerTreeHostImplClient), void ScheduledActionInvalidateCompositorFrameSink() override; void SendBeginMainFrameNotExpectedSoon() override; - DrawResult DrawAndSwapInternal(bool forced_draw); + DrawResult DrawInternal(bool forced_draw); bool IsImplThread() const; bool IsMainThreadBlocked() const; diff --git a/chromium/cc/trees/proxy_main.cc b/chromium/cc/trees/proxy_main.cc index e02a86b8776..513f84dc9ff 100644 --- a/chromium/cc/trees/proxy_main.cc +++ b/chromium/cc/trees/proxy_main.cc @@ -10,7 +10,6 @@ #include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event_argument.h" #include "base/trace_event/trace_event_synthetic_delay.h" -#include "cc/animation/animation_events.h" #include "cc/debug/benchmark_instrumentation.h" #include "cc/debug/devtools_instrumentation.h" #include "cc/output/compositor_frame_sink.h" @@ -18,7 +17,7 @@ #include "cc/resources/ui_resource_manager.h" #include "cc/trees/blocking_task_runner.h" #include "cc/trees/layer_tree_host_in_process.h" -#include "cc/trees/remote_channel_main.h" +#include "cc/trees/mutator_host.h" #include "cc/trees/scoped_abort_remaining_swap_promises.h" #include "cc/trees/threaded_channel.h" @@ -34,17 +33,6 @@ std::unique_ptr<ProxyMain> ProxyMain::CreateThreaded( return proxy_main; } -std::unique_ptr<ProxyMain> ProxyMain::CreateRemote( - RemoteProtoChannel* remote_proto_channel, - LayerTreeHostInProcess* layer_tree_host, - TaskRunnerProvider* task_runner_provider) { - std::unique_ptr<ProxyMain> proxy_main( - new ProxyMain(layer_tree_host, task_runner_provider)); - proxy_main->SetChannel(RemoteChannelMain::Create( - remote_proto_channel, proxy_main.get(), task_runner_provider)); - return proxy_main; -} - ProxyMain::ProxyMain(LayerTreeHostInProcess* layer_tree_host, TaskRunnerProvider* task_runner_provider) : layer_tree_host_(layer_tree_host), @@ -72,9 +60,9 @@ void ProxyMain::SetChannel(std::unique_ptr<ChannelMain> channel_main) { channel_main_ = std::move(channel_main); } -void ProxyMain::DidCompleteSwapBuffers() { +void ProxyMain::DidReceiveCompositorFrameAck() { DCHECK(IsMainThread()); - layer_tree_host_->DidCompleteSwapBuffers(); + layer_tree_host_->DidReceiveCompositorFrameAck(); } void ProxyMain::BeginMainFrameNotExpectedSoon() { @@ -88,7 +76,7 @@ void ProxyMain::DidCommitAndDrawFrame() { layer_tree_host_->DidCommitAndDrawFrame(); } -void ProxyMain::SetAnimationEvents(std::unique_ptr<AnimationEvents> events) { +void ProxyMain::SetAnimationEvents(std::unique_ptr<MutatorEvents> events) { TRACE_EVENT0("cc", "ProxyMain::SetAnimationEvents"); DCHECK(IsMainThread()); layer_tree_host_->SetAnimationEvents(std::move(events)); @@ -351,7 +339,7 @@ void ProxyMain::MainThreadHasStoppedFlinging() { void ProxyMain::Start() { DCHECK(IsMainThread()); - DCHECK(layer_tree_host_->IsThreaded() || layer_tree_host_->IsRemoteServer()); + DCHECK(layer_tree_host_->IsThreaded()); DCHECK(channel_main_); // Create LayerTreeHostImpl. @@ -401,11 +389,12 @@ void ProxyMain::ReleaseCompositorFrameSink() { completion.Wait(); } -void ProxyMain::UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) { +void ProxyMain::UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) { DCHECK(IsMainThread()); - channel_main_->UpdateTopControlsStateOnImpl(constraints, current, animate); + channel_main_->UpdateBrowserControlsStateOnImpl(constraints, current, + animate); } bool ProxyMain::SendCommitRequestToImplThreadIfNeeded( diff --git a/chromium/cc/trees/proxy_main.h b/chromium/cc/trees/proxy_main.h index 6bd6d7870f7..d455af6be19 100644 --- a/chromium/cc/trees/proxy_main.h +++ b/chromium/cc/trees/proxy_main.h @@ -7,16 +7,14 @@ #include "base/macros.h" #include "cc/base/cc_export.h" -#include "cc/input/top_controls_state.h" +#include "cc/input/browser_controls_state.h" #include "cc/trees/channel_main.h" #include "cc/trees/proxy.h" #include "cc/trees/proxy_common.h" -#include "cc/trees/remote_proto_channel.h" namespace cc { -class AnimationEvents; -class BeginFrameSource; +class MutatorEvents; class ChannelMain; class CompositorFrameSink; class LayerTreeHostInProcess; @@ -31,11 +29,6 @@ class CC_EXPORT ProxyMain : public Proxy { LayerTreeHostInProcess* layer_tree_host, TaskRunnerProvider* task_runner_provider); - static std::unique_ptr<ProxyMain> CreateRemote( - RemoteProtoChannel* remote_proto_channel, - LayerTreeHostInProcess* layer_tree_host, - TaskRunnerProvider* task_runner_provider); - ~ProxyMain() override; // Commits between the main and impl threads are processed through a pipeline @@ -48,10 +41,10 @@ class CC_EXPORT ProxyMain : public Proxy { COMMIT_PIPELINE_STAGE, }; - void DidCompleteSwapBuffers(); + void DidReceiveCompositorFrameAck(); void BeginMainFrameNotExpectedSoon(); void DidCommitAndDrawFrame(); - void SetAnimationEvents(std::unique_ptr<AnimationEvents> events); + void SetAnimationEvents(std::unique_ptr<MutatorEvents> events); void DidLoseCompositorFrameSink(); void RequestNewCompositorFrameSink(); void DidInitializeCompositorFrameSink(bool success); @@ -99,9 +92,9 @@ class CC_EXPORT ProxyMain : public Proxy { void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override; bool MainFrameWillHappenForTesting() override; void ReleaseCompositorFrameSink() override; - void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) override; + void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) override; // This sets the channel used by ProxyMain to communicate with ProxyImpl. void SetChannel(std::unique_ptr<ChannelMain> channel_main); diff --git a/chromium/cc/trees/remote_channel_impl.cc b/chromium/cc/trees/remote_channel_impl.cc deleted file mode 100644 index 32d2bdb02af..00000000000 --- a/chromium/cc/trees/remote_channel_impl.cc +++ /dev/null @@ -1,518 +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/trees/remote_channel_impl.h" - -#include "base/bind_helpers.h" -#include "base/memory/ptr_util.h" -#include "base/single_thread_task_runner.h" -#include "cc/animation/animation_events.h" -#include "cc/proto/compositor_message.pb.h" -#include "cc/proto/compositor_message_to_impl.pb.h" -#include "cc/proto/compositor_message_to_main.pb.h" -#include "cc/proto/gfx_conversions.h" -#include "cc/trees/layer_tree_host_in_process.h" -#include "cc/trees/layer_tree_settings.h" - -namespace cc { - -RemoteChannelImpl::RemoteChannelImpl(LayerTreeHostInProcess* layer_tree_host, - RemoteProtoChannel* remote_proto_channel, - TaskRunnerProvider* task_runner_provider) - : task_runner_provider_(task_runner_provider), - main_thread_vars_unsafe_(this, layer_tree_host, remote_proto_channel), - compositor_thread_vars_unsafe_( - main().remote_channel_weak_factory.GetWeakPtr()) { - DCHECK(task_runner_provider_->IsMainThread()); - - main().remote_proto_channel->SetProtoReceiver(this); -} - -RemoteChannelImpl::~RemoteChannelImpl() { - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(!main().started); - - main().remote_proto_channel->SetProtoReceiver(nullptr); -} - -std::unique_ptr<ProxyImpl> RemoteChannelImpl::CreateProxyImpl( - ChannelImpl* channel_impl, - LayerTreeHostInProcess* layer_tree_host, - TaskRunnerProvider* task_runner_provider) { - DCHECK(task_runner_provider_->IsImplThread()); - return base::MakeUnique<ProxyImpl>(channel_impl, layer_tree_host, - task_runner_provider); -} - -void RemoteChannelImpl::OnProtoReceived( - std::unique_ptr<proto::CompositorMessage> proto) { - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(main().started); - DCHECK(proto->has_to_impl()); - - // If we don't have an CompositorFrameSink, queue the message and defer - // processing it till we initialize a new CompositorFrameSink. - if (main().waiting_for_compositor_frame_sink_initialization) { - VLOG(1) << "Queueing message proto since CompositorFrameSink was released."; - main().pending_messages.push(proto->to_impl()); - } else { - HandleProto(proto->to_impl()); - } -} - -void RemoteChannelImpl::HandleProto( - const proto::CompositorMessageToImpl& proto) { - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(proto.has_message_type()); - DCHECK(!main().waiting_for_compositor_frame_sink_initialization); - - switch (proto.message_type()) { - case proto::CompositorMessageToImpl::UNKNOWN: - NOTIMPLEMENTED() << "Ignoring message of UNKNOWN type"; - break; - case proto::CompositorMessageToImpl::SET_NEEDS_COMMIT: - VLOG(1) << "Received commit request from the engine."; - ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ProxyImpl::SetNeedsCommitOnImpl, proxy_impl_weak_ptr_)); - break; - case proto::CompositorMessageToImpl::SET_DEFER_COMMITS: { - const proto::SetDeferCommits& defer_commits_message = - proto.defer_commits_message(); - bool defer_commits = defer_commits_message.defer_commits(); - VLOG(1) << "Received set defer commits to: " << defer_commits - << " from the engine."; - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyImpl::SetDeferCommitsOnImpl, - proxy_impl_weak_ptr_, defer_commits)); - } break; - case proto::CompositorMessageToImpl::START_COMMIT: { - VLOG(1) << "Received commit proto from the engine."; - base::TimeTicks main_thread_start_time = base::TimeTicks::Now(); - const proto::StartCommit& start_commit_message = - proto.start_commit_message(); - - main().layer_tree_host->FromProtobufForCommit( - start_commit_message.layer_tree_host()); - - { - DebugScopedSetMainThreadBlocked main_thread_blocked( - task_runner_provider_); - CompletionEvent completion; - VLOG(1) << "Starting commit."; - ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ProxyImpl::NotifyReadyToCommitOnImpl, - proxy_impl_weak_ptr_, &completion, - main().layer_tree_host, main_thread_start_time, false)); - completion.Wait(); - } - } break; - case proto::CompositorMessageToImpl::BEGIN_MAIN_FRAME_ABORTED: { - base::TimeTicks main_thread_start_time = base::TimeTicks::Now(); - const proto::BeginMainFrameAborted& begin_main_frame_aborted_message = - proto.begin_main_frame_aborted_message(); - CommitEarlyOutReason reason = CommitEarlyOutReasonFromProtobuf( - begin_main_frame_aborted_message.reason()); - std::vector<std::unique_ptr<SwapPromise>> empty_swap_promises; - VLOG(1) << "Received BeginMainFrameAborted from the engine with reason: " - << CommitEarlyOutReasonToString(reason); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ProxyImpl::BeginMainFrameAbortedOnImpl, - proxy_impl_weak_ptr_, reason, main_thread_start_time, - base::Passed(&empty_swap_promises))); - } break; - case proto::CompositorMessageToImpl::SET_NEEDS_REDRAW: { - VLOG(1) << "Received redraw request from the engine."; - const proto::SetNeedsRedraw& set_needs_redraw_message = - proto.set_needs_redraw_message(); - gfx::Rect damaged_rect = - ProtoToRect(set_needs_redraw_message.damaged_rect()); - PostSetNeedsRedrawToImpl(damaged_rect); - } break; - } -} - -bool RemoteChannelImpl::IsStarted() const { - DCHECK(task_runner_provider_->IsMainThread()); - return main().started; -} - -bool RemoteChannelImpl::CommitToActiveTree() const { - return false; -} - -void RemoteChannelImpl::SetCompositorFrameSink( - CompositorFrameSink* compositor_frame_sink) { - DCHECK(task_runner_provider_->IsMainThread()); - - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyImpl::InitializeCompositorFrameSinkOnImpl, - proxy_impl_weak_ptr_, compositor_frame_sink)); -} - -void RemoteChannelImpl::ReleaseCompositorFrameSink() { - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(!main().waiting_for_compositor_frame_sink_initialization); - VLOG(1) << "Releasing CompositorFrameSink"; - - { - CompletionEvent completion; - DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyImpl::ReleaseCompositorFrameSinkOnImpl, - proxy_impl_weak_ptr_, &completion)); - completion.Wait(); - } - - main().waiting_for_compositor_frame_sink_initialization = true; -} - -void RemoteChannelImpl::SetVisible(bool visible) { - DCHECK(task_runner_provider_->IsMainThread()); - VLOG(1) << "Setting visibility to: " << visible; - - ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ProxyImpl::SetVisibleOnImpl, proxy_impl_weak_ptr_, visible)); -} - -void RemoteChannelImpl::SetNeedsAnimate() { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -void RemoteChannelImpl::SetNeedsUpdateLayers() { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -void RemoteChannelImpl::SetNeedsCommit() { - // Ideally commits should be requested only on the server. But we have to - // allow this call since the LayerTreeHostInProcesswill currently ask for a - // commit in 2 cases: - // 1) When it is being initialized from a protobuf for a commit. - // 2) When it loses the CompositorFrameSink. - NOTIMPLEMENTED() << "Commits should not be requested on the client"; -} - -void RemoteChannelImpl::SetNeedsRedraw(const gfx::Rect& damage_rect) { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -void RemoteChannelImpl::SetNextCommitWaitsForActivation() { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -void RemoteChannelImpl::NotifyInputThrottledUntilCommit() { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -void RemoteChannelImpl::SetDeferCommits(bool defer_commits) { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -void RemoteChannelImpl::MainThreadHasStoppedFlinging() { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -bool RemoteChannelImpl::CommitRequested() const { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; - return false; -} - -bool RemoteChannelImpl::BeginMainFrameRequested() const { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; - return false; -} - -void RemoteChannelImpl::Start() { - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(!main().started); - - CompletionEvent completion; - { - DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&RemoteChannelImpl::InitializeImplOnImpl, - base::Unretained(this), &completion, - main().layer_tree_host)); - completion.Wait(); - } - main().started = true; -} - -void RemoteChannelImpl::Stop() { - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(main().started); - - { - CompletionEvent completion; - DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyImpl::FinishGLOnImpl, proxy_impl_weak_ptr_, - &completion)); - completion.Wait(); - } - { - CompletionEvent completion; - DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&RemoteChannelImpl::ShutdownImplOnImpl, - base::Unretained(this), &completion)); - completion.Wait(); - } - - main().started = false; - main().remote_channel_weak_factory.InvalidateWeakPtrs(); -} - -void RemoteChannelImpl::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) { - // TODO(vollick): add support for compositor worker. -} - -bool RemoteChannelImpl::SupportsImplScrolling() const { - return true; -} - -void RemoteChannelImpl::UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) { - NOTREACHED() << "Should not be called on the remote client LayerTreeHost"; -} - -bool RemoteChannelImpl::MainFrameWillHappenForTesting() { - DCHECK(task_runner_provider_->IsMainThread()); - bool main_frame_will_happen; - { - CompletionEvent completion; - DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); - ImplThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&ProxyImpl::MainFrameWillHappenOnImplForTesting, - proxy_impl_weak_ptr_, &completion, &main_frame_will_happen)); - completion.Wait(); - } - return main_frame_will_happen; -} - -void RemoteChannelImpl::DidCompleteSwapBuffers() { - DCHECK(task_runner_provider_->IsImplThread()); - MainThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&RemoteChannelImpl::DidCompleteSwapBuffersOnMain, - impl().remote_channel_weak_ptr)); -} - -void RemoteChannelImpl::BeginMainFrameNotExpectedSoon() {} - -void RemoteChannelImpl::DidCommitAndDrawFrame() { - DCHECK(task_runner_provider_->IsImplThread()); - MainThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&RemoteChannelImpl::DidCommitAndDrawFrameOnMain, - impl().remote_channel_weak_ptr)); -} - -void RemoteChannelImpl::SetAnimationEvents( - std::unique_ptr<AnimationEvents> queue) {} - -void RemoteChannelImpl::DidLoseCompositorFrameSink() { - DCHECK(task_runner_provider_->IsImplThread()); - - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&RemoteChannelImpl::DidLoseCompositorFrameSinkOnMain, - impl().remote_channel_weak_ptr)); -} - -void RemoteChannelImpl::RequestNewCompositorFrameSink() { - DCHECK(task_runner_provider_->IsImplThread()); - - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&RemoteChannelImpl::RequestNewCompositorFrameSinkOnMain, - impl().remote_channel_weak_ptr)); -} - -void RemoteChannelImpl::DidInitializeCompositorFrameSink(bool success) { - DCHECK(task_runner_provider_->IsImplThread()); - - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&RemoteChannelImpl::DidInitializeCompositorFrameSinkOnMain, - impl().remote_channel_weak_ptr, success)); -} - -void RemoteChannelImpl::DidCompletePageScaleAnimation() {} - -void RemoteChannelImpl::BeginMainFrame( - std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state) { - std::unique_ptr<proto::CompositorMessage> proto; - proto.reset(new proto::CompositorMessage); - proto::CompositorMessageToMain* to_main_proto = proto->mutable_to_main(); - - to_main_proto->set_message_type( - proto::CompositorMessageToMain::BEGIN_MAIN_FRAME); - proto::BeginMainFrame* begin_main_frame_message = - to_main_proto->mutable_begin_main_frame_message(); - begin_main_frame_state->ToProtobuf( - begin_main_frame_message->mutable_begin_main_frame_state()); - - SendMessageProto(std::move(proto)); -} - -void RemoteChannelImpl::SendMessageProto( - std::unique_ptr<proto::CompositorMessage> proto) { - DCHECK(task_runner_provider_->IsImplThread()); - - MainThreadTaskRunner()->PostTask( - FROM_HERE, - base::Bind(&RemoteChannelImpl::SendMessageProtoOnMain, - impl().remote_channel_weak_ptr, base::Passed(&proto))); -} - -void RemoteChannelImpl::DidCompleteSwapBuffersOnMain() { - DCHECK(task_runner_provider_->IsMainThread()); - main().layer_tree_host->DidCompleteSwapBuffers(); -} - -void RemoteChannelImpl::DidCommitAndDrawFrameOnMain() { - DCHECK(task_runner_provider_->IsMainThread()); - main().layer_tree_host->DidCommitAndDrawFrame(); -} - -void RemoteChannelImpl::DidLoseCompositorFrameSinkOnMain() { - DCHECK(task_runner_provider_->IsMainThread()); - - main().layer_tree_host->DidLoseCompositorFrameSink(); -} - -void RemoteChannelImpl::RequestNewCompositorFrameSinkOnMain() { - DCHECK(task_runner_provider_->IsMainThread()); - - main().layer_tree_host->RequestNewCompositorFrameSink(); -} - -void RemoteChannelImpl::DidInitializeCompositorFrameSinkOnMain(bool success) { - DCHECK(task_runner_provider_->IsMainThread()); - - if (!success) { - main().layer_tree_host->DidFailToInitializeCompositorFrameSink(); - return; - } - - VLOG(1) << "CompositorFrameSink initialized successfully"; - main().layer_tree_host->DidInitializeCompositorFrameSink(); - - // If we were waiting for CompositorFrameSink initialization, we might have - // queued some messages. Relay them now that a new CompositorFrameSink has - // been initialized. - main().waiting_for_compositor_frame_sink_initialization = false; - while (!main().pending_messages.empty()) { - VLOG(1) << "Handling queued message"; - HandleProto(main().pending_messages.front()); - main().pending_messages.pop(); - } - - // The commit after a new CompositorFrameSink can early out, in which case we - // will never redraw. Schedule one just to be safe. - PostSetNeedsRedrawToImpl(gfx::Rect( - main().layer_tree_host->GetLayerTree()->device_viewport_size())); -} - -void RemoteChannelImpl::SendMessageProtoOnMain( - std::unique_ptr<proto::CompositorMessage> proto) { - DCHECK(task_runner_provider_->IsMainThread()); - VLOG(1) << "Sending BeginMainFrame request to the engine."; - - main().remote_proto_channel->SendCompositorProto(*proto); -} - -void RemoteChannelImpl::PostSetNeedsRedrawToImpl( - const gfx::Rect& damaged_rect) { - DCHECK(task_runner_provider_->IsMainThread()); - - ImplThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyImpl::SetNeedsRedrawOnImpl, - proxy_impl_weak_ptr_, damaged_rect)); -} - -void RemoteChannelImpl::InitializeImplOnImpl( - CompletionEvent* completion, - LayerTreeHostInProcess* layer_tree_host) { - DCHECK(task_runner_provider_->IsMainThreadBlocked()); - DCHECK(task_runner_provider_->IsImplThread()); - - impl().proxy_impl = - CreateProxyImpl(this, layer_tree_host, task_runner_provider_); - impl().proxy_impl_weak_factory = - base::MakeUnique<base::WeakPtrFactory<ProxyImpl>>( - impl().proxy_impl.get()); - proxy_impl_weak_ptr_ = impl().proxy_impl_weak_factory->GetWeakPtr(); - completion->Signal(); -} - -void RemoteChannelImpl::ShutdownImplOnImpl(CompletionEvent* completion) { - DCHECK(task_runner_provider_->IsMainThreadBlocked()); - DCHECK(task_runner_provider_->IsImplThread()); - - // We must invalidate the proxy_impl weak ptrs and destroy the weak ptr - // factory before destroying proxy_impl. - impl().proxy_impl_weak_factory->InvalidateWeakPtrs(); - impl().proxy_impl_weak_factory.reset(); - - impl().proxy_impl.reset(); - completion->Signal(); -} - -RemoteChannelImpl::MainThreadOnly& RemoteChannelImpl::main() { - DCHECK(task_runner_provider_->IsMainThread()); - return main_thread_vars_unsafe_; -} - -const RemoteChannelImpl::MainThreadOnly& RemoteChannelImpl::main() const { - DCHECK(task_runner_provider_->IsMainThread()); - return main_thread_vars_unsafe_; -} - -RemoteChannelImpl::CompositorThreadOnly& RemoteChannelImpl::impl() { - DCHECK(task_runner_provider_->IsImplThread()); - return compositor_thread_vars_unsafe_; -} - -const RemoteChannelImpl::CompositorThreadOnly& RemoteChannelImpl::impl() const { - DCHECK(task_runner_provider_->IsImplThread()); - return compositor_thread_vars_unsafe_; -} - -base::SingleThreadTaskRunner* RemoteChannelImpl::MainThreadTaskRunner() const { - return task_runner_provider_->MainThreadTaskRunner(); -} - -base::SingleThreadTaskRunner* RemoteChannelImpl::ImplThreadTaskRunner() const { - return task_runner_provider_->ImplThreadTaskRunner(); -} - -RemoteChannelImpl::MainThreadOnly::MainThreadOnly( - RemoteChannelImpl* remote_channel_impl, - LayerTreeHostInProcess* layer_tree_host, - RemoteProtoChannel* remote_proto_channel) - : layer_tree_host(layer_tree_host), - remote_proto_channel(remote_proto_channel), - started(false), - waiting_for_compositor_frame_sink_initialization(false), - remote_channel_weak_factory(remote_channel_impl) { - DCHECK(layer_tree_host); - DCHECK(remote_proto_channel); -} - -RemoteChannelImpl::MainThreadOnly::~MainThreadOnly() {} - -RemoteChannelImpl::CompositorThreadOnly::CompositorThreadOnly( - base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr) - : proxy_impl(nullptr), - proxy_impl_weak_factory(nullptr), - remote_channel_weak_ptr(remote_channel_weak_ptr) {} - -RemoteChannelImpl::CompositorThreadOnly::~CompositorThreadOnly() {} - -} // namespace cc diff --git a/chromium/cc/trees/remote_channel_impl.h b/chromium/cc/trees/remote_channel_impl.h deleted file mode 100644 index f77a53efd3d..00000000000 --- a/chromium/cc/trees/remote_channel_impl.h +++ /dev/null @@ -1,208 +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_TREES_REMOTE_CHANNEL_IMPL_H_ -#define CC_TREES_REMOTE_CHANNEL_IMPL_H_ - -#include <queue> - -#include "base/macros.h" -#include "base/memory/weak_ptr.h" -#include "cc/base/cc_export.h" -#include "cc/base/completion_event.h" -#include "cc/proto/compositor_message_to_impl.pb.h" -#include "cc/trees/channel_impl.h" -#include "cc/trees/proxy.h" -#include "cc/trees/proxy_impl.h" -#include "cc/trees/remote_proto_channel.h" - -namespace cc { -class LayerTreeHostInProcess; - -namespace proto { -class CompositorMessage; -class CompositorMessageToImpl; -class CompositorMessageToMain; -} - -// The Proxy and ChannelImpl implementation for the remote compositor. -// The object life cycle and communication across threads is as follows: -// -// The RemoteChannelImpl is created by the remote client LayerTreeHost, which -// initializes the impl side of the compositor. -// -// Main Thread | Impl Thread -// | -// Proxy::Start | -// | | -// | RemoteChannelImpl -// --------------------------------------------------------------------------- -// RemoteChannelImpl::Start()---PostTask---> RemoteChannelImpl:: -// InitializeImplOnImpl -// | -// ProxyImpl::Create -// | -// . -// . -// ProxyImpl::ScheduledActionBegin -// CompositorFrameSinkCreation -// | -// ChannelImpl::RequestNewCompositorFrameSink -// | -// RemoteChannelImpl:: | -// RequestNewCompositorFrameSink()<----PostTask-------------- -// . -// . -// | -// RemoteChannelImpl:: -// ~RemoteChannelImpl() ---PostTask---> RemoteChannelImpl:: -// ShutdownImplOnImpl -// ---------------------------------------------------------------------------- -// -// The class is created and destroyed on the main thread but can be safely -// called from the main or impl thread. It is safe to call RemoteChannelImpl on -// the impl thread since: -// 1) The only impl threaded callers of RemoteChannelImpl is the -// RemoteChannelImpl itself and ProxyImpl which is created and owned by the -// RemoteChannelImpl. -// 2) The RemoteChannelImpl blocks the main thread in its dtor to wait for the -// impl-thread teardown to complete, which ensures that any tasks queued to call -// it on the impl thread are run before it is destroyed on the main thread. -// -// The RemoteChannelImpl receives and processes messages from the remote server -// compositor on the main thread. The requests from ProxyImpl are received on -// the impl thread which may be directed to the LayerTreeHostInProcesson the -// client (for instance output surface requests) or sent to the -// LayerTreeHostInProcess on the server. The messages to the server are created -// on the impl thread and sent using the RemoteProtoChannel on the main thread. -class CC_EXPORT RemoteChannelImpl : public ChannelImpl, - public RemoteProtoChannel::ProtoReceiver, - public Proxy { - public: - RemoteChannelImpl(LayerTreeHostInProcess* layer_tree_host, - RemoteProtoChannel* remote_proto_channel, - TaskRunnerProvider* task_runner_provider); - ~RemoteChannelImpl() override; - - // virtual for testing. - virtual std::unique_ptr<ProxyImpl> CreateProxyImpl( - ChannelImpl* channel_impl, - LayerTreeHostInProcess* layer_tree_host, - TaskRunnerProvider* task_runner_provider); - - private: - struct MainThreadOnly { - LayerTreeHostInProcess* layer_tree_host; - RemoteProtoChannel* remote_proto_channel; - - bool started; - - // This is set to true if we lost the output surface and can not push any - // commits to the impl thread. - bool waiting_for_compositor_frame_sink_initialization; - - // The queue of messages received from the server. The messages are added to - // this queue if we are waiting for a new output surface to be initialized. - std::queue<proto::CompositorMessageToImpl> pending_messages; - - base::WeakPtrFactory<RemoteChannelImpl> remote_channel_weak_factory; - - MainThreadOnly(RemoteChannelImpl*, - LayerTreeHostInProcess* layer_tree_host, - RemoteProtoChannel* remote_proto_channel); - ~MainThreadOnly(); - }; - - struct CompositorThreadOnly { - std::unique_ptr<ProxyImpl> proxy_impl; - std::unique_ptr<base::WeakPtrFactory<ProxyImpl>> proxy_impl_weak_factory; - base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr; - - CompositorThreadOnly( - base::WeakPtr<RemoteChannelImpl> remote_channel_weak_ptr); - ~CompositorThreadOnly(); - }; - - // called on main thread. - // RemoteProtoChannel::ProtoReceiver implementation. - void OnProtoReceived( - std::unique_ptr<proto::CompositorMessage> proto) override; - - // Proxy implementation - bool IsStarted() const override; - bool CommitToActiveTree() const override; - void SetCompositorFrameSink( - CompositorFrameSink* compositor_frame_sink) override; - void ReleaseCompositorFrameSink() override; - void SetVisible(bool visible) override; - void SetNeedsAnimate() override; - void SetNeedsUpdateLayers() override; - void SetNeedsCommit() override; - void SetNeedsRedraw(const gfx::Rect& damage_rect) override; - void SetNextCommitWaitsForActivation() override; - void NotifyInputThrottledUntilCommit() override; - void SetDeferCommits(bool defer_commits) override; - void MainThreadHasStoppedFlinging() override; - bool CommitRequested() const override; - bool BeginMainFrameRequested() const override; - void Start() override; - void Stop() override; - void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override; - bool SupportsImplScrolling() const override; - void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) override; - bool MainFrameWillHappenForTesting() override; - - // Called on impl thread. - // ChannelImpl implementation - void DidCompleteSwapBuffers() override; - void BeginMainFrameNotExpectedSoon() override; - void DidCommitAndDrawFrame() override; - void SetAnimationEvents(std::unique_ptr<AnimationEvents> queue) override; - void DidLoseCompositorFrameSink() override; - void RequestNewCompositorFrameSink() override; - void DidInitializeCompositorFrameSink(bool success) override; - void DidCompletePageScaleAnimation() override; - void BeginMainFrame(std::unique_ptr<BeginMainFrameAndCommitState> - begin_main_frame_state) override; - - void SendMessageProto(std::unique_ptr<proto::CompositorMessage> proto); - - // called on main thread. - void HandleProto(const proto::CompositorMessageToImpl& proto); - void DidCompleteSwapBuffersOnMain(); - void DidCommitAndDrawFrameOnMain(); - void DidLoseCompositorFrameSinkOnMain(); - void RequestNewCompositorFrameSinkOnMain(); - void DidInitializeCompositorFrameSinkOnMain(bool success); - void SendMessageProtoOnMain(std::unique_ptr<proto::CompositorMessage> proto); - void PostSetNeedsRedrawToImpl(const gfx::Rect& damaged_rect); - - void InitializeImplOnImpl(CompletionEvent* completion, - LayerTreeHostInProcess* layer_tree_host); - void ShutdownImplOnImpl(CompletionEvent* completion); - - MainThreadOnly& main(); - const MainThreadOnly& main() const; - CompositorThreadOnly& impl(); - const CompositorThreadOnly& impl() const; - - base::SingleThreadTaskRunner* MainThreadTaskRunner() const; - base::SingleThreadTaskRunner* ImplThreadTaskRunner() const; - - TaskRunnerProvider* task_runner_provider_; - - // use accessors instead of these variables directly - MainThreadOnly main_thread_vars_unsafe_; - CompositorThreadOnly compositor_thread_vars_unsafe_; - - base::WeakPtr<ProxyImpl> proxy_impl_weak_ptr_; - - DISALLOW_COPY_AND_ASSIGN(RemoteChannelImpl); -}; - -} // namespace cc - -#endif // CC_TREES_REMOTE_CHANNEL_IMPL_H_ diff --git a/chromium/cc/trees/remote_channel_main.cc b/chromium/cc/trees/remote_channel_main.cc deleted file mode 100644 index 6b490697a04..00000000000 --- a/chromium/cc/trees/remote_channel_main.cc +++ /dev/null @@ -1,278 +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/trees/remote_channel_main.h" - -#include <memory> - -#include "base/memory/ptr_util.h" -#include "cc/proto/base_conversions.h" -#include "cc/proto/compositor_message.pb.h" -#include "cc/proto/compositor_message_to_impl.pb.h" -#include "cc/proto/compositor_message_to_main.pb.h" -#include "cc/proto/gfx_conversions.h" -#include "cc/trees/layer_tree_host_in_process.h" -#include "cc/trees/proxy_main.h" - -namespace cc { - -std::unique_ptr<RemoteChannelMain> RemoteChannelMain::Create( - RemoteProtoChannel* remote_proto_channel, - ProxyMain* proxy_main, - TaskRunnerProvider* task_runner_provider) { - return base::WrapUnique(new RemoteChannelMain( - remote_proto_channel, proxy_main, task_runner_provider)); -} - -RemoteChannelMain::RemoteChannelMain(RemoteProtoChannel* remote_proto_channel, - ProxyMain* proxy_main, - TaskRunnerProvider* task_runner_provider) - : remote_proto_channel_(remote_proto_channel), - proxy_main_(proxy_main), - task_runner_provider_(task_runner_provider), - initialized_(false), - weak_factory_(this) { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::RemoteChannelMain"); - DCHECK(remote_proto_channel_); - DCHECK(proxy_main_); - DCHECK(task_runner_provider_); - DCHECK(task_runner_provider_->IsMainThread()); - remote_proto_channel_->SetProtoReceiver(this); -} - -RemoteChannelMain::~RemoteChannelMain() { - TRACE_EVENT0("cc.remote", "~RemoteChannelMain::RemoteChannelMain"); - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(!initialized_); - - remote_proto_channel_->SetProtoReceiver(nullptr); -} - -void RemoteChannelMain::OnProtoReceived( - std::unique_ptr<proto::CompositorMessage> proto) { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::OnProtoReceived"); - DCHECK(task_runner_provider_->IsMainThread()); - DCHECK(proto->has_to_main()); - - HandleProto(proto->to_main()); -} - -void RemoteChannelMain::UpdateTopControlsStateOnImpl( - TopControlsState constraints, - TopControlsState current, - bool animate) {} - -void RemoteChannelMain::InitializeCompositorFrameSinkOnImpl( - CompositorFrameSink*) { - NOTREACHED() << "Should not be called on the server LayerTreeHost"; -} - -void RemoteChannelMain::InitializeMutatorOnImpl( - std::unique_ptr<LayerTreeMutator> mutator) { - // TODO(vollick): add support for CompositorWorker. - NOTIMPLEMENTED(); -} - -void RemoteChannelMain::MainThreadHasStoppedFlingingOnImpl() { - NOTIMPLEMENTED(); -} - -void RemoteChannelMain::SetInputThrottledUntilCommitOnImpl(bool is_throttled) {} - -void RemoteChannelMain::SetDeferCommitsOnImpl(bool defer_commits) { - TRACE_EVENT1("cc.remote", "RemoteChannelMain::SetDeferCommitsOnImpl", - "defer_commits", defer_commits); - proto::CompositorMessage proto; - proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); - to_impl_proto->set_message_type( - proto::CompositorMessageToImpl::SET_DEFER_COMMITS); - proto::SetDeferCommits* defer_commits_message = - to_impl_proto->mutable_defer_commits_message(); - defer_commits_message->set_defer_commits(defer_commits); - - VLOG(1) << "Sending defer commits: " << defer_commits << " to client."; - SendMessageProto(proto); -} - -void RemoteChannelMain::SetVisibleOnImpl(bool visible) { - NOTIMPLEMENTED() << "Visibility is not controlled by the server"; -} - -void RemoteChannelMain::ReleaseCompositorFrameSinkOnImpl( - CompletionEvent* completion) { - NOTREACHED() << "Should not be called on the server LayerTreeHost"; - completion->Signal(); -} - -void RemoteChannelMain::MainFrameWillHappenOnImplForTesting( - CompletionEvent* completion, - bool* main_frame_will_happen) { - // For the LayerTreeTests in remote mode, LayerTreeTest directly calls - // RemoteChannelImpl::MainFrameWillHappenForTesting and avoids adding a - // message type for tests to the compositor protocol. - NOTREACHED(); -} - -void RemoteChannelMain::SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::SetNeedsRedrawOnImpl"); - proto::CompositorMessage proto; - proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); - to_impl_proto->set_message_type( - proto::CompositorMessageToImpl::SET_NEEDS_REDRAW); - proto::SetNeedsRedraw* set_needs_redraw_message = - to_impl_proto->mutable_set_needs_redraw_message(); - RectToProto(damage_rect, set_needs_redraw_message->mutable_damaged_rect()); - - VLOG(1) << "Sending redraw request to client."; - SendMessageProto(proto); - - // The client will not inform us when the frame buffers are swapped. - MainThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&RemoteChannelMain::DidCompleteSwapBuffers, - weak_factory_.GetWeakPtr())); -} - -void RemoteChannelMain::SetNeedsCommitOnImpl() { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::SetNeedsCommitOnImpl"); - proto::CompositorMessage proto; - proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); - to_impl_proto->set_message_type( - proto::CompositorMessageToImpl::SET_NEEDS_COMMIT); - - VLOG(1) << "Sending commit request to client."; - SendMessageProto(proto); -} - -void RemoteChannelMain::BeginMainFrameAbortedOnImpl( - CommitEarlyOutReason reason, - base::TimeTicks main_thread_start_time, - std::vector<std::unique_ptr<SwapPromise>> swap_promises) { - TRACE_EVENT1("cc.remote", "RemoteChannelMain::BeginMainFrameAbortedOnImpl", - "reason", CommitEarlyOutReasonToString(reason)); - proto::CompositorMessage proto; - proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); - to_impl_proto->set_message_type( - proto::CompositorMessageToImpl::BEGIN_MAIN_FRAME_ABORTED); - proto::BeginMainFrameAborted* begin_main_frame_aborted_message = - to_impl_proto->mutable_begin_main_frame_aborted_message(); - CommitEarlyOutReasonToProtobuf( - reason, begin_main_frame_aborted_message->mutable_reason()); - - VLOG(1) << "Sending BeginMainFrameAborted message to client with reason: " - << CommitEarlyOutReasonToString(reason); - SendMessageProto(proto); - - // Notify swap promises that commit had no updates. In the local compositor - // case this goes to the impl thread to be queued up in case we have an - // activation pending but that never happens for remote compositor. - for (const auto& swap_promise : swap_promises) - swap_promise->DidNotSwap(SwapPromise::COMMIT_NO_UPDATE); -} - -void RemoteChannelMain::NotifyReadyToCommitOnImpl( - CompletionEvent* completion, - LayerTreeHostInProcess* layer_tree_host, - base::TimeTicks main_thread_start_time, - bool hold_commit_for_activation) { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::NotifyReadyToCommitOnImpl"); - proto::CompositorMessage proto; - proto::CompositorMessageToImpl* to_impl_proto = proto.mutable_to_impl(); - to_impl_proto->set_message_type(proto::CompositorMessageToImpl::START_COMMIT); - proto::StartCommit* start_commit_message = - to_impl_proto->mutable_start_commit_message(); - std::vector<std::unique_ptr<SwapPromise>> swap_promises; - layer_tree_host->ToProtobufForCommit( - start_commit_message->mutable_layer_tree_host(), &swap_promises); - - VLOG(1) << "Sending commit message to client. Commit bytes size: " - << proto.ByteSize(); - SendMessageProto(proto); - - // Activate the swap promises after the commit is queued. - // In the threaded compositor, activation implies that the pending tree on the - // impl thread has been activated. While the impl thread for the remote - // compositor is on the client, the embedder still expects to receive these - // events in order to drive decisions that depend on impl frame production. - // So we dispatch these events after a commit message is sent to the client. - // Sending the commit message implies that a visual update has been queued for - // the client, which is the closest we can come to offering an indicator akin - // to an impl frame queued for display. - for (const auto& swap_promise : swap_promises) - swap_promise->DidActivate(); - - // In order to avoid incurring the overhead for the client to send us a - // message for when a frame to be committed is drawn we inform the embedder - // that the draw was successful immediately after sending the commit message. - // Since the compositing state may be used by the embedder to throttle - // commit/draw requests, it is better to allow them to propagate rather than - // incurring a round-trip to get Acks for draw from the client for each frame. - - // This is done as a separate PostTask to ensure that these calls run after - // LayerTreeHostClient::DidCommit and stay consistent with the - // behaviour in the threaded compositor. - MainThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&RemoteChannelMain::DidCommitAndDrawFrame, - weak_factory_.GetWeakPtr())); - - completion->Signal(); -} - -void RemoteChannelMain::SynchronouslyInitializeImpl( - LayerTreeHostInProcess* layer_tree_host) { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::SynchronouslyInitializeImpl"); - DCHECK(!initialized_); - - initialized_ = true; -} - -void RemoteChannelMain::SynchronouslyCloseImpl() { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::SynchronouslyCloseImpl"); - DCHECK(initialized_); - - initialized_ = false; -} - -void RemoteChannelMain::SendMessageProto( - const proto::CompositorMessage& proto) { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::SendMessageProto"); - remote_proto_channel_->SendCompositorProto(proto); -} - -void RemoteChannelMain::HandleProto( - const proto::CompositorMessageToMain& proto) { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::HandleProto"); - DCHECK(proto.has_message_type()); - - switch (proto.message_type()) { - case proto::CompositorMessageToMain::UNKNOWN: - NOTIMPLEMENTED() << "Ignoring message proto of unknown type"; - break; - case proto::CompositorMessageToMain::BEGIN_MAIN_FRAME: { - TRACE_EVENT0("cc.remote", "RemoteChannelMain::BeginMainFrame"); - VLOG(1) << "Received BeginMainFrame request from client."; - const proto::BeginMainFrame& begin_main_frame_message = - proto.begin_main_frame_message(); - std::unique_ptr<BeginMainFrameAndCommitState> begin_main_frame_state; - begin_main_frame_state.reset(new BeginMainFrameAndCommitState); - begin_main_frame_state->FromProtobuf( - begin_main_frame_message.begin_main_frame_state()); - proxy_main_->BeginMainFrame(std::move(begin_main_frame_state)); - } break; - } -} - -void RemoteChannelMain::DidCommitAndDrawFrame() { - proxy_main_->DidCommitAndDrawFrame(); - DidCompleteSwapBuffers(); -} - -void RemoteChannelMain::DidCompleteSwapBuffers() { - proxy_main_->DidCompleteSwapBuffers(); -} - -base::SingleThreadTaskRunner* RemoteChannelMain::MainThreadTaskRunner() const { - return task_runner_provider_->MainThreadTaskRunner(); -} - -} // namespace cc diff --git a/chromium/cc/trees/remote_channel_main.h b/chromium/cc/trees/remote_channel_main.h deleted file mode 100644 index 43e49c6225a..00000000000 --- a/chromium/cc/trees/remote_channel_main.h +++ /dev/null @@ -1,91 +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_TREES_REMOTE_CHANNEL_MAIN_H_ -#define CC_TREES_REMOTE_CHANNEL_MAIN_H_ - -#include "base/macros.h" -#include "cc/base/cc_export.h" -#include "cc/trees/channel_main.h" -#include "cc/trees/remote_proto_channel.h" -#include "cc/trees/task_runner_provider.h" - -namespace cc { -class ProxyMain; - -namespace proto { -class CompositorMessage; -class CompositorMessageToMain; -} - -class CC_EXPORT RemoteChannelMain : public ChannelMain, - public RemoteProtoChannel::ProtoReceiver { - public: - static std::unique_ptr<RemoteChannelMain> Create( - RemoteProtoChannel* remote_proto_channel, - ProxyMain* proxy_main, - TaskRunnerProvider* task_runner_provider); - - ~RemoteChannelMain() override; - - // ChannelMain implementation - void UpdateTopControlsStateOnImpl(TopControlsState constraints, - TopControlsState current, - bool animate) override; - void InitializeCompositorFrameSinkOnImpl(CompositorFrameSink*) override; - void InitializeMutatorOnImpl( - std::unique_ptr<LayerTreeMutator> mutator) override; - void MainThreadHasStoppedFlingingOnImpl() override; - void SetInputThrottledUntilCommitOnImpl(bool is_throttled) override; - void SetDeferCommitsOnImpl(bool defer_commits) override; - void SetVisibleOnImpl(bool visible) override; - void ReleaseCompositorFrameSinkOnImpl(CompletionEvent* completion) override; - void MainFrameWillHappenOnImplForTesting( - CompletionEvent* completion, - bool* main_frame_will_happen) override; - void SetNeedsRedrawOnImpl(const gfx::Rect& damage_rect) override; - void SetNeedsCommitOnImpl() override; - void BeginMainFrameAbortedOnImpl( - CommitEarlyOutReason reason, - base::TimeTicks main_thread_start_time, - std::vector<std::unique_ptr<SwapPromise>> swap_promises) override; - void NotifyReadyToCommitOnImpl(CompletionEvent* completion, - LayerTreeHostInProcess* layer_tree_host, - base::TimeTicks main_thread_start_time, - bool hold_commit_for_activation) override; - void SynchronouslyInitializeImpl( - LayerTreeHostInProcess* layer_tree_host) override; - void SynchronouslyCloseImpl() override; - - // RemoteProtoChannel::ProtoReceiver implementation - void OnProtoReceived( - std::unique_ptr<proto::CompositorMessage> proto) override; - - protected: - RemoteChannelMain(RemoteProtoChannel* remote_proto_channel, - ProxyMain* proxy_main, - TaskRunnerProvider* task_runner_provider); - - private: - void SendMessageProto(const proto::CompositorMessage& proto); - void HandleProto(const proto::CompositorMessageToMain& proto); - void DidCommitAndDrawFrame(); - void DidCompleteSwapBuffers(); - - base::SingleThreadTaskRunner* MainThreadTaskRunner() const; - - RemoteProtoChannel* remote_proto_channel_; - ProxyMain* proxy_main_; - TaskRunnerProvider* task_runner_provider_; - - bool initialized_; - - base::WeakPtrFactory<RemoteChannelMain> weak_factory_; - - DISALLOW_COPY_AND_ASSIGN(RemoteChannelMain); -}; - -} // namespace cc - -#endif // CC_TREES_REMOTE_CHANNEL_MAIN_H_ diff --git a/chromium/cc/trees/remote_proto_channel.h b/chromium/cc/trees/remote_proto_channel.h deleted file mode 100644 index 8f7ad099a13..00000000000 --- a/chromium/cc/trees/remote_proto_channel.h +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright 2015 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_REMOTE_PROTO_CHANNEL_H_ -#define CC_TREES_REMOTE_PROTO_CHANNEL_H_ - -#include <memory> - -#include "cc/base/cc_export.h" - -namespace cc { - -namespace proto { -class CompositorMessage; -} - -// Provides a bridge for getting compositor protobuf messages to/from the -// outside world. -class CC_EXPORT RemoteProtoChannel { - public: - // Meant to be implemented by a RemoteChannel that needs to receive and parse - // incoming protobufs. - class CC_EXPORT ProtoReceiver { - public: - // TODO(khushalsagar): This should probably include a closure that returns - // the status of processing this proto. See crbug/576974 - virtual void OnProtoReceived( - std::unique_ptr<proto::CompositorMessage> proto) = 0; - - protected: - virtual ~ProtoReceiver() {} - }; - - // Called by the ProtoReceiver. The RemoteProtoChannel must outlive its - // receiver. - virtual void SetProtoReceiver(ProtoReceiver* receiver) = 0; - - virtual void SendCompositorProto(const proto::CompositorMessage& proto) = 0; - - protected: - virtual ~RemoteProtoChannel() {} -}; - -} // namespace cc - -#endif // CC_TREES_REMOTE_PROTO_CHANNEL_H_ diff --git a/chromium/cc/trees/scroll_node.cc b/chromium/cc/trees/scroll_node.cc index a20fe2f84f6..5da6957545a 100644 --- a/chromium/cc/trees/scroll_node.cc +++ b/chromium/cc/trees/scroll_node.cc @@ -3,11 +3,10 @@ // found in the LICENSE file. #include "base/trace_event/trace_event_argument.h" -#include "cc/animation/element_id.h" #include "cc/base/math_util.h" #include "cc/input/main_thread_scrolling_reason.h" #include "cc/proto/gfx_conversions.h" -#include "cc/proto/property_tree.pb.h" +#include "cc/trees/element_id.h" #include "cc/trees/scroll_node.h" namespace cc { @@ -26,8 +25,7 @@ ScrollNode::ScrollNode() should_flatten(false), user_scrollable_horizontal(false), user_scrollable_vertical(false), - transform_id(0), - num_drawn_descendants(0) {} + transform_id(0) {} ScrollNode::ScrollNode(const ScrollNode& other) = default; @@ -52,60 +50,6 @@ bool ScrollNode::operator==(const ScrollNode& other) const { element_id == other.element_id && transform_id == other.transform_id; } -void ScrollNode::ToProtobuf(proto::TreeNode* proto) const { - proto->set_id(id); - proto->set_parent_id(parent_id); - proto->set_owner_id(owner_id); - - DCHECK(!proto->has_scroll_node_data()); - proto::ScrollNodeData* data = proto->mutable_scroll_node_data(); - data->set_scrollable(scrollable); - data->set_main_thread_scrolling_reasons(main_thread_scrolling_reasons); - data->set_contains_non_fast_scrollable_region( - contains_non_fast_scrollable_region); - SizeToProto(scroll_clip_layer_bounds, - data->mutable_scroll_clip_layer_bounds()); - SizeToProto(bounds, data->mutable_bounds()); - data->set_max_scroll_offset_affected_by_page_scale( - max_scroll_offset_affected_by_page_scale); - data->set_is_inner_viewport_scroll_layer(is_inner_viewport_scroll_layer); - data->set_is_outer_viewport_scroll_layer(is_outer_viewport_scroll_layer); - Vector2dFToProto(offset_to_transform_parent, - data->mutable_offset_to_transform_parent()); - data->set_should_flatten(should_flatten); - data->set_user_scrollable_horizontal(user_scrollable_horizontal); - data->set_user_scrollable_vertical(user_scrollable_vertical); - element_id.ToProtobuf(data->mutable_element_id()); - data->set_transform_id(transform_id); -} - -void ScrollNode::FromProtobuf(const proto::TreeNode& proto) { - id = proto.id(); - parent_id = proto.parent_id(); - owner_id = proto.owner_id(); - - DCHECK(proto.has_scroll_node_data()); - const proto::ScrollNodeData& data = proto.scroll_node_data(); - - scrollable = data.scrollable(); - main_thread_scrolling_reasons = data.main_thread_scrolling_reasons(); - contains_non_fast_scrollable_region = - data.contains_non_fast_scrollable_region(); - scroll_clip_layer_bounds = ProtoToSize(data.scroll_clip_layer_bounds()); - bounds = ProtoToSize(data.bounds()); - max_scroll_offset_affected_by_page_scale = - data.max_scroll_offset_affected_by_page_scale(); - is_inner_viewport_scroll_layer = data.is_inner_viewport_scroll_layer(); - is_outer_viewport_scroll_layer = data.is_outer_viewport_scroll_layer(); - offset_to_transform_parent = - ProtoToVector2dF(data.offset_to_transform_parent()); - should_flatten = data.should_flatten(); - user_scrollable_horizontal = data.user_scrollable_horizontal(); - user_scrollable_vertical = data.user_scrollable_vertical(); - element_id.FromProtobuf(data.element_id()); - transform_id = data.transform_id(); -} - void ScrollNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); diff --git a/chromium/cc/trees/scroll_node.h b/chromium/cc/trees/scroll_node.h index 05154e43ea6..f68fd59e1e1 100644 --- a/chromium/cc/trees/scroll_node.h +++ b/chromium/cc/trees/scroll_node.h @@ -17,10 +17,6 @@ class TracedValue; namespace cc { -namespace proto { -class TreeNode; -} // namespace proto - struct CC_EXPORT ScrollNode { ScrollNode(); ScrollNode(const ScrollNode& other); @@ -61,13 +57,8 @@ struct CC_EXPORT ScrollNode { bool user_scrollable_vertical; ElementId element_id; int transform_id; - // Number of drawn layers pointing to this node or any of its descendants. - int num_drawn_descendants; bool operator==(const ScrollNode& other) const; - - void ToProtobuf(proto::TreeNode* proto) const; - void FromProtobuf(const proto::TreeNode& proto); void AsValueInto(base::trace_event::TracedValue* value) const; }; diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc index 901f3960729..593a7dc0629 100644 --- a/chromium/cc/trees/single_thread_proxy.cc +++ b/chromium/cc/trees/single_thread_proxy.cc @@ -8,7 +8,6 @@ #include "base/memory/ptr_util.h" #include "base/profiler/scoped_tracker.h" #include "base/trace_event/trace_event.h" -#include "cc/animation/animation_events.h" #include "cc/debug/benchmark_instrumentation.h" #include "cc/debug/devtools_instrumentation.h" #include "cc/output/compositor_frame_sink.h" @@ -23,6 +22,7 @@ #include "cc/trees/layer_tree_host_in_process.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/scoped_abort_remaining_swap_promises.h" namespace cc { @@ -39,7 +39,7 @@ SingleThreadProxy::SingleThreadProxy(LayerTreeHostInProcess* layer_tree_host, LayerTreeHostSingleThreadClient* client, TaskRunnerProvider* task_runner_provider) : layer_tree_host_(layer_tree_host), - client_(client), + single_thread_client_(client), task_runner_provider_(task_runner_provider), next_frame_is_newly_committed_frame_(false), #if DCHECK_IS_ON() @@ -156,7 +156,7 @@ void SingleThreadProxy::SetCompositorFrameSink( void SingleThreadProxy::SetNeedsAnimate() { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsAnimate"); DCHECK(task_runner_provider_->IsMainThread()); - client_->RequestScheduleAnimation(); + single_thread_client_->RequestScheduleAnimation(); if (animate_requested_) return; animate_requested_ = true; @@ -229,7 +229,7 @@ void SingleThreadProxy::CommitComplete() { void SingleThreadProxy::SetNeedsCommit() { DCHECK(task_runner_provider_->IsMainThread()); - client_->RequestScheduleComposite(); + single_thread_client_->RequestScheduleComposite(); if (commit_requested_) return; commit_requested_ = true; @@ -289,16 +289,17 @@ void SingleThreadProxy::Stop() { DebugScopedSetMainThreadBlocked main_thread_blocked(task_runner_provider_); DebugScopedSetImplThread impl(task_runner_provider_); + // Prevent the scheduler from performing actions while we're in an + // inconsistent state. + if (scheduler_on_impl_thread_) + scheduler_on_impl_thread_->Stop(); // Take away the CompositorFrameSink before destroying things so it doesn't // try to call into its client mid-shutdown. layer_tree_host_impl_->ReleaseCompositorFrameSink(); - - BlockingTaskRunner::CapturePostTasks blocked( - task_runner_provider_->blocking_main_thread_task_runner()); scheduler_on_impl_thread_ = nullptr; layer_tree_host_impl_ = nullptr; } - layer_tree_host_ = NULL; + layer_tree_host_ = nullptr; } void SingleThreadProxy::SetMutator(std::unique_ptr<LayerTreeMutator> mutator) { @@ -330,7 +331,7 @@ void SingleThreadProxy::NotifyReadyToDraw() { } void SingleThreadProxy::SetNeedsRedrawOnImplThread() { - client_->RequestScheduleComposite(); + single_thread_client_->RequestScheduleComposite(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->SetNeedsRedraw(); } @@ -338,7 +339,7 @@ void SingleThreadProxy::SetNeedsRedrawOnImplThread() { void SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread() { TRACE_EVENT0("cc", "SingleThreadProxy::SetNeedsOneBeginImplFrameOnImplThread"); - client_->RequestScheduleComposite(); + single_thread_client_->RequestScheduleComposite(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->SetNeedsOneBeginImplFrame(); } @@ -350,7 +351,7 @@ void SingleThreadProxy::SetNeedsPrepareTilesOnImplThread() { } void SingleThreadProxy::SetNeedsCommitOnImplThread() { - client_->RequestScheduleComposite(); + single_thread_client_->RequestScheduleComposite(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->SetNeedsBeginMainFrame(); } @@ -364,7 +365,7 @@ void SingleThreadProxy::SetVideoNeedsBeginFrames(bool needs_begin_frames) { } void SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread( - std::unique_ptr<AnimationEvents> events) { + std::unique_ptr<MutatorEvents> events) { TRACE_EVENT0( "cc", "SingleThreadProxy::PostAnimationEventsToMainThreadOnImplThread"); DCHECK(task_runner_provider_->IsImplThread()); @@ -408,7 +409,7 @@ void SingleThreadProxy::DidLoseCompositorFrameSinkOnImplThread() { // the output surface if already in BEGIN_IMPL_FRAME_STATE_IDLE. layer_tree_host_->DidLoseCompositorFrameSink(); } - client_->DidAbortSwapBuffers(); + single_thread_client_->DidLoseCompositorFrameSink(); if (scheduler_on_impl_thread_) scheduler_on_impl_thread_->DidLoseCompositorFrameSink(); compositor_frame_sink_lost_ = true; @@ -419,12 +420,12 @@ void SingleThreadProxy::SetBeginFrameSource(BeginFrameSource* source) { scheduler_on_impl_thread_->SetBeginFrameSource(source); } -void SingleThreadProxy::DidSwapBuffersCompleteOnImplThread() { +void SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread() { TRACE_EVENT0("cc,benchmark", - "SingleThreadProxy::DidSwapBuffersCompleteOnImplThread"); + "SingleThreadProxy::DidReceiveCompositorFrameAckOnImplThread"); if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidSwapBuffersComplete(); - layer_tree_host_->DidCompleteSwapBuffers(); + scheduler_on_impl_thread_->DidReceiveCompositorFrameAck(); + layer_tree_host_->DidReceiveCompositorFrameAck(); } void SingleThreadProxy::OnDrawForCompositorFrameSink( @@ -549,8 +550,9 @@ DrawResult SingleThreadProxy::DoComposite(LayerTreeHostImpl::FrameData* frame) { if (draw_frame) { if (layer_tree_host_impl_->DrawLayers(frame)) { if (scheduler_on_impl_thread_) - scheduler_on_impl_thread_->DidSwapBuffers(); - client_->DidPostSwapBuffers(); + // Drawing implies we submitted a frame to the CompositorFrameSink. + scheduler_on_impl_thread_->DidSubmitCompositorFrame(); + single_thread_client_->DidSubmitCompositorFrame(); } } layer_tree_host_impl_->DidDrawAllLayers(*frame); @@ -687,13 +689,13 @@ void SingleThreadProxy::BeginMainFrameAbortedOnImplThread( scheduler_on_impl_thread_->BeginMainFrameAborted(reason); } -DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapIfPossible() { +DrawResult SingleThreadProxy::ScheduledActionDrawIfPossible() { DebugScopedSetImplThread impl(task_runner_provider_); LayerTreeHostImpl::FrameData frame; return DoComposite(&frame); } -DrawResult SingleThreadProxy::ScheduledActionDrawAndSwapForced() { +DrawResult SingleThreadProxy::ScheduledActionDrawForced() { NOTREACHED(); return INVALID_RESULT; } @@ -732,10 +734,11 @@ void SingleThreadProxy::ScheduledActionInvalidateCompositorFrameSink() { NOTREACHED(); } -void SingleThreadProxy::UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) { - NOTREACHED() << "Top Controls are used only in threaded mode"; +void SingleThreadProxy::UpdateBrowserControlsState( + BrowserControlsState constraints, + BrowserControlsState current, + bool animate) { + NOTREACHED() << "Browser Controls are used only in threaded mode"; } void SingleThreadProxy::DidFinishImplFrame() { diff --git a/chromium/cc/trees/single_thread_proxy.h b/chromium/cc/trees/single_thread_proxy.h index 05aea535125..2fdcfd60798 100644 --- a/chromium/cc/trees/single_thread_proxy.h +++ b/chromium/cc/trees/single_thread_proxy.h @@ -19,9 +19,8 @@ namespace cc { -class AnimationEvents; +class MutatorEvents; class BeginFrameSource; -class ContextProvider; class LayerTreeHostInProcess; class LayerTreeHostSingleThreadClient; @@ -57,16 +56,16 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void SetMutator(std::unique_ptr<LayerTreeMutator> mutator) override; bool SupportsImplScrolling() const override; bool MainFrameWillHappenForTesting() override; - void UpdateTopControlsState(TopControlsState constraints, - TopControlsState current, - bool animate) override; + void UpdateBrowserControlsState(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) override; // SchedulerClient implementation void WillBeginImplFrame(const BeginFrameArgs& args) override; void DidFinishImplFrame() override; void ScheduledActionSendBeginMainFrame(const BeginFrameArgs& args) override; - DrawResult ScheduledActionDrawAndSwapIfPossible() override; - DrawResult ScheduledActionDrawAndSwapForced() override; + DrawResult ScheduledActionDrawIfPossible() override; + DrawResult ScheduledActionDrawForced() override; void ScheduledActionCommit() override; void ScheduledActionActivateSyncTree() override; void ScheduledActionBeginCompositorFrameSinkCreation() override; @@ -77,7 +76,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // LayerTreeHostImplClient implementation void DidLoseCompositorFrameSinkOnImplThread() override; void SetBeginFrameSource(BeginFrameSource* source) override; - void DidSwapBuffersCompleteOnImplThread() override; + void DidReceiveCompositorFrameAckOnImplThread() override; void OnCanDrawStateChanged(bool can_draw) override; void NotifyReadyToActivate() override; void NotifyReadyToDraw() override; @@ -87,7 +86,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, void SetNeedsCommitOnImplThread() override; void SetVideoNeedsBeginFrames(bool needs_begin_frames) override; void PostAnimationEventsToMainThreadOnImplThread( - std::unique_ptr<AnimationEvents> events) override; + std::unique_ptr<MutatorEvents> events) override; bool IsInsideDraw() override; void RenewTreePriority() override {} void PostDelayedAnimationTaskOnImplThread(const base::Closure& task, @@ -123,7 +122,7 @@ class CC_EXPORT SingleThreadProxy : public Proxy, // Accessed on main thread only. LayerTreeHostInProcess* layer_tree_host_; - LayerTreeHostSingleThreadClient* client_; + LayerTreeHostSingleThreadClient* single_thread_client_; TaskRunnerProvider* task_runner_provider_; diff --git a/chromium/cc/animation/target_property.cc b/chromium/cc/trees/target_property.cc index f39d93d526f..cabff92b5a5 100644 --- a/chromium/cc/animation/target_property.cc +++ b/chromium/cc/trees/target_property.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "cc/animation/target_property.h" +#include "cc/trees/target_property.h" #include "base/macros.h" diff --git a/chromium/cc/animation/target_property.h b/chromium/cc/trees/target_property.h index 632e826a00c..34ddf3fd7cc 100644 --- a/chromium/cc/animation/target_property.h +++ b/chromium/cc/trees/target_property.h @@ -2,8 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#ifndef CC_ANIMATION_TARGET_PROPERTY_H_ -#define CC_ANIMATION_TARGET_PROPERTY_H_ +#ifndef CC_TREES_TARGET_PROPERTY_H_ +#define CC_TREES_TARGET_PROPERTY_H_ #include <bitset> @@ -31,4 +31,4 @@ using TargetProperties = std::bitset<TargetProperty::LAST_TARGET_PROPERTY + 1>; } // namespace cc -#endif // CC_ANIMATION_TARGET_PROPERTY_H_ +#endif // CC_TREES_TARGET_PROPERTY_H_ diff --git a/chromium/cc/trees/task_runner_provider.h b/chromium/cc/trees/task_runner_provider.h index 5092e533475..e4c7b195cc4 100644 --- a/chromium/cc/trees/task_runner_provider.h +++ b/chromium/cc/trees/task_runner_provider.h @@ -19,9 +19,6 @@ #include "cc/base/cc_export.h" namespace base { -namespace trace_event { -class TracedValue; -} class SingleThreadTaskRunner; } diff --git a/chromium/cc/trees/threaded_channel.cc b/chromium/cc/trees/threaded_channel.cc index 7ff17e1cccb..05bf230942a 100644 --- a/chromium/cc/trees/threaded_channel.cc +++ b/chromium/cc/trees/threaded_channel.cc @@ -9,9 +9,9 @@ #include "base/memory/ptr_util.h" #include "base/single_thread_task_runner.h" #include "base/trace_event/trace_event.h" -#include "cc/animation/animation_events.h" -#include "cc/animation/layer_tree_mutator.h" #include "cc/trees/layer_tree_host.h" +#include "cc/trees/layer_tree_mutator.h" +#include "cc/trees/mutator_host.h" namespace cc { @@ -37,14 +37,15 @@ ThreadedChannel::~ThreadedChannel() { DCHECK(!IsInitialized()); } -void ThreadedChannel::UpdateTopControlsStateOnImpl(TopControlsState constraints, - TopControlsState current, - bool animate) { +void ThreadedChannel::UpdateBrowserControlsStateOnImpl( + BrowserControlsState constraints, + BrowserControlsState current, + bool animate) { DCHECK(IsMainThread()); ImplThreadTaskRunner()->PostTask( FROM_HERE, - base::Bind(&ProxyImpl::UpdateTopControlsStateOnImpl, proxy_impl_weak_ptr_, - constraints, current, animate)); + base::Bind(&ProxyImpl::UpdateBrowserControlsStateOnImpl, + proxy_impl_weak_ptr_, constraints, current, animate)); } void ThreadedChannel::InitializeCompositorFrameSinkOnImpl( @@ -191,10 +192,10 @@ void ThreadedChannel::SynchronouslyCloseImpl() { main().initialized = false; } -void ThreadedChannel::DidCompleteSwapBuffers() { +void ThreadedChannel::DidReceiveCompositorFrameAck() { DCHECK(IsImplThread()); MainThreadTaskRunner()->PostTask( - FROM_HERE, base::Bind(&ProxyMain::DidCompleteSwapBuffers, + FROM_HERE, base::Bind(&ProxyMain::DidReceiveCompositorFrameAck, impl().proxy_main_weak_ptr)); } @@ -213,7 +214,7 @@ void ThreadedChannel::DidCommitAndDrawFrame() { } void ThreadedChannel::SetAnimationEvents( - std::unique_ptr<AnimationEvents> events) { + std::unique_ptr<MutatorEvents> events) { DCHECK(IsImplThread()); MainThreadTaskRunner()->PostTask( FROM_HERE, base::Bind(&ProxyMain::SetAnimationEvents, diff --git a/chromium/cc/trees/threaded_channel.h b/chromium/cc/trees/threaded_channel.h index be0954d6120..b94f15e2629 100644 --- a/chromium/cc/trees/threaded_channel.h +++ b/chromium/cc/trees/threaded_channel.h @@ -84,9 +84,9 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { ~ThreadedChannel() override; // ChannelMain Implementation - void UpdateTopControlsStateOnImpl(TopControlsState constraints, - TopControlsState current, - bool animate) override; + void UpdateBrowserControlsStateOnImpl(BrowserControlsState constraints, + BrowserControlsState current, + bool animate) override; void InitializeCompositorFrameSinkOnImpl( CompositorFrameSink* output_surface) override; void InitializeMutatorOnImpl( @@ -116,10 +116,10 @@ class CC_EXPORT ThreadedChannel : public ChannelMain, public ChannelImpl { void SynchronouslyCloseImpl() override; // ChannelImpl Implementation - void DidCompleteSwapBuffers() override; + void DidReceiveCompositorFrameAck() override; void BeginMainFrameNotExpectedSoon() override; void DidCommitAndDrawFrame() override; - void SetAnimationEvents(std::unique_ptr<AnimationEvents> events) override; + void SetAnimationEvents(std::unique_ptr<MutatorEvents> events) override; void DidLoseCompositorFrameSink() override; void RequestNewCompositorFrameSink() override; void DidInitializeCompositorFrameSink(bool success) override; diff --git a/chromium/cc/trees/transform_node.cc b/chromium/cc/trees/transform_node.cc index 0060c3a06e0..b0655785c10 100644 --- a/chromium/cc/trees/transform_node.cc +++ b/chromium/cc/trees/transform_node.cc @@ -5,7 +5,6 @@ #include "base/trace_event/trace_event_argument.h" #include "cc/base/math_util.h" #include "cc/proto/gfx_conversions.h" -#include "cc/proto/property_tree.pb.h" #include "cc/trees/transform_node.h" #include "ui/gfx/geometry/point3_f.h" @@ -30,11 +29,11 @@ TransformNode::TransformNode() node_and_ancestors_are_flat(true), node_and_ancestors_have_only_integer_translation(true), scrolls(false), - needs_surface_contents_scale(false), - affected_by_inner_viewport_bounds_delta_x(false), - affected_by_inner_viewport_bounds_delta_y(false), - affected_by_outer_viewport_bounds_delta_x(false), - affected_by_outer_viewport_bounds_delta_y(false), + should_be_snapped(false), + moved_by_inner_viewport_bounds_delta_x(false), + moved_by_inner_viewport_bounds_delta_y(false), + moved_by_outer_viewport_bounds_delta_x(false), + moved_by_outer_viewport_bounds_delta_y(false), in_subtree_of_page_scale_layer(false), transform_changed(false), post_local_scale_factor(1.0f) {} @@ -64,22 +63,21 @@ bool TransformNode::operator==(const TransformNode& other) const { node_and_ancestors_have_only_integer_translation == other.node_and_ancestors_have_only_integer_translation && scrolls == other.scrolls && - needs_surface_contents_scale == other.needs_surface_contents_scale && - affected_by_inner_viewport_bounds_delta_x == - other.affected_by_inner_viewport_bounds_delta_x && - affected_by_inner_viewport_bounds_delta_y == - other.affected_by_inner_viewport_bounds_delta_y && - affected_by_outer_viewport_bounds_delta_x == - other.affected_by_outer_viewport_bounds_delta_x && - affected_by_outer_viewport_bounds_delta_y == - other.affected_by_outer_viewport_bounds_delta_y && + should_be_snapped == other.should_be_snapped && + moved_by_inner_viewport_bounds_delta_x == + other.moved_by_inner_viewport_bounds_delta_x && + moved_by_inner_viewport_bounds_delta_y == + other.moved_by_inner_viewport_bounds_delta_y && + moved_by_outer_viewport_bounds_delta_x == + other.moved_by_outer_viewport_bounds_delta_x && + moved_by_outer_viewport_bounds_delta_y == + other.moved_by_outer_viewport_bounds_delta_y && in_subtree_of_page_scale_layer == other.in_subtree_of_page_scale_layer && transform_changed == other.transform_changed && post_local_scale_factor == other.post_local_scale_factor && - surface_contents_scale == other.surface_contents_scale && scroll_offset == other.scroll_offset && - scroll_snap == other.scroll_snap && + snap_amount == other.snap_amount && source_offset == other.source_offset && source_to_parent == other.source_to_parent; } @@ -102,124 +100,6 @@ void TransformNode::update_post_local_transform( transform_origin.z()); } -void TransformNode::ToProtobuf(proto::TreeNode* proto) const { - proto->set_id(id); - proto->set_parent_id(parent_id); - proto->set_owner_id(owner_id); - - DCHECK(!proto->has_transform_node_data()); - proto::TranformNodeData* data = proto->mutable_transform_node_data(); - - TransformToProto(pre_local, data->mutable_pre_local()); - TransformToProto(local, data->mutable_local()); - TransformToProto(post_local, data->mutable_post_local()); - - TransformToProto(to_parent, data->mutable_to_parent()); - - data->set_source_node_id(source_node_id); - data->set_sorting_context_id(sorting_context_id); - - data->set_needs_local_transform_update(needs_local_transform_update); - - data->set_node_and_ancestors_are_animated_or_invertible( - node_and_ancestors_are_animated_or_invertible); - - data->set_is_invertible(is_invertible); - data->set_ancestors_are_invertible(ancestors_are_invertible); - - data->set_has_potential_animation(has_potential_animation); - data->set_is_currently_animating(is_currently_animating); - data->set_to_screen_is_potentially_animated( - to_screen_is_potentially_animated); - data->set_has_only_translation_animations(has_only_translation_animations); - - data->set_flattens_inherited_transform(flattens_inherited_transform); - data->set_node_and_ancestors_are_flat(node_and_ancestors_are_flat); - - data->set_node_and_ancestors_have_only_integer_translation( - node_and_ancestors_have_only_integer_translation); - data->set_scrolls(scrolls); - data->set_needs_surface_contents_scale(needs_surface_contents_scale); - - data->set_affected_by_inner_viewport_bounds_delta_x( - affected_by_inner_viewport_bounds_delta_x); - data->set_affected_by_inner_viewport_bounds_delta_y( - affected_by_inner_viewport_bounds_delta_y); - data->set_affected_by_outer_viewport_bounds_delta_x( - affected_by_outer_viewport_bounds_delta_x); - data->set_affected_by_outer_viewport_bounds_delta_y( - affected_by_outer_viewport_bounds_delta_y); - - data->set_in_subtree_of_page_scale_layer(in_subtree_of_page_scale_layer); - data->set_transform_changed(transform_changed); - data->set_post_local_scale_factor(post_local_scale_factor); - - Vector2dFToProto(surface_contents_scale, - data->mutable_surface_contents_scale()); - ScrollOffsetToProto(scroll_offset, data->mutable_scroll_offset()); - Vector2dFToProto(scroll_snap, data->mutable_scroll_snap()); - Vector2dFToProto(source_offset, data->mutable_source_offset()); - Vector2dFToProto(source_to_parent, data->mutable_source_to_parent()); -} - -void TransformNode::FromProtobuf(const proto::TreeNode& proto) { - id = proto.id(); - parent_id = proto.parent_id(); - owner_id = proto.owner_id(); - - DCHECK(proto.has_transform_node_data()); - const proto::TranformNodeData& data = proto.transform_node_data(); - - pre_local = ProtoToTransform(data.pre_local()); - local = ProtoToTransform(data.local()); - post_local = ProtoToTransform(data.post_local()); - - to_parent = ProtoToTransform(data.to_parent()); - - source_node_id = data.source_node_id(); - sorting_context_id = data.sorting_context_id(); - - needs_local_transform_update = data.needs_local_transform_update(); - - node_and_ancestors_are_animated_or_invertible = - data.node_and_ancestors_are_animated_or_invertible(); - - is_invertible = data.is_invertible(); - ancestors_are_invertible = data.ancestors_are_invertible(); - - has_potential_animation = data.has_potential_animation(); - is_currently_animating = data.is_currently_animating(); - to_screen_is_potentially_animated = data.to_screen_is_potentially_animated(); - has_only_translation_animations = data.has_only_translation_animations(); - - flattens_inherited_transform = data.flattens_inherited_transform(); - node_and_ancestors_are_flat = data.node_and_ancestors_are_flat(); - - node_and_ancestors_have_only_integer_translation = - data.node_and_ancestors_have_only_integer_translation(); - scrolls = data.scrolls(); - needs_surface_contents_scale = data.needs_surface_contents_scale(); - - affected_by_inner_viewport_bounds_delta_x = - data.affected_by_inner_viewport_bounds_delta_x(); - affected_by_inner_viewport_bounds_delta_y = - data.affected_by_inner_viewport_bounds_delta_y(); - affected_by_outer_viewport_bounds_delta_x = - data.affected_by_outer_viewport_bounds_delta_x(); - affected_by_outer_viewport_bounds_delta_y = - data.affected_by_outer_viewport_bounds_delta_y(); - - in_subtree_of_page_scale_layer = data.in_subtree_of_page_scale_layer(); - transform_changed = data.transform_changed(); - post_local_scale_factor = data.post_local_scale_factor(); - - surface_contents_scale = ProtoToVector2dF(data.surface_contents_scale()); - scroll_offset = ProtoToScrollOffset(data.scroll_offset()); - scroll_snap = ProtoToVector2dF(data.scroll_snap()); - source_offset = ProtoToVector2dF(data.source_offset()); - source_to_parent = ProtoToVector2dF(data.source_to_parent()); -} - void TransformNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("id", id); value->SetInteger("parent_id", parent_id); @@ -233,11 +113,11 @@ void TransformNode::AsValueInto(base::trace_event::TracedValue* value) const { value->SetInteger("source_node_id", source_node_id); value->SetInteger("sorting_context_id", sorting_context_id); MathUtil::AddToTracedValue("scroll_offset", scroll_offset, value); - MathUtil::AddToTracedValue("scroll_snap", scroll_snap, value); + MathUtil::AddToTracedValue("snap_amount", snap_amount, value); } TransformCachedNodeData::TransformCachedNodeData() - : target_id(-1), content_target_id(-1) {} + : target_id(-1), content_target_id(-1), is_showing_backface(false) {} TransformCachedNodeData::TransformCachedNodeData( const TransformCachedNodeData& other) = default; @@ -246,30 +126,10 @@ TransformCachedNodeData::~TransformCachedNodeData() {} bool TransformCachedNodeData::operator==( const TransformCachedNodeData& other) const { - return from_target == other.from_target && to_target == other.to_target && - from_screen == other.from_screen && to_screen == other.to_screen && + return from_screen == other.from_screen && to_screen == other.to_screen && target_id == other.target_id && - content_target_id == other.content_target_id; -} - -void TransformCachedNodeData::ToProtobuf( - proto::TransformCachedNodeData* proto) const { - TransformToProto(from_target, proto->mutable_from_target()); - TransformToProto(to_target, proto->mutable_to_target()); - TransformToProto(from_screen, proto->mutable_from_screen()); - TransformToProto(to_screen, proto->mutable_to_screen()); - proto->set_target_id(target_id); - proto->set_content_target_id(content_target_id); -} - -void TransformCachedNodeData::FromProtobuf( - const proto::TransformCachedNodeData& proto) { - from_target = ProtoToTransform(proto.from_target()); - to_target = ProtoToTransform(proto.to_target()); - from_screen = ProtoToTransform(proto.from_screen()); - to_screen = ProtoToTransform(proto.to_screen()); - target_id = proto.target_id(); - content_target_id = proto.content_target_id(); + content_target_id == other.content_target_id && + is_showing_backface == other.is_showing_backface; } } // namespace cc diff --git a/chromium/cc/trees/transform_node.h b/chromium/cc/trees/transform_node.h index 1e8c3910aaa..b94bf9ee2eb 100644 --- a/chromium/cc/trees/transform_node.h +++ b/chromium/cc/trees/transform_node.h @@ -18,11 +18,6 @@ class TracedValue; namespace cc { -namespace proto { -class TransformCachedNodeData; -class TreeNode; -} // namespace proto - struct CC_EXPORT TransformNode { TransformNode(); TransformNode(const TransformNode&); @@ -94,14 +89,14 @@ struct CC_EXPORT TransformNode { bool scrolls : 1; - bool needs_surface_contents_scale : 1; + bool should_be_snapped : 1; // These are used to position nodes wrt the right or bottom of the inner or // outer viewport. - bool affected_by_inner_viewport_bounds_delta_x : 1; - bool affected_by_inner_viewport_bounds_delta_y : 1; - bool affected_by_outer_viewport_bounds_delta_x : 1; - bool affected_by_outer_viewport_bounds_delta_y : 1; + bool moved_by_inner_viewport_bounds_delta_x : 1; + bool moved_by_inner_viewport_bounds_delta_y : 1; + bool moved_by_outer_viewport_bounds_delta_x : 1; + bool moved_by_outer_viewport_bounds_delta_y : 1; // Layer scale factor is used as a fallback when we either cannot adjust // raster scale or if the raster scale cannot be extracted from the screen @@ -115,14 +110,13 @@ struct CC_EXPORT TransformNode { // TODO(vollick): will be moved when accelerated effects are implemented. float post_local_scale_factor; - gfx::Vector2dF surface_contents_scale; - // TODO(vollick): will be moved when accelerated effects are implemented. gfx::ScrollOffset scroll_offset; - // We scroll snap where possible, but this means fixed-pos elements must be - // adjusted. This value stores the snapped amount for this purpose. - gfx::Vector2dF scroll_snap; + // This value stores the snapped amount whenever we snap. If the snap is due + // to a scroll, we need it to calculate fixed-pos elements adjustment, even + // otherwise we may need it to undo the snapping next frame. + gfx::Vector2dF snap_amount; // TODO(vollick): will be moved when accelerated effects are implemented. gfx::Vector2dF source_offset; @@ -140,9 +134,6 @@ struct CC_EXPORT TransformNode { void update_post_local_transform(const gfx::PointF& position, const gfx::Point3F& transform_origin); - void ToProtobuf(proto::TreeNode* proto) const; - void FromProtobuf(const proto::TreeNode& proto); - void AsValueInto(base::trace_event::TracedValue* value) const; }; @@ -152,8 +143,6 @@ struct CC_EXPORT TransformCachedNodeData { TransformCachedNodeData(const TransformCachedNodeData& other); ~TransformCachedNodeData(); - gfx::Transform from_target; - gfx::Transform to_target; gfx::Transform from_screen; gfx::Transform to_screen; int target_id; @@ -161,10 +150,9 @@ struct CC_EXPORT TransformCachedNodeData { // with this transform node. int content_target_id; - bool operator==(const TransformCachedNodeData& other) const; + bool is_showing_backface : 1; - void ToProtobuf(proto::TransformCachedNodeData* proto) const; - void FromProtobuf(const proto::TransformCachedNodeData& proto); + bool operator==(const TransformCachedNodeData& other) const; }; } // namespace cc diff --git a/chromium/cc/trees/tree_synchronizer.h b/chromium/cc/trees/tree_synchronizer.h index 58688b76706..b088eaf0284 100644 --- a/chromium/cc/trees/tree_synchronizer.h +++ b/chromium/cc/trees/tree_synchronizer.h @@ -14,7 +14,6 @@ namespace cc { class LayerImpl; class LayerTree; -class LayerTreeHost; class LayerTreeImpl; class Layer; diff --git a/chromium/cc/trees/tree_synchronizer_unittest.cc b/chromium/cc/trees/tree_synchronizer_unittest.cc index f656634636a..682ce60d673 100644 --- a/chromium/cc/trees/tree_synchronizer_unittest.cc +++ b/chromium/cc/trees/tree_synchronizer_unittest.cc @@ -13,6 +13,7 @@ #include "base/format_macros.h" #include "base/memory/ptr_util.h" #include "base/strings/stringprintf.h" +#include "cc/animation/animation_host.h" #include "cc/layers/layer.h" #include "cc/layers/layer_impl.h" #include "cc/test/animation_test_common.h" @@ -20,7 +21,6 @@ #include "cc/test/fake_layer_tree_host.h" #include "cc/test/fake_rendering_stats_instrumentation.h" #include "cc/test/stub_layer_tree_host_single_thread_client.h" -#include "cc/test/test_shared_bitmap_manager.h" #include "cc/test/test_task_graph_runner.h" #include "cc/trees/effect_node.h" #include "cc/trees/layer_tree_host_common.h" @@ -128,7 +128,10 @@ void ExpectTreesAreIdentical(Layer* root_layer, class TreeSynchronizerTest : public testing::Test { protected: TreeSynchronizerTest() - : host_(FakeLayerTreeHost::Create(&client_, &task_graph_runner_)) {} + : animation_host_(AnimationHost::CreateForTesting(ThreadInstance::MAIN)), + host_(FakeLayerTreeHost::Create(&client_, + &task_graph_runner_, + animation_host_.get())) {} bool is_equal(ScrollTree::ScrollOffsetMap map, ScrollTree::ScrollOffsetMap other) { @@ -151,6 +154,7 @@ class TreeSynchronizerTest : public testing::Test { FakeLayerTreeHostClient client_; StubLayerTreeHostSingleThreadClient single_thread_client_; TestTaskGraphRunner task_graph_runner_; + std::unique_ptr<AnimationHost> animation_host_; std::unique_ptr<FakeLayerTreeHost> host_; }; @@ -483,7 +487,6 @@ TEST_F(TreeSynchronizerTest, SynchronizeCurrentlyScrollingNode) { FakeLayerTreeHostImplClient client; FakeImplTaskRunnerProvider task_runner_provider; FakeRenderingStatsInstrumentation stats_instrumentation; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl* host_impl = host_->host_impl(); host_impl->CreatePendingTree(); @@ -531,7 +534,6 @@ TEST_F(TreeSynchronizerTest, SynchronizeScrollTreeScrollOffsetMap) { FakeLayerTreeHostImplClient client; FakeImplTaskRunnerProvider task_runner_provider; FakeRenderingStatsInstrumentation stats_instrumentation; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl* host_impl = host_->host_impl(); host_impl->CreatePendingTree(); @@ -627,7 +629,6 @@ TEST_F(TreeSynchronizerTest, RefreshPropertyTreesCachedData) { FakeLayerTreeHostImplClient client; FakeImplTaskRunnerProvider task_runner_provider; FakeRenderingStatsInstrumentation stats_instrumentation; - TestSharedBitmapManager shared_bitmap_manager; TestTaskGraphRunner task_graph_runner; FakeLayerTreeHostImpl* host_impl = host_->host_impl(); host_impl->CreatePendingTree(); |