summaryrefslogtreecommitdiffstats
path: root/chromium/cc
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-11 11:32:04 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-03-18 13:40:17 +0000
commit31ccca0778db85c159634478b4ec7997f6704860 (patch)
tree3d33fc3afd9d5ec95541e1bbe074a9cf8da12a0e /chromium/cc
parent248b70b82a40964d5594eb04feca0fa36716185d (diff)
BASELINE: Update Chromium to 80.0.3987.136
Change-Id: I98e1649aafae85ba3a83e67af00bb27ef301db7b Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
Diffstat (limited to 'chromium/cc')
-rw-r--r--chromium/cc/BUILD.gn9
-rw-r--r--chromium/cc/DEPS2
-rw-r--r--chromium/cc/OWNERS2
-rw-r--r--chromium/cc/animation/BUILD.gn2
-rw-r--r--chromium/cc/animation/animation.cc71
-rw-r--r--chromium/cc/animation/animation.h17
-rw-r--r--chromium/cc/animation/animation_delegate.h2
-rw-r--r--chromium/cc/animation/animation_events.cc37
-rw-r--r--chromium/cc/animation/animation_events.h26
-rw-r--r--chromium/cc/animation/animation_host.cc61
-rw-r--r--chromium/cc/animation/animation_host.h5
-rw-r--r--chromium/cc/animation/animation_host_unittest.cc2
-rw-r--r--chromium/cc/animation/element_animations.cc35
-rw-r--r--chromium/cc/animation/element_animations.h6
-rw-r--r--chromium/cc/animation/element_animations_unittest.cc122
-rw-r--r--chromium/cc/animation/keyframe_effect.cc154
-rw-r--r--chromium/cc/animation/keyframe_effect.h11
-rw-r--r--chromium/cc/animation/keyframe_model.h3
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve.cc112
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve.h50
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve_factory.cc76
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve_factory.h38
-rw-r--r--chromium/cc/animation/scroll_offset_animation_curve_unittest.cc97
-rw-r--r--chromium/cc/animation/scroll_offset_animations_impl.cc16
-rw-r--r--chromium/cc/animation/scroll_offset_animations_impl.h12
-rw-r--r--chromium/cc/animation/scroll_timeline.h4
-rw-r--r--chromium/cc/animation/single_keyframe_effect_animation.cc13
-rw-r--r--chromium/cc/animation/single_keyframe_effect_animation.h4
-rw-r--r--chromium/cc/animation/worklet_animation.cc21
-rw-r--r--chromium/cc/animation/worklet_animation.h10
-rw-r--r--chromium/cc/animation/worklet_animation_unittest.cc46
-rw-r--r--chromium/cc/base/devtools_instrumentation.cc65
-rw-r--r--chromium/cc/base/devtools_instrumentation.h46
-rw-r--r--chromium/cc/debug/debug_colors.cc11
-rw-r--r--chromium/cc/debug/debug_colors.h4
-rw-r--r--chromium/cc/debug/layer_tree_debug_state.cc6
-rw-r--r--chromium/cc/debug/layer_tree_debug_state.h1
-rw-r--r--chromium/cc/input/README.md106
-rw-r--r--chromium/cc/input/browser_controls_offset_manager.cc245
-rw-r--r--chromium/cc/input/browser_controls_offset_manager.h64
-rw-r--r--chromium/cc/input/browser_controls_offset_manager_client.h8
-rw-r--r--chromium/cc/input/browser_controls_offset_manager_unittest.cc212
-rw-r--r--chromium/cc/input/input_handler.h12
-rw-r--r--chromium/cc/input/layer_selection_bound.cc6
-rw-r--r--chromium/cc/input/layer_selection_bound.h4
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason.cc5
-rw-r--r--chromium/cc/input/main_thread_scrolling_reason_unittest.cc40
-rw-r--r--chromium/cc/input/scroll_snap_data.cc132
-rw-r--r--chromium/cc/input/scroll_snap_data.h56
-rw-r--r--chromium/cc/input/scroll_snap_data_unittest.cc313
-rw-r--r--chromium/cc/input/scroll_state.cc14
-rw-r--r--chromium/cc/input/scroll_state.h17
-rw-r--r--chromium/cc/input/scroll_state_data.h4
-rw-r--r--chromium/cc/input/scroll_state_unittest.cc16
-rw-r--r--chromium/cc/input/scrollbar.h42
-rw-r--r--chromium/cc/input/scrollbar_controller.cc289
-rw-r--r--chromium/cc/input/scrollbar_controller.h56
-rw-r--r--chromium/cc/input/single_scrollbar_animation_controller_thinning.cc5
-rw-r--r--chromium/cc/input/snap_fling_controller.cc4
-rw-r--r--chromium/cc/input/snap_fling_controller.h7
-rw-r--r--chromium/cc/input/snap_fling_controller_unittest.cc10
-rw-r--r--chromium/cc/input/snap_selection_strategy.cc21
-rw-r--r--chromium/cc/input/snap_selection_strategy.h23
-rw-r--r--chromium/cc/ipc/BUILD.gn22
-rw-r--r--chromium/cc/ipc/OWNERS2
-rw-r--r--chromium/cc/ipc/README.md12
-rw-r--r--chromium/cc/ipc/cc_param_traits.cc25
-rw-r--r--chromium/cc/ipc/cc_param_traits_macros.h17
-rw-r--r--chromium/cc/layers/heads_up_display_layer_impl.cc26
-rw-r--r--chromium/cc/layers/layer.cc88
-rw-r--r--chromium/cc/layers/layer.h108
-rw-r--r--chromium/cc/layers/layer_client.h45
-rw-r--r--chromium/cc/layers/layer_impl.cc82
-rw-r--r--chromium/cc/layers/layer_impl.h14
-rw-r--r--chromium/cc/layers/layer_impl_unittest.cc2
-rw-r--r--chromium/cc/layers/painted_overlay_scrollbar_layer.cc63
-rw-r--r--chromium/cc/layers/painted_overlay_scrollbar_layer.h13
-rw-r--r--chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc11
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer.cc137
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer.h28
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl.cc68
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl.h6
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc2
-rw-r--r--chromium/cc/layers/painted_scrollbar_layer_unittest.cc48
-rw-r--r--chromium/cc/layers/picture_layer.cc18
-rw-r--r--chromium/cc/layers/picture_layer.h2
-rw-r--r--chromium/cc/layers/picture_layer_impl.cc20
-rw-r--r--chromium/cc/layers/picture_layer_impl_unittest.cc67
-rw-r--r--chromium/cc/layers/picture_layer_unittest.cc70
-rw-r--r--chromium/cc/layers/scrollbar_layer_base.cc13
-rw-r--r--chromium/cc/layers/scrollbar_layer_base.h11
-rw-r--r--chromium/cc/layers/scrollbar_layer_unittest.cc75
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer.cc11
-rw-r--r--chromium/cc/layers/solid_color_scrollbar_layer.h2
-rw-r--r--chromium/cc/layers/surface_layer_impl.cc2
-rw-r--r--chromium/cc/layers/texture_layer_impl_unittest.cc36
-rw-r--r--chromium/cc/layers/tile_size_calculator.cc19
-rw-r--r--chromium/cc/layers/tile_size_calculator.h1
-rw-r--r--chromium/cc/layers/video_layer_impl.cc2
-rw-r--r--chromium/cc/layers/viewport.cc34
-rw-r--r--chromium/cc/layers/viewport.h29
-rw-r--r--chromium/cc/metrics/begin_main_frame_metrics.cc3
-rw-r--r--chromium/cc/metrics/begin_main_frame_metrics.h2
-rw-r--r--chromium/cc/metrics/compositor_frame_reporter.cc240
-rw-r--r--chromium/cc/metrics/compositor_frame_reporter.h60
-rw-r--r--chromium/cc/metrics/compositor_frame_reporting_controller.cc11
-rw-r--r--chromium/cc/metrics/compositor_frame_reporting_controller.h3
-rw-r--r--chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc75
-rw-r--r--chromium/cc/metrics/compositor_timing_history.cc39
-rw-r--r--chromium/cc/metrics/compositor_timing_history.h19
-rw-r--r--chromium/cc/metrics/compositor_timing_history_unittest.cc2
-rw-r--r--chromium/cc/metrics/frame_sequence_metrics_unittest.cc75
-rw-r--r--chromium/cc/metrics/frame_sequence_tracker.cc417
-rw-r--r--chromium/cc/metrics/frame_sequence_tracker.h162
-rw-r--r--chromium/cc/metrics/frame_sequence_tracker_unittest.cc71
-rw-r--r--chromium/cc/metrics/throughput_ukm_reporter.cc51
-rw-r--r--chromium/cc/metrics/throughput_ukm_reporter.h31
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc13
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h10
-rw-r--r--chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc252
-rw-r--r--chromium/cc/mojom/BUILD.gn16
-rw-r--r--chromium/cc/mojom/OWNERS5
-rw-r--r--chromium/cc/mojom/README.md10
-rw-r--r--chromium/cc/mojom/touch_action.mojom8
-rw-r--r--chromium/cc/mojom/touch_action.typemap12
-rw-r--r--chromium/cc/paint/discardable_image_map.cc68
-rw-r--r--chromium/cc/paint/discardable_image_map_unittest.cc60
-rw-r--r--chromium/cc/paint/display_item_list.h2
-rw-r--r--chromium/cc/paint/filter_operations.cc2
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.cc28
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry.h1
-rw-r--r--chromium/cc/paint/image_transfer_cache_entry_unittest.cc141
-rw-r--r--chromium/cc/paint/paint_canvas.h11
-rw-r--r--chromium/cc/paint/paint_image.cc20
-rw-r--r--chromium/cc/paint/paint_image.h7
-rw-r--r--chromium/cc/paint/paint_image_unittest.cc4
-rw-r--r--chromium/cc/paint/paint_op_buffer.cc39
-rw-r--r--chromium/cc/paint/paint_op_buffer.h8
-rw-r--r--chromium/cc/paint/paint_recorder.h2
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.cc5
-rw-r--r--chromium/cc/raster/bitmap_raster_buffer_provider.h5
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.cc112
-rw-r--r--chromium/cc/raster/gpu_raster_buffer_provider.h26
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.cc16
-rw-r--r--chromium/cc/raster/one_copy_raster_buffer_provider.h5
-rw-r--r--chromium/cc/raster/raster_buffer_provider.h5
-rw-r--r--chromium/cc/raster/raster_buffer_provider_perftest.cc16
-rw-r--r--chromium/cc/raster/raster_buffer_provider_unittest.cc99
-rw-r--r--chromium/cc/raster/raster_source.h3
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.cc5
-rw-r--r--chromium/cc/raster/zero_copy_raster_buffer_provider.h5
-rw-r--r--chromium/cc/resources/resource_pool.cc1
-rw-r--r--chromium/cc/scheduler/begin_frame_tracker.cc45
-rw-r--r--chromium/cc/scheduler/begin_frame_tracker.h12
-rw-r--r--chromium/cc/scheduler/scheduler.cc101
-rw-r--r--chromium/cc/scheduler/scheduler.h19
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.cc328
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.h41
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine_unittest.cc82
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc81
-rw-r--r--chromium/cc/tiles/frame_viewer_instrumentation.h3
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.cc105
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache.h11
-rw-r--r--chromium/cc/tiles/gpu_image_decode_cache_unittest.cc98
-rw-r--r--chromium/cc/tiles/image_controller.cc32
-rw-r--r--chromium/cc/tiles/image_controller.h6
-rw-r--r--chromium/cc/tiles/image_controller_unittest.cc9
-rw-r--r--chromium/cc/tiles/image_decode_cache.cc22
-rw-r--r--chromium/cc/tiles/image_decode_cache.h11
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.cc32
-rw-r--r--chromium/cc/tiles/software_image_decode_cache.h62
-rw-r--r--chromium/cc/tiles/tile_manager.cc32
-rw-r--r--chromium/cc/tiles/tile_manager.h13
-rw-r--r--chromium/cc/tiles/tile_manager_unittest.cc25
-rw-r--r--chromium/cc/tiles/tile_priority.cc15
-rw-r--r--chromium/cc/tiles/tile_priority.h5
-rw-r--r--chromium/cc/trees/browser_controls_params.cc26
-rw-r--r--chromium/cc/trees/browser_controls_params.h44
-rw-r--r--chromium/cc/trees/damage_tracker_unittest.cc55
-rw-r--r--chromium/cc/trees/debug_rect_history.cc22
-rw-r--r--chromium/cc/trees/debug_rect_history.h17
-rw-r--r--chromium/cc/trees/draw_properties_unittest.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host.cc172
-rw-r--r--chromium/cc/trees/layer_tree_host.h39
-rw-r--r--chromium/cc/trees/layer_tree_host_client.h8
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.cc568
-rw-r--r--chromium/cc/trees/layer_tree_host_impl.h79
-rw-r--r--chromium/cc/trees/layer_tree_host_impl_unittest.cc3001
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_filters.cc44
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_readback.cc8
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc36
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc2
-rw-r--r--chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc6
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest.cc159
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_animation.cc36
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_context.cc3
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc28
-rw-r--r--chromium/cc/trees/layer_tree_host_unittest_scroll.cc431
-rw-r--r--chromium/cc/trees/layer_tree_impl.cc259
-rw-r--r--chromium/cc/trees/layer_tree_impl.h81
-rw-r--r--chromium/cc/trees/layer_tree_impl_unittest.cc280
-rw-r--r--chromium/cc/trees/layer_tree_mutator.cc9
-rw-r--r--chromium/cc/trees/layer_tree_mutator.h15
-rw-r--r--chromium/cc/trees/layer_tree_settings.h8
-rw-r--r--chromium/cc/trees/property_tree.cc71
-rw-r--r--chromium/cc/trees/property_tree.h35
-rw-r--r--chromium/cc/trees/proxy_impl.cc8
-rw-r--r--chromium/cc/trees/render_frame_metadata.cc3
-rw-r--r--chromium/cc/trees/render_frame_metadata.h9
-rw-r--r--chromium/cc/trees/scroll_and_scale_set.cc17
-rw-r--r--chromium/cc/trees/scroll_and_scale_set.h16
-rw-r--r--chromium/cc/trees/single_thread_proxy.cc9
-rw-r--r--chromium/cc/trees/ukm_manager.cc79
-rw-r--r--chromium/cc/trees/ukm_manager.h6
-rw-r--r--chromium/cc/typemaps.gni5
216 files changed, 8125 insertions, 5193 deletions
diff --git a/chromium/cc/BUILD.gn b/chromium/cc/BUILD.gn
index da40ffada58..335cbec2c77 100644
--- a/chromium/cc/BUILD.gn
+++ b/chromium/cc/BUILD.gn
@@ -77,7 +77,6 @@ cc_component("cc") {
"layers/heads_up_display_layer_impl.h",
"layers/layer.cc",
"layers/layer.h",
- "layers/layer_client.h",
"layers/layer_collections.h",
"layers/layer_impl.cc",
"layers/layer_impl.h",
@@ -159,6 +158,8 @@ cc_component("cc") {
"metrics/compositor_timing_history.h",
"metrics/frame_sequence_tracker.cc",
"metrics/frame_sequence_tracker.h",
+ "metrics/throughput_ukm_reporter.cc",
+ "metrics/throughput_ukm_reporter.h",
"raster/bitmap_raster_buffer_provider.cc",
"raster/bitmap_raster_buffer_provider.h",
"raster/gpu_raster_buffer_provider.cc",
@@ -277,6 +278,8 @@ cc_component("cc") {
"trees/animated_paint_worklet_tracker.h",
"trees/animation_effect_timings.h",
"trees/animation_options.h",
+ "trees/browser_controls_params.cc",
+ "trees/browser_controls_params.h",
"trees/clip_expander.cc",
"trees/clip_expander.h",
"trees/clip_node.cc",
@@ -374,6 +377,7 @@ cc_component("cc") {
"//cc/base",
"//cc/paint",
"//components/viz/common",
+ "//services/tracing/public/cpp:cpp",
"//skia",
]
deps = [
@@ -474,8 +478,6 @@ cc_test_static_library("test_support") {
"test/layer_tree_pixel_test.h",
"test/layer_tree_test.cc",
"test/layer_tree_test.h",
- "test/mock_layer_client.cc",
- "test/mock_layer_client.h",
"test/mock_layer_tree_mutator.cc",
"test/mock_layer_tree_mutator.h",
"test/mock_occlusion_tracker.h",
@@ -643,6 +645,7 @@ cc_test("cc_unittests") {
"metrics/compositor_frame_reporter_unittest.cc",
"metrics/compositor_frame_reporting_controller_unittest.cc",
"metrics/compositor_timing_history_unittest.cc",
+ "metrics/frame_sequence_metrics_unittest.cc",
"metrics/frame_sequence_tracker_unittest.cc",
"mojo_embedder/async_layer_tree_frame_sink_unittest.cc",
"paint/discardable_image_map_unittest.cc",
diff --git a/chromium/cc/DEPS b/chromium/cc/DEPS
index 8d3576c0da9..fa357abd483 100644
--- a/chromium/cc/DEPS
+++ b/chromium/cc/DEPS
@@ -29,11 +29,13 @@ include_rules = [
"+mojo/public/cpp/system/platform_handle.h",
"+skia/ext",
"+services/metrics/public/cpp",
+ "+services/tracing/public/cpp",
"+third_party/khronos/GLES2/gl2.h",
"+third_party/khronos/GLES2/gl2ext.h",
"+third_party/libyuv",
"+third_party/skia/include",
"+third_party/skia/src/core/SkRemoteGlyphCache.h",
+ "+third_party/perfetto/protos/perfetto/trace/track_event",
"+ui/events/types",
"+ui/latency",
"+ui/gfx",
diff --git a/chromium/cc/OWNERS b/chromium/cc/OWNERS
index 820c023d3a5..c5524c67483 100644
--- a/chromium/cc/OWNERS
+++ b/chromium/cc/OWNERS
@@ -9,6 +9,7 @@
enne@chromium.org
danakj@chromium.org
pdr@chromium.org
+wangxianzhu@chromium.org
# mac-specific
ccameron@chromium.org
@@ -30,6 +31,7 @@ flackr@chromium.org
chrishtr@chromium.org
weiliangc@chromium.org
pdr@chromium.org
+wangxianzhu@chromium.org
# animation
flackr@chromium.org
diff --git a/chromium/cc/animation/BUILD.gn b/chromium/cc/animation/BUILD.gn
index cdad662a244..19627f46816 100644
--- a/chromium/cc/animation/BUILD.gn
+++ b/chromium/cc/animation/BUILD.gn
@@ -32,6 +32,8 @@ cc_component("animation") {
"keyframed_animation_curve.h",
"scroll_offset_animation_curve.cc",
"scroll_offset_animation_curve.h",
+ "scroll_offset_animation_curve_factory.cc",
+ "scroll_offset_animation_curve_factory.h",
"scroll_offset_animations.cc",
"scroll_offset_animations.h",
"scroll_offset_animations_impl.cc",
diff --git a/chromium/cc/animation/animation.cc b/chromium/cc/animation/animation.cc
index 9d32d45f668..5bc03dde436 100644
--- a/chromium/cc/animation/animation.cc
+++ b/chromium/cc/animation/animation.cc
@@ -271,36 +271,55 @@ void Animation::RemoveFromTicking() {
animation_host_->RemoveFromTicking(this);
}
-void Animation::NotifyKeyframeModelStarted(const AnimationEvent& event) {
- if (animation_delegate_) {
- animation_delegate_->NotifyAnimationStarted(
- event.monotonic_time, event.target_property, event.group_id);
- }
-}
-
-void Animation::NotifyKeyframeModelFinished(const AnimationEvent& event) {
- if (animation_delegate_) {
- animation_delegate_->NotifyAnimationFinished(
- event.monotonic_time, event.target_property, event.group_id);
- }
-}
-
-void Animation::NotifyKeyframeModelAborted(const AnimationEvent& event) {
- if (animation_delegate_) {
- animation_delegate_->NotifyAnimationAborted(
- event.monotonic_time, event.target_property, event.group_id);
+void Animation::DispatchAndDelegateAnimationEvent(const AnimationEvent& event) {
+ if (event.ShouldDispatchToKeyframeEffectAndModel()) {
+ KeyframeEffect* keyframe_effect =
+ GetKeyframeEffectById(event.uid.effect_id);
+ if (!keyframe_effect ||
+ !keyframe_effect->DispatchAnimationEventToKeyframeModel(event)) {
+ // If we fail to dispatch the event, it is to clean up an obsolete
+ // animation and should not notify the delegate.
+ // TODO(gerchiko): Determine when we expect the referenced animations not
+ // to exist.
+ return;
+ }
}
+ DelegateAnimationEvent(event);
}
-void Animation::NotifyKeyframeModelTakeover(const AnimationEvent& event) {
- DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET);
-
+void Animation::DelegateAnimationEvent(const AnimationEvent& event) {
if (animation_delegate_) {
- DCHECK(event.curve);
- std::unique_ptr<AnimationCurve> animation_curve = event.curve->Clone();
- animation_delegate_->NotifyAnimationTakeover(
- event.monotonic_time, event.target_property, event.animation_start_time,
- std::move(animation_curve));
+ switch (event.type) {
+ case AnimationEvent::STARTED:
+ animation_delegate_->NotifyAnimationStarted(
+ event.monotonic_time, event.target_property, event.group_id);
+ break;
+
+ case AnimationEvent::FINISHED:
+ animation_delegate_->NotifyAnimationFinished(
+ event.monotonic_time, event.target_property, event.group_id);
+ break;
+
+ case AnimationEvent::ABORTED:
+ animation_delegate_->NotifyAnimationAborted(
+ event.monotonic_time, event.target_property, event.group_id);
+ break;
+
+ case AnimationEvent::TAKEOVER:
+ // TODO(crbug.com/1018213): Routing TAKEOVER events is broken.
+ DCHECK(!event.is_impl_only);
+ DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET);
+ DCHECK(event.curve);
+ animation_delegate_->NotifyAnimationTakeover(
+ event.monotonic_time, event.target_property,
+ event.animation_start_time, event.curve->Clone());
+ break;
+
+ case AnimationEvent::TIME_UPDATED:
+ DCHECK(!event.is_impl_only);
+ animation_delegate_->NotifyLocalTimeUpdated(event.local_time);
+ break;
+ }
}
}
diff --git a/chromium/cc/animation/animation.h b/chromium/cc/animation/animation.h
index 06df05510a6..9697a657589 100644
--- a/chromium/cc/animation/animation.h
+++ b/chromium/cc/animation/animation.h
@@ -95,17 +95,19 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
virtual void PushPropertiesTo(Animation* animation_impl);
- void UpdateState(bool start_ready_keyframe_models, AnimationEvents* events);
+ virtual void UpdateState(bool start_ready_keyframe_models,
+ AnimationEvents* events);
virtual void Tick(base::TimeTicks monotonic_time);
void AddToTicking();
void RemoveFromTicking();
- // AnimationDelegate routing.
- void NotifyKeyframeModelStarted(const AnimationEvent& event);
- void NotifyKeyframeModelFinished(const AnimationEvent& event);
- void NotifyKeyframeModelAborted(const AnimationEvent& event);
- void NotifyKeyframeModelTakeover(const AnimationEvent& event);
+ // Dispatches animation event to the animation keyframe effect and model when
+ // appropriate, based on the event characteristics.
+ // Delegates animation event that was successfully dispatched or doesn't need
+ // to be dispatched.
+ void DispatchAndDelegateAnimationEvent(const AnimationEvent& event);
+
size_t TickingKeyframeModelsCount() const;
bool AffectsCustomProperty() const;
@@ -146,6 +148,9 @@ class CC_ANIMATION_EXPORT Animation : public base::RefCounted<Animation> {
void PushAttachedKeyframeEffectsToImplThread(Animation* animation_impl) const;
void PushPropertiesToImplThread(Animation* animation_impl);
+ // Delegates animation event
+ void DelegateAnimationEvent(const AnimationEvent& event);
+
protected:
explicit Animation(int id);
virtual ~Animation();
diff --git a/chromium/cc/animation/animation_delegate.h b/chromium/cc/animation/animation_delegate.h
index 013e3431848..0adbb115c59 100644
--- a/chromium/cc/animation/animation_delegate.h
+++ b/chromium/cc/animation/animation_delegate.h
@@ -35,6 +35,8 @@ class CC_ANIMATION_EXPORT AnimationDelegate {
int target_property,
base::TimeTicks animation_start_time,
std::unique_ptr<AnimationCurve> curve) = 0;
+ virtual void NotifyLocalTimeUpdated(
+ base::Optional<base::TimeDelta> local_time) = 0;
protected:
virtual ~AnimationDelegate() {}
diff --git a/chromium/cc/animation/animation_events.cc b/chromium/cc/animation/animation_events.cc
index 4d9387aa43e..1382569b09f 100644
--- a/chromium/cc/animation/animation_events.cc
+++ b/chromium/cc/animation/animation_events.cc
@@ -7,20 +7,36 @@
namespace cc {
AnimationEvent::AnimationEvent(AnimationEvent::Type type,
- ElementId element_id,
+ UniqueKeyframeModelId uid,
int group_id,
int target_property,
base::TimeTicks monotonic_time)
: type(type),
- element_id(element_id),
+ uid(uid),
group_id(group_id),
target_property(target_property),
monotonic_time(monotonic_time),
- is_impl_only(false) {}
+ is_impl_only(false),
+ local_time() {}
+
+AnimationEvent::AnimationEvent(int timeline_id,
+ int animation_id,
+ base::Optional<base::TimeDelta> local_time)
+ : type(TIME_UPDATED),
+ // Initializing model_id with an invalid value (0).
+ // Also initializing keyframe_id with 0 which in its case is a valid
+ // value. However this is safe since keyframe_id and model_id are not used
+ // when routing a TIME_UPDATED event.
+ uid({timeline_id, animation_id, 0, 0}),
+ group_id(),
+ target_property(),
+ monotonic_time(),
+ is_impl_only(false),
+ local_time(local_time) {}
AnimationEvent::AnimationEvent(const AnimationEvent& other) {
type = other.type;
- element_id = other.element_id;
+ uid = other.uid;
group_id = other.group_id;
target_property = other.target_property;
monotonic_time = other.monotonic_time;
@@ -28,11 +44,12 @@ AnimationEvent::AnimationEvent(const AnimationEvent& other) {
animation_start_time = other.animation_start_time;
if (other.curve)
curve = other.curve->Clone();
+ local_time = other.local_time;
}
AnimationEvent& AnimationEvent::operator=(const AnimationEvent& other) {
type = other.type;
- element_id = other.element_id;
+ uid = other.uid;
group_id = other.group_id;
target_property = other.target_property;
monotonic_time = other.monotonic_time;
@@ -40,6 +57,7 @@ AnimationEvent& AnimationEvent::operator=(const AnimationEvent& other) {
animation_start_time = other.animation_start_time;
if (other.curve)
curve = other.curve->Clone();
+ local_time = other.local_time;
return *this;
}
@@ -53,4 +71,13 @@ bool AnimationEvents::IsEmpty() const {
return events_.empty();
}
+bool AnimationEvent::ShouldDispatchToKeyframeEffectAndModel() const {
+ // TIME_UPDATED events are used to synchronize effect time between cc and
+ // main thread worklet animations. Keyframe models are not involved in
+ // this process.
+ // is_impl_only events are not dispatched because they don't have
+ // corresponding main thread components.
+ return type != TIME_UPDATED && !is_impl_only;
+}
+
} // namespace cc
diff --git a/chromium/cc/animation/animation_events.h b/chromium/cc/animation/animation_events.h
index cec76160ce8..2835c41336f 100644
--- a/chromium/cc/animation/animation_events.h
+++ b/chromium/cc/animation/animation_events.h
@@ -10,28 +10,41 @@
#include "cc/animation/animation_curve.h"
#include "cc/animation/animation_export.h"
-#include "cc/animation/keyframe_model.h"
-#include "cc/paint/element_id.h"
#include "cc/trees/mutator_host.h"
namespace cc {
struct CC_ANIMATION_EXPORT AnimationEvent {
- enum Type { STARTED, FINISHED, ABORTED, TAKEOVER };
+ enum Type { STARTED, FINISHED, ABORTED, TAKEOVER, TIME_UPDATED };
+
+ typedef size_t KeyframeEffectId;
+ struct UniqueKeyframeModelId {
+ int timeline_id;
+ int animation_id;
+ KeyframeEffectId effect_id;
+ int model_id;
+ };
AnimationEvent(Type type,
- ElementId element_id,
+ UniqueKeyframeModelId uid,
int group_id,
int target_property,
base::TimeTicks monotonic_time);
+ // Constructs AnimationEvent of TIME_UPDATED type.
+ AnimationEvent(int timeline_id,
+ int animation_id,
+ base::Optional<base::TimeDelta> local_time);
+
AnimationEvent(const AnimationEvent& other);
AnimationEvent& operator=(const AnimationEvent& other);
~AnimationEvent();
+ bool ShouldDispatchToKeyframeEffectAndModel() const;
+
Type type;
- ElementId element_id;
+ UniqueKeyframeModelId uid;
int group_id;
int target_property;
base::TimeTicks monotonic_time;
@@ -40,6 +53,9 @@ struct CC_ANIMATION_EXPORT AnimationEvent {
// For continuing a scroll offset animation on the main thread.
base::TimeTicks animation_start_time;
std::unique_ptr<AnimationCurve> curve;
+
+ // Set for TIME_UPDATED events.
+ base::Optional<base::TimeDelta> local_time;
};
class CC_ANIMATION_EXPORT AnimationEvents : public MutatorEvents {
diff --git a/chromium/cc/animation/animation_host.cc b/chromium/cc/animation/animation_host.cc
index 2e4dbb4e434..10c6f2ecd83 100644
--- a/chromium/cc/animation/animation_host.cc
+++ b/chromium/cc/animation/animation_host.cc
@@ -490,31 +490,12 @@ void AnimationHost::SetAnimationEvents(
for (size_t event_index = 0; event_index < events->events_.size();
++event_index) {
- ElementId element_id = events->events_[event_index].element_id;
-
- // Use the map of all ElementAnimations, not just ticking animations, since
- // non-ticking animations may still receive events for impl-only animations.
- const ElementToAnimationsMap& all_element_animations =
- element_to_animations_map_;
- auto iter = all_element_animations.find(element_id);
- if (iter != all_element_animations.end()) {
- switch (events->events_[event_index].type) {
- case AnimationEvent::STARTED:
- (*iter).second->NotifyAnimationStarted(events->events_[event_index]);
- break;
-
- case AnimationEvent::FINISHED:
- (*iter).second->NotifyAnimationFinished(events->events_[event_index]);
- break;
-
- case AnimationEvent::ABORTED:
- (*iter).second->NotifyAnimationAborted(events->events_[event_index]);
- break;
-
- case AnimationEvent::TAKEOVER:
- (*iter).second->NotifyAnimationTakeover(events->events_[event_index]);
- break;
- }
+ AnimationEvent& event = events->events_[event_index];
+ AnimationTimeline* timeline = GetTimelineById(event.uid.timeline_id);
+ if (timeline) {
+ Animation* animation = timeline->GetAnimationById(event.uid.animation_id);
+ if (animation)
+ animation->DispatchAndDelegateAnimationEvent(event);
}
}
}
@@ -667,7 +648,7 @@ void AnimationHost::ImplOnlyScrollAnimationCreate(
base::TimeDelta delayed_by,
base::TimeDelta animation_start_offset) {
DCHECK(scroll_offset_animations_impl_);
- scroll_offset_animations_impl_->ScrollAnimationCreate(
+ scroll_offset_animations_impl_->MouseWheelScrollAnimationCreate(
element_id, target_offset, current_offset, delayed_by,
animation_start_offset);
}
@@ -730,6 +711,20 @@ void AnimationHost::SetLayerTreeMutator(
mutator_->SetClient(this);
}
+WorkletAnimation* AnimationHost::FindWorkletAnimation(WorkletAnimationId id) {
+ // TODO(majidvp): Use a map to make lookup O(1)
+ auto animation = std::find_if(
+ ticking_animations_.begin(), ticking_animations_.end(), [id](auto& it) {
+ return it->IsWorkletAnimation() &&
+ ToWorkletAnimation(it.get())->worklet_animation_id() == id;
+ });
+
+ if (animation == ticking_animations_.end())
+ return nullptr;
+
+ return ToWorkletAnimation(animation->get());
+}
+
void AnimationHost::SetMutationUpdate(
std::unique_ptr<MutatorOutputState> output_state) {
if (!output_state)
@@ -739,17 +734,9 @@ void AnimationHost::SetMutationUpdate(
for (auto& animation_state : output_state->animations) {
WorkletAnimationId id = animation_state.worklet_animation_id;
- // TODO(majidvp): Use a map to make lookup O(1)
- auto to_update = std::find_if(
- ticking_animations_.begin(), ticking_animations_.end(), [id](auto& it) {
- return it->IsWorkletAnimation() &&
- ToWorkletAnimation(it.get())->worklet_animation_id() == id;
- });
-
- if (to_update == ticking_animations_.end())
- continue;
-
- ToWorkletAnimation(to_update->get())->SetOutputState(animation_state);
+ WorkletAnimation* to_update = FindWorkletAnimation(id);
+ if (to_update)
+ to_update->SetOutputState(animation_state);
}
}
diff --git a/chromium/cc/animation/animation_host.h b/chromium/cc/animation/animation_host.h
index fa0a1a5a0a6..a31347032b7 100644
--- a/chromium/cc/animation/animation_host.h
+++ b/chromium/cc/animation/animation_host.h
@@ -32,6 +32,7 @@ class LayerTreeHost;
class KeyframeEffect;
class ScrollOffsetAnimations;
class ScrollOffsetAnimationsImpl;
+class WorkletAnimation;
enum class ThreadInstance { MAIN, IMPL };
@@ -235,6 +236,10 @@ class CC_ANIMATION_EXPORT AnimationHost : public MutatorHost,
const ScrollTree& scroll_tree,
bool is_active_tree);
+ // Returns a pointer to a worklet animation by worklet animation id or null
+ // if there is no match.
+ WorkletAnimation* FindWorkletAnimation(WorkletAnimationId id);
+
ElementToAnimationsMap element_to_animations_map_;
AnimationsList ticking_animations_;
diff --git a/chromium/cc/animation/animation_host_unittest.cc b/chromium/cc/animation/animation_host_unittest.cc
index 206919ee556..45fd8ccc4db 100644
--- a/chromium/cc/animation/animation_host_unittest.cc
+++ b/chromium/cc/animation/animation_host_unittest.cc
@@ -177,7 +177,7 @@ TEST_F(AnimationHostTest, FastLayerTreeMutatorUpdateTakesEffectInSameFrame) {
// Ticking host should cause layer tree mutator to update output state which
// should take effect in the same animation frame.
- TickAnimationsTransferEvents(base::TimeTicks(), 0u);
+ TickAnimationsTransferEvents(base::TimeTicks(), 1u);
// Emulate behavior in PrepareToDraw. Animation worklet updates are best
// effort, and the animation tick is deferred until draw to allow time for the
diff --git a/chromium/cc/animation/element_animations.cc b/chromium/cc/animation/element_animations.cc
index 08cf3f95751..03996f2b245 100644
--- a/chromium/cc/animation/element_animations.cc
+++ b/chromium/cc/animation/element_animations.cc
@@ -175,41 +175,6 @@ void ElementAnimations::RemoveKeyframeEffectsFromTicking() const {
keyframe_effect.RemoveFromTicking();
}
-void ElementAnimations::NotifyAnimationStarted(const AnimationEvent& event) {
- DCHECK(!event.is_impl_only);
- for (auto& keyframe_effect : keyframe_effects_list_) {
- if (keyframe_effect.NotifyKeyframeModelStarted(event))
- break;
- }
-}
-
-void ElementAnimations::NotifyAnimationFinished(const AnimationEvent& event) {
- DCHECK(!event.is_impl_only);
- for (auto& keyframe_effect : keyframe_effects_list_) {
- if (keyframe_effect.NotifyKeyframeModelFinished(event))
- break;
- }
-}
-
-void ElementAnimations::NotifyAnimationTakeover(const AnimationEvent& event) {
- DCHECK(!event.is_impl_only);
- DCHECK(event.target_property == TargetProperty::SCROLL_OFFSET);
-
- for (auto& keyframe_effect : keyframe_effects_list_)
- keyframe_effect.NotifyKeyframeModelTakeover(event);
-}
-
-void ElementAnimations::NotifyAnimationAborted(const AnimationEvent& event) {
- DCHECK(!event.is_impl_only);
-
- for (auto& keyframe_effect : keyframe_effects_list_) {
- if (keyframe_effect.NotifyKeyframeModelAborted(event))
- break;
- }
-
- UpdateClientAnimationState();
-}
-
bool ElementAnimations::AnimationsPreserveAxisAlignment() const {
for (auto& keyframe_effect : keyframe_effects_list_) {
if (!keyframe_effect.AnimationsPreserveAxisAlignment())
diff --git a/chromium/cc/animation/element_animations.h b/chromium/cc/animation/element_animations.h
index 3bf69aa9d13..22a29defd10 100644
--- a/chromium/cc/animation/element_animations.h
+++ b/chromium/cc/animation/element_animations.h
@@ -26,7 +26,6 @@ class FilterOperations;
class KeyframeEffect;
class TransformOperations;
enum class ElementListType;
-struct AnimationEvent;
// An ElementAnimations owns a list of all KeyframeEffects attached to a single
// target (represented by an ElementId).
@@ -89,11 +88,6 @@ class CC_ANIMATION_EXPORT ElementAnimations
bool IsCurrentlyAnimatingProperty(TargetProperty::Type target_property,
ElementListType list_type) const;
- void NotifyAnimationStarted(const AnimationEvent& event);
- void NotifyAnimationFinished(const AnimationEvent& event);
- void NotifyAnimationAborted(const AnimationEvent& event);
- void NotifyAnimationTakeover(const AnimationEvent& event);
-
bool has_element_in_active_list() const {
return has_element_in_active_list_;
}
diff --git a/chromium/cc/animation/element_animations_unittest.cc b/chromium/cc/animation/element_animations_unittest.cc
index 54920ea0693..6b274dd13f5 100644
--- a/chromium/cc/animation/element_animations_unittest.cc
+++ b/chromium/cc/animation/element_animations_unittest.cc
@@ -13,6 +13,7 @@
#include "cc/animation/keyframe_effect.h"
#include "cc/animation/keyframed_animation_curve.h"
#include "cc/animation/scroll_offset_animation_curve.h"
+#include "cc/animation/scroll_offset_animation_curve_factory.h"
#include "cc/animation/single_keyframe_effect_animation.h"
#include "cc/animation/transform_operations.h"
#include "cc/test/animation_test_common.h"
@@ -266,9 +267,8 @@ TEST_F(ElementAnimationsTest,
// Animation with initial value set.
std::unique_ptr<ScrollOffsetAnimationCurve> curve_fixed(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
curve_fixed->SetInitialValue(initial_value);
const int animation1_id = 1;
std::unique_ptr<KeyframeModel> animation_fixed(KeyframeModel::Create(
@@ -284,9 +284,8 @@ TEST_F(ElementAnimationsTest,
// Animation without initial value set.
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
const int animation2_id = 2;
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), animation2_id, 1, TargetProperty::SCROLL_OFFSET));
@@ -369,7 +368,7 @@ TEST_F(ElementAnimationsTest, AddedAnimationIsDestroyed) {
EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type);
// The actual detachment happens here, inside the callback
- animation2->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation2->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_TRUE(delegate.started());
}
@@ -401,7 +400,7 @@ TEST_F(ElementAnimationsTest, DoNotClobberStartTimes) {
// Synchronize the start times.
EXPECT_EQ(1u, events->events_.size());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_EQ(animation_->keyframe_effect()
->GetKeyframeModelById(keyframe_model_id)
->start_time(),
@@ -448,7 +447,7 @@ TEST_F(ElementAnimationsTest, UseSpecifiedStartTimes) {
// Synchronize the start times.
EXPECT_EQ(1u, events->events_.size());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_EQ(start_time, animation_->keyframe_effect()
->GetKeyframeModelById(keyframe_model_id)
@@ -505,7 +504,7 @@ TEST_F(ElementAnimationsTest, Activation) {
animation_impl_->Tick(kInitialTickTime);
animation_impl_->UpdateState(true, events.get());
EXPECT_EQ(1u, events->events_.size());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_EQ(1u, host->ticking_animations_for_testing().size());
EXPECT_EQ(1u, host_impl->ticking_animations_for_testing().size());
@@ -532,8 +531,7 @@ TEST_F(ElementAnimationsTest, Activation) {
EXPECT_EQ(0u, host_impl->ticking_animations_for_testing().size());
EXPECT_EQ(1u, events->events_.size());
- animation_->keyframe_effect()->NotifyKeyframeModelFinished(
- events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(1500));
animation_->UpdateState(true, nullptr);
@@ -587,7 +585,7 @@ TEST_F(ElementAnimationsTest, SyncPause) {
animation_->Tick(time);
animation_->UpdateState(true, nullptr);
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_EQ(KeyframeModel::RUNNING,
animation_impl_->keyframe_effect()
@@ -664,7 +662,7 @@ TEST_F(ElementAnimationsTest, DoNotSyncFinishedAnimation) {
EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type);
// Notify main thread animations that the animation has started.
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
// Complete animation on impl thread.
events = CreateEventsForTesting();
@@ -673,8 +671,7 @@ TEST_F(ElementAnimationsTest, DoNotSyncFinishedAnimation) {
EXPECT_EQ(1u, events->events_.size());
EXPECT_EQ(AnimationEvent::FINISHED, events->events_[0].type);
- animation_->keyframe_effect()->NotifyKeyframeModelFinished(
- events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
animation_->Tick(kInitialTickTime + TimeDelta::FromSeconds(2));
animation_->UpdateState(true, nullptr);
@@ -715,7 +712,7 @@ TEST_F(ElementAnimationsTest, AnimationsAreDeleted) {
// There should be a STARTED event for the animation.
EXPECT_EQ(1u, events->events_.size());
EXPECT_EQ(AnimationEvent::STARTED, events->events_[0].type);
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(1000));
animation_->UpdateState(true, nullptr);
@@ -737,8 +734,7 @@ TEST_F(ElementAnimationsTest, AnimationsAreDeleted) {
EXPECT_TRUE(animation_->GetKeyframeModel(TargetProperty::OPACITY));
EXPECT_TRUE(animation_impl_->GetKeyframeModel(TargetProperty::OPACITY));
- animation_->keyframe_effect()->NotifyKeyframeModelFinished(
- events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(3000));
animation_->UpdateState(true, nullptr);
@@ -894,9 +890,8 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransition) {
gfx::ScrollOffset initial_value(100.f, 300.f);
gfx::ScrollOffset target_value(300.f, 200.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
@@ -928,7 +923,7 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransition) {
EXPECT_EQ(initial_value,
client_impl_.GetScrollOffset(element_id_, ElementListType::ACTIVE));
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
animation_->Tick(kInitialTickTime + duration / 2);
animation_->UpdateState(true, nullptr);
EXPECT_TRUE(animation_->keyframe_effect()->HasTickingKeyframeModel());
@@ -965,9 +960,8 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransitionOnImplOnly) {
gfx::ScrollOffset initial_value(100.f, 300.f);
gfx::ScrollOffset target_value(300.f, 200.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
curve->SetInitialValue(initial_value);
double duration_in_seconds = curve->Duration().InSecondsF();
@@ -1067,9 +1061,8 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransitionNoImplProvider) {
gfx::ScrollOffset initial_value(500.f, 100.f);
gfx::ScrollOffset target_value(300.f, 200.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
@@ -1109,7 +1102,7 @@ TEST_F(ElementAnimationsTest, ScrollOffsetTransitionNoImplProvider) {
animation_impl_->UpdateState(true, events.get());
DCHECK_EQ(1UL, events->events_.size());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
animation_->Tick(kInitialTickTime + duration / 2);
animation_->UpdateState(true, nullptr);
EXPECT_TRUE(animation_->keyframe_effect()->HasTickingKeyframeModel());
@@ -1146,9 +1139,8 @@ TEST_F(ElementAnimationsTest, ScrollOffsetRemovalClearsScrollDelta) {
// First test the 1-argument version of RemoveKeyframeModel.
gfx::ScrollOffset target_value(300.f, 200.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
int keyframe_model_id = 1;
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
@@ -1177,9 +1169,8 @@ TEST_F(ElementAnimationsTest, ScrollOffsetRemovalClearsScrollDelta) {
->scroll_offset_animation_was_interrupted());
// Now, test the 2-argument version of RemoveKeyframeModel.
- curve = ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT));
+ curve = ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value);
keyframe_model = KeyframeModel::Create(std::move(curve), keyframe_model_id, 0,
TargetProperty::SCROLL_OFFSET);
keyframe_model->set_needs_synchronized_start_time(true);
@@ -1270,9 +1261,8 @@ TEST_F(ElementAnimationsTest,
gfx::ScrollOffset initial_value(100.f, 300.f);
gfx::ScrollOffset target_value(300.f, 200.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
curve->SetInitialValue(initial_value);
TimeDelta duration = curve->Duration();
std::unique_ptr<KeyframeModel> to_add(KeyframeModel::Create(
@@ -1333,7 +1323,7 @@ TEST_F(ElementAnimationsTest, SpecifiedStartTimesAreSentToMainThreadDelegate) {
// Synchronize the start times.
EXPECT_EQ(1u, events->events_.size());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
// Validate start time on the main thread delegate.
EXPECT_EQ(start_time, delegate.start_time());
@@ -1352,6 +1342,7 @@ TEST_F(ElementAnimationsTest,
std::unique_ptr<AnimationCurve>(new FakeFloatTransition(1.0, 0.f, 1.f)),
1, TargetProperty::OPACITY));
to_add->set_needs_synchronized_start_time(true);
+ int keyframe_model_id = to_add->id();
// We should pause at the first keyframe indefinitely waiting for that
// animation to start.
@@ -1370,9 +1361,12 @@ TEST_F(ElementAnimationsTest,
EXPECT_EQ(0.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE));
// Send the synchronized start time.
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(AnimationEvent(
- AnimationEvent::STARTED, ElementId(), 1, TargetProperty::OPACITY,
- kInitialTickTime + TimeDelta::FromMilliseconds(2000)));
+ animation_->DispatchAndDelegateAnimationEvent(
+ AnimationEvent(AnimationEvent::STARTED,
+ {animation_->animation_timeline()->id(), animation_->id(),
+ animation_->keyframe_effect()->id(), keyframe_model_id},
+ 1, TargetProperty::OPACITY,
+ kInitialTickTime + TimeDelta::FromMilliseconds(2000)));
animation_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(5000));
animation_->UpdateState(true, events.get());
EXPECT_EQ(1.f, client_.GetOpacity(element_id_, ElementListType::ACTIVE));
@@ -2017,7 +2011,7 @@ TEST_F(ElementAnimationsTest, ImplThreadAbortedAnimationGetsDeleted) {
KeyframeModel::WAITING_FOR_DELETION,
animation_impl_->GetKeyframeModel(TargetProperty::OPACITY)->run_state());
- animation_->keyframe_effect()->NotifyKeyframeModelAborted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_EQ(KeyframeModel::ABORTED,
animation_->GetKeyframeModel(TargetProperty::OPACITY)->run_state());
EXPECT_TRUE(delegate.aborted());
@@ -2054,9 +2048,8 @@ TEST_F(ElementAnimationsTest, ImplThreadTakeoverAnimationGetsDeleted) {
gfx::ScrollOffset initial_value(100.f, 300.f);
gfx::ScrollOffset target_value(300.f, 200.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
curve->SetInitialValue(initial_value);
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), keyframe_model_id, 0, TargetProperty::SCROLL_OFFSET));
@@ -2093,8 +2086,7 @@ TEST_F(ElementAnimationsTest, ImplThreadTakeoverAnimationGetsDeleted) {
animation_impl_->GetKeyframeModel(TargetProperty::SCROLL_OFFSET));
// MT receives the event to take over.
- animation_->keyframe_effect()->NotifyKeyframeModelTakeover(
- events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_TRUE(delegate.takeover());
// SingleKeyframeEffectAnimation::NotifyAnimationTakeover requests
@@ -2680,7 +2672,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenTransformAnimationChanges) {
animation_impl_->Tick(kInitialTickTime);
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
// Finish the animation.
@@ -2753,7 +2745,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenTransformAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_->RemoveKeyframeModel(keyframe_model_id);
@@ -2806,7 +2798,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenTransformAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_impl_->AbortKeyframeModelsWithProperty(TargetProperty::TRANSFORM,
@@ -2823,7 +2815,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenTransformAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(4000));
animation_impl_->UpdateState(true, events.get());
- element_animations_->NotifyAnimationAborted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_FALSE(client_.GetHasPotentialTransformAnimation(
element_id_, ElementListType::ACTIVE));
EXPECT_FALSE(client_.GetTransformIsCurrentlyAnimating(
@@ -2907,7 +2899,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenOpacityAnimationChanges) {
animation_impl_->Tick(kInitialTickTime);
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
// Finish the animation.
@@ -2969,7 +2961,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenOpacityAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_->RemoveKeyframeModel(keyframe_model_id);
@@ -3021,7 +3013,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenOpacityAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_impl_->AbortKeyframeModelsWithProperty(TargetProperty::OPACITY,
@@ -3038,7 +3030,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenOpacityAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(4000));
animation_impl_->UpdateState(true, events.get());
- element_animations_->NotifyAnimationAborted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_FALSE(client_.GetHasPotentialOpacityAnimation(
element_id_, ElementListType::ACTIVE));
EXPECT_FALSE(client_.GetOpacityIsCurrentlyAnimating(element_id_,
@@ -3121,7 +3113,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenFilterAnimationChanges) {
animation_impl_->Tick(kInitialTickTime);
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
// Finish the animation.
@@ -3183,7 +3175,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenFilterAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_->RemoveKeyframeModel(keyframe_model_id);
@@ -3235,7 +3227,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenFilterAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_impl_->AbortKeyframeModelsWithProperty(TargetProperty::FILTER,
@@ -3252,7 +3244,7 @@ TEST_F(ElementAnimationsTest, ObserverNotifiedWhenFilterAnimationChanges) {
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(4000));
animation_impl_->UpdateState(true, events.get());
- element_animations_->NotifyAnimationAborted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_FALSE(client_.GetHasPotentialFilterAnimation(element_id_,
ElementListType::ACTIVE));
EXPECT_FALSE(client_.GetFilterIsCurrentlyAnimating(element_id_,
@@ -3336,7 +3328,7 @@ TEST_F(ElementAnimationsTest,
animation_impl_->Tick(kInitialTickTime);
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
// Finish the animation.
@@ -3398,7 +3390,7 @@ TEST_F(ElementAnimationsTest,
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_->RemoveKeyframeModel(keyframe_model_id);
@@ -3450,7 +3442,7 @@ TEST_F(ElementAnimationsTest,
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(2000));
animation_impl_->UpdateState(true, events.get());
- animation_->keyframe_effect()->NotifyKeyframeModelStarted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
events->events_.clear();
animation_impl_->AbortKeyframeModelsWithProperty(
@@ -3467,7 +3459,7 @@ TEST_F(ElementAnimationsTest,
animation_impl_->Tick(kInitialTickTime + TimeDelta::FromMilliseconds(4000));
animation_impl_->UpdateState(true, events.get());
- element_animations_->NotifyAnimationAborted(events->events_[0]);
+ animation_->DispatchAndDelegateAnimationEvent(events->events_[0]);
EXPECT_FALSE(client_.GetHasPotentialBackdropFilterAnimation(
element_id_, ElementListType::ACTIVE));
EXPECT_FALSE(client_.GetBackdropFilterIsCurrentlyAnimating(
diff --git a/chromium/cc/animation/keyframe_effect.cc b/chromium/cc/animation/keyframe_effect.cc
index ecbd64a259d..d3a7543adc1 100644
--- a/chromium/cc/animation/keyframe_effect.cc
+++ b/chromium/cc/animation/keyframe_effect.cc
@@ -11,6 +11,7 @@
#include "cc/animation/animation.h"
#include "cc/animation/animation_curve.h"
#include "cc/animation/animation_host.h"
+#include "cc/animation/animation_timeline.h"
#include "cc/animation/keyframe_model.h"
#include "cc/animation/scroll_offset_animation_curve.h"
#include "cc/animation/transform_operations.h"
@@ -394,62 +395,65 @@ void KeyframeEffect::KeyframeModelAdded() {
element_animations_->UpdateClientAnimationState();
}
-bool KeyframeEffect::NotifyKeyframeModelStarted(const AnimationEvent& event) {
+bool KeyframeEffect::DispatchAnimationEventToKeyframeModel(
+ const AnimationEvent& event) {
DCHECK(!event.is_impl_only);
- for (auto& keyframe_model : keyframe_models_) {
- if (keyframe_model->group() == event.group_id &&
- keyframe_model->target_property_id() == event.target_property &&
- keyframe_model->needs_synchronized_start_time()) {
- keyframe_model->set_needs_synchronized_start_time(false);
- if (!keyframe_model->has_set_start_time())
- keyframe_model->set_start_time(event.monotonic_time);
- animation_->NotifyKeyframeModelStarted(event);
- return true;
- }
- }
- return false;
-}
-
-bool KeyframeEffect::NotifyKeyframeModelFinished(const AnimationEvent& event) {
- DCHECK(!event.is_impl_only);
- for (auto& keyframe_model : keyframe_models_) {
- if (keyframe_model->group() == event.group_id &&
- keyframe_model->target_property_id() == event.target_property) {
- keyframe_model->set_received_finished_event(true);
- animation_->NotifyKeyframeModelFinished(event);
- return true;
- }
- }
-
- // This is for the case when a keyframe_model is already removed on main
- // thread, but the impl version of it sent a finished event and is now waiting
- // for deletion. We would need to delete that keyframe_model during push
- // properties.
- SetNeedsPushProperties();
- return false;
-}
+ KeyframeModel* keyframe_model = GetKeyframeModelById(event.uid.model_id);
+ bool dispatched = false;
+ switch (event.type) {
+ case AnimationEvent::STARTED:
+ if (keyframe_model && keyframe_model->needs_synchronized_start_time()) {
+ keyframe_model->set_needs_synchronized_start_time(false);
+ if (!keyframe_model->has_set_start_time())
+ keyframe_model->set_start_time(event.monotonic_time);
+ dispatched = true;
+ }
+ break;
-void KeyframeEffect::NotifyKeyframeModelTakeover(const AnimationEvent& event) {
- DCHECK(!event.is_impl_only);
+ case AnimationEvent::FINISHED:
+ if (keyframe_model) {
+ keyframe_model->set_received_finished_event(true);
+ dispatched = true;
+ } else {
+ // This is for the case when a keyframe_model is already removed on main
+ // thread, but the impl version of it sent a finished event and is now
+ // waiting for deletion. We would need to delete that keyframe_model
+ // during push properties.
+ SetNeedsPushProperties();
+ }
+ break;
- // We need to purge KeyframeModels marked for deletion on CT.
- SetNeedsPushProperties();
+ case AnimationEvent::ABORTED:
+ if (keyframe_model) {
+ keyframe_model->SetRunState(KeyframeModel::ABORTED,
+ event.monotonic_time);
+ keyframe_model->set_received_finished_event(true);
+ dispatched = true;
+
+ ElementAnimations* element_animations =
+ animation_->animation_host()
+ ->GetElementAnimationsForElementId(element_id())
+ .get();
+ if (element_animations)
+ element_animations->UpdateClientAnimationState();
+ }
+ break;
- animation_->NotifyKeyframeModelTakeover(event);
-}
+ case AnimationEvent::TAKEOVER:
+ // TODO(crbug.com/1018213): Routing TAKEOVER events is broken.
+ // We need to purge KeyframeModels marked for deletion on CT.
+ SetNeedsPushProperties();
+ dispatched = true;
+ break;
-bool KeyframeEffect::NotifyKeyframeModelAborted(const AnimationEvent& event) {
- DCHECK(!event.is_impl_only);
- for (auto& keyframe_model : keyframe_models_) {
- if (keyframe_model->group() == event.group_id &&
- keyframe_model->target_property_id() == event.target_property) {
- keyframe_model->SetRunState(KeyframeModel::ABORTED, event.monotonic_time);
- keyframe_model->set_received_finished_event(true);
- animation_->NotifyKeyframeModelAborted(event);
- return true;
- }
+ case AnimationEvent::TIME_UPDATED:
+ // TIME_UPDATED events are used to synchronize effect time between cc and
+ // main thread worklet animations. Keyframe models are not involved in
+ // this process.
+ NOTREACHED();
+ break;
}
- return false;
+ return dispatched;
}
bool KeyframeEffect::HasTickingKeyframeModel() const {
@@ -778,6 +782,10 @@ void KeyframeEffect::PushPropertiesTo(KeyframeEffect* keyframe_effect_impl) {
}
}
+ keyframe_effect_impl->scroll_offset_animation_was_interrupted_ =
+ scroll_offset_animation_was_interrupted_;
+ scroll_offset_animation_was_interrupted_ = false;
+
// If neither main nor impl have any KeyframeModels, there is nothing further
// to synchronize.
if (!has_any_keyframe_model() &&
@@ -799,9 +807,6 @@ void KeyframeEffect::PushPropertiesTo(KeyframeEffect* keyframe_effect_impl) {
if (current_impl)
keyframe_model->PushPropertiesTo(current_impl);
}
- keyframe_effect_impl->scroll_offset_animation_was_interrupted_ =
- scroll_offset_animation_was_interrupted_;
- scroll_offset_animation_was_interrupted_ = false;
keyframe_effect_impl->UpdateTickingState();
}
@@ -1082,7 +1087,10 @@ void KeyframeEffect::GenerateEvent(AnimationEvents* events,
if (!events)
return;
- AnimationEvent event(type, element_id_, keyframe_model.group(),
+ AnimationEvent event(type,
+ {animation_->animation_timeline()->id(),
+ animation_->id(), id(), keyframe_model.id()},
+ keyframe_model.group(),
keyframe_model.target_property_id(), monotonic_time);
event.is_impl_only = keyframe_model.is_impl_only();
if (!event.is_impl_only) {
@@ -1090,22 +1098,7 @@ void KeyframeEffect::GenerateEvent(AnimationEvents* events,
return;
}
// For impl only animations notify delegate directly, do not record the event.
- switch (type) {
- case AnimationEvent::FINISHED:
- animation_->NotifyKeyframeModelFinished(event);
- break;
- case AnimationEvent::STARTED:
- animation_->NotifyKeyframeModelStarted(event);
- break;
- case AnimationEvent::ABORTED:
- animation_->NotifyKeyframeModelAborted(event);
- break;
- case AnimationEvent::TAKEOVER:
- // We never expect to receive a TAKEOVER notification on impl only
- // animations.
- NOTREACHED();
- break;
- }
+ animation_->DispatchAndDelegateAnimationEvent(event);
}
void KeyframeEffect::GenerateTakeoverEventForScrollAnimation(
@@ -1116,17 +1109,28 @@ void KeyframeEffect::GenerateTakeoverEventForScrollAnimation(
if (!events)
return;
- AnimationEvent takeover_event(
- AnimationEvent::TAKEOVER, element_id_, keyframe_model.group(),
- keyframe_model.target_property_id(), monotonic_time);
+ AnimationEvent takeover_event(AnimationEvent::TAKEOVER,
+ {animation_->animation_timeline()->id(),
+ animation_->id(), id(), keyframe_model.id()},
+ keyframe_model.group(),
+ keyframe_model.target_property_id(),
+ monotonic_time);
takeover_event.animation_start_time = keyframe_model.start_time();
const ScrollOffsetAnimationCurve* scroll_offset_animation_curve =
keyframe_model.curve()->ToScrollOffsetAnimationCurve();
takeover_event.curve = scroll_offset_animation_curve->Clone();
- // Notify the compositor that the animation is finished.
- animation_->NotifyKeyframeModelFinished(takeover_event);
// Notify main thread.
events->events_.push_back(takeover_event);
+
+ AnimationEvent finished_event(AnimationEvent::FINISHED,
+ {animation_->animation_timeline()->id(),
+ animation_->id(), id(), keyframe_model.id()},
+ keyframe_model.group(),
+ keyframe_model.target_property_id(),
+ monotonic_time);
+ // Notify the compositor that the animation is finished.
+ finished_event.is_impl_only = true;
+ animation_->DispatchAndDelegateAnimationEvent(finished_event);
}
} // namespace cc
diff --git a/chromium/cc/animation/keyframe_effect.h b/chromium/cc/animation/keyframe_effect.h
index e3816763e85..a450d22a003 100644
--- a/chromium/cc/animation/keyframe_effect.h
+++ b/chromium/cc/animation/keyframe_effect.h
@@ -105,14 +105,9 @@ class CC_ANIMATION_EXPORT KeyframeEffect {
void KeyframeModelAdded();
- // The following methods should be called to notify the KeyframeEffect that
- // an animation event has been received for the same target (ElementId) as
- // this keyframe_effect. If the event matches a KeyframeModel owned by this
- // KeyframeEffect the call will return true, else it will return false.
- bool NotifyKeyframeModelStarted(const AnimationEvent& event);
- bool NotifyKeyframeModelFinished(const AnimationEvent& event);
- void NotifyKeyframeModelTakeover(const AnimationEvent& event);
- bool NotifyKeyframeModelAborted(const AnimationEvent& event);
+ // Dispatches animation event to a keyframe model specified as part of the
+ // event. Returns true if the event is dispatched, false otherwise.
+ bool DispatchAnimationEventToKeyframeModel(const AnimationEvent& event);
// Returns true if there are any KeyframeModels that have neither finished
// nor aborted.
diff --git a/chromium/cc/animation/keyframe_model.h b/chromium/cc/animation/keyframe_model.h
index c5e0dee5b4d..b7b52cd8cbf 100644
--- a/chromium/cc/animation/keyframe_model.h
+++ b/chromium/cc/animation/keyframe_model.h
@@ -22,9 +22,6 @@ class AnimationCurve;
// It represents a model of the keyframes (internally represented as a curve).
class CC_ANIMATION_EXPORT KeyframeModel {
public:
- // TODO(yigu): RunState is supposed to be managed/accessed at Animation
- // level rather than KeyframeModel level. See https://crbug.com/812652.
- //
// KeyframeModels begin in the 'WAITING_FOR_TARGET_AVAILABILITY' state. A
// KeyframeModel waiting for target availibility will run as soon as its
// target property is free (and all the KeyframeModels animating with it are
diff --git a/chromium/cc/animation/scroll_offset_animation_curve.cc b/chromium/cc/animation/scroll_offset_animation_curve.cc
index 6ec55b7472b..bcb46ad170e 100644
--- a/chromium/cc/animation/scroll_offset_animation_curve.cc
+++ b/chromium/cc/animation/scroll_offset_animation_curve.cc
@@ -14,8 +14,6 @@
#include "cc/base/time_util.h"
#include "ui/gfx/animation/tween.h"
-using DurationBehavior = cc::ScrollOffsetAnimationCurve::DurationBehavior;
-
const double kConstantDuration = 9.0;
const double kDurationDivisor = 60.0;
@@ -44,7 +42,7 @@ static float MaximumDimension(const gfx::Vector2dF& delta) {
return std::abs(delta.x()) > std::abs(delta.y()) ? delta.x() : delta.y();
}
-static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity(
+static std::unique_ptr<TimingFunction> EaseInOutWithInitialVelocity(
double velocity) {
// Clamp velocity to a sane value.
velocity = base::ClampToRange(velocity, -1000.0, 1000.0);
@@ -61,33 +59,30 @@ static std::unique_ptr<TimingFunction> EaseOutWithInitialVelocity(
base::Optional<double>
ScrollOffsetAnimationCurve::animation_duration_for_testing_;
-std::unique_ptr<ScrollOffsetAnimationCurve> ScrollOffsetAnimationCurve::Create(
- const gfx::ScrollOffset& target_value,
- std::unique_ptr<TimingFunction> timing_function,
- DurationBehavior duration_behavior) {
- return base::WrapUnique(new ScrollOffsetAnimationCurve(
- target_value, std::move(timing_function), duration_behavior));
-}
-
ScrollOffsetAnimationCurve::ScrollOffsetAnimationCurve(
const gfx::ScrollOffset& target_value,
std::unique_ptr<TimingFunction> timing_function,
- DurationBehavior duration_behavior)
+ AnimationType animation_type,
+ base::Optional<DurationBehavior> duration_behavior)
: target_value_(target_value),
timing_function_(std::move(timing_function)),
+ animation_type_(animation_type),
duration_behavior_(duration_behavior),
- has_set_initial_value_(false) {}
+ has_set_initial_value_(false) {
+ DCHECK_EQ((animation_type == AnimationType::kEaseInOut),
+ duration_behavior.has_value());
+}
ScrollOffsetAnimationCurve::~ScrollOffsetAnimationCurve() = default;
-base::TimeDelta ScrollOffsetAnimationCurve::SegmentDuration(
+// static
+base::TimeDelta ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
const gfx::Vector2dF& delta,
- DurationBehavior behavior,
- base::TimeDelta delayed_by,
- float velocity) {
+ DurationBehavior duration_behavior,
+ base::TimeDelta delayed_by) {
double duration = kConstantDuration;
if (!animation_duration_for_testing_) {
- switch (behavior) {
+ switch (duration_behavior) {
case DurationBehavior::CONSTANT:
duration = kConstantDuration;
break;
@@ -102,24 +97,33 @@ base::TimeDelta ScrollOffsetAnimationCurve::SegmentDuration(
duration = base::ClampToRange(duration, kInverseDeltaMinDuration,
kInverseDeltaMaxDuration);
break;
- case DurationBehavior::CONSTANT_VELOCITY:
- duration =
- std::abs(MaximumDimension(delta) / velocity * kDurationDivisor);
- break;
- default:
- NOTREACHED();
}
+ duration /= kDurationDivisor;
} else {
duration = animation_duration_for_testing_.value();
}
- base::TimeDelta time_delta = base::TimeDelta::FromMicroseconds(
- duration / kDurationDivisor * base::Time::kMicrosecondsPerSecond);
+ base::TimeDelta delay_adjusted_duration =
+ base::TimeDelta::FromSecondsD(duration) - delayed_by;
+ return (delay_adjusted_duration >= base::TimeDelta())
+ ? delay_adjusted_duration
+ : base::TimeDelta();
+}
- time_delta -= delayed_by;
- if (time_delta >= base::TimeDelta())
- return time_delta;
- return base::TimeDelta();
+// static
+base::TimeDelta ScrollOffsetAnimationCurve::LinearSegmentDuration(
+ const gfx::Vector2dF& delta,
+ base::TimeDelta delayed_by,
+ float velocity) {
+ double duration_in_seconds =
+ (animation_duration_for_testing_.has_value())
+ ? animation_duration_for_testing_.value()
+ : std::abs(MaximumDimension(delta) / velocity);
+ base::TimeDelta delay_adjusted_duration =
+ base::TimeDelta::FromSecondsD(duration_in_seconds) - delayed_by;
+ return (delay_adjusted_duration >= base::TimeDelta())
+ ? delay_adjusted_duration
+ : base::TimeDelta();
}
void ScrollOffsetAnimationCurve::SetInitialValue(
@@ -128,9 +132,17 @@ void ScrollOffsetAnimationCurve::SetInitialValue(
float velocity) {
initial_value_ = initial_value;
has_set_initial_value_ = true;
- total_animation_duration_ =
- SegmentDuration(target_value_.DeltaFrom(initial_value_),
- duration_behavior_, delayed_by, velocity);
+ gfx::Vector2dF delta = target_value_.DeltaFrom(initial_value);
+ switch (animation_type_) {
+ case AnimationType::kEaseInOut:
+ total_animation_duration_ = EaseInOutSegmentDuration(
+ delta, duration_behavior_.value(), delayed_by);
+ break;
+ case AnimationType::kLinear:
+ total_animation_duration_ =
+ LinearSegmentDuration(delta, delayed_by, velocity);
+ break;
+ }
}
bool ScrollOffsetAnimationCurve::HasSetInitialValue() const {
@@ -159,10 +171,10 @@ gfx::ScrollOffset ScrollOffsetAnimationCurve::GetValue(
double progress = timing_function_->GetValue(TimeUtil::Divide(t, duration));
return gfx::ScrollOffset(
- gfx::Tween::FloatValueBetween(
- progress, initial_value_.x(), target_value_.x()),
- gfx::Tween::FloatValueBetween(
- progress, initial_value_.y(), target_value_.y()));
+ gfx::Tween::FloatValueBetween(progress, initial_value_.x(),
+ target_value_.x()),
+ gfx::Tween::FloatValueBetween(progress, initial_value_.y(),
+ target_value_.y()));
}
base::TimeDelta ScrollOffsetAnimationCurve::Duration() const {
@@ -181,8 +193,9 @@ std::unique_ptr<ScrollOffsetAnimationCurve>
ScrollOffsetAnimationCurve::CloneToScrollOffsetAnimationCurve() const {
std::unique_ptr<TimingFunction> timing_function(
static_cast<TimingFunction*>(timing_function_->Clone().release()));
- std::unique_ptr<ScrollOffsetAnimationCurve> curve_clone =
- Create(target_value_, std::move(timing_function), duration_behavior_);
+ std::unique_ptr<ScrollOffsetAnimationCurve> curve_clone = base::WrapUnique(
+ new ScrollOffsetAnimationCurve(target_value_, std::move(timing_function),
+ animation_type_, duration_behavior_));
curve_clone->initial_value_ = initial_value_;
curve_clone->total_animation_duration_ = total_animation_duration_;
curve_clone->last_retarget_ = last_retarget_;
@@ -192,7 +205,7 @@ ScrollOffsetAnimationCurve::CloneToScrollOffsetAnimationCurve() const {
void ScrollOffsetAnimationCurve::SetAnimationDurationForTesting(
base::TimeDelta duration) {
- animation_duration_for_testing_ = duration.InSecondsF() * kDurationDivisor;
+ animation_duration_for_testing_ = duration.InSecondsF();
}
static base::TimeDelta VelocityBasedDurationBound(
@@ -227,6 +240,15 @@ static base::TimeDelta VelocityBasedDurationBound(
void ScrollOffsetAnimationCurve::UpdateTarget(
base::TimeDelta t,
const gfx::ScrollOffset& new_target) {
+ DCHECK_NE(animation_type_, AnimationType::kLinear)
+ << "UpdateTarget is not supported on linear scroll animations.";
+ EaseInOutUpdateTarget(t, new_target);
+}
+
+void ScrollOffsetAnimationCurve::EaseInOutUpdateTarget(
+ base::TimeDelta t,
+ const gfx::ScrollOffset& new_target) {
+ DCHECK_EQ(animation_type_, AnimationType::kEaseInOut);
if (std::abs(MaximumDimension(target_value_.DeltaFrom(new_target))) <
kEpsilon) {
target_value_ = new_target;
@@ -243,8 +265,8 @@ void ScrollOffsetAnimationCurve::UpdateTarget(
// The last segment was of zero duration.
if ((total_animation_duration_ - last_retarget_).is_zero()) {
DCHECK_EQ(t, last_retarget_);
- total_animation_duration_ = SegmentDuration(new_delta, duration_behavior_,
- delayed_by, /*velocity*/ 0);
+ total_animation_duration_ = EaseInOutSegmentDuration(
+ new_delta, duration_behavior_.value(), delayed_by);
target_value_ = new_target;
return;
}
@@ -257,8 +279,8 @@ void ScrollOffsetAnimationCurve::UpdateTarget(
// segment duration. This minimizes the "rubber-band" bouncing effect when
// old_normalized_velocity is large and new_delta is small.
base::TimeDelta new_duration =
- std::min(SegmentDuration(new_delta, duration_behavior_, delayed_by,
- /*velocity*/ 0),
+ std::min(EaseInOutSegmentDuration(new_delta, duration_behavior_.value(),
+ delayed_by),
VelocityBasedDurationBound(old_delta, old_normalized_velocity,
old_duration, new_delta));
@@ -281,7 +303,7 @@ void ScrollOffsetAnimationCurve::UpdateTarget(
target_value_ = new_target;
total_animation_duration_ = t + new_duration;
last_retarget_ = t;
- timing_function_ = EaseOutWithInitialVelocity(new_normalized_velocity);
+ timing_function_ = EaseInOutWithInitialVelocity(new_normalized_velocity);
}
} // namespace cc
diff --git a/chromium/cc/animation/scroll_offset_animation_curve.h b/chromium/cc/animation/scroll_offset_animation_curve.h
index 42b774b9c47..1438fe4bd74 100644
--- a/chromium/cc/animation/scroll_offset_animation_curve.h
+++ b/chromium/cc/animation/scroll_offset_animation_curve.h
@@ -26,7 +26,8 @@ class TimingFunction;
class CC_ANIMATION_EXPORT ScrollOffsetAnimationCurve : public AnimationCurve {
public:
- // Indicates how the animation duration should be computed.
+ // Indicates how the animation duration should be computed for Ease-in-out
+ // style scroll animation curves.
enum class DurationBehavior {
// Duration proportional to scroll delta; used for programmatic scrolls.
DELTA_BASED,
@@ -35,19 +36,23 @@ class CC_ANIMATION_EXPORT ScrollOffsetAnimationCurve : public AnimationCurve {
// Duration inversely proportional to scroll delta within certain bounds.
// Used for mouse wheels, makes fast wheel flings feel "snappy" while
// preserving smoothness of slow wheel movements.
- INVERSE_DELTA,
- // Constant velocity; used for autoscrolls.
- CONSTANT_VELOCITY,
+ INVERSE_DELTA
};
- static std::unique_ptr<ScrollOffsetAnimationCurve> Create(
- const gfx::ScrollOffset& target_value,
- std::unique_ptr<TimingFunction> timing_function,
- DurationBehavior = DurationBehavior::DELTA_BASED);
- static base::TimeDelta SegmentDuration(const gfx::Vector2dF& delta,
- DurationBehavior behavior,
- base::TimeDelta delayed_by,
- float velocity);
+ // There is inherent delay in input processing; it may take many milliseconds
+ // from the time of user input to when when we're actually able to handle it
+ // here. This delay is represented by the |delayed_by| value. The way we have
+ // decided to factor this in is by reducing the duration of the resulting
+ // animation by this delayed amount. This also applies to
+ // LinearSegmentDuration.
+ static base::TimeDelta EaseInOutSegmentDuration(
+ const gfx::Vector2dF& delta,
+ DurationBehavior duration_behavior,
+ base::TimeDelta delayed_by);
+
+ static base::TimeDelta LinearSegmentDuration(const gfx::Vector2dF& delta,
+ base::TimeDelta delayed_by,
+ float velocity);
ScrollOffsetAnimationCurve(const ScrollOffsetAnimationCurve&) = delete;
~ScrollOffsetAnimationCurve() override;
@@ -84,9 +89,19 @@ class CC_ANIMATION_EXPORT ScrollOffsetAnimationCurve : public AnimationCurve {
static void SetAnimationDurationForTesting(base::TimeDelta duration);
private:
- ScrollOffsetAnimationCurve(const gfx::ScrollOffset& target_value,
- std::unique_ptr<TimingFunction> timing_function,
- DurationBehavior);
+ friend class ScrollOffsetAnimationCurveFactory;
+ enum class AnimationType { kLinear, kEaseInOut };
+
+ // |duration_behavior| should be provided if (and only if) |animation_type| is
+ // kEaseInOut.
+ ScrollOffsetAnimationCurve(
+ const gfx::ScrollOffset& target_value,
+ std::unique_ptr<TimingFunction> timing_function,
+ AnimationType animation_type,
+ base::Optional<DurationBehavior> duration_behavior = base::nullopt);
+
+ void EaseInOutUpdateTarget(base::TimeDelta t,
+ const gfx::ScrollOffset& new_target);
gfx::ScrollOffset initial_value_;
gfx::ScrollOffset target_value_;
@@ -96,7 +111,10 @@ class CC_ANIMATION_EXPORT ScrollOffsetAnimationCurve : public AnimationCurve {
base::TimeDelta last_retarget_;
std::unique_ptr<TimingFunction> timing_function_;
- DurationBehavior duration_behavior_;
+ AnimationType animation_type_;
+
+ // Only valid when |animation_type_| is EASE_IN_OUT.
+ base::Optional<DurationBehavior> duration_behavior_;
bool has_set_initial_value_;
diff --git a/chromium/cc/animation/scroll_offset_animation_curve_factory.cc b/chromium/cc/animation/scroll_offset_animation_curve_factory.cc
new file mode 100644
index 00000000000..9efcda486a5
--- /dev/null
+++ b/chromium/cc/animation/scroll_offset_animation_curve_factory.cc
@@ -0,0 +1,76 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/animation/scroll_offset_animation_curve_factory.h"
+
+#include "base/memory/ptr_util.h"
+#include "cc/animation/timing_function.h"
+
+namespace cc {
+namespace {
+ScrollOffsetAnimationCurve::DurationBehavior GetDurationBehaviorFromScrollType(
+ ScrollOffsetAnimationCurveFactory::ScrollType scroll_type) {
+ switch (scroll_type) {
+ case ScrollOffsetAnimationCurveFactory::ScrollType::kProgrammatic:
+ return ScrollOffsetAnimationCurve::DurationBehavior::DELTA_BASED;
+ case ScrollOffsetAnimationCurveFactory::ScrollType::kKeyboard:
+ return ScrollOffsetAnimationCurve::DurationBehavior::CONSTANT;
+ case ScrollOffsetAnimationCurveFactory::ScrollType::kMouseWheel:
+ return ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA;
+ case ScrollOffsetAnimationCurveFactory::ScrollType::kAutoScroll:
+ NOTREACHED();
+ return ScrollOffsetAnimationCurve::DurationBehavior::DELTA_BASED;
+ }
+}
+} // namespace
+
+// static
+std::unique_ptr<ScrollOffsetAnimationCurve>
+ScrollOffsetAnimationCurveFactory::CreateAnimation(
+ const gfx::ScrollOffset& target_value,
+ ScrollType scroll_type) {
+ return (scroll_type == ScrollType::kAutoScroll)
+ ? CreateLinearAnimation(target_value)
+ : CreateEaseInOutAnimation(
+ target_value,
+ GetDurationBehaviorFromScrollType(scroll_type));
+}
+
+// static
+std::unique_ptr<ScrollOffsetAnimationCurve>
+ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ const gfx::ScrollOffset& target_value,
+ ScrollOffsetAnimationCurve::DurationBehavior duration_behavior) {
+ return CreateEaseInOutAnimation(target_value, duration_behavior);
+}
+
+// static
+std::unique_ptr<ScrollOffsetAnimationCurve>
+ScrollOffsetAnimationCurveFactory::CreateLinearAnimationForTesting(
+ const gfx::ScrollOffset& target_value) {
+ return CreateLinearAnimation(target_value);
+}
+
+// static
+std::unique_ptr<ScrollOffsetAnimationCurve>
+ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimation(
+ const gfx::ScrollOffset& target_value,
+ ScrollOffsetAnimationCurve::DurationBehavior duration_behavior) {
+ return base::WrapUnique(new ScrollOffsetAnimationCurve(
+ target_value,
+ CubicBezierTimingFunction::CreatePreset(
+ CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
+ ScrollOffsetAnimationCurve::AnimationType::kEaseInOut,
+ duration_behavior));
+}
+
+// static
+std::unique_ptr<ScrollOffsetAnimationCurve>
+ScrollOffsetAnimationCurveFactory::CreateLinearAnimation(
+ const gfx::ScrollOffset& target_value) {
+ return base::WrapUnique(new ScrollOffsetAnimationCurve(
+ target_value, LinearTimingFunction::Create(),
+ ScrollOffsetAnimationCurve::AnimationType::kLinear));
+}
+} // namespace cc
diff --git a/chromium/cc/animation/scroll_offset_animation_curve_factory.h b/chromium/cc/animation/scroll_offset_animation_curve_factory.h
new file mode 100644
index 00000000000..c3438ae2cb7
--- /dev/null
+++ b/chromium/cc/animation/scroll_offset_animation_curve_factory.h
@@ -0,0 +1,38 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_ANIMATION_SCROLL_OFFSET_ANIMATION_CURVE_FACTORY_H_
+#define CC_ANIMATION_SCROLL_OFFSET_ANIMATION_CURVE_FACTORY_H_
+
+#include "cc/animation/scroll_offset_animation_curve.h"
+
+namespace cc {
+class CC_ANIMATION_EXPORT ScrollOffsetAnimationCurveFactory {
+ public:
+ enum class ScrollType { kProgrammatic, kKeyboard, kMouseWheel, kAutoScroll };
+
+ static std::unique_ptr<ScrollOffsetAnimationCurve> CreateAnimation(
+ const gfx::ScrollOffset& target_value,
+ ScrollType scroll_type);
+
+ static std::unique_ptr<ScrollOffsetAnimationCurve>
+ CreateEaseInOutAnimationForTesting(
+ const gfx::ScrollOffset& target_value,
+ ScrollOffsetAnimationCurve::DurationBehavior duration_behavior =
+ ScrollOffsetAnimationCurve::DurationBehavior::DELTA_BASED);
+
+ static std::unique_ptr<ScrollOffsetAnimationCurve>
+ CreateLinearAnimationForTesting(const gfx::ScrollOffset& target_value);
+
+ private:
+ static std::unique_ptr<ScrollOffsetAnimationCurve> CreateEaseInOutAnimation(
+ const gfx::ScrollOffset& target_value,
+ ScrollOffsetAnimationCurve::DurationBehavior duration_hint);
+
+ static std::unique_ptr<ScrollOffsetAnimationCurve> CreateLinearAnimation(
+ const gfx::ScrollOffset& target_value);
+};
+} // namespace cc
+
+#endif // CC_ANIMATION_SCROLL_OFFSET_ANIMATION_CURVE_FACTORY_H_
diff --git a/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc b/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc
index 61bc09be18e..70790871d9d 100644
--- a/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc
+++ b/chromium/cc/animation/scroll_offset_animation_curve_unittest.cc
@@ -4,10 +4,13 @@
#include "cc/animation/scroll_offset_animation_curve.h"
+#include "cc/animation/scroll_offset_animation_curve_factory.h"
#include "cc/animation/timing_function.h"
#include "cc/test/geometry_test_utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+using DurationBehavior = cc::ScrollOffsetAnimationCurve::DurationBehavior;
+
const double kConstantDuration = 9.0;
const double kDurationDivisor = 60.0;
const double kInverseDeltaMaxDuration = 12.0;
@@ -18,9 +21,8 @@ namespace {
TEST(ScrollOffsetAnimationCurveTest, DeltaBasedDuration) {
gfx::ScrollOffset target_value(100.f, 200.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
curve->SetInitialValue(target_value);
EXPECT_DOUBLE_EQ(0.0, curve->Duration().InSecondsF());
@@ -62,9 +64,8 @@ TEST(ScrollOffsetAnimationCurveTest, GetValue) {
gfx::ScrollOffset initial_value(2.f, 40.f);
gfx::ScrollOffset target_value(10.f, 20.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
curve->SetInitialValue(initial_value);
base::TimeDelta duration = curve->Duration();
@@ -95,9 +96,8 @@ TEST(ScrollOffsetAnimationCurveTest, Clone) {
gfx::ScrollOffset initial_value(2.f, 40.f);
gfx::ScrollOffset target_value(10.f, 20.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value));
curve->SetInitialValue(initial_value);
base::TimeDelta duration = curve->Duration();
@@ -129,15 +129,13 @@ TEST(ScrollOffsetAnimationCurveTest, Clone) {
EXPECT_NEAR(37.4168f, value.y(), 0.0002f);
}
-TEST(ScrollOffsetAnimationCurveTest, UpdateTarget) {
+TEST(ScrollOffsetAnimationCurveTest, EaseInOutUpdateTarget) {
gfx::ScrollOffset initial_value(0.f, 0.f);
gfx::ScrollOffset target_value(0.f, 3600.f);
double duration = kConstantDuration / kDurationDivisor;
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_value, CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
- ScrollOffsetAnimationCurve::DurationBehavior::CONSTANT));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ target_value, DurationBehavior::CONSTANT));
curve->SetInitialValue(initial_value);
EXPECT_NEAR(duration, curve->Duration().InSecondsF(), 0.0002f);
EXPECT_NEAR(
@@ -180,11 +178,8 @@ TEST(ScrollOffsetAnimationCurveTest, UpdateTarget) {
TEST(ScrollOffsetAnimationCurveTest, InverseDeltaDuration) {
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(0.f, 100.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(0.f, 100.f), DurationBehavior::INVERSE_DELTA));
curve->SetInitialValue(gfx::ScrollOffset());
double smallDeltaDuration = curve->Duration().InSecondsF();
@@ -205,14 +200,13 @@ TEST(ScrollOffsetAnimationCurveTest, InverseDeltaDuration) {
EXPECT_EQ(largeDeltaDuration, curve->Duration().InSecondsF());
}
-TEST(ScrollOffsetAnimationCurveTest, ConstantVelocityDuration) {
+TEST(ScrollOffsetAnimationCurveTest, LinearAnimation) {
// Testing autoscroll downwards for a scroller of length 1000px.
gfx::ScrollOffset current_offset(0.f, 0.f);
gfx::ScrollOffset target_offset(0.f, 1000.f);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- target_offset, LinearTimingFunction::Create(),
- ScrollOffsetAnimationCurve::DurationBehavior::CONSTANT_VELOCITY));
+ ScrollOffsetAnimationCurveFactory::CreateLinearAnimationForTesting(
+ target_offset));
const float autoscroll_velocity = 800.f; // pixels per second.
curve->SetInitialValue(current_offset, base::TimeDelta(),
@@ -234,11 +228,8 @@ TEST(ScrollOffsetAnimationCurveTest, ConstantVelocityDuration) {
TEST(ScrollOffsetAnimationCurveTest, CurveWithDelay) {
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(0.f, 100.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(0.f, 100.f), DurationBehavior::INVERSE_DELTA));
double duration_in_seconds = kInverseDeltaMaxDuration / kDurationDivisor;
double delay_in_seconds = 0.02;
double curve_duration = duration_in_seconds - delay_in_seconds;
@@ -254,12 +245,10 @@ TEST(ScrollOffsetAnimationCurveTest, CurveWithDelay) {
}
TEST(ScrollOffsetAnimationCurveTest, CurveWithLargeDelay) {
+ DurationBehavior duration_hint = DurationBehavior::INVERSE_DELTA;
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(0.f, 100.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(0.f, 100.f), duration_hint));
curve->SetInitialValue(gfx::ScrollOffset(),
base::TimeDelta::FromSecondsD(0.2));
EXPECT_EQ(0.f, curve->Duration().InSecondsF());
@@ -267,22 +256,19 @@ TEST(ScrollOffsetAnimationCurveTest, CurveWithLargeDelay) {
// Re-targeting when animation duration is 0.
curve->UpdateTarget(base::TimeDelta::FromSecondsD(-0.01),
gfx::ScrollOffset(0.f, 300.f));
- double duration =
- ScrollOffsetAnimationCurve::SegmentDuration(
- gfx::Vector2dF(0.f, 200.f),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA,
- base::TimeDelta::FromSecondsD(0.01), /*velocity*/ 0)
- .InSecondsF();
+ double duration = ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
+ gfx::Vector2dF(0.f, 200.f), duration_hint,
+ base::TimeDelta::FromSecondsD(0.01))
+ .InSecondsF();
EXPECT_EQ(duration, curve->Duration().InSecondsF());
// Re-targeting before last_retarget_, the difference should be accounted for
// in duration.
curve->UpdateTarget(base::TimeDelta::FromSecondsD(-0.01),
gfx::ScrollOffset(0.f, 500.f));
- duration = ScrollOffsetAnimationCurve::SegmentDuration(
- gfx::Vector2dF(0.f, 500.f),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA,
- base::TimeDelta::FromSecondsD(0.01), /*velocity*/ 0)
+ duration = ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
+ gfx::Vector2dF(0.f, 500.f), duration_hint,
+ base::TimeDelta::FromSecondsD(0.01))
.InSecondsF();
EXPECT_EQ(duration, curve->Duration().InSecondsF());
@@ -293,12 +279,10 @@ TEST(ScrollOffsetAnimationCurveTest, CurveWithLargeDelay) {
// This test verifies that if the last segment duration is zero, ::UpdateTarget
// simply updates the total animation duration see crbug.com/645317.
TEST(ScrollOffsetAnimationCurveTest, UpdateTargetZeroLastSegmentDuration) {
+ DurationBehavior duration_hint = DurationBehavior::INVERSE_DELTA;
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(0.f, 100.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(0.f, 100.f), duration_hint));
double duration_in_seconds = kInverseDeltaMaxDuration / kDurationDivisor;
double delay_in_seconds = 0.02;
double curve_duration = duration_in_seconds - delay_in_seconds;
@@ -312,10 +296,9 @@ TEST(ScrollOffsetAnimationCurveTest, UpdateTargetZeroLastSegmentDuration) {
gfx::ScrollOffset(0.f, 200.f) -
curve->GetValue(base::TimeDelta::FromSecondsD(0.05));
double expected_duration =
- ScrollOffsetAnimationCurve::SegmentDuration(
- gfx::Vector2dF(new_delta.x(), new_delta.y()),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA,
- base::TimeDelta(), /*velocity*/ 0)
+ ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
+ gfx::Vector2dF(new_delta.x(), new_delta.y()), duration_hint,
+ base::TimeDelta())
.InSecondsF() +
0.05;
curve->UpdateTarget(base::TimeDelta::FromSecondsD(0.05),
@@ -332,12 +315,10 @@ TEST(ScrollOffsetAnimationCurveTest, UpdateTargetZeroLastSegmentDuration) {
// Re-target 3, this should set total_animation_duration based on new_delta.
new_delta = gfx::ScrollOffset(0.f, 500.f) -
curve->GetValue(base::TimeDelta::FromSecondsD(0.05));
- expected_duration =
- ScrollOffsetAnimationCurve::SegmentDuration(
- gfx::Vector2dF(new_delta.x(), new_delta.y()),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA,
- base::TimeDelta::FromSecondsD(0.15), /*velocity*/ 0)
- .InSecondsF();
+ expected_duration = ScrollOffsetAnimationCurve::EaseInOutSegmentDuration(
+ gfx::Vector2dF(new_delta.x(), new_delta.y()),
+ duration_hint, base::TimeDelta::FromSecondsD(0.15))
+ .InSecondsF();
curve->UpdateTarget(base::TimeDelta::FromSecondsD(-0.1),
gfx::ScrollOffset(0.f, 500.f));
EXPECT_NEAR(expected_duration, curve->Duration().InSecondsF(), 0.0002f);
diff --git a/chromium/cc/animation/scroll_offset_animations_impl.cc b/chromium/cc/animation/scroll_offset_animations_impl.cc
index 5c7ff936114..bd2df46089c 100644
--- a/chromium/cc/animation/scroll_offset_animations_impl.cc
+++ b/chromium/cc/animation/scroll_offset_animations_impl.cc
@@ -10,6 +10,7 @@
#include "cc/animation/animation_id_provider.h"
#include "cc/animation/animation_timeline.h"
#include "cc/animation/element_animations.h"
+#include "cc/animation/scroll_offset_animation_curve_factory.h"
#include "cc/animation/single_keyframe_effect_animation.h"
#include "cc/animation/timing_function.h"
@@ -41,27 +42,26 @@ void ScrollOffsetAnimationsImpl::AutoScrollAnimationCreate(
float autoscroll_velocity,
base::TimeDelta animation_start_offset) {
std::unique_ptr<ScrollOffsetAnimationCurve> curve =
- ScrollOffsetAnimationCurve::Create(
- target_offset, LinearTimingFunction::Create(),
- ScrollOffsetAnimationCurve::DurationBehavior::CONSTANT_VELOCITY);
+ ScrollOffsetAnimationCurveFactory::CreateAnimation(
+ target_offset,
+ ScrollOffsetAnimationCurveFactory::ScrollType::kAutoScroll);
curve->SetInitialValue(current_offset, base::TimeDelta(),
autoscroll_velocity);
ScrollAnimationCreateInternal(element_id, std::move(curve),
animation_start_offset);
}
-void ScrollOffsetAnimationsImpl::ScrollAnimationCreate(
+void ScrollOffsetAnimationsImpl::MouseWheelScrollAnimationCreate(
ElementId element_id,
const gfx::ScrollOffset& target_offset,
const gfx::ScrollOffset& current_offset,
base::TimeDelta delayed_by,
base::TimeDelta animation_start_offset) {
std::unique_ptr<ScrollOffsetAnimationCurve> curve =
- ScrollOffsetAnimationCurve::Create(
+ ScrollOffsetAnimationCurveFactory::CreateAnimation(
target_offset,
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT),
- ScrollOffsetAnimationCurve::DurationBehavior::INVERSE_DELTA);
+ ScrollOffsetAnimationCurveFactory::ScrollType::kMouseWheel);
+
curve->SetInitialValue(current_offset, delayed_by);
ScrollAnimationCreateInternal(element_id, std::move(curve),
animation_start_offset);
diff --git a/chromium/cc/animation/scroll_offset_animations_impl.h b/chromium/cc/animation/scroll_offset_animations_impl.h
index 4371deed459..3f5b8b3ad27 100644
--- a/chromium/cc/animation/scroll_offset_animations_impl.h
+++ b/chromium/cc/animation/scroll_offset_animations_impl.h
@@ -41,11 +41,11 @@ class CC_ANIMATION_EXPORT ScrollOffsetAnimationsImpl
// |delayed_by| shrinks the duration of the
// animation. |animation_start_offset| causes us to start the animation
// partway through.
- void ScrollAnimationCreate(ElementId element_id,
- const gfx::ScrollOffset& target_offset,
- const gfx::ScrollOffset& current_offset,
- base::TimeDelta delayed_by,
- base::TimeDelta animation_start_offset);
+ void MouseWheelScrollAnimationCreate(ElementId element_id,
+ const gfx::ScrollOffset& target_offset,
+ const gfx::ScrollOffset& current_offset,
+ base::TimeDelta delayed_by,
+ base::TimeDelta animation_start_offset);
bool ScrollAnimationUpdateTarget(ElementId element_id,
const gfx::Vector2dF& scroll_delta,
@@ -75,6 +75,8 @@ class CC_ANIMATION_EXPORT ScrollOffsetAnimationsImpl
base::TimeTicks animation_start_time,
std::unique_ptr<AnimationCurve> curve) override {
}
+ void NotifyLocalTimeUpdated(
+ base::Optional<base::TimeDelta> local_time) override {}
bool IsAnimating() const;
diff --git a/chromium/cc/animation/scroll_timeline.h b/chromium/cc/animation/scroll_timeline.h
index 66b39d562fc..d3003e90b69 100644
--- a/chromium/cc/animation/scroll_timeline.h
+++ b/chromium/cc/animation/scroll_timeline.h
@@ -22,6 +22,10 @@ class ScrollTree;
// https://wicg.github.io/scroll-animations/#scrolltimeline-interface.
class CC_ANIMATION_EXPORT ScrollTimeline {
public:
+ // cc does not know about writing modes. The ScrollDirection below is
+ // converted using blink::scroll_timeline_util::ConvertOrientation which takes
+ // the spec-compliant ScrollDirection enumeration.
+ // https://drafts.csswg.org/scroll-animations/#scrolldirection-enumeration
enum ScrollDirection {
ScrollUp,
ScrollDown,
diff --git a/chromium/cc/animation/single_keyframe_effect_animation.cc b/chromium/cc/animation/single_keyframe_effect_animation.cc
index a467e5ee4e3..bbc0cfa7fd3 100644
--- a/chromium/cc/animation/single_keyframe_effect_animation.cc
+++ b/chromium/cc/animation/single_keyframe_effect_animation.cc
@@ -95,13 +95,16 @@ void SingleKeyframeEffectAnimation::AbortKeyframeModel(int keyframe_model_id) {
GetKeyframeEffect()->id());
}
-bool SingleKeyframeEffectAnimation::NotifyKeyframeModelFinishedForTesting(
+void SingleKeyframeEffectAnimation::NotifyKeyframeModelFinishedForTesting(
+ int timeline_id,
+ int keyframe_model_id,
TargetProperty::Type target_property,
int group_id) {
- AnimationEvent event(AnimationEvent::FINISHED,
- GetKeyframeEffect()->element_id(), group_id,
- target_property, base::TimeTicks());
- return GetKeyframeEffect()->NotifyKeyframeModelFinished(event);
+ AnimationEvent event(
+ AnimationEvent::FINISHED,
+ {timeline_id, id(), GetKeyframeEffect()->id(), keyframe_model_id},
+ group_id, target_property, base::TimeTicks());
+ DispatchAndDelegateAnimationEvent(event);
}
KeyframeModel* SingleKeyframeEffectAnimation::GetKeyframeModel(
diff --git a/chromium/cc/animation/single_keyframe_effect_animation.h b/chromium/cc/animation/single_keyframe_effect_animation.h
index a79566ae28e..68eab8495fb 100644
--- a/chromium/cc/animation/single_keyframe_effect_animation.h
+++ b/chromium/cc/animation/single_keyframe_effect_animation.h
@@ -50,7 +50,9 @@ class CC_ANIMATION_EXPORT SingleKeyframeEffectAnimation : public Animation {
virtual void RemoveKeyframeModel(int keyframe_model_id);
void AbortKeyframeModel(int keyframe_model_id);
- bool NotifyKeyframeModelFinishedForTesting(
+ void NotifyKeyframeModelFinishedForTesting(
+ int timeline_id,
+ int keyframe_model_id,
TargetProperty::Type target_property,
int group_id);
KeyframeModel* GetKeyframeModel(TargetProperty::Type target_property) const;
diff --git a/chromium/cc/animation/worklet_animation.cc b/chromium/cc/animation/worklet_animation.cc
index a6d109fac1b..811b9e41337 100644
--- a/chromium/cc/animation/worklet_animation.cc
+++ b/chromium/cc/animation/worklet_animation.cc
@@ -5,7 +5,9 @@
#include "cc/animation/worklet_animation.h"
#include <utility>
+#include "cc/animation/animation_delegate.h"
#include "cc/animation/animation_id_provider.h"
+#include "cc/animation/animation_timeline.h"
#include "cc/animation/keyframe_effect.h"
#include "cc/animation/scroll_timeline.h"
#include "cc/trees/animation_effect_timings.h"
@@ -50,6 +52,7 @@ WorkletAnimation::WorkletAnimation(
options_(std::move(options)),
effect_timings_(std::move(effect_timings)),
local_time_(base::nullopt),
+ last_synced_local_time_(base::nullopt),
start_time_(base::nullopt),
last_current_time_(base::nullopt),
has_pending_tree_lock_(false),
@@ -107,6 +110,19 @@ void WorkletAnimation::Tick(base::TimeTicks monotonic_time) {
keyframe_effect()->Tick(monotonic_time);
}
+void WorkletAnimation::UpdateState(bool start_ready_animations,
+ AnimationEvents* events) {
+ Animation::UpdateState(start_ready_animations, events);
+ if (last_synced_local_time_ != local_time_) {
+ AnimationEvent event(animation_timeline()->id(), id_, local_time_);
+ // TODO(http://crbug.com/1013654): Instead of pushing multiple events per
+ // single main frame, push just the recent one to be handled by next main
+ // frame.
+ events->events_.push_back(event);
+ last_synced_local_time_ = local_time_;
+ }
+}
+
void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
@@ -131,6 +147,9 @@ void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
DCHECK(is_timeline_active || state_ == State::REMOVED);
+ // TODO(https://crbug.com/1011138): Initialize current_time to null if the
+ // timeline is inactive. It might be inactive here when state is
+ // State::REMOVED.
base::Optional<base::TimeDelta> current_time =
CurrentTime(monotonic_time, scroll_tree, is_active_tree);
@@ -141,6 +160,8 @@ void WorkletAnimation::UpdateInputState(MutatorInputState* input_state,
if (!is_timeline_active)
current_time = last_current_time_;
+ // TODO(https://crbug.com/1011138): Do not early exit if state is
+ // State::REMOVED. The animation must be removed in this case.
if (!current_time)
return;
last_current_time_ = current_time;
diff --git a/chromium/cc/animation/worklet_animation.h b/chromium/cc/animation/worklet_animation.h
index 508c0be4cf4..84e52079011 100644
--- a/chromium/cc/animation/worklet_animation.h
+++ b/chromium/cc/animation/worklet_animation.h
@@ -64,6 +64,9 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
void Tick(base::TimeTicks monotonic_time) override;
+ void UpdateState(bool start_ready_animations,
+ AnimationEvents* events) override;
+
void UpdateInputState(MutatorInputState* input_state,
base::TimeTicks monotonic_time,
const ScrollTree& scroll_tree,
@@ -130,7 +133,7 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
}
// Updates the playback rate of the Impl thread instance.
- // Called by the UI thread WorletAnimation instance during commit.
+ // Called by the UI thread WorkletAnimation instance during commit.
void SetPlaybackRate(double playback_rate);
bool IsTimelineActive(const ScrollTree& scroll_tree,
@@ -163,6 +166,11 @@ class CC_ANIMATION_EXPORT WorkletAnimation final
// The value comes from the user script that runs inside the animation worklet
// global scope.
base::Optional<base::TimeDelta> local_time_;
+ // Local time passed to the main thread worklet animation to update its
+ // keyframe effect. We only set the most recent local time, meaning that if
+ // there are multiple compositor frames without a single main frame only
+ // the local time associated with the latest frame is sent to the main thread.
+ base::Optional<base::TimeDelta> last_synced_local_time_;
base::Optional<base::TimeTicks> start_time_;
diff --git a/chromium/cc/animation/worklet_animation_unittest.cc b/chromium/cc/animation/worklet_animation_unittest.cc
index 4d0e61ea073..cd33dee5afa 100644
--- a/chromium/cc/animation/worklet_animation_unittest.cc
+++ b/chromium/cc/animation/worklet_animation_unittest.cc
@@ -112,6 +112,52 @@ TEST_F(WorkletAnimationTest, LocalTimeIsUsedWhenTicking) {
expected_opacity);
}
+// Test generation of animation events by worklet animations.
+TEST_F(WorkletAnimationTest, AnimationEventLocalTimeUpdate) {
+ AttachWorkletAnimation();
+
+ base::Optional<base::TimeDelta> local_time = base::TimeDelta::FromSecondsD(1);
+ MutatorOutputState::AnimationState state(worklet_animation_id_);
+ state.local_times.push_back(local_time);
+ worklet_animation_->SetOutputState(state);
+
+ std::unique_ptr<MutatorEvents> mutator_events = host_->CreateEvents();
+ auto* animation_events = static_cast<AnimationEvents*>(mutator_events.get());
+ worklet_animation_->UpdateState(true, animation_events);
+
+ // One event is generated as a result of update state.
+ EXPECT_EQ(1u, animation_events->events_.size());
+ AnimationEvent event = animation_events->events_[0];
+ EXPECT_EQ(AnimationEvent::TIME_UPDATED, event.type);
+ EXPECT_EQ(worklet_animation_->id(), event.uid.animation_id);
+ EXPECT_EQ(local_time, event.local_time);
+
+ // If the state is not updated no more events is generated.
+ mutator_events = host_->CreateEvents();
+ animation_events = static_cast<AnimationEvents*>(mutator_events.get());
+ worklet_animation_->UpdateState(true, animation_events);
+ EXPECT_EQ(0u, animation_events->events_.size());
+
+ // If local time is set to the same value no event is generated.
+ worklet_animation_->SetOutputState(state);
+ mutator_events = host_->CreateEvents();
+ animation_events = static_cast<AnimationEvents*>(mutator_events.get());
+ worklet_animation_->UpdateState(true, animation_events);
+ EXPECT_EQ(0u, animation_events->events_.size());
+
+ // If local time is set to null value, an animation event with null local
+ // time is generated.
+ state.local_times.clear();
+ local_time = base::nullopt;
+ state.local_times.push_back(local_time);
+ worklet_animation_->SetOutputState(state);
+ mutator_events = host_->CreateEvents();
+ animation_events = static_cast<AnimationEvents*>(mutator_events.get());
+ worklet_animation_->UpdateState(true, animation_events);
+ EXPECT_EQ(1u, animation_events->events_.size());
+ EXPECT_EQ(local_time, animation_events->events_[0].local_time);
+}
+
TEST_F(WorkletAnimationTest, CurrentTimeCorrectlyUsesScrollTimeline) {
auto scroll_timeline = std::make_unique<MockScrollTimeline>();
EXPECT_CALL(*scroll_timeline, IsActive(_, _)).WillRepeatedly(Return(true));
diff --git a/chromium/cc/base/devtools_instrumentation.cc b/chromium/cc/base/devtools_instrumentation.cc
index 667b0eb8414..72b7be7a999 100644
--- a/chromium/cc/base/devtools_instrumentation.cc
+++ b/chromium/cc/base/devtools_instrumentation.cc
@@ -37,6 +37,7 @@ const char kLayerId[] = "layerId";
const char kLayerTreeId[] = "layerTreeId";
const char kPixelRefId[] = "pixelRefId";
+const char kImageUploadTask[] = "ImageUploadTask";
const char kImageDecodeTask[] = "ImageDecodeTask";
const char kBeginFrame[] = "BeginFrame";
const char kNeedsBeginFrameChanged[] = "NeedsBeginFrameChanged";
@@ -50,14 +51,47 @@ const char kCompositeLayers[] = "CompositeLayers";
const char kPaintSetup[] = "PaintSetup";
const char kUpdateLayer[] = "UpdateLayer";
+ScopedImageUploadTask::ScopedImageUploadTask(const void* image_ptr,
+ ImageType image_type)
+ : ScopedImageTask(image_type) {
+ TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline,
+ internal::kImageUploadTask, internal::kPixelRefId,
+ reinterpret_cast<uint64_t>(image_ptr));
+}
+
+ScopedImageUploadTask::~ScopedImageUploadTask() {
+ TRACE_EVENT_END0(internal::CategoryName::kTimeline,
+ internal::kImageUploadTask);
+ if (suppress_metrics_)
+ return;
+
+ auto duration = base::TimeTicks::Now() - start_time_;
+ switch (image_type_) {
+ case ImageType::kWebP:
+ UmaHistogramCustomMicrosecondsTimes(
+ "Renderer4.ImageUploadTaskDurationUs.WebP", duration, hist_min_,
+ hist_max_, bucket_count_);
+ break;
+ case ImageType::kJpeg:
+ UmaHistogramCustomMicrosecondsTimes(
+ "Renderer4.ImageUploadTaskDurationUs.Jpeg", duration, hist_min_,
+ hist_max_, bucket_count_);
+ break;
+ case ImageType::kOther:
+ UmaHistogramCustomMicrosecondsTimes(
+ "Renderer4.ImageUploadTaskDurationUs.Other", duration, hist_min_,
+ hist_max_, bucket_count_);
+ break;
+ }
+}
+
ScopedImageDecodeTask::ScopedImageDecodeTask(const void* image_ptr,
DecodeType decode_type,
TaskType task_type,
ImageType image_type)
- : decode_type_(decode_type),
- task_type_(task_type),
- start_time_(base::TimeTicks::Now()),
- image_type_(image_type) {
+ : ScopedImageTask(image_type),
+ decode_type_(decode_type),
+ task_type_(task_type) {
TRACE_EVENT_BEGIN1(internal::CategoryName::kTimeline,
internal::kImageDecodeTask, internal::kPixelRefId,
reinterpret_cast<uint64_t>(image_ptr));
@@ -69,37 +103,34 @@ ScopedImageDecodeTask::~ScopedImageDecodeTask() {
if (suppress_metrics_)
return;
- const uint32_t bucket_count = 50;
- base::TimeDelta min = base::TimeDelta::FromMicroseconds(1);
- base::TimeDelta max = base::TimeDelta::FromMilliseconds(1000);
auto duration = base::TimeTicks::Now() - start_time_;
switch (image_type_) {
case ImageType::kWebP:
RecordMicrosecondTimesUmaByDecodeType(
- "Renderer4.ImageDecodeTaskDurationUs.WebP", duration, min, max,
- bucket_count, decode_type_);
+ "Renderer4.ImageDecodeTaskDurationUs.WebP", duration, hist_min_,
+ hist_max_, bucket_count_, decode_type_);
break;
case ImageType::kJpeg:
RecordMicrosecondTimesUmaByDecodeType(
- "Renderer4.ImageDecodeTaskDurationUs.Jpeg", duration, min, max,
- bucket_count, decode_type_);
+ "Renderer4.ImageDecodeTaskDurationUs.Jpeg", duration, hist_min_,
+ hist_max_, bucket_count_, decode_type_);
break;
case ImageType::kOther:
RecordMicrosecondTimesUmaByDecodeType(
- "Renderer4.ImageDecodeTaskDurationUs.Other", duration, min, max,
- bucket_count, decode_type_);
+ "Renderer4.ImageDecodeTaskDurationUs.Other", duration, hist_min_,
+ hist_max_, bucket_count_, decode_type_);
break;
}
switch (task_type_) {
case kInRaster:
RecordMicrosecondTimesUmaByDecodeType(
- "Renderer4.ImageDecodeTaskDurationUs", duration, min, max,
- bucket_count, decode_type_);
+ "Renderer4.ImageDecodeTaskDurationUs", duration, hist_min_, hist_max_,
+ bucket_count_, decode_type_);
break;
case kOutOfRaster:
RecordMicrosecondTimesUmaByDecodeType(
- "Renderer4.ImageDecodeTaskDurationUs.OutOfRaster", duration, min, max,
- bucket_count, decode_type_);
+ "Renderer4.ImageDecodeTaskDurationUs.OutOfRaster", duration,
+ hist_min_, hist_max_, bucket_count_, decode_type_);
break;
}
}
diff --git a/chromium/cc/base/devtools_instrumentation.h b/chromium/cc/base/devtools_instrumentation.h
index f47b1278588..12e4c9c7016 100644
--- a/chromium/cc/base/devtools_instrumentation.h
+++ b/chromium/cc/base/devtools_instrumentation.h
@@ -64,12 +64,45 @@ class CC_BASE_EXPORT ScopedLayerTask {
const char* event_name_;
};
-class CC_BASE_EXPORT ScopedImageDecodeTask {
+class CC_BASE_EXPORT ScopedImageTask {
public:
- enum DecodeType { kSoftware, kGpu };
- enum TaskType { kInRaster, kOutOfRaster };
enum ImageType { kWebP, kJpeg, kOther };
+ ScopedImageTask(ImageType image_type)
+ : image_type_(image_type), start_time_(base::TimeTicks::Now()) {}
+ ScopedImageTask(const ScopedImageTask&) = delete;
+ ~ScopedImageTask() = default;
+ ScopedImageTask& operator=(const ScopedImageTask&) = delete;
+
+ // Prevents logging duration metrics. Used in cases where a task performed
+ // uninteresting work or was terminated early.
+ void SuppressMetrics() { suppress_metrics_ = true; }
+
+ protected:
+ bool suppress_metrics_ = false;
+ const ImageType image_type_;
+ const base::TimeTicks start_time_;
+
+ // UMA histogram parameters
+ const uint32_t bucket_count_ = 50;
+ base::TimeDelta hist_min_ = base::TimeDelta::FromMicroseconds(1);
+ base::TimeDelta hist_max_ = base::TimeDelta::FromMilliseconds(1000);
+};
+
+class CC_BASE_EXPORT ScopedImageUploadTask : public ScopedImageTask {
+ public:
+ ScopedImageUploadTask(const void* image_ptr, ImageType image_type);
+ ScopedImageUploadTask(const ScopedImageUploadTask&) = delete;
+ ~ScopedImageUploadTask();
+
+ ScopedImageUploadTask& operator=(const ScopedImageUploadTask&) = delete;
+};
+
+class CC_BASE_EXPORT ScopedImageDecodeTask : public ScopedImageTask {
+ public:
+ enum TaskType { kInRaster, kOutOfRaster };
+ enum DecodeType { kSoftware, kGpu };
+
ScopedImageDecodeTask(const void* image_ptr,
DecodeType decode_type,
TaskType task_type,
@@ -79,16 +112,9 @@ class CC_BASE_EXPORT ScopedImageDecodeTask {
ScopedImageDecodeTask& operator=(const ScopedImageDecodeTask&) = delete;
- // Prevents logging duration metrics. Used in cases where a task performed
- // uninteresting work or was terminated early.
- void SuppressMetrics() { suppress_metrics_ = true; }
-
private:
const DecodeType decode_type_;
const TaskType task_type_;
- const base::TimeTicks start_time_;
- bool suppress_metrics_ = false;
- const ImageType image_type_;
};
class CC_BASE_EXPORT ScopedLayerTreeTask {
diff --git a/chromium/cc/debug/debug_colors.cc b/chromium/cc/debug/debug_colors.cc
index c16f4fbec8b..2edd38e2e0b 100644
--- a/chromium/cc/debug/debug_colors.cc
+++ b/chromium/cc/debug/debug_colors.cc
@@ -276,6 +276,17 @@ SkColor DebugColors::NonFastScrollableRectFillColor() {
return SkColorSetARGB(30, 238, 163, 59);
}
+// Main-thread scrolling reason rects in yellow-orange.
+SkColor DebugColors::MainThreadScrollingReasonRectBorderColor() {
+ return SkColorSetARGB(255, 200, 100, 0);
+}
+int DebugColors::MainThreadScrollingReasonRectBorderWidth() {
+ return 2;
+}
+SkColor DebugColors::MainThreadScrollingReasonRectFillColor() {
+ return SkColorSetARGB(30, 200, 100, 0);
+}
+
// Animation bounds are lime-green.
SkColor DebugColors::LayerAnimationBoundsBorderColor() {
return SkColorSetARGB(255, 112, 229, 0);
diff --git a/chromium/cc/debug/debug_colors.h b/chromium/cc/debug/debug_colors.h
index 8e13fcbb8d4..639656a889e 100644
--- a/chromium/cc/debug/debug_colors.h
+++ b/chromium/cc/debug/debug_colors.h
@@ -104,6 +104,10 @@ class CC_DEBUG_EXPORT DebugColors {
static int NonFastScrollableRectBorderWidth();
static SkColor NonFastScrollableRectFillColor();
+ static SkColor MainThreadScrollingReasonRectBorderColor();
+ static int MainThreadScrollingReasonRectBorderWidth();
+ static SkColor MainThreadScrollingReasonRectFillColor();
+
static SkColor LayerAnimationBoundsBorderColor();
static int LayerAnimationBoundsBorderWidth();
static SkColor LayerAnimationBoundsFillColor();
diff --git a/chromium/cc/debug/layer_tree_debug_state.cc b/chromium/cc/debug/layer_tree_debug_state.cc
index 8c154cc8f55..66d1e134c43 100644
--- a/chromium/cc/debug/layer_tree_debug_state.cc
+++ b/chromium/cc/debug/layer_tree_debug_state.cc
@@ -21,6 +21,7 @@ LayerTreeDebugState::LayerTreeDebugState()
show_wheel_event_handler_rects(false),
show_scroll_event_handler_rects(false),
show_non_fast_scrollable_rects(false),
+ show_main_thread_scrolling_reason_rects(false),
show_layer_animation_bounds_rects(false),
slow_down_raster_scale_factor(0),
rasterize_only_visible_content(false),
@@ -50,6 +51,7 @@ bool LayerTreeDebugState::ShowHudRects() const {
show_surface_damage_rects || show_screen_space_rects ||
show_touch_event_handler_rects || show_wheel_event_handler_rects ||
show_scroll_event_handler_rects || show_non_fast_scrollable_rects ||
+ show_main_thread_scrolling_reason_rects ||
show_layer_animation_bounds_rects || show_layout_shift_regions;
}
@@ -71,6 +73,8 @@ bool LayerTreeDebugState::Equal(const LayerTreeDebugState& a,
a.show_wheel_event_handler_rects == b.show_wheel_event_handler_rects &&
a.show_scroll_event_handler_rects == b.show_scroll_event_handler_rects &&
a.show_non_fast_scrollable_rects == b.show_non_fast_scrollable_rects &&
+ a.show_main_thread_scrolling_reason_rects ==
+ b.show_main_thread_scrolling_reason_rects &&
a.show_layer_animation_bounds_rects ==
b.show_layer_animation_bounds_rects &&
a.slow_down_raster_scale_factor == b.slow_down_raster_scale_factor &&
@@ -96,6 +100,8 @@ LayerTreeDebugState LayerTreeDebugState::Unite(const LayerTreeDebugState& a,
r.show_wheel_event_handler_rects |= b.show_wheel_event_handler_rects;
r.show_scroll_event_handler_rects |= b.show_scroll_event_handler_rects;
r.show_non_fast_scrollable_rects |= b.show_non_fast_scrollable_rects;
+ r.show_main_thread_scrolling_reason_rects |=
+ b.show_main_thread_scrolling_reason_rects;
r.show_layer_animation_bounds_rects |= b.show_layer_animation_bounds_rects;
if (b.slow_down_raster_scale_factor)
diff --git a/chromium/cc/debug/layer_tree_debug_state.h b/chromium/cc/debug/layer_tree_debug_state.h
index 50dd2308edb..db18711a3f0 100644
--- a/chromium/cc/debug/layer_tree_debug_state.h
+++ b/chromium/cc/debug/layer_tree_debug_state.h
@@ -41,6 +41,7 @@ class CC_DEBUG_EXPORT LayerTreeDebugState {
bool show_wheel_event_handler_rects;
bool show_scroll_event_handler_rects;
bool show_non_fast_scrollable_rects;
+ bool show_main_thread_scrolling_reason_rects;
bool show_layer_animation_bounds_rects;
int slow_down_raster_scale_factor;
diff --git a/chromium/cc/input/README.md b/chromium/cc/input/README.md
new file mode 100644
index 00000000000..a5337e9cb94
--- /dev/null
+++ b/chromium/cc/input/README.md
@@ -0,0 +1,106 @@
+# cc/input
+
+This directory contains code specific to input handling and scrolling in in the
+compositor.
+
+The renderer compositor typically receives, on the compositor thread, all input
+events arriving from the browser. In some cases, the compositor can process
+input without consulting the main thread. We strive for this since it means
+input doesn't have to block on a potentially busy main thread.
+
+If the compositor determines that Blink must be consulted to correctly handle
+the event. e.g. For detailed hit-testing or correct paint output. In these
+cases, the event will be posted to the Blink main thread.
+
+See [InputHandlerProxy](../../ui/events/blink/input_handler_proxy.cc) for the
+entry point to this code.
+
+## Scrolling
+
+### Viewport
+
+Viewport scrolling is special compared to scrolling regular ScrollNodes. The
+main difference is that the viewport is composed of two scrollers: the inner
+and outer scrollers. These correspond to the visual and layout viewports in
+Blink, respectively.
+
+The reason for this composition is pinch-zoom; when a user zooms in, the layout
+viewport remains unchanged (position: fixed elements don't stick to the user's
+screen) and the user can pan the visual viewport within the layout viewport.
+See [this demo](http://bokand.github.io/viewport/index.html) for a visual,
+interactive example.
+
+This arrangement requires some special distribution and bubbling of
+scroll delta. Additionally, viewport scrolling is also responsible for
+overscroll effects like rubber-banding and gestural-navigation as well as URL
+bar movement on Android.
+
+Notably, that the UI compositor as well as renderer compositors for
+out-of-process iframes will not have an inner or an outer viewport scroll node.
+
+#### Scroll Chain Structure
+
+The inner viewport scroll node is always the first and only child of the root
+scroll node; it is the top-level scrollable node in the scroll tree. The outer
+viewport will typically be the one child of the inner viewport scroll node;
+however, this may be changed on certain pages. This happens when a page is
+given a non-document root scroller. For more information the root
+scroller see the
+[README](../../third_party/blink/renderer/core/page/scrolling/README.md) in
+Blink's core/page/scrolling directory.
+
+#### Scrolling the Viewport
+
+Viewport scroll nodes are typically not scrolled directly, like other scroll
+nodes. Instead, they're scrolled by using the cc::Viewport object. cc::Viewport
+is an object that's lives on the LayerTreeHostImpl and operates on the active
+tree's inner and outer scroll nodes. It encapsulates the bubbling,
+distribution, top controls, etc. behavior we associate with scrolling the
+viewport.
+
+We use the outer viewport scroll node to represent cc::Viewport scrolling in
+cases where the scroller must be represented by a scroll node (e.g.
+CurrentlyScrollingNode). In these cases we make sure to check for the outer
+scroll node use cc::Viewport instead. This means that in cases where we want
+"viewport" scrolling, we must use the outer viewport scroll node. This can also
+happen when the inner viewport is reached in the scroll chain, for example, by
+scroll bubbling from a `position: fixed` subtree; we use the outer scroll node
+to scroll this case.
+
+The scroll chain is terminated once we've scrolled the cc::Viewport. i.e.
+scrolls don't bubble above the cc::Viewport.
+
+#### Root Scroller Nuances
+
+When we have a non-document root scroller, there are cases where we
+specifically wish to scroll only the inner viewport. For example, when a
+scroll started from a non-descendant of the root scroller or a `position:
+fixed` element and bubbles up. In these cases, we shouldn't scroll using
+cc::Viewport because that would scroll the root scroller as well. Doing so
+would create a difference in how scrolls chain based on which element is the
+root scroller, something we must avoid for interop and compatibility reasons.
+
+This means that when we reach the inner viewport scroll node in the scroll
+chain we need to know whether to use cc::Viewport or not. Blink sets the
+|prevent\_viewport\_scrolling\_from\_inner| bit on the inner viewport scroll
+node so that the compositor can know that scrolls bubbling to the inner
+viewport should not use the cc::Viewport class.
+
+## Other Docs
+
+* [Blink Scrolling](../../third_party/blink/renderer/core/page/scrolling/README.md)
+ provides information about similar concepts in Blink and the web-platform.
+
+## Glossary
+
+### Inner Viewport
+
+Also called the "Visual Viewport" in web/Blink terminology. This is the
+viewport the user actually sees and corresponds to the content visible in the
+browser window.
+
+### Outer Viewport
+
+Also called the "Layout Viewport" in web/Blink terminology. This is the main
+"content scroller" in a given page, typically the document (`<html>`) element.
+This is the scroller to which position: fixed elements remain fixed to.
diff --git a/chromium/cc/input/browser_controls_offset_manager.cc b/chromium/cc/input/browser_controls_offset_manager.cc
index afbe9770086..fb59212a41d 100644
--- a/chromium/cc/input/browser_controls_offset_manager.cc
+++ b/chromium/cc/input/browser_controls_offset_manager.cc
@@ -10,6 +10,7 @@
#include "base/logging.h"
#include "base/memory/ptr_util.h"
+#include "base/numerics/ranges.h"
#include "cc/input/browser_controls_offset_manager_client.h"
#include "cc/trees/layer_tree_impl.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
@@ -38,10 +39,6 @@ BrowserControlsOffsetManager::BrowserControlsOffsetManager(
float controls_show_threshold,
float controls_hide_threshold)
: client_(client),
- animation_initialized_(false),
- animation_start_value_(0.f),
- animation_stop_value_(0.f),
- animation_direction_(NO_ANIMATION),
permitted_state_(BrowserControlsState::kBoth),
accumulated_scroll_delta_(0.f),
baseline_top_content_offset_(0.f),
@@ -65,24 +62,43 @@ float BrowserControlsOffsetManager::ContentTopOffset() const {
}
float BrowserControlsOffsetManager::TopControlsShownRatio() const {
- return client_->CurrentBrowserControlsShownRatio();
+ return client_->CurrentTopControlsShownRatio();
}
float BrowserControlsOffsetManager::TopControlsHeight() const {
return client_->TopControlsHeight();
}
+float BrowserControlsOffsetManager::TopControlsMinHeight() const {
+ return client_->TopControlsMinHeight();
+}
+
+float BrowserControlsOffsetManager::TopControlsMinShownRatio() const {
+ return TopControlsHeight() ? TopControlsMinHeight() / TopControlsHeight()
+ : 0.f;
+}
+
float BrowserControlsOffsetManager::BottomControlsHeight() const {
return client_->BottomControlsHeight();
}
+float BrowserControlsOffsetManager::BottomControlsMinHeight() const {
+ return client_->BottomControlsMinHeight();
+}
+
+float BrowserControlsOffsetManager::BottomControlsMinShownRatio() const {
+ return BottomControlsHeight()
+ ? BottomControlsMinHeight() / BottomControlsHeight()
+ : 0.f;
+}
+
float BrowserControlsOffsetManager::ContentBottomOffset() const {
return BottomControlsHeight() > 0
? BottomControlsShownRatio() * BottomControlsHeight() : 0.0f;
}
float BrowserControlsOffsetManager::BottomControlsShownRatio() const {
- return TopControlsShownRatio();
+ return client_->CurrentBottomControlsShownRatio();
}
void BrowserControlsOffsetManager::UpdateBrowserControlsState(
@@ -113,21 +129,28 @@ void BrowserControlsOffsetManager::UpdateBrowserControlsState(
return;
// Don't do anything if there is no change in offset.
- float final_shown_ratio = 1.f;
+ float final_top_shown_ratio = 1.f;
+ float final_bottom_shown_ratio = 1.f;
+ AnimationDirection direction = SHOWING_CONTROLS;
if (constraints == BrowserControlsState::kHidden ||
- current == BrowserControlsState::kHidden)
- final_shown_ratio = 0.f;
- if (final_shown_ratio == TopControlsShownRatio()) {
- TRACE_EVENT_INSTANT0("cc", "Ratio Unchanged", TRACE_EVENT_SCOPE_THREAD);
+ current == BrowserControlsState::kHidden) {
+ final_top_shown_ratio = TopControlsMinShownRatio();
+ final_bottom_shown_ratio = BottomControlsMinShownRatio();
+ direction = HIDING_CONTROLS;
+ }
+ if (final_top_shown_ratio == TopControlsShownRatio() &&
+ final_bottom_shown_ratio == BottomControlsShownRatio()) {
+ TRACE_EVENT_INSTANT0("cc", "Ratios Unchanged", TRACE_EVENT_SCOPE_THREAD);
ResetAnimations();
return;
}
if (animate) {
- SetupAnimation(final_shown_ratio ? SHOWING_CONTROLS : HIDING_CONTROLS);
+ SetupAnimation(direction);
} else {
ResetAnimations();
- client_->SetCurrentBrowserControlsShownRatio(final_shown_ratio);
+ client_->SetCurrentBrowserControlsShownRatio(final_top_shown_ratio,
+ final_bottom_shown_ratio);
}
}
@@ -139,6 +162,13 @@ BrowserControlsState BrowserControlsOffsetManager::PullConstraintForMainThread(
return permitted_state_;
}
+void BrowserControlsOffsetManager::OnBrowserControlsParamsChanged(
+ bool animate_changes) {
+ // TODO(sinansahin): We should decide how to animate the controls at this
+ // point. If no animation is needed, we will need to snap to the final ratio,
+ // e.g. old min-height to 0.
+}
+
void BrowserControlsOffsetManager::ScrollBegin() {
if (pinch_gesture_active_)
return;
@@ -151,32 +181,57 @@ gfx::Vector2dF BrowserControlsOffsetManager::ScrollBy(
const gfx::Vector2dF& pending_delta) {
// 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)
+ if (!TopControlsHeight() && !BottomControlsHeight())
return pending_delta;
if (pinch_gesture_active_)
return pending_delta;
- if (permitted_state_ == BrowserControlsState::kShown && pending_delta.y() > 0)
- return pending_delta;
- else if (permitted_state_ == BrowserControlsState::kHidden &&
- pending_delta.y() < 0)
+ if ((permitted_state_ == BrowserControlsState::kShown &&
+ pending_delta.y() > 0) ||
+ (permitted_state_ == BrowserControlsState::kHidden &&
+ pending_delta.y() < 0))
return pending_delta;
accumulated_scroll_delta_ += pending_delta.y();
+ // We want to base our calculations on top or bottom controls. After consuming
+ // the scroll delta, we will calculate a shown ratio for the controls. The
+ // top controls have the priority because they need to visually be in sync
+ // with the web contents.
+ bool base_on_top_controls = TopControlsHeight();
+
float old_top_offset = ContentTopOffset();
- float baseline_content_offset = TopControlsHeight()
- ? baseline_top_content_offset_ : baseline_bottom_content_offset_;
+ float baseline_content_offset = base_on_top_controls
+ ? baseline_top_content_offset_
+ : baseline_bottom_content_offset_;
+ // The top and bottom controls ratios can be calculated independently.
+ // However, we want the (normalized) ratios to be equal when scrolling.
+ // Having normalized ratios in this context means the top and bottom controls
+ // reach the min and max ratios at the same time when scrolling or during
+ // the usual show/hide animations, but they can have different shown ratios at
+ // any time.
+ float shown_ratio =
+ (baseline_content_offset - accumulated_scroll_delta_) /
+ (base_on_top_controls ? TopControlsHeight() : BottomControlsHeight());
+
+ float min_ratio = base_on_top_controls ? TopControlsMinShownRatio()
+ : BottomControlsMinShownRatio();
+ float normalized_shown_ratio =
+ (base::ClampToRange(shown_ratio, min_ratio, 1.f) - min_ratio) /
+ (1.f - min_ratio);
+ // Even though the real shown ratios (shown height / total height) of the top
+ // and bottom controls can be different, they share the same
+ // relative/normalized ratio to keep them in sync.
client_->SetCurrentBrowserControlsShownRatio(
- (baseline_content_offset - accumulated_scroll_delta_) / controls_height);
+ TopControlsMinShownRatio() +
+ normalized_shown_ratio * (1.f - TopControlsMinShownRatio()),
+ BottomControlsMinShownRatio() +
+ normalized_shown_ratio * (1.f - BottomControlsMinShownRatio()));
// If the controls are fully visible, treat the current position as the
// new baseline even if the gesture didn't end.
- if (TopControlsShownRatio() == 1.f)
+ if (TopControlsShownRatio() == 1.f && BottomControlsShownRatio() == 1.f)
ResetBaseline();
ResetAnimations();
@@ -216,40 +271,30 @@ void BrowserControlsOffsetManager::MainThreadHasStoppedFlinging() {
gfx::Vector2dF BrowserControlsOffsetManager::Animate(
base::TimeTicks monotonic_time) {
- if (!has_animation() || !client_->HaveRootScrollNode())
+ if (!HasAnimation() || !client_->HaveRootScrollNode())
return gfx::Vector2dF();
- if (!animation_initialized_) {
- // Setup the animation start and time here so that they use the same clock
- // as frame times. This is helpful for tests that mock time.
- animation_start_time_ = monotonic_time;
- animation_stop_time_ =
- animation_start_time_ +
- base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs);
- animation_initialized_ = true;
- }
-
float old_offset = ContentTopOffset();
- float new_ratio = gfx::Tween::ClampedFloatValueBetween(
- monotonic_time, animation_start_time_, animation_start_value_,
- animation_stop_time_, animation_stop_value_);
- client_->SetCurrentBrowserControlsShownRatio(new_ratio);
-
- if (IsAnimationComplete(new_ratio))
- ResetAnimations();
+ float new_top_ratio = top_controls_animation_.Tick(monotonic_time);
+ if (new_top_ratio < 0)
+ new_top_ratio = TopControlsShownRatio();
+ float new_bottom_ratio = bottom_controls_animation_.Tick(monotonic_time);
+ if (new_bottom_ratio < 0)
+ new_bottom_ratio = BottomControlsShownRatio();
+ client_->SetCurrentBrowserControlsShownRatio(new_top_ratio, new_bottom_ratio);
gfx::Vector2dF scroll_delta(0.f, ContentTopOffset() - old_offset);
return scroll_delta;
}
-void BrowserControlsOffsetManager::ResetAnimations() {
- animation_initialized_ = false;
- animation_start_time_ = base::TimeTicks();
- animation_start_value_ = 0.f;
- animation_stop_time_ = base::TimeTicks();
- animation_stop_value_ = 0.f;
+bool BrowserControlsOffsetManager::HasAnimation() {
+ return top_controls_animation_.IsInitialized() ||
+ bottom_controls_animation_.IsInitialized();
+}
- animation_direction_ = NO_ANIMATION;
+void BrowserControlsOffsetManager::ResetAnimations() {
+ top_controls_animation_.Reset();
+ bottom_controls_animation_.Reset();
}
void BrowserControlsOffsetManager::SetupAnimation(
@@ -258,32 +303,51 @@ void BrowserControlsOffsetManager::SetupAnimation(
DCHECK(direction != HIDING_CONTROLS || TopControlsShownRatio() > 0.f);
DCHECK(direction != SHOWING_CONTROLS || TopControlsShownRatio() < 1.f);
- if (has_animation() && animation_direction_ == direction)
+ if (top_controls_animation_.IsInitialized() &&
+ top_controls_animation_.Direction() == direction &&
+ bottom_controls_animation_.IsInitialized() &&
+ bottom_controls_animation_.Direction() == direction)
return;
if (!TopControlsHeight() && !BottomControlsHeight()) {
- client_->SetCurrentBrowserControlsShownRatio(
- direction == HIDING_CONTROLS ? 0.f : 1.f);
+ float ratio = direction == HIDING_CONTROLS ? 0.f : 1.f;
+ client_->SetCurrentBrowserControlsShownRatio(ratio, ratio);
return;
}
- animation_start_value_ = TopControlsShownRatio();
+ top_controls_animation_.SetBounds(TopControlsMinShownRatio(), 1.f);
+ bottom_controls_animation_.SetBounds(BottomControlsMinShownRatio(), 1.f);
+
+ // Providing artificially larger/smaller stop ratios to make the animation
+ // faster if the start ratio is closer to stop ratio.
+ const float max_stop_ratio = direction == SHOWING_CONTROLS ? 1 : -1;
+ float top_start_ratio = TopControlsShownRatio();
+ float top_stop_ratio = top_start_ratio + max_stop_ratio;
+ top_controls_animation_.Initialize(direction, top_start_ratio,
+ top_stop_ratio);
- const float max_ending_ratio = (direction == SHOWING_CONTROLS ? 1 : -1);
- animation_stop_value_ = animation_start_value_ + max_ending_ratio;
+ float bottom_start_ratio = BottomControlsShownRatio();
+ float bottom_stop_ratio = bottom_start_ratio + max_stop_ratio;
+ bottom_controls_animation_.Initialize(direction, bottom_start_ratio,
+ bottom_stop_ratio);
- animation_direction_ = direction;
client_->DidChangeBrowserControlsPosition();
}
void BrowserControlsOffsetManager::StartAnimationIfNecessary() {
- if (TopControlsShownRatio() == 0.f || TopControlsShownRatio() == 1.f)
+ if ((TopControlsShownRatio() == TopControlsMinShownRatio() ||
+ TopControlsShownRatio() == 1.f) &&
+ (BottomControlsShownRatio() == BottomControlsMinShownRatio() ||
+ BottomControlsShownRatio() == 1.f))
return;
- if (TopControlsShownRatio() >= 1.f - controls_hide_threshold_) {
+ float normalized_top_ratio =
+ (TopControlsShownRatio() - TopControlsMinShownRatio()) /
+ (1.f - TopControlsMinShownRatio());
+ if (normalized_top_ratio >= 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() <= controls_show_threshold_) {
+ } else if (normalized_top_ratio <= controls_show_threshold_) {
// If we're showing so little that the show threshold won't trigger, hide.
SetupAnimation(HIDING_CONTROLS);
} else {
@@ -295,15 +359,66 @@ void BrowserControlsOffsetManager::StartAnimationIfNecessary() {
}
}
-bool BrowserControlsOffsetManager::IsAnimationComplete(float new_ratio) {
- return (animation_direction_ == SHOWING_CONTROLS && new_ratio >= 1.f) ||
- (animation_direction_ == HIDING_CONTROLS && new_ratio <= 0.f);
-}
-
void BrowserControlsOffsetManager::ResetBaseline() {
accumulated_scroll_delta_ = 0.f;
baseline_top_content_offset_ = ContentTopOffset();
baseline_bottom_content_offset_ = ContentBottomOffset();
}
+// class Animation
+
+void BrowserControlsOffsetManager::Animation::Initialize(
+ AnimationDirection direction,
+ float start_value,
+ float stop_value) {
+ direction_ = direction;
+ start_value_ = start_value;
+ stop_value_ = stop_value;
+ initialized_ = true;
+}
+
+float BrowserControlsOffsetManager::Animation::Tick(
+ base::TimeTicks monotonic_time) {
+ if (!IsInitialized())
+ return -1;
+
+ if (!started_) {
+ start_time_ = monotonic_time;
+ stop_time_ =
+ start_time_ + base::TimeDelta::FromMilliseconds(kShowHideMaxDurationMs);
+ started_ = true;
+ }
+
+ float value = gfx::Tween::ClampedFloatValueBetween(
+ monotonic_time, start_time_, start_value_, stop_time_, stop_value_);
+
+ if (IsComplete(value)) {
+ value = stop_value_;
+ Reset();
+ }
+ return base::ClampToRange(value, min_value_, max_value_);
+}
+
+void BrowserControlsOffsetManager::Animation::SetBounds(float min, float max) {
+ min_value_ = min;
+ max_value_ = max;
+}
+
+void BrowserControlsOffsetManager::Animation::Reset() {
+ started_ = false;
+ initialized_ = false;
+ start_time_ = base::TimeTicks();
+ start_value_ = 0.f;
+ stop_time_ = base::TimeTicks();
+ stop_value_ = 0.f;
+ direction_ = NO_ANIMATION;
+}
+
+bool BrowserControlsOffsetManager::Animation::IsComplete(float value) {
+ return (direction_ == SHOWING_CONTROLS &&
+ (value >= stop_value_ || value >= max_value_)) ||
+ (direction_ == HIDING_CONTROLS &&
+ (value <= stop_value_ || value <= min_value_));
+}
+
} // namespace cc
diff --git a/chromium/cc/input/browser_controls_offset_manager.h b/chromium/cc/input/browser_controls_offset_manager.h
index af00d337961..7e06c1e253a 100644
--- a/chromium/cc/input/browser_controls_offset_manager.h
+++ b/chromium/cc/input/browser_controls_offset_manager.h
@@ -40,6 +40,9 @@ class CC_EXPORT BrowserControlsOffsetManager {
float ContentTopOffset() const;
float TopControlsShownRatio() const;
float TopControlsHeight() const;
+ float TopControlsMinHeight() const;
+ // The minimum shown ratio top controls can have.
+ float TopControlsMinShownRatio() const;
// The amount of offset of the web content area, calculating from the bottom.
// Same as the current shown height of the bottom controls.
@@ -47,10 +50,12 @@ class CC_EXPORT BrowserControlsOffsetManager {
// Similar to TopControlsHeight(), this method should return a static value.
// The current animated height should be acquired from ContentBottomOffset().
float BottomControlsHeight() const;
+ float BottomControlsMinHeight() const;
float BottomControlsShownRatio() const;
+ // The minimum shown ratio bottom controls can have.
+ float BottomControlsMinShownRatio() const;
- bool has_animation() const { return animation_direction_ != NO_ANIMATION; }
- AnimationDirection animation_direction() { return animation_direction_; }
+ bool HasAnimation();
void UpdateBrowserControlsState(BrowserControlsState constraints,
BrowserControlsState current,
@@ -59,6 +64,8 @@ class CC_EXPORT BrowserControlsOffsetManager {
BrowserControlsState PullConstraintForMainThread(
bool* out_changed_since_commit);
+ void OnBrowserControlsParamsChanged(bool animate_changes);
+
void ScrollBegin();
gfx::Vector2dF ScrollBy(const gfx::Vector2dF& pending_delta);
void ScrollEnd();
@@ -81,21 +88,11 @@ class CC_EXPORT BrowserControlsOffsetManager {
void ResetAnimations();
void SetupAnimation(AnimationDirection direction);
void StartAnimationIfNecessary();
- bool IsAnimationComplete(float new_ratio);
void ResetBaseline();
// The client manages the lifecycle of this.
BrowserControlsOffsetManagerClient* client_;
- // animation_initialized_ tracks if we've initialized the start and end
- // times since that must happen at a BeginFrame.
- bool animation_initialized_;
- base::TimeTicks animation_start_time_;
- float animation_start_value_;
- base::TimeTicks animation_stop_time_;
- float animation_stop_value_;
- AnimationDirection animation_direction_;
-
BrowserControlsState permitted_state_;
// Accumulated scroll delta since last baseline reset
@@ -118,6 +115,49 @@ class CC_EXPORT BrowserControlsOffsetManager {
// Used to track whether the constraint has changed and we need up reflect
// the changes to Blink.
bool constraint_changed_since_commit_;
+
+ // Class that holds and manages the state of the controls animations.
+ class Animation {
+ public:
+ Animation() = default;
+
+ // Whether the animation is initialized with a direction and start and stop
+ // values.
+ bool IsInitialized() { return initialized_; }
+ bool Direction() { return direction_; }
+ void Initialize(AnimationDirection direction,
+ float start_value,
+ float stop_value);
+ // Returns the animated value for the given monotonic time tick if the
+ // animation is initialized. Otherwise, returns -1.
+ float Tick(base::TimeTicks monotonic_time);
+ // Set the minimum and maximum values the animation can have.
+ void SetBounds(float min, float max);
+ void Reset();
+
+ private:
+ bool IsComplete(float value);
+
+ // Whether the animation is running.
+ bool started_ = false;
+ // Whether the animation is initialized by setting start and stop time and
+ // values.
+ bool initialized_ = false;
+ AnimationDirection direction_ = NO_ANIMATION;
+ // Monotonic start and stop times.
+ base::TimeTicks start_time_;
+ base::TimeTicks stop_time_;
+ // Start and stop values.
+ float start_value_ = 0.f;
+ float stop_value_ = 0.f;
+ // Minimum and maximum values the animation can have, used to decide if the
+ // animation is complete.
+ float min_value_ = 0.f;
+ float max_value_ = 1.f;
+ };
+
+ Animation top_controls_animation_;
+ Animation bottom_controls_animation_;
};
} // namespace cc
diff --git a/chromium/cc/input/browser_controls_offset_manager_client.h b/chromium/cc/input/browser_controls_offset_manager_client.h
index 5a2ce4cb5dc..8d97b85dd48 100644
--- a/chromium/cc/input/browser_controls_offset_manager_client.h
+++ b/chromium/cc/input/browser_controls_offset_manager_client.h
@@ -10,9 +10,13 @@ namespace cc {
class CC_EXPORT BrowserControlsOffsetManagerClient {
public:
virtual float TopControlsHeight() const = 0;
+ virtual float TopControlsMinHeight() const = 0;
virtual float BottomControlsHeight() const = 0;
- virtual void SetCurrentBrowserControlsShownRatio(float ratio) = 0;
- virtual float CurrentBrowserControlsShownRatio() const = 0;
+ virtual float BottomControlsMinHeight() const = 0;
+ virtual void SetCurrentBrowserControlsShownRatio(float top_ratio,
+ float bottom_ratio) = 0;
+ virtual float CurrentTopControlsShownRatio() const = 0;
+ virtual float CurrentBottomControlsShownRatio() const = 0;
virtual void DidChangeBrowserControlsPosition() = 0;
virtual bool HaveRootScrollNode() const = 0;
virtual void SetNeedsCommit() = 0;
diff --git a/chromium/cc/input/browser_controls_offset_manager_unittest.cc b/chromium/cc/input/browser_controls_offset_manager_unittest.cc
index 3a8cfdc7df8..d838c4a0cf6 100644
--- a/chromium/cc/input/browser_controls_offset_manager_unittest.cc
+++ b/chromium/cc/input/browser_controls_offset_manager_unittest.cc
@@ -28,18 +28,17 @@ class MockBrowserControlsOffsetManagerClient
MockBrowserControlsOffsetManagerClient(float top_controls_height,
float browser_controls_show_threshold,
float browser_controls_hide_threshold)
- : host_impl_(&task_runner_provider_,
- &task_graph_runner_),
+ : host_impl_(&task_runner_provider_, &task_graph_runner_),
redraw_needed_(false),
update_draw_properties_needed_(false),
- bottom_controls_height_(0.f),
+ browser_controls_params_({top_controls_height, 0, 0, 0, false, false}),
+ bottom_controls_shown_ratio_(1.f),
top_controls_shown_ratio_(1.f),
- top_controls_height_(top_controls_height),
browser_controls_show_threshold_(browser_controls_show_threshold),
browser_controls_hide_threshold_(browser_controls_hide_threshold) {
active_tree_ = std::make_unique<LayerTreeImpl>(
&host_impl_, new SyncedProperty<ScaleGroup>, new SyncedBrowserControls,
- new SyncedElasticOverscroll);
+ new SyncedBrowserControls, new SyncedElasticOverscroll);
root_scroll_layer_ = LayerImpl::Create(active_tree_.get(), 1);
}
@@ -53,21 +52,43 @@ class MockBrowserControlsOffsetManagerClient
bool HaveRootScrollNode() const override { return true; }
float BottomControlsHeight() const override {
- return bottom_controls_height_;
+ return browser_controls_params_.bottom_controls_height;
}
- float TopControlsHeight() const override { return top_controls_height_; }
+ float BottomControlsMinHeight() const override {
+ return browser_controls_params_.bottom_controls_min_height;
+ }
+
+ float TopControlsHeight() const override {
+ return browser_controls_params_.top_controls_height;
+ }
+
+ float TopControlsMinHeight() const override {
+ return browser_controls_params_.top_controls_min_height;
+ }
+
+ void SetCurrentBrowserControlsShownRatio(float top_ratio,
+ float bottom_ratio) override {
+ AssertAndClamp(&top_ratio);
+ top_controls_shown_ratio_ = top_ratio;
+
+ AssertAndClamp(&bottom_ratio);
+ bottom_controls_shown_ratio_ = bottom_ratio;
+ }
- 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());
- ratio = std::max(ratio, 0.f);
- ratio = std::min(ratio, 1.f);
- top_controls_shown_ratio_ = ratio;
+ void AssertAndClamp(float* ratio) {
+ ASSERT_FALSE(std::isnan(*ratio));
+ ASSERT_FALSE(*ratio == std::numeric_limits<float>::infinity());
+ ASSERT_FALSE(*ratio == -std::numeric_limits<float>::infinity());
+ *ratio = std::max(*ratio, 0.f);
+ *ratio = std::min(*ratio, 1.f);
}
- float CurrentBrowserControlsShownRatio() const override {
+ float CurrentBottomControlsShownRatio() const override {
+ return bottom_controls_shown_ratio_;
+ }
+
+ float CurrentTopControlsShownRatio() const override {
return top_controls_shown_ratio_;
}
@@ -84,10 +105,8 @@ class MockBrowserControlsOffsetManagerClient
return manager_.get();
}
- void SetBrowserControlsHeight(float height) { top_controls_height_ = height; }
-
- void SetBottomControlsHeight(float height) {
- bottom_controls_height_ = height;
+ void SetBrowserControlsParams(BrowserControlsParams params) {
+ browser_controls_params_ = params;
}
private:
@@ -100,9 +119,9 @@ class MockBrowserControlsOffsetManagerClient
bool redraw_needed_;
bool update_draw_properties_needed_;
- float bottom_controls_height_;
+ BrowserControlsParams browser_controls_params_;
+ float bottom_controls_shown_ratio_;
float top_controls_shown_ratio_;
- float top_controls_height_;
float browser_controls_show_threshold_;
float browser_controls_hide_threshold_;
};
@@ -166,7 +185,7 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownHideAnimation) {
EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -175,13 +194,13 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownHideAnimation) {
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
@@ -189,7 +208,7 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownHideAnimation) {
TEST(BrowserControlsOffsetManagerTest,
BottomControlsPartialShownHideAnimation) {
MockBrowserControlsOffsetManagerClient client(0.f, 0.5f, 0.5f);
- client.SetBottomControlsHeight(100.f);
+ client.SetBrowserControlsParams({0, 0, 100, 0, false, false});
BrowserControlsOffsetManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
@@ -203,7 +222,7 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -212,13 +231,13 @@ TEST(BrowserControlsOffsetManagerTest,
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->BottomControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_LT(manager->BottomControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(0.f, manager->BottomControlsShownRatio());
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
@@ -238,7 +257,7 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownShowAnimation) {
EXPECT_FLOAT_EQ(70.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -247,13 +266,13 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownShowAnimation) {
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset());
}
@@ -261,7 +280,7 @@ TEST(BrowserControlsOffsetManagerTest, PartialShownShowAnimation) {
TEST(BrowserControlsOffsetManagerTest,
BottomControlsPartialShownShowAnimation) {
MockBrowserControlsOffsetManagerClient client(0.f, 0.5f, 0.5f);
- client.SetBottomControlsHeight(100.f);
+ client.SetBrowserControlsParams({0, 0, 100, 0, false, false});
BrowserControlsOffsetManager* manager = client.manager();
manager->ScrollBegin();
@@ -270,7 +289,7 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -279,13 +298,13 @@ TEST(BrowserControlsOffsetManagerTest,
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->BottomControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_GT(manager->BottomControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(1.f, manager->BottomControlsShownRatio());
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
@@ -302,7 +321,7 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(80.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -311,13 +330,13 @@ TEST(BrowserControlsOffsetManagerTest,
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset());
}
@@ -334,7 +353,7 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(70.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -343,13 +362,13 @@ TEST(BrowserControlsOffsetManagerTest,
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
@@ -370,7 +389,7 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(20.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -379,13 +398,13 @@ TEST(BrowserControlsOffsetManagerTest,
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
@@ -406,7 +425,7 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(30.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -415,13 +434,13 @@ TEST(BrowserControlsOffsetManagerTest,
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(100.f, manager->ContentTopOffset());
}
@@ -452,7 +471,7 @@ TEST(BrowserControlsOffsetManagerTest, PinchIgnoresScroll) {
EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
}
TEST(BrowserControlsOffsetManagerTest, PinchBeginStartsAnimationIfNecessary) {
@@ -464,17 +483,17 @@ TEST(BrowserControlsOffsetManagerTest, PinchBeginStartsAnimationIfNecessary) {
EXPECT_FLOAT_EQ(-100.f, manager->ControlsTopOffset());
manager->PinchBegin();
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
manager->PinchEnd();
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
manager->ScrollBy(gfx::Vector2dF(0.f, -15.f));
EXPECT_FLOAT_EQ(-85.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(15.f, manager->ContentTopOffset());
manager->PinchBegin();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
base::TimeTicks time = base::TimeTicks::Now();
@@ -483,24 +502,24 @@ TEST(BrowserControlsOffsetManagerTest, PinchBeginStartsAnimationIfNecessary) {
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_LT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
manager->PinchEnd();
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
manager->ScrollBy(gfx::Vector2dF(0.f, -55.f));
EXPECT_FLOAT_EQ(-45.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(55.f, manager->ContentTopOffset());
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
manager->ScrollEnd();
- EXPECT_TRUE(manager->has_animation());
+ EXPECT_TRUE(manager->HasAnimation());
time = base::TimeTicks::Now();
@@ -509,13 +528,13 @@ TEST(BrowserControlsOffsetManagerTest, PinchBeginStartsAnimationIfNecessary) {
manager->Animate(time);
EXPECT_EQ(manager->TopControlsShownRatio(), previous);
- while (manager->has_animation()) {
+ while (manager->HasAnimation()) {
previous = manager->TopControlsShownRatio();
time = base::TimeDelta::FromMicroseconds(100) + time;
manager->Animate(time);
EXPECT_GT(manager->TopControlsShownRatio(), previous);
}
- EXPECT_FALSE(manager->has_animation());
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
}
@@ -526,13 +545,13 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
- client.SetBrowserControlsHeight(100.f);
- EXPECT_FALSE(manager->has_animation());
+ client.SetBrowserControlsParams({100, 0, 0, 0, false, false});
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(100.f, manager->TopControlsHeight());
EXPECT_FLOAT_EQ(0, manager->ControlsTopOffset());
- client.SetBrowserControlsHeight(50.f);
- EXPECT_FALSE(manager->has_animation());
+ client.SetBrowserControlsParams({50, 0, 0, 0, false, false});
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(50.f, manager->TopControlsHeight());
EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
}
@@ -548,13 +567,13 @@ TEST(BrowserControlsOffsetManagerTest,
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
manager->ScrollEnd();
- client.SetBrowserControlsHeight(50.f);
- EXPECT_FALSE(manager->has_animation());
+ client.SetBrowserControlsParams({50, 0, 0, 0, false, false});
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(-50.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
- client.SetBrowserControlsHeight(0.f);
- EXPECT_FALSE(manager->has_animation());
+ client.SetBrowserControlsParams({0, 0, 0, 0, false, false});
+ EXPECT_FALSE(manager->HasAnimation());
EXPECT_FLOAT_EQ(0.f, manager->ControlsTopOffset());
EXPECT_FLOAT_EQ(0.f, manager->ContentTopOffset());
}
@@ -570,13 +589,13 @@ TEST(BrowserControlsOffsetManagerTest, ScrollByWithZeroHeightControlsIsNoop) {
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.CurrentBrowserControlsShownRatio());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio());
manager->ScrollEnd();
}
TEST(BrowserControlsOffsetManagerTest, ScrollThenRestoreBottomControls) {
MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f);
- client.SetBottomControlsHeight(100.f);
+ client.SetBrowserControlsParams({0, 0, 100, 0, false, false});
BrowserControlsOffsetManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 20.f));
@@ -594,7 +613,7 @@ TEST(BrowserControlsOffsetManagerTest, ScrollThenRestoreBottomControls) {
TEST(BrowserControlsOffsetManagerTest,
ScrollThenRestoreBottomControlsNoTopControls) {
MockBrowserControlsOffsetManagerClient client(0.f, 0.5f, 0.5f);
- client.SetBottomControlsHeight(100.f);
+ client.SetBrowserControlsParams({0, 0, 100, 0, false, false});
BrowserControlsOffsetManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 20.f));
@@ -611,7 +630,7 @@ TEST(BrowserControlsOffsetManagerTest,
TEST(BrowserControlsOffsetManagerTest, HideAndPeekBottomControls) {
MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f);
- client.SetBottomControlsHeight(100.f);
+ client.SetBrowserControlsParams({0, 0, 100, 0, false, false});
BrowserControlsOffsetManager* manager = client.manager();
manager->ScrollBegin();
manager->ScrollBy(gfx::Vector2dF(0.f, 300.f));
@@ -629,19 +648,60 @@ TEST(BrowserControlsOffsetManagerTest, HideAndPeekBottomControls) {
TEST(BrowserControlsOffsetManagerTest,
HideAndImmediateShowKeepsControlsVisible) {
MockBrowserControlsOffsetManagerClient client(100.f, 0.5f, 0.5f);
- client.SetBottomControlsHeight(100.f);
+ client.SetBrowserControlsParams({0, 0, 100, 0, false, false});
BrowserControlsOffsetManager* manager = client.manager();
- EXPECT_FLOAT_EQ(1.f, client.CurrentBrowserControlsShownRatio());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentBottomControlsShownRatio());
manager->UpdateBrowserControlsState(BrowserControlsState::kBoth,
BrowserControlsState::kHidden, true);
- EXPECT_TRUE(manager->has_animation());
- EXPECT_FLOAT_EQ(1.f, client.CurrentBrowserControlsShownRatio());
+ EXPECT_TRUE(manager->HasAnimation());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentBottomControlsShownRatio());
manager->UpdateBrowserControlsState(BrowserControlsState::kBoth,
BrowserControlsState::kShown, true);
- EXPECT_FALSE(manager->has_animation());
- EXPECT_FLOAT_EQ(1.f, client.CurrentBrowserControlsShownRatio());
+ EXPECT_FALSE(manager->HasAnimation());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentBottomControlsShownRatio());
+}
+
+TEST(BrowserControlsOffsetManagerTest,
+ ScrollWithMinHeightSetForTopControlsOnly) {
+ MockBrowserControlsOffsetManagerClient client(100, 0.5f, 0.5f);
+ client.SetBrowserControlsParams({100, 30, 100, 0, false, false});
+ BrowserControlsOffsetManager* manager = client.manager();
+ EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentBottomControlsShownRatio());
+
+ manager->ScrollBegin();
+ manager->ScrollBy(gfx::Vector2dF(0, 150));
+ EXPECT_FLOAT_EQ(30.f / 100, client.CurrentTopControlsShownRatio());
+ EXPECT_FLOAT_EQ(0.f, client.CurrentBottomControlsShownRatio());
+ manager->ScrollEnd();
+
+ manager->ScrollBegin();
+ manager->ScrollBy(gfx::Vector2dF(0, -70));
+ EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentBottomControlsShownRatio());
+ manager->ScrollEnd();
+}
+
+TEST(BrowserControlsOffsetManagerTest, ScrollWithMinHeightSetForBothControls) {
+ MockBrowserControlsOffsetManagerClient client(100, 0.5f, 0.5f);
+ client.SetBrowserControlsParams({100, 30, 100, 20, false, false});
+ BrowserControlsOffsetManager* manager = client.manager();
+ EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentBottomControlsShownRatio());
+
+ manager->ScrollBegin();
+ manager->ScrollBy(gfx::Vector2dF(0, 150));
+ EXPECT_FLOAT_EQ(30.f / 100, client.CurrentTopControlsShownRatio());
+ EXPECT_FLOAT_EQ(20.f / 100, client.CurrentBottomControlsShownRatio());
+ manager->ScrollEnd();
+
+ manager->ScrollBegin();
+ manager->ScrollBy(gfx::Vector2dF(0, -70));
+ EXPECT_FLOAT_EQ(1.f, client.CurrentTopControlsShownRatio());
+ EXPECT_FLOAT_EQ(1.f, client.CurrentBottomControlsShownRatio());
+ manager->ScrollEnd();
}
} // namespace
diff --git a/chromium/cc/input/input_handler.h b/chromium/cc/input/input_handler.h
index f39e0062ffe..50896f5ffa5 100644
--- a/chromium/cc/input/input_handler.h
+++ b/chromium/cc/input/input_handler.h
@@ -25,11 +25,11 @@ class Point;
class ScrollOffset;
class SizeF;
class Vector2dF;
-}
+} // namespace gfx
namespace ui {
class LatencyInfo;
-}
+} // namespace ui
namespace cc {
@@ -198,6 +198,8 @@ class CC_EXPORT InputHandler {
virtual InputHandlerPointerResult MouseMoveAt(
const gfx::Point& mouse_position) = 0;
+ // TODO(arakeri): Pass in the modifier instead of a bool once the refactor
+ // (crbug.com/1022097) is done. For details, see crbug.com/1016955.
virtual InputHandlerPointerResult MouseDown(const gfx::PointF& mouse_position,
bool shift_modifier) = 0;
virtual InputHandlerPointerResult MouseUp(
@@ -206,7 +208,7 @@ class CC_EXPORT InputHandler {
// Stop scrolling the selected layer. Should only be called if ScrollBegin()
// returned SCROLL_STARTED. Snap to a snap position if |should_snap| is true.
- virtual void ScrollEnd(ScrollState* scroll_state, bool should_snap) = 0;
+ virtual void ScrollEnd(bool should_snap) = 0;
// Requests a callback to UpdateRootLayerStateForSynchronousInputHandler()
// giving the current root scroll and page scale information.
@@ -278,10 +280,10 @@ class CC_EXPORT InputHandler {
// |natural_displacement_in_viewport| is the estimated total scrolling for
// the active scroll sequence.
// Returns false if their is no position to snap to.
- virtual bool GetSnapFlingInfo(
+ virtual bool GetSnapFlingInfoAndSetSnapTarget(
const gfx::Vector2dF& natural_displacement_in_viewport,
gfx::Vector2dF* initial_offset,
- gfx::Vector2dF* target_offset) const = 0;
+ gfx::Vector2dF* target_offset) = 0;
protected:
InputHandler() = default;
diff --git a/chromium/cc/input/layer_selection_bound.cc b/chromium/cc/input/layer_selection_bound.cc
index 55f2e3a5fb4..81af0bf7d32 100644
--- a/chromium/cc/input/layer_selection_bound.cc
+++ b/chromium/cc/input/layer_selection_bound.cc
@@ -15,7 +15,7 @@ LayerSelectionBound::~LayerSelectionBound() = default;
bool LayerSelectionBound::operator==(const LayerSelectionBound& other) const {
return type == other.type && layer_id == other.layer_id &&
- edge_top == other.edge_top && edge_bottom == other.edge_bottom &&
+ edge_start == other.edge_start && edge_end == other.edge_end &&
hidden == other.hidden;
}
@@ -25,8 +25,8 @@ bool LayerSelectionBound::operator!=(const LayerSelectionBound& other) const {
std::string LayerSelectionBound::ToString() const {
return base::StringPrintf("LayerSelectionBound(%s, %s, %d)",
- edge_top.ToString().c_str(),
- edge_bottom.ToString().c_str(), hidden);
+ edge_start.ToString().c_str(),
+ edge_end.ToString().c_str(), hidden);
}
} // namespace cc
diff --git a/chromium/cc/input/layer_selection_bound.h b/chromium/cc/input/layer_selection_bound.h
index a2a2583c143..43561075a34 100644
--- a/chromium/cc/input/layer_selection_bound.h
+++ b/chromium/cc/input/layer_selection_bound.h
@@ -19,8 +19,8 @@ struct CC_EXPORT LayerSelectionBound {
~LayerSelectionBound();
gfx::SelectionBound::Type type;
- gfx::Point edge_top;
- gfx::Point edge_bottom;
+ gfx::Point edge_start;
+ gfx::Point edge_end;
int layer_id;
// Whether this bound is hidden (clipped out/occluded) within the painted
// content of the layer (as opposed to being outside of the layer's bounds).
diff --git a/chromium/cc/input/main_thread_scrolling_reason.cc b/chromium/cc/input/main_thread_scrolling_reason.cc
index 4b5cac239f0..172249f5bb3 100644
--- a/chromium/cc/input/main_thread_scrolling_reason.cc
+++ b/chromium/cc/input/main_thread_scrolling_reason.cc
@@ -5,12 +5,13 @@
#include "cc/input/main_thread_scrolling_reason.h"
#include "base/stl_util.h"
+#include "base/strings/string_util.h"
#include "base/trace_event/traced_value.h"
namespace cc {
std::string MainThreadScrollingReason::AsText(uint32_t reasons) {
- base::trace_event::TracedValue traced_value;
+ base::trace_event::TracedValue traced_value(0, /*force_json=*/true);
AddToTracedValue(reasons, traced_value);
std::string result = traced_value.ToString();
// Remove '{main_thread_scrolling_reasons:[', ']}', and any '"' chars.
@@ -19,6 +20,8 @@ std::string MainThreadScrollingReason::AsText(uint32_t reasons) {
result =
result.substr(array_start_pos + 1, array_end_pos - array_start_pos - 1);
base::Erase(result, '\"');
+ // Add spaces after all commas.
+ base::ReplaceChars(result, ",", ", ", &result);
return result;
}
diff --git a/chromium/cc/input/main_thread_scrolling_reason_unittest.cc b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
index 3970af2eade..8744d643907 100644
--- a/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
+++ b/chromium/cc/input/main_thread_scrolling_reason_unittest.cc
@@ -13,26 +13,26 @@ using MainThreadScrollingReasonTest = testing::Test;
TEST_F(MainThreadScrollingReasonTest, AsText) {
EXPECT_EQ("", MainThreadScrollingReason::AsText(0));
EXPECT_EQ(
- "Has background-attachment:fixed,"
- "Has non-layer viewport-constrained objects,"
- "Threaded scrolling is disabled,"
- "Scrollbar scrolling,"
- "Frame overlay,"
- "Handling scroll from main thread,"
- "Has opacity and LCD text,"
- "Has transform and LCD text,"
- "Background is not opaque in rect and LCD text,"
- "Has clip related property,"
- "Has box shadow from non-root layer,"
- "Is not stacking context and LCD text,"
- "Non fast scrollable region,"
- "Failed hit test,"
- "No scrolling layer,"
- "Not scrollable,"
- "Continuing main thread scroll,"
- "Non-invertible transform,"
- "Page-based scrolling,"
- "Wheel event handler region,"
+ "Has background-attachment:fixed, "
+ "Has non-layer viewport-constrained objects, "
+ "Threaded scrolling is disabled, "
+ "Scrollbar scrolling, "
+ "Frame overlay, "
+ "Handling scroll from main thread, "
+ "Has opacity and LCD text, "
+ "Has transform and LCD text, "
+ "Background is not opaque in rect and LCD text, "
+ "Has clip related property, "
+ "Has box shadow from non-root layer, "
+ "Is not stacking context and LCD text, "
+ "Non fast scrollable region, "
+ "Failed hit test, "
+ "No scrolling layer, "
+ "Not scrollable, "
+ "Continuing main thread scroll, "
+ "Non-invertible transform, "
+ "Page-based scrolling, "
+ "Wheel event handler region, "
"Touch event handler region",
MainThreadScrollingReason::AsText(0xffffffffu));
}
diff --git a/chromium/cc/input/scroll_snap_data.cc b/chromium/cc/input/scroll_snap_data.cc
index 2121d1ca658..730326a36b9 100644
--- a/chromium/cc/input/scroll_snap_data.cc
+++ b/chromium/cc/input/scroll_snap_data.cc
@@ -111,7 +111,9 @@ void SnapContainerData::AddSnapAreaData(SnapAreaData snap_area_data) {
bool SnapContainerData::FindSnapPosition(
const SnapSelectionStrategy& strategy,
- gfx::ScrollOffset* snap_position) const {
+ gfx::ScrollOffset* snap_position,
+ TargetSnapAreaElementIds* target_element_ids) const {
+ *target_element_ids = TargetSnapAreaElementIds();
if (scroll_snap_type_.is_none)
return false;
@@ -124,54 +126,113 @@ bool SnapContainerData::FindSnapPosition(
if (!should_snap_on_x && !should_snap_on_y)
return false;
- base::Optional<SnapSearchResult> closest_x, closest_y;
- // A region that includes every reachable scroll position.
- gfx::RectF scrollable_region(0, 0, max_position_.x(), max_position_.y());
+ bool should_prioritize_x_target =
+ strategy.ShouldPrioritizeSnapTargets() &&
+ target_snap_area_element_ids_.x != ElementId();
+ bool should_prioritize_y_target =
+ strategy.ShouldPrioritizeSnapTargets() &&
+ target_snap_area_element_ids_.y != ElementId();
+
+ base::Optional<SnapSearchResult> selected_x, selected_y;
if (should_snap_on_x) {
- // Start from current position in the cross axis. The search algorithm
- // expects the cross axis position to be inside scroller bounds. But since
- // we cannot always assume that the incoming value fits this criteria we
- // clamp it to the bounds to ensure this variant.
- SnapSearchResult initial_snap_position_y = {
- base::ClampToRange(base_position.y(), 0.f, max_position_.y()),
- gfx::RangeF(0, max_position_.x())};
- closest_x =
- FindClosestValidArea(SearchAxis::kX, strategy, initial_snap_position_y);
+ if (should_prioritize_x_target) {
+ // TODO(http://crbug.com/866127): If the target snap area is covering the
+ // snapport then we should fallback to the default "closest-area" method
+ // instead.
+ selected_x = GetTargetSnapAreaSearchResult(SearchAxis::kX);
+ DCHECK(selected_x.has_value());
+ } else {
+ // Start from current position in the cross axis. The search algorithm
+ // expects the cross axis position to be inside scroller bounds. But since
+ // we cannot always assume that the incoming value fits this criteria we
+ // clamp it to the bounds to ensure this variant.
+ SnapSearchResult initial_snap_position_y = {
+ base::ClampToRange(base_position.y(), 0.f, max_position_.y()),
+ gfx::RangeF(0, max_position_.x())};
+
+ selected_x = FindClosestValidArea(SearchAxis::kX, strategy,
+ initial_snap_position_y);
+ }
}
if (should_snap_on_y) {
- SnapSearchResult initial_snap_position_x = {
- base::ClampToRange(base_position.x(), 0.f, max_position_.x()),
- gfx::RangeF(0, max_position_.y())};
- closest_y =
- FindClosestValidArea(SearchAxis::kY, strategy, initial_snap_position_x);
+ if (should_prioritize_y_target) {
+ selected_y = GetTargetSnapAreaSearchResult(SearchAxis::kY);
+ DCHECK(selected_y.has_value());
+ } else {
+ SnapSearchResult initial_snap_position_x = {
+ base::ClampToRange(base_position.x(), 0.f, max_position_.x()),
+ gfx::RangeF(0, max_position_.y())};
+ selected_y = FindClosestValidArea(SearchAxis::kY, strategy,
+ initial_snap_position_x);
+ }
}
- if (!closest_x.has_value() && !closest_y.has_value())
+ if (!selected_x.has_value() && !selected_y.has_value())
return false;
// If snapping in one axis pushes off-screen the other snap area, this snap
// position is invalid. https://drafts.csswg.org/css-scroll-snap-1/#snap-scope
- // In this case, we choose the axis whose snap area is closer, and find a
- // mutual visible snap area on the other axis.
- if (closest_x.has_value() && closest_y.has_value() &&
- !IsMutualVisible(closest_x.value(), closest_y.value())) {
- bool candidate_on_x_axis_is_closer =
- std::abs(closest_x.value().snap_offset() - base_position.x()) <=
- std::abs(closest_y.value().snap_offset() - base_position.y());
- if (candidate_on_x_axis_is_closer) {
- closest_y =
- FindClosestValidArea(SearchAxis::kY, strategy, closest_x.value());
+ // In this case, first check if we need to prioritize the snap area from
+ // one axis over the other and select that axis, or if we don't prioritize an
+ // axis over the other, we choose the axis whose snap area is closer.
+ // Then find a new snap area on the other axis that is mutually visible with
+ // the selected axis' snap area.
+ if (selected_x.has_value() && selected_y.has_value() &&
+ !IsMutualVisible(selected_x.value(), selected_y.value())) {
+ bool keep_candidate_on_x = should_prioritize_x_target;
+ if (should_prioritize_x_target == should_prioritize_y_target) {
+ keep_candidate_on_x =
+ std::abs(selected_x.value().snap_offset() - base_position.x()) <=
+ std::abs(selected_y.value().snap_offset() - base_position.y());
+ }
+ if (keep_candidate_on_x) {
+ selected_y =
+ FindClosestValidArea(SearchAxis::kY, strategy, selected_x.value());
} else {
- closest_x =
- FindClosestValidArea(SearchAxis::kX, strategy, closest_y.value());
+ selected_x =
+ FindClosestValidArea(SearchAxis::kX, strategy, selected_y.value());
}
}
*snap_position = strategy.current_position();
- if (closest_x.has_value())
- snap_position->set_x(closest_x.value().snap_offset());
- if (closest_y.has_value())
- snap_position->set_y(closest_y.value().snap_offset());
+ if (selected_x.has_value()) {
+ snap_position->set_x(selected_x.value().snap_offset());
+ target_element_ids->x = selected_x.value().element_id();
+ }
+
+ if (selected_y.has_value()) {
+ snap_position->set_y(selected_y.value().snap_offset());
+ target_element_ids->y = selected_y.value().element_id();
+ }
+
+ return true;
+}
+
+base::Optional<SnapSearchResult>
+SnapContainerData::GetTargetSnapAreaSearchResult(SearchAxis axis) const {
+ ElementId target_id = axis == SearchAxis::kX
+ ? target_snap_area_element_ids_.x
+ : target_snap_area_element_ids_.y;
+ if (target_id == ElementId())
+ return base::nullopt;
+ for (const SnapAreaData& area : snap_area_list_) {
+ if (area.element_id == target_id)
+ return GetSnapSearchResult(axis, area);
+ }
+ return base::nullopt;
+}
+
+const TargetSnapAreaElementIds& SnapContainerData::GetTargetSnapAreaElementIds()
+ const {
+ return target_snap_area_element_ids_;
+}
+
+bool SnapContainerData::SetTargetSnapAreaElementIds(
+ TargetSnapAreaElementIds ids) {
+ if (target_snap_area_element_ids_ == ids)
+ return false;
+
+ target_snap_area_element_ids_ = ids;
return true;
}
@@ -354,6 +415,7 @@ SnapSearchResult SnapContainerData::GetSnapSearchResult(
}
result.Clip(max_position_.y(), max_position_.x());
}
+ result.set_element_id(area.element_id);
return result;
}
diff --git a/chromium/cc/input/scroll_snap_data.h b/chromium/cc/input/scroll_snap_data.h
index 998d314ce14..52f5acd1457 100644
--- a/chromium/cc/input/scroll_snap_data.h
+++ b/chromium/cc/input/scroll_snap_data.h
@@ -9,6 +9,7 @@
#include "base/optional.h"
#include "cc/cc_export.h"
+#include "cc/paint/element_id.h"
#include "ui/gfx/geometry/rect_f.h"
#include "ui/gfx/geometry/scroll_offset.h"
#include "ui/gfx/range/range_f.h"
@@ -97,6 +98,8 @@ class SnapSearchResult {
// Union the visible_range of the two SnapSearchResult if they represent two
// snap areas that are both covering the snapport at the current offset.
+ // The |element_id_| of this is arbitrarily chosen because both snap areas
+ // cover the snapport and are therefore both valid.
void Union(const SnapSearchResult& other);
float snap_offset() const { return snap_offset_; }
@@ -105,12 +108,18 @@ class SnapSearchResult {
gfx::RangeF visible_range() const { return visible_range_; }
void set_visible_range(const gfx::RangeF& range);
+ ElementId element_id() const { return element_id_; }
+ void set_element_id(ElementId id) { element_id_ = id; }
+
private:
float snap_offset_;
// This is the range on the cross axis, within which the SnapArea generating
// this |snap_offset| is visible. We expect the range to be in order (as
// opposed to reversed), i.e., start() < end().
gfx::RangeF visible_range_;
+
+ // The ElementId of the snap area that corresponds to this SnapSearchResult.
+ ElementId element_id_;
};
// Snap area is a bounding box that could be snapped to when a scroll happens in
@@ -125,11 +134,15 @@ struct SnapAreaData {
SnapAreaData() {}
- SnapAreaData(const ScrollSnapAlign& align, const gfx::RectF& rec, bool msnap)
- : scroll_snap_align(align), rect(rec), must_snap(msnap) {}
+ SnapAreaData(const ScrollSnapAlign& align,
+ const gfx::RectF& rec,
+ bool msnap,
+ ElementId id)
+ : scroll_snap_align(align), rect(rec), must_snap(msnap), element_id(id) {}
bool operator==(const SnapAreaData& other) const {
- return (other.scroll_snap_align == scroll_snap_align) &&
+ return (other.element_id == element_id) &&
+ (other.scroll_snap_align == scroll_snap_align) &&
(other.rect == rect) && (other.must_snap == must_snap);
}
@@ -146,6 +159,21 @@ struct SnapAreaData {
// Whether this area has scroll-snap-stop: always.
// See https://www.w3.org/TR/css-scroll-snap-1/#scroll-snap-stop
bool must_snap;
+
+ // ElementId of the corresponding snap area.
+ ElementId element_id;
+};
+
+struct TargetSnapAreaElementIds {
+ TargetSnapAreaElementIds() = default;
+ TargetSnapAreaElementIds(ElementId x_id, ElementId y_id) : x(x_id), y(y_id) {}
+ bool operator==(const TargetSnapAreaElementIds& other) const {
+ return (other.x == x) && (other.y == y);
+ }
+
+ // Note that the same element can be snapped to on both the x and y axes.
+ ElementId x;
+ ElementId y;
};
typedef std::vector<SnapAreaData> SnapAreaList;
@@ -177,15 +205,23 @@ class CC_EXPORT SnapContainerData {
return (other.scroll_snap_type_ == scroll_snap_type_) &&
(other.rect_ == rect_) && (other.max_position_ == max_position_) &&
(other.proximity_range_ == proximity_range_) &&
- (other.snap_area_list_ == snap_area_list_);
+ (other.snap_area_list_ == snap_area_list_) &&
+ (other.target_snap_area_element_ids_ ==
+ target_snap_area_element_ids_);
}
bool operator!=(const SnapContainerData& other) const {
return !(*this == other);
}
+ // Returns true if a snap position was found.
bool FindSnapPosition(const SnapSelectionStrategy& strategy,
- gfx::ScrollOffset* snap_position) const;
+ gfx::ScrollOffset* snap_position,
+ TargetSnapAreaElementIds* target_element_ids) const;
+
+ const TargetSnapAreaElementIds& GetTargetSnapAreaElementIds() const;
+ // Returns true if the target snap area element ids were changed.
+ bool SetTargetSnapAreaElementIds(TargetSnapAreaElementIds ids);
void AddSnapAreaData(SnapAreaData snap_area_data);
size_t size() const { return snap_area_list_.size(); }
@@ -235,6 +271,11 @@ class CC_EXPORT SnapContainerData {
const SnapSelectionStrategy& strategy,
const SnapSearchResult& cross_axis_snap_result) const;
+ // Finds the snap area associated with the target snap area element id for the
+ // given axis.
+ base::Optional<SnapSearchResult> GetTargetSnapAreaSearchResult(
+ SearchAxis axis) const;
+
// Returns all the info needed to snap at this area on the given axis,
// including:
// - The offset at which the snap area and the snap container meet the
@@ -268,6 +309,11 @@ class CC_EXPORT SnapContainerData {
// happens, we iterate through the snap_area_list to find the best snap
// position.
std::vector<SnapAreaData> snap_area_list_;
+
+ // Represents the ElementId(s) of the latest targeted snap areas.
+ // ElementId(s) will be invalid (ElementId::kInvalidElementId) if the snap
+ // container is not snapped to a position.
+ TargetSnapAreaElementIds target_snap_area_element_ids_;
};
CC_EXPORT std::ostream& operator<<(std::ostream&, const SnapAreaData&);
diff --git a/chromium/cc/input/scroll_snap_data_unittest.cc b/chromium/cc/input/scroll_snap_data_unittest.cc
index 704b47e81e8..8335957864c 100644
--- a/chromium/cc/input/scroll_snap_data_unittest.cc
+++ b/chromium/cc/input/scroll_snap_data_unittest.cc
@@ -10,23 +10,30 @@
namespace cc {
-class ScrollSnapDataTest : public testing::Test {};
+class ScrollSnapDataTest : public testing::Test {
+ public:
+ TargetSnapAreaElementIds target_elements;
+};
TEST_F(ScrollSnapDataTest, StartAlignmentCalculation) {
SnapContainerData container(
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(10, 10, 200, 300), gfx::ScrollOffset(600, 800));
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(100, 150, 100, 100), false);
+ gfx::RectF(100, 150, 100, 100), false, ElementId(10));
container.AddSnapAreaData(area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(90, snap_position.x());
EXPECT_EQ(140, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, CenterAlignmentCalculation) {
@@ -34,16 +41,19 @@ TEST_F(ScrollSnapDataTest, CenterAlignmentCalculation) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(10, 10, 200, 300), gfx::ScrollOffset(600, 800));
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kCenter),
- gfx::RectF(100, 150, 100, 100), false);
+ gfx::RectF(100, 150, 100, 100), false, ElementId(10));
container.AddSnapAreaData(area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(40, snap_position.x());
EXPECT_EQ(40, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, EndAlignmentCalculation) {
@@ -51,16 +61,19 @@ TEST_F(ScrollSnapDataTest, EndAlignmentCalculation) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(10, 10, 200, 200), gfx::ScrollOffset(600, 800));
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kEnd),
- gfx::RectF(150, 200, 100, 100), false);
+ gfx::RectF(150, 200, 100, 100), false, ElementId(10));
container.AddSnapAreaData(area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(40, snap_position.x());
EXPECT_EQ(90, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, UnreachableSnapPositionCalculation) {
@@ -68,19 +81,22 @@ TEST_F(ScrollSnapDataTest, UnreachableSnapPositionCalculation) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(100, 100));
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kEnd, SnapAlignment::kStart),
- gfx::RectF(200, 0, 100, 100), false);
+ gfx::RectF(200, 0, 100, 100), false, ElementId(10));
container.AddSnapAreaData(area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(50, 50),
true, true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
// Aligning to start on x would lead the scroll offset larger than max, and
// aligning to end on y would lead the scroll offset smaller than zero. So
// we expect these are clamped.
EXPECT_EQ(100, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionIndependently) {
@@ -89,12 +105,13 @@ TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionIndependently) {
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
SnapAreaData snap_x_only(
ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
- gfx::RectF(80, 0, 150, 150), false);
+ gfx::RectF(80, 0, 150, 150), false, ElementId(10));
SnapAreaData snap_y_only(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
- gfx::RectF(0, 70, 150, 150), false);
+ gfx::RectF(0, 70, 150, 150), false, ElementId(20));
SnapAreaData snap_on_both(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(50, 150, 150, 150), false);
+ gfx::RectF(50, 150, 150, 150), false,
+ ElementId(30));
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
container.AddSnapAreaData(snap_on_both);
@@ -103,9 +120,12 @@ TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionIndependently) {
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
true, true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(80, snap_position.x());
EXPECT_EQ(70, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(20)),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionOnAxisValueBoth) {
@@ -114,12 +134,13 @@ TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionOnAxisValueBoth) {
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
SnapAreaData snap_x_only(
ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
- gfx::RectF(80, 0, 150, 150), false);
+ gfx::RectF(80, 0, 150, 150), false, ElementId(10));
SnapAreaData snap_y_only(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
- gfx::RectF(0, 70, 150, 150), false);
+ gfx::RectF(0, 70, 150, 150), false, ElementId(20));
SnapAreaData snap_on_both(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(50, 150, 150, 150), false);
+ gfx::RectF(50, 150, 150, 150), false,
+ ElementId(30));
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
@@ -128,9 +149,12 @@ TEST_F(ScrollSnapDataTest, FindsClosestSnapPositionOnAxisValueBoth) {
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(40, 120),
true, true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(50, snap_position.x());
EXPECT_EQ(150, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(30), ElementId(30)),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonScrolledAxis) {
@@ -139,10 +163,10 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonScrolledAxis) {
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
SnapAreaData snap_x_only(
ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
- gfx::RectF(80, 0, 150, 150), false);
+ gfx::RectF(80, 0, 150, 150), false, ElementId(10));
SnapAreaData snap_y_only(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
- gfx::RectF(0, 70, 150, 150), false);
+ gfx::RectF(0, 70, 150, 150), false, ElementId(20));
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
@@ -150,9 +174,12 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonScrolledAxis) {
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
true, false);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(80, snap_position.x());
EXPECT_EQ(100, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonVisibleAreas) {
@@ -161,10 +188,10 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonVisibleAreas) {
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
SnapAreaData snap_x_only(
ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
- gfx::RectF(300, 400, 100, 100), false);
+ gfx::RectF(300, 400, 100, 100), false, ElementId(10));
SnapAreaData snap_y_only(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
- gfx::RectF(400, 300, 100, 100), false);
+ gfx::RectF(400, 300, 100, 100), false, ElementId(20));
container.AddSnapAreaData(snap_x_only);
container.AddSnapAreaData(snap_y_only);
@@ -172,7 +199,9 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapOnNonVisibleAreas) {
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
true);
- EXPECT_FALSE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_FALSE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
+ EXPECT_EQ(TargetSnapAreaElementIds(), target_elements);
}
TEST_F(ScrollSnapDataTest, SnapOnClosestAxisFirstIfVisibilityConflicts) {
@@ -187,13 +216,13 @@ TEST_F(ScrollSnapDataTest, SnapOnClosestAxisFirstIfVisibilityConflicts) {
// conflict with the snap point on x.
SnapAreaData snap_x(
ScrollSnapAlign(SnapAlignment::kNone, SnapAlignment::kStart),
- gfx::RectF(150, 0, 100, 100), false);
+ gfx::RectF(150, 0, 100, 100), false, ElementId(10));
SnapAreaData snap_y1(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
- gfx::RectF(0, 180, 100, 100), false);
+ gfx::RectF(0, 180, 100, 100), false, ElementId(20));
SnapAreaData snap_y2(
ScrollSnapAlign(SnapAlignment::kStart, SnapAlignment::kNone),
- gfx::RectF(250, 80, 100, 100), false);
+ gfx::RectF(250, 80, 100, 100), false, ElementId(30));
container.AddSnapAreaData(snap_x);
container.AddSnapAreaData(snap_y1);
container.AddSnapAreaData(snap_y2);
@@ -202,9 +231,12 @@ TEST_F(ScrollSnapDataTest, SnapOnClosestAxisFirstIfVisibilityConflicts) {
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(0, 0), true,
true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(150, snap_position.x());
EXPECT_EQ(80, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(30)),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, DoesNotSnapToPositionsOutsideProximityRange) {
@@ -214,20 +246,23 @@ TEST_F(ScrollSnapDataTest, DoesNotSnapToPositionsOutsideProximityRange) {
container.set_proximity_range(gfx::ScrollOffset(50, 50));
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(80, 160, 100, 100), false);
+ gfx::RectF(80, 160, 100, 100), false, ElementId(10));
container.AddSnapAreaData(area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndPosition(gfx::ScrollOffset(100, 100),
true, true);
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
// The snap position on x, 80, is within the proximity range of [50, 150].
// However, the snap position on y, 160, is outside the proximity range of
// [50, 150], so we should only snap on x.
EXPECT_EQ(80, snap_position.x());
EXPECT_EQ(100, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, MandatoryReturnsToCurrentIfNoValidAreaForward) {
@@ -235,38 +270,45 @@ TEST_F(ScrollSnapDataTest, MandatoryReturnsToCurrentIfNoValidAreaForward) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(600, 0, 100, 100), false);
+ gfx::RectF(600, 0, 100, 100), false, ElementId(10));
container.AddSnapAreaData(area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> direction_strategy =
SnapSelectionStrategy::CreateForDirection(gfx::ScrollOffset(600, 0),
gfx::ScrollOffset(5, 0));
- EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position));
+ EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position,
+ &target_elements));
// The snap direction is right. However, there is no valid snap position on
// that direction. So we have to stay at the current snap position of 600 as
// the snap type is mandatory.
EXPECT_EQ(600, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
SnapSelectionStrategy::CreateForEndAndDirection(
gfx::ScrollOffset(600, 0), gfx::ScrollOffset(15, 15));
- EXPECT_TRUE(
- container.FindSnapPosition(*end_direction_strategy, &snap_position));
+ EXPECT_TRUE(container.FindSnapPosition(*end_direction_strategy,
+ &snap_position, &target_elements));
// The snap direction is down and right. However, there is no valid snap
// position on that direction. So we have to stay at the current snap position
// of (600, 0) as the snap type is mandatory.
EXPECT_EQ(600, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ target_elements);
// If the scroll-snap-type is proximity, we wouldn't consider the current
// snap area valid even if there is no snap area forward.
container.set_scroll_snap_type(
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kProximity));
- EXPECT_FALSE(container.FindSnapPosition(*direction_strategy, &snap_position));
- EXPECT_FALSE(
- container.FindSnapPosition(*end_direction_strategy, &snap_position));
+ EXPECT_FALSE(container.FindSnapPosition(*direction_strategy, &snap_position,
+ &target_elements));
+ EXPECT_FALSE(container.FindSnapPosition(*end_direction_strategy,
+ &snap_position, &target_elements));
+ EXPECT_EQ(TargetSnapAreaElementIds(), target_elements);
}
TEST_F(ScrollSnapDataTest, MandatorySnapsBackwardIfNoValidAreaForward) {
@@ -274,38 +316,45 @@ TEST_F(ScrollSnapDataTest, MandatorySnapsBackwardIfNoValidAreaForward) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
SnapAreaData area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(600, 0, 100, 100), false);
+ gfx::RectF(600, 0, 100, 100), false, ElementId(10));
container.AddSnapAreaData(area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> direction_strategy =
SnapSelectionStrategy::CreateForDirection(gfx::ScrollOffset(650, 0),
gfx::ScrollOffset(5, 0));
- EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position));
+ EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position,
+ &target_elements));
// The snap direction is right. However, there is no valid snap position on
// that direction. So we have to scroll back to the snap position of 600 as
// the snap type is mandatory.
EXPECT_EQ(600, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
SnapSelectionStrategy::CreateForEndAndDirection(
gfx::ScrollOffset(650, 10), gfx::ScrollOffset(15, 15));
- EXPECT_TRUE(
- container.FindSnapPosition(*end_direction_strategy, &snap_position));
+ EXPECT_TRUE(container.FindSnapPosition(*end_direction_strategy,
+ &snap_position, &target_elements));
// The snap direction is down and right. However, there is no valid snap
// position on that direction. So we have to scroll back to the snap position
// of (600, 0) as the snap type is mandatory.
EXPECT_EQ(600, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ target_elements);
// If the scroll-snap-type is proximity, we wouldn't consider the backward
// snap area valid even if there is no snap area forward.
container.set_scroll_snap_type(
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kProximity));
- EXPECT_FALSE(container.FindSnapPosition(*direction_strategy, &snap_position));
- EXPECT_FALSE(
- container.FindSnapPosition(*end_direction_strategy, &snap_position));
+ EXPECT_FALSE(container.FindSnapPosition(*direction_strategy, &snap_position,
+ &target_elements));
+ EXPECT_FALSE(container.FindSnapPosition(*end_direction_strategy,
+ &snap_position, &target_elements));
+ EXPECT_EQ(TargetSnapAreaElementIds(), target_elements);
}
TEST_F(ScrollSnapDataTest, ShouldNotPassScrollSnapStopAlwaysElement) {
@@ -313,11 +362,12 @@ TEST_F(ScrollSnapDataTest, ShouldNotPassScrollSnapStopAlwaysElement) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(2000, 2000));
SnapAreaData must_snap_1(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(200, 0, 100, 100), true);
+ gfx::RectF(200, 0, 100, 100), true, ElementId(10));
SnapAreaData must_snap_2(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(400, 0, 100, 100), true);
+ gfx::RectF(400, 0, 100, 100), true, ElementId(20));
SnapAreaData closer_to_target(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(600, 0, 100, 100), false);
+ gfx::RectF(600, 0, 100, 100), false,
+ ElementId(30));
container.AddSnapAreaData(must_snap_1);
container.AddSnapAreaData(must_snap_2);
container.AddSnapAreaData(closer_to_target);
@@ -326,14 +376,17 @@ TEST_F(ScrollSnapDataTest, ShouldNotPassScrollSnapStopAlwaysElement) {
std::unique_ptr<SnapSelectionStrategy> end_direction_strategy =
SnapSelectionStrategy::CreateForEndAndDirection(
gfx::ScrollOffset(0, 0), gfx::ScrollOffset(600, 0));
- EXPECT_TRUE(
- container.FindSnapPosition(*end_direction_strategy, &snap_position));
+
+ EXPECT_TRUE(container.FindSnapPosition(*end_direction_strategy,
+ &snap_position, &target_elements));
// Even though closer_to_target and must_snap_2 are closer to the target
// position of the scroll, the must_snap_1 which is closer to the start
// shouldn't be passed.
EXPECT_EQ(200, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, SnapStopAlwaysOverridesCoveringSnapArea) {
@@ -341,9 +394,10 @@ TEST_F(ScrollSnapDataTest, SnapStopAlwaysOverridesCoveringSnapArea) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(600, 800));
SnapAreaData stop_area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(100, 0, 100, 100), true);
+ gfx::RectF(100, 0, 100, 100), true, ElementId(10));
SnapAreaData covering_area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(250, 0, 600, 600), false);
+ gfx::RectF(250, 0, 600, 600), false,
+ ElementId(20));
container.AddSnapAreaData(stop_area);
container.AddSnapAreaData(covering_area);
@@ -351,13 +405,17 @@ TEST_F(ScrollSnapDataTest, SnapStopAlwaysOverridesCoveringSnapArea) {
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndAndDirection(
gfx::ScrollOffset(0, 0), gfx::ScrollOffset(300, 0));
+
// The fling is from (0, 0) to (300, 0), and the destination would make
// the |covering_area| perfectly cover the snapport. However, another area
// with snap-stop:always precedes this |covering_area| so we snap at
// (100, 100).
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(100, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, SnapStopAlwaysInReverseDirection) {
@@ -365,19 +423,23 @@ TEST_F(ScrollSnapDataTest, SnapStopAlwaysInReverseDirection) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
SnapAreaData stop_area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(100, 0, 100, 100), true);
+ gfx::RectF(100, 0, 100, 100), true, ElementId(10));
container.AddSnapAreaData(stop_area);
gfx::ScrollOffset snap_position;
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndAndDirection(
gfx::ScrollOffset(150, 0), gfx::ScrollOffset(200, 0));
+
// The fling is from (150, 0) to (350, 0), but the snap position is in the
// reverse direction at (100, 0). Since the container has mandatory for
// snapstrictness, we should go back to snap at (100, 0).
- EXPECT_TRUE(container.FindSnapPosition(*strategy, &snap_position));
+ EXPECT_TRUE(
+ container.FindSnapPosition(*strategy, &snap_position, &target_elements));
EXPECT_EQ(100, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
}
TEST_F(ScrollSnapDataTest, SnapStopAlwaysNotInterferingWithDirectionStrategy) {
@@ -385,9 +447,9 @@ TEST_F(ScrollSnapDataTest, SnapStopAlwaysNotInterferingWithDirectionStrategy) {
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
SnapAreaData closer_area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(100, 0, 1, 1), false);
+ gfx::RectF(100, 0, 1, 1), false, ElementId(10));
SnapAreaData stop_area(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(120, 0, 1, 1), true);
+ gfx::RectF(120, 0, 1, 1), true, ElementId(20));
container.AddSnapAreaData(closer_area);
container.AddSnapAreaData(stop_area);
@@ -398,9 +460,148 @@ TEST_F(ScrollSnapDataTest, SnapStopAlwaysNotInterferingWithDirectionStrategy) {
SnapSelectionStrategy::CreateForDirection(gfx::ScrollOffset(90, 0),
gfx::ScrollOffset(50, 0));
snap_position = gfx::ScrollOffset();
- EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position));
+ EXPECT_TRUE(container.FindSnapPosition(*direction_strategy, &snap_position,
+ &target_elements));
EXPECT_EQ(100, snap_position.x());
EXPECT_EQ(0, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ target_elements);
+}
+
+TEST_F(ScrollSnapDataTest, SnapToOneTargetElementOnX) {
+ SnapContainerData container(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
+
+ SnapAreaData closer_area_x(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(100, 0, 1, 1), false, ElementId(10));
+ SnapAreaData target_area_x(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(200, 100, 1, 1), false, ElementId(20));
+ SnapAreaData closer_area_y(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(300, 50, 1, 1), false, ElementId(30));
+
+ container.AddSnapAreaData(closer_area_x);
+ container.AddSnapAreaData(target_area_x);
+ container.AddSnapAreaData(closer_area_y);
+ container.SetTargetSnapAreaElementIds(
+ TargetSnapAreaElementIds(ElementId(20), ElementId()));
+
+ // Even though closer_area_x is closer to the scroll offset, the container
+ // should snap to the target for the x-axis. However, since the target is not
+ // set for the y-axis, the target on the y-axis should be closer_area_y.
+ std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
+ SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(0, 0));
+
+ gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+ EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
+ &snap_position, &target_elements));
+
+ EXPECT_EQ(200, snap_position.x());
+ EXPECT_EQ(50, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(20), ElementId(30)),
+ target_elements);
+}
+
+TEST_F(ScrollSnapDataTest, SnapToOneTargetElementOnY) {
+ SnapContainerData container(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 200, 300), gfx::ScrollOffset(600, 800));
+
+ SnapAreaData closer_area_y(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(0, 100, 1, 1), false, ElementId(10));
+ SnapAreaData target_area_y(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(100, 200, 1, 1), false, ElementId(20));
+ SnapAreaData closer_area_x(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(50, 300, 1, 1), false, ElementId(30));
+
+ container.AddSnapAreaData(closer_area_y);
+ container.AddSnapAreaData(target_area_y);
+ container.AddSnapAreaData(closer_area_x);
+ container.SetTargetSnapAreaElementIds(
+ TargetSnapAreaElementIds(ElementId(), ElementId(20)));
+
+ // Even though closer_area_y is closer to the scroll offset, the container
+ // should snap to the target for the y-axis. However, since the target is not
+ // set for the x-axis, the target on the x-axis should be closer_area_x.
+ std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
+ SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(0, 0));
+
+ gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+ EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
+ &snap_position, &target_elements));
+
+ EXPECT_EQ(50, snap_position.x());
+ EXPECT_EQ(200, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(30), ElementId(20)),
+ target_elements);
+}
+
+TEST_F(ScrollSnapDataTest, SnapToTwoTargetElementsMutualVisible) {
+ SnapContainerData container(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 300, 300), gfx::ScrollOffset(600, 800));
+
+ SnapAreaData target_area_x(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(100, 200, 1, 1), false, ElementId(10));
+ SnapAreaData target_area_y(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(200, 100, 1, 1), false, ElementId(20));
+ SnapAreaData closer_area_both(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(0, 0, 1, 1), false, ElementId(30));
+
+ container.AddSnapAreaData(target_area_x);
+ container.AddSnapAreaData(target_area_y);
+ container.AddSnapAreaData(closer_area_both);
+ container.SetTargetSnapAreaElementIds(
+ TargetSnapAreaElementIds(ElementId(10), ElementId(20)));
+
+ // The container should snap to both target areas since they are mutually
+ // visible, while ignoring the snap area that is closest to the scroll offset.
+ std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
+ SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(0, 0));
+
+ gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+ EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
+ &snap_position, &target_elements));
+
+ EXPECT_EQ(100, snap_position.x());
+ EXPECT_EQ(100, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(20)),
+ target_elements);
+}
+
+TEST_F(ScrollSnapDataTest, SnapToTwoTargetElementsNotMutualVisible) {
+ SnapContainerData container(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 300, 300), gfx::ScrollOffset(600, 800));
+
+ SnapAreaData target_area_x(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(100, 500, 1, 1), false, ElementId(10));
+ SnapAreaData target_area_y(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(500, 100, 1, 1), false, ElementId(20));
+ SnapAreaData area_mutually_visible_to_targets(
+ ScrollSnapAlign(SnapAlignment::kStart), gfx::RectF(350, 350, 1, 1), false,
+ ElementId(30));
+
+ container.AddSnapAreaData(target_area_x);
+ container.AddSnapAreaData(target_area_y);
+ container.AddSnapAreaData(area_mutually_visible_to_targets);
+ container.SetTargetSnapAreaElementIds(
+ TargetSnapAreaElementIds(ElementId(10), ElementId(20)));
+
+ // The container cannot snap to both targets, so it should snap to the one
+ // closer to the scroll offset, and then snap to the closest mutually visible
+ // snap area on the other axis.
+ std::unique_ptr<SnapSelectionStrategy> target_element_strategy =
+ SnapSelectionStrategy::CreateForTargetElement(gfx::ScrollOffset(10, 0));
+
+ gfx::ScrollOffset snap_position = gfx::ScrollOffset();
+ EXPECT_TRUE(container.FindSnapPosition(*target_element_strategy,
+ &snap_position, &target_elements));
+
+ EXPECT_EQ(100, snap_position.x());
+ EXPECT_EQ(350, snap_position.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(30)),
+ target_elements);
}
} // namespace cc
diff --git a/chromium/cc/input/scroll_state.cc b/chromium/cc/input/scroll_state.cc
index e578c325352..521882a0636 100644
--- a/chromium/cc/input/scroll_state.cc
+++ b/chromium/cc/input/scroll_state.cc
@@ -6,13 +6,11 @@
#include <utility>
-#include "cc/trees/layer_tree_impl.h"
#include "cc/trees/scroll_node.h"
namespace cc {
-ScrollState::ScrollState(ScrollStateData data)
- : data_(data), layer_tree_impl_(nullptr) {}
+ScrollState::ScrollState(ScrollStateData data) : data_(data) {}
ScrollState::ScrollState(const ScrollState& other) = default;
@@ -26,14 +24,4 @@ void ScrollState::ConsumeDelta(double x, double y) {
data_.delta_consumed_for_scroll_sequence = true;
}
-void ScrollState::DistributeToScrollChainDescendant() {
- if (!scroll_chain_.empty()) {
- ScrollNode* next = scroll_chain_.front();
- scroll_chain_.pop_front();
-
- ScrollTree& scroll_tree = layer_tree_impl_->property_trees()->scroll_tree;
- scroll_tree.DistributeScroll(next, this);
- }
-}
-
} // namespace cc
diff --git a/chromium/cc/input/scroll_state.h b/chromium/cc/input/scroll_state.h
index 658d356dc91..ff68e3cdcac 100644
--- a/chromium/cc/input/scroll_state.h
+++ b/chromium/cc/input/scroll_state.h
@@ -15,8 +15,6 @@
namespace cc {
-class LayerTreeImpl;
-
// ScrollState is based on the proposal for scroll customization in blink, found
// here: https://goo.gl/1ipTpP.
class CC_EXPORT ScrollState {
@@ -27,9 +25,6 @@ class CC_EXPORT ScrollState {
// Reduce deltas by x, y.
void ConsumeDelta(double x, double y);
- // Pops the first layer off of |scroll_chain_| and calls
- // |DistributeScroll| on it.
- void DistributeToScrollChainDescendant();
// Positive when scrolling right.
double delta_x() const { return data_.delta_x; }
// Positive when scrolling down.
@@ -63,13 +58,6 @@ class CC_EXPORT ScrollState {
data_.is_direct_manipulation = is_direct_manipulation;
}
- void set_scroll_chain_and_layer_tree(
- const std::list<ScrollNode*>& scroll_chain,
- LayerTreeImpl* layer_tree_impl) {
- layer_tree_impl_ = layer_tree_impl;
- scroll_chain_ = scroll_chain;
- }
-
void set_current_native_scrolling_node(ScrollNode* scroll_node) {
data_.set_current_native_scrolling_node(scroll_node);
}
@@ -85,8 +73,6 @@ class CC_EXPORT ScrollState {
data_.delta_consumed_for_scroll_sequence = delta_consumed;
}
- bool FullyConsumed() const { return !data_.delta_x && !data_.delta_y; }
-
void set_caused_scroll(bool x, bool y) {
data_.caused_scroll_x |= x;
data_.caused_scroll_y |= y;
@@ -101,13 +87,10 @@ class CC_EXPORT ScrollState {
double delta_granularity() const { return data_.delta_granularity; }
- LayerTreeImpl* layer_tree_impl() { return layer_tree_impl_; }
ScrollStateData* data() { return &data_; }
private:
ScrollStateData data_;
- LayerTreeImpl* layer_tree_impl_;
- std::list<ScrollNode*> scroll_chain_;
};
} // namespace cc
diff --git a/chromium/cc/input/scroll_state_data.h b/chromium/cc/input/scroll_state_data.h
index c3f2e1c5f1e..3a325134bb4 100644
--- a/chromium/cc/input/scroll_state_data.h
+++ b/chromium/cc/input/scroll_state_data.h
@@ -77,9 +77,13 @@ class CC_EXPORT ScrollStateData {
// possible, we should store the scroll node.
// The last scroll node to respond to a scroll, or null if none exists.
+ // TODO(bokan): This is redundant with the member below.
ScrollNode* current_native_scrolling_node_;
// The id of the last native element to respond to a scroll, or 0 if none
// exists.
+ // TODO(bokan): In the compositor, this is now only used as an override to
+ // scroller targeting, i.e. we'll latch scrolling to the specified
+ // element_id. It will be renamed when the main thread is also converted.
ElementId current_native_scrolling_element_;
};
diff --git a/chromium/cc/input/scroll_state_unittest.cc b/chromium/cc/input/scroll_state_unittest.cc
index b0ce86ac9b1..730d635bd19 100644
--- a/chromium/cc/input/scroll_state_unittest.cc
+++ b/chromium/cc/input/scroll_state_unittest.cc
@@ -32,29 +32,24 @@ TEST_F(ScrollStateTest, ConsumeDeltaNative) {
EXPECT_FLOAT_EQ(delta_x, scroll_state.delta_x());
EXPECT_FLOAT_EQ(delta_y, scroll_state.delta_y());
EXPECT_FALSE(scroll_state.delta_consumed_for_scroll_sequence());
- EXPECT_FALSE(scroll_state.FullyConsumed());
scroll_state.ConsumeDelta(0, 0);
EXPECT_FLOAT_EQ(delta_x, scroll_state.delta_x());
EXPECT_FLOAT_EQ(delta_y, scroll_state.delta_y());
EXPECT_FALSE(scroll_state.delta_consumed_for_scroll_sequence());
- EXPECT_FALSE(scroll_state.FullyConsumed());
scroll_state.ConsumeDelta(delta_x_to_consume, 0);
EXPECT_FLOAT_EQ(delta_x - delta_x_to_consume, scroll_state.delta_x());
EXPECT_FLOAT_EQ(delta_y, scroll_state.delta_y());
EXPECT_TRUE(scroll_state.delta_consumed_for_scroll_sequence());
- EXPECT_FALSE(scroll_state.FullyConsumed());
scroll_state.ConsumeDelta(0, delta_y_to_consume);
EXPECT_FLOAT_EQ(delta_x - delta_x_to_consume, scroll_state.delta_x());
EXPECT_FLOAT_EQ(delta_y - delta_y_to_consume, scroll_state.delta_y());
EXPECT_TRUE(scroll_state.delta_consumed_for_scroll_sequence());
- EXPECT_FALSE(scroll_state.FullyConsumed());
scroll_state.ConsumeDelta(scroll_state.delta_x(), scroll_state.delta_y());
EXPECT_TRUE(scroll_state.delta_consumed_for_scroll_sequence());
- EXPECT_TRUE(scroll_state.FullyConsumed());
}
TEST_F(ScrollStateTest, CurrentNativeScrollingScrollable) {
@@ -73,15 +68,4 @@ TEST_F(ScrollStateTest, CurrentNativeScrollingScrollable) {
scroll_state.set_current_native_scrolling_node(scroll_node);
EXPECT_EQ(scroll_node, scroll_state.current_native_scrolling_node());
}
-
-TEST_F(ScrollStateTest, FullyConsumed) {
- ScrollStateData scroll_state_data;
- scroll_state_data.delta_x = 1;
- scroll_state_data.delta_y = 3;
- ScrollState scroll_state(scroll_state_data);
-
- EXPECT_FALSE(scroll_state.FullyConsumed());
- scroll_state.ConsumeDelta(1, 3);
- EXPECT_TRUE(scroll_state.FullyConsumed());
-}
} // namespace cc
diff --git a/chromium/cc/input/scrollbar.h b/chromium/cc/input/scrollbar.h
index 4c739c69dba..2a5e6cb571e 100644
--- a/chromium/cc/input/scrollbar.h
+++ b/chromium/cc/input/scrollbar.h
@@ -5,6 +5,7 @@
#ifndef CC_INPUT_SCROLLBAR_H_
#define CC_INPUT_SCROLLBAR_H_
+#include "base/memory/ref_counted.h"
#include "cc/cc_export.h"
#include "cc/paint/paint_canvas.h"
#include "ui/gfx/geometry/point.h"
@@ -33,8 +34,7 @@ enum ScrollbarOrientation { HORIZONTAL, VERTICAL };
enum ScrollbarPart {
THUMB,
- TRACK,
- TICKMARKS,
+ TRACK_BUTTONS_TICKMARKS, // for PartNeedsRepaint() and PaintPart() only.
BACK_BUTTON,
FORWARD_BUTTON,
BACK_TRACK,
@@ -42,41 +42,45 @@ enum ScrollbarPart {
NO_PART,
};
-class Scrollbar {
+class Scrollbar : public base::RefCounted<Scrollbar> {
public:
- virtual ~Scrollbar() {}
-
virtual ScrollbarOrientation Orientation() const = 0;
virtual bool IsLeftSideVerticalScrollbar() const = 0;
- virtual gfx::Point Location() const = 0;
+ virtual bool IsSolidColor() const = 0;
virtual bool IsOverlay() const = 0;
virtual bool HasThumb() const = 0;
virtual bool SupportsDragSnapBack() const = 0;
- virtual int ThumbThickness() const = 0;
- virtual int ThumbLength() const = 0;
- // Returns the track rect relative to the scrollbar's origin.
+ // The following rects are all relative to the scrollbar's origin.
+ // The location of ThumbRect reflects scroll offset, but cc will ignore it
+ // because the compositor thread will compute thumb location from scroll
+ // offset.
+ virtual gfx::Rect ThumbRect() const = 0;
virtual gfx::Rect TrackRect() const = 0;
- // Returns the back button rect relative to the scrollbar's origin.
virtual gfx::Rect BackButtonRect() const = 0;
- // Returns the forward button rect relative to the scrollbar's origin.
virtual gfx::Rect ForwardButtonRect() const = 0;
virtual float ThumbOpacity() const = 0;
virtual bool HasTickmarks() const = 0;
- // Whether we need to repaint the part. Only THUMB and TRACK are supported.
- // For TRACK, the return value means that the track, any buttons or tickmarks
- // need repaint.
- virtual bool NeedsPaintPart(ScrollbarPart part) const = 0;
- // Paints the part. Only THUMB, TRACK and TICKMARKS are supported. When TRACK
- // is specified, track, buttons and tickmarks will be painted. The canvas's
- // coordinate space is relative to the part's origin.
- virtual void PaintPart(PaintCanvas* canvas, ScrollbarPart part) = 0;
+ // Whether we need to repaint the part. Only THUMB and TRACK_BUTTONS_TICKMARKS
+ // are supported.
+ virtual bool NeedsRepaintPart(ScrollbarPart part) const = 0;
+
+ // Paints the part in the given rect. The implementation should paint
+ // relative to the rect, and doesn't need to know the current coordinate
+ // space of |canvas|. Only THUMB, TRACK_BUTTONS_TICKMARKS are supported.
+ virtual void PaintPart(PaintCanvas* canvas,
+ ScrollbarPart part,
+ const gfx::Rect& rect) = 0;
virtual bool UsesNinePatchThumbResource() const = 0;
virtual gfx::Size NinePatchThumbCanvasSize() const = 0;
virtual gfx::Rect NinePatchThumbAperture() const = 0;
+
+ protected:
+ friend class base::RefCounted<Scrollbar>;
+ virtual ~Scrollbar() {}
};
} // namespace cc
diff --git a/chromium/cc/input/scrollbar_controller.cc b/chromium/cc/input/scrollbar_controller.cc
index 2f4221e3d59..62f433c9440 100644
--- a/chromium/cc/input/scrollbar_controller.cc
+++ b/chromium/cc/input/scrollbar_controller.cc
@@ -25,7 +25,6 @@ ScrollbarController::ScrollbarController(
LayerTreeHostImpl* layer_tree_host_impl)
: layer_tree_host_impl_(layer_tree_host_impl),
scrollbar_scroll_is_active_(false),
- currently_captured_scrollbar_(nullptr),
last_known_pointer_position_(gfx::PointF(0, 0)),
drag_processed_for_current_frame_(false),
cancelable_autoscroll_task_(nullptr) {}
@@ -36,20 +35,34 @@ void ScrollbarController::WillBeginImplFrame() {
}
gfx::Vector2dF ScrollbarController::GetThumbRelativePoint(
+ const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF position_in_widget) {
bool clipped;
const gfx::PointF position_in_layer =
- GetScrollbarRelativePosition(position_in_widget, &clipped);
+ GetScrollbarRelativePosition(scrollbar, position_in_widget, &clipped);
if (clipped)
return gfx::Vector2d(0, 0);
- const gfx::RectF thumb_rect(
- currently_captured_scrollbar_->ComputeThumbQuadRect());
+ const gfx::RectF thumb_rect(scrollbar->ComputeThumbQuadRect());
DCHECK(thumb_rect.Contains(position_in_layer));
return position_in_layer - gfx::PointF(thumb_rect.origin());
}
+// Retrieves the ScrollbarLayerImplBase corresponding to the stashed ElementId.
+ScrollbarLayerImplBase* ScrollbarController::ScrollbarLayer() {
+ if (!captured_scrollbar_metadata_.has_value())
+ return nullptr;
+
+ const ScrollbarSet scrollbars = layer_tree_host_impl_->ScrollbarsFor(
+ captured_scrollbar_metadata_->scroll_element_id);
+ for (ScrollbarLayerImplBase* scrollbar : scrollbars) {
+ if (captured_scrollbar_metadata_->orientation == scrollbar->orientation())
+ return scrollbar;
+ }
+ return nullptr;
+}
+
// Performs hit test and prepares scroll deltas that will be used by GSB and
// GSU.
InputHandlerPointerResult ScrollbarController::HandlePointerDown(
@@ -65,30 +78,32 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown(
if (!(layer_impl && layer_impl->ToScrollbarLayer()))
return InputHandlerPointerResult();
- currently_captured_scrollbar_ = layer_impl->ToScrollbarLayer();
+ const ScrollbarLayerImplBase* scrollbar = layer_impl->ToScrollbarLayer();
+ captured_scrollbar_metadata_ = CapturedScrollbarMetadata();
+ captured_scrollbar_metadata_->scroll_element_id =
+ scrollbar->scroll_element_id();
+ captured_scrollbar_metadata_->orientation = scrollbar->orientation();
+
InputHandlerPointerResult scroll_result;
- scroll_result.target_scroller =
- currently_captured_scrollbar_->scroll_element_id();
+ scroll_result.target_scroller = scrollbar->scroll_element_id();
scroll_result.type = PointerResultType::kScrollbarScroll;
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
const ScrollbarPart scrollbar_part =
- GetScrollbarPartFromPointerDown(position_in_widget);
+ GetScrollbarPartFromPointerDown(scrollbar, position_in_widget);
scroll_result.scroll_offset = GetScrollOffsetForScrollbarPart(
- scrollbar_part, currently_captured_scrollbar_->orientation(),
- shift_modifier);
+ scrollbar, scrollbar_part, shift_modifier);
last_known_pointer_position_ = position_in_widget;
scrollbar_scroll_is_active_ = true;
scroll_result.scroll_units = Granularity(scrollbar_part, shift_modifier);
if (scrollbar_part == ScrollbarPart::THUMB) {
drag_state_ = DragState();
drag_state_->anchor_relative_to_thumb_ =
- GetThumbRelativePoint(position_in_widget);
+ GetThumbRelativePoint(scrollbar, position_in_widget);
// Record the current scroller offset. This will be needed to snap the
// thumb back to its original position if the pointer moves too far away
// from the track during a thumb drag.
- drag_state_->scroll_position_at_start_ =
- currently_captured_scrollbar_->current_pos();
+ drag_state_->scroll_position_at_start_ = scrollbar->current_pos();
}
if (!scroll_result.scroll_offset.IsZero()) {
@@ -97,13 +112,12 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown(
// have the potential of initiating an autoscroll (if held down for long
// enough).
DCHECK(scrollbar_part != ScrollbarPart::THUMB);
- cancelable_autoscroll_task_ =
- std::make_unique<base::CancelableClosure>(base::Bind(
- &ScrollbarController::StartAutoScrollAnimation,
- base::Unretained(this),
- InitialDeltaToAutoscrollVelocity(scroll_result.scroll_offset),
- currently_captured_scrollbar_->scroll_element_id(),
- scrollbar_part));
+ cancelable_autoscroll_task_ = std::make_unique<base::CancelableOnceClosure>(
+ base::BindOnce(&ScrollbarController::StartAutoScrollAnimation,
+ base::Unretained(this),
+ InitialDeltaToAutoscrollVelocity(
+ scrollbar, scroll_result.scroll_offset),
+ scrollbar, scrollbar_part));
layer_tree_host_impl_->task_runner_provider()
->ImplThreadTaskRunner()
->PostDelayedTask(FROM_HERE, cancelable_autoscroll_task_->callback(),
@@ -113,24 +127,23 @@ InputHandlerPointerResult ScrollbarController::HandlePointerDown(
}
bool ScrollbarController::SnapToDragOrigin(
+ const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF pointer_position_in_widget) {
// Consult the ScrollbarTheme to check if thumb snapping is supported on the
// current platform.
- if (!currently_captured_scrollbar_->SupportsDragSnapBack())
+ if (!(scrollbar && scrollbar->SupportsDragSnapBack()))
return false;
bool clipped = false;
- const gfx::PointF pointer_position_in_layer =
- GetScrollbarRelativePosition(pointer_position_in_widget, &clipped);
+ const gfx::PointF pointer_position_in_layer = GetScrollbarRelativePosition(
+ scrollbar, pointer_position_in_widget, &clipped);
if (clipped)
return false;
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
- const ScrollbarOrientation orientation =
- currently_captured_scrollbar_->orientation();
- const gfx::Rect forward_track_rect =
- currently_captured_scrollbar_->ForwardTrackRect();
+ const ScrollbarOrientation orientation = scrollbar->orientation();
+ const gfx::Rect forward_track_rect = scrollbar->ForwardTrackRect();
// When dragging the thumb, there needs to exist "gutters" on either side of
// the track. The thickness of these gutters is a multiple of the track (or
@@ -146,7 +159,7 @@ bool ScrollbarController::SnapToDragOrigin(
if (!track_thickness) {
// For overlay scrollbars (or for tests that do not set up a track
// thickness), use the thumb_thickness instead to determine the gutters.
- const int thumb_thickness = currently_captured_scrollbar_->ThumbThickness();
+ const int thumb_thickness = scrollbar->ThumbThickness();
// If the thumb doesn't have thickness, the gutters can't be determined.
// Snapping shouldn't occur in this case.
@@ -188,62 +201,60 @@ ui::input_types::ScrollGranularity ScrollbarController::Granularity(
return ui::input_types::ScrollGranularity::kScrollByPixel;
}
-float ScrollbarController::GetScrollDeltaForShiftClick() {
+float ScrollbarController::GetScrollDeltaForAbsoluteJump(
+ const ScrollbarLayerImplBase* scrollbar) {
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
bool clipped = false;
- const gfx::PointF pointer_position_in_layer =
- GetScrollbarRelativePosition(last_known_pointer_position_, &clipped);
+ const gfx::PointF pointer_position_in_layer = GetScrollbarRelativePosition(
+ scrollbar, last_known_pointer_position_, &clipped);
if (clipped)
return 0;
- const ScrollbarOrientation orientation =
- currently_captured_scrollbar_->orientation();
- const float pointer_location = orientation == ScrollbarOrientation::VERTICAL
- ? pointer_position_in_layer.y()
- : pointer_position_in_layer.x();
+ const float pointer_location =
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
+ ? pointer_position_in_layer.y()
+ : pointer_position_in_layer.x();
// During a shift + click, the pointers current location (on the track) needs
// to be considered as the center of the thumb and the thumb origin needs to
// be calculated based on that. This will ensure that when shift + click is
// processed, the thumb will be centered on the pointer.
- const int thumb_length = currently_captured_scrollbar_->ThumbLength();
+ const int thumb_length = scrollbar->ThumbLength();
const float desired_thumb_origin = pointer_location - thumb_length / 2.f;
- const gfx::Rect thumb_rect(
- currently_captured_scrollbar_->ComputeThumbQuadRect());
+ const gfx::Rect thumb_rect(scrollbar->ComputeThumbQuadRect());
const float current_thumb_origin =
- orientation == ScrollbarOrientation::VERTICAL ? thumb_rect.y()
- : thumb_rect.x();
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
+ ? thumb_rect.y()
+ : thumb_rect.x();
const float delta =
round(std::abs(desired_thumb_origin - current_thumb_origin));
- return delta * GetScrollerToScrollbarRatio();
+ return delta * GetScrollerToScrollbarRatio(scrollbar);
}
gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition(
+ const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF pointer_position_in_widget) {
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
- const ScrollbarOrientation orientation =
- currently_captured_scrollbar_->orientation();
- if (SnapToDragOrigin(pointer_position_in_widget)) {
- const float delta = currently_captured_scrollbar_->current_pos() -
- drag_state_->scroll_position_at_start_;
- return orientation == ScrollbarOrientation::VERTICAL
+ if (SnapToDragOrigin(scrollbar, pointer_position_in_widget)) {
+ const float delta =
+ scrollbar->current_pos() - drag_state_->scroll_position_at_start_;
+ return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, -delta)
: gfx::ScrollOffset(-delta, 0);
}
- const gfx::Rect thumb_rect(
- currently_captured_scrollbar_->ComputeThumbQuadRect());
+ const gfx::Rect thumb_rect(scrollbar->ComputeThumbQuadRect());
const gfx::PointF drag_position_relative_to_layer =
gfx::PointF(thumb_rect.origin()) + drag_state_->anchor_relative_to_thumb_;
bool clipped = false;
- const gfx::PointF pointer_position_in_layer =
- GetScrollbarRelativePosition(pointer_position_in_widget, &clipped);
+ const gfx::PointF pointer_position_in_layer = GetScrollbarRelativePosition(
+ scrollbar, pointer_position_in_widget, &clipped);
if (clipped)
return gfx::ScrollOffset(0, 0);
@@ -252,8 +263,9 @@ gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition(
const gfx::Vector2dF pointer_delta =
pointer_position_in_layer - drag_position_relative_to_layer;
- float scaled_scroller_to_scrollbar_ratio = GetScrollerToScrollbarRatio();
- float current_scroll_position = currently_captured_scrollbar_->current_pos();
+ float scaled_scroller_to_scrollbar_ratio =
+ GetScrollerToScrollbarRatio(scrollbar);
+ float current_scroll_position = scrollbar->current_pos();
// Thumb position needs to be floored and Values between 0 and 1 are rounded
// to one to match main thread per pixel behavior. Corresponding main thread
@@ -264,9 +276,10 @@ gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition(
? 1.0
: floorf(thumb_position);
- float delta_in_orientation = orientation == ScrollbarOrientation::VERTICAL
- ? pointer_delta.y()
- : pointer_delta.x();
+ float delta_in_orientation =
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
+ ? pointer_delta.y()
+ : pointer_delta.x();
// This is effectively equal to delta_in_orientation *
// scaled_scroller_to_scrollbar_ratio but is necessary due to truncated delta
@@ -280,7 +293,7 @@ gfx::ScrollOffset ScrollbarController::GetScrollOffsetForDragPosition(
gfx::ScrollOffset scaled_thumb_drag_delta;
// Scroll delta floored to match main thread per pixel behavior
- orientation == ScrollbarOrientation::VERTICAL
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? scaled_thumb_drag_delta.set_y(floorf(scroll_delta))
: scaled_thumb_drag_delta.set_x(floorf(scroll_delta));
@@ -297,7 +310,9 @@ InputHandlerPointerResult ScrollbarController::HandlePointerMove(
// If a thumb drag is not in progress or if a GSU was already produced for a
// thumb drag in this frame, there's no point in continuing on. Please see the
// header file for details.
- if (!drag_state_.has_value() || drag_processed_for_current_frame_)
+ const ScrollbarLayerImplBase* scrollbar = ScrollbarLayer();
+ if (!scrollbar || !drag_state_.has_value() ||
+ drag_processed_for_current_frame_)
return scroll_result;
const ScrollNode* currently_scrolling_node =
@@ -312,7 +327,7 @@ InputHandlerPointerResult ScrollbarController::HandlePointerMove(
// If scroll_offset can't be consumed, there's no point in continuing on.
const gfx::ScrollOffset scroll_offset(
- GetScrollOffsetForDragPosition(position_in_widget));
+ GetScrollOffsetForDragPosition(scrollbar, position_in_widget));
const gfx::Vector2dF clamped_scroll_offset(
layer_tree_host_impl_->ComputeScrollDelta(
*currently_scrolling_node, ScrollOffsetToVector2dF(scroll_offset)));
@@ -331,14 +346,14 @@ InputHandlerPointerResult ScrollbarController::HandlePointerMove(
return scroll_result;
}
-float ScrollbarController::GetScrollerToScrollbarRatio() {
+float ScrollbarController::GetScrollerToScrollbarRatio(
+ const ScrollbarLayerImplBase* scrollbar) {
// Calculating the delta by which the scroller layer should move when
// dragging the thumb depends on the following factors:
// - scrollbar_track_length
// - scrollbar_thumb_length
// - scroll_layer_length
// - viewport_length
- // - device_scale_factor
// - position_in_widget
//
// When a thumb drag is in progress, for every pixel that the pointer moves,
@@ -348,6 +363,8 @@ float ScrollbarController::GetScrollerToScrollbarRatio() {
// (scroll_layer_length - viewport_length) /
// (scrollbar_track_length - scrollbar_thumb_length)
//
+ // PS: Note that since this is a "ratio", it need not be scaled by the DSF.
+ //
// |<--------------------- scroll_layer_length -------------------------->|
//
// +------------------------------------------------+......................
@@ -371,50 +388,51 @@ float ScrollbarController::GetScrollerToScrollbarRatio() {
// |<- scrollbar_thumb_length ->|
//
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
- float scroll_layer_length =
- currently_captured_scrollbar_->scroll_layer_length();
- float scrollbar_track_length = currently_captured_scrollbar_->TrackLength();
- gfx::Rect thumb_rect(currently_captured_scrollbar_->ComputeThumbQuadRect());
- const ScrollbarOrientation orientation =
- currently_captured_scrollbar_->orientation();
- float scrollbar_thumb_length = orientation == ScrollbarOrientation::VERTICAL
- ? thumb_rect.height()
- : thumb_rect.width();
+ float scroll_layer_length = scrollbar->scroll_layer_length();
+ float scrollbar_track_length = scrollbar->TrackLength();
+ gfx::Rect thumb_rect(scrollbar->ComputeThumbQuadRect());
+ float scrollbar_thumb_length =
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
+ ? thumb_rect.height()
+ : thumb_rect.width();
const LayerImpl* owner_scroll_layer =
layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId(
- currently_captured_scrollbar_->scroll_element_id());
+ scrollbar->scroll_element_id());
const float viewport_length =
- orientation == ScrollbarOrientation::VERTICAL
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? owner_scroll_layer->scroll_container_bounds().height()
: (owner_scroll_layer->scroll_container_bounds().width());
- // For platforms which have use_zoom_for_dsf set to false (like Mac), the
- // device_scale_factor should not be used while determining the
- // scaled_scroller_to_scrollbar_ratio as thumb drag would appear jittery due
- // to constant over and under corrections.
- // (See ScrollbarController::ScreenSpaceScaleFactor()).
- float scaled_scroller_to_scrollbar_ratio =
- ((scroll_layer_length - viewport_length) /
- (scrollbar_track_length - scrollbar_thumb_length)) *
- ScreenSpaceScaleFactor();
+ return ((scroll_layer_length - viewport_length) /
+ (scrollbar_track_length - scrollbar_thumb_length));
+}
- return scaled_scroller_to_scrollbar_ratio;
+void ScrollbarController::ResetState() {
+ drag_processed_for_current_frame_ = false;
+ drag_state_ = base::nullopt;
+ autoscroll_state_ = base::nullopt;
+ captured_scrollbar_metadata_ = base::nullopt;
+}
+
+void ScrollbarController::DidUnregisterScrollbar(ElementId element_id) {
+ if (captured_scrollbar_metadata_.has_value() &&
+ captured_scrollbar_metadata_->scroll_element_id == element_id)
+ ResetState();
}
void ScrollbarController::RecomputeAutoscrollStateIfNeeded() {
- if (!autoscroll_state_.has_value())
+ if (!autoscroll_state_.has_value() ||
+ !captured_scrollbar_metadata_.has_value())
return;
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
- const ScrollbarOrientation orientation =
- currently_captured_scrollbar_->orientation();
- const gfx::Rect thumb_quad =
- currently_captured_scrollbar_->ComputeThumbQuadRect();
+ const ScrollbarLayerImplBase* scrollbar = ScrollbarLayer();
+ const gfx::Rect thumb_quad = scrollbar->ComputeThumbQuadRect();
bool clipped;
- gfx::PointF scroller_relative_position(
- GetScrollbarRelativePosition(last_known_pointer_position_, &clipped));
+ gfx::PointF scroller_relative_position(GetScrollbarRelativePosition(
+ scrollbar, last_known_pointer_position_, &clipped));
if (clipped)
return;
@@ -425,7 +443,7 @@ void ScrollbarController::RecomputeAutoscrollStateIfNeeded() {
int thumb_start = 0;
int thumb_end = 0;
int pointer_position = 0;
- if (orientation == ScrollbarOrientation::VERTICAL) {
+ if (scrollbar->orientation() == ScrollbarOrientation::VERTICAL) {
thumb_start = thumb_quad.y();
thumb_end = thumb_quad.y() + thumb_quad.height();
pointer_position = scroller_relative_position.y();
@@ -451,48 +469,45 @@ void ScrollbarController::RecomputeAutoscrollStateIfNeeded() {
// always has a constant value to animate to (which is '0'. See the function
// ScrollbarController::StartAutoScrollAnimation).
if (autoscroll_state_->direction == AutoScrollDirection::AUTOSCROLL_FORWARD) {
- const float scroll_layer_length =
- currently_captured_scrollbar_->scroll_layer_length();
+ const float scroll_layer_length = scrollbar->scroll_layer_length();
if (autoscroll_state_->scroll_layer_length != scroll_layer_length) {
layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort();
- StartAutoScrollAnimation(
- autoscroll_state_->velocity,
- currently_captured_scrollbar_->scroll_element_id(),
- autoscroll_state_->pressed_scrollbar_part);
+ StartAutoScrollAnimation(autoscroll_state_->velocity, scrollbar,
+ autoscroll_state_->pressed_scrollbar_part);
}
}
// The animations need to be aborted/restarted based on the pointer location
// (i.e leaving/entering the track/arrows, reaching the track end etc). The
// autoscroll_state_ however, needs to be reset on pointer changes.
- const gfx::RectF scrollbar_part_rect(
- GetRectForScrollbarPart(autoscroll_state_->pressed_scrollbar_part));
+ const gfx::RectF scrollbar_part_rect(GetRectForScrollbarPart(
+ scrollbar, autoscroll_state_->pressed_scrollbar_part));
if (!scrollbar_part_rect.Contains(scroller_relative_position)) {
// Stop animating if pointer moves outside the rect bounds.
layer_tree_host_impl_->mutator_host()->ScrollAnimationAbort();
} else if (scrollbar_part_rect.Contains(scroller_relative_position) &&
!layer_tree_host_impl_->mutator_host()->IsElementAnimating(
- currently_captured_scrollbar_->scroll_element_id())) {
+ scrollbar->scroll_element_id())) {
// Start animating if pointer re-enters the bounds.
- StartAutoScrollAnimation(autoscroll_state_->velocity,
- currently_captured_scrollbar_->scroll_element_id(),
+ StartAutoScrollAnimation(autoscroll_state_->velocity, scrollbar,
autoscroll_state_->pressed_scrollbar_part);
}
}
// Helper to calculate the autoscroll velocity.
float ScrollbarController::InitialDeltaToAutoscrollVelocity(
+ const ScrollbarLayerImplBase* scrollbar,
gfx::ScrollOffset scroll_offset) const {
- const float scroll_delta = currently_captured_scrollbar_->orientation() ==
- ScrollbarOrientation::VERTICAL
- ? scroll_offset.y()
- : scroll_offset.x();
+ const float scroll_delta =
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
+ ? scroll_offset.y()
+ : scroll_offset.x();
return scroll_delta * kAutoscrollMultiplier;
}
void ScrollbarController::StartAutoScrollAnimation(
const float velocity,
- ElementId element_id,
+ const ScrollbarLayerImplBase* scrollbar,
ScrollbarPart pressed_scrollbar_part) {
// Autoscroll and thumb drag are mutually exclusive. Both can't be active at
// the same time.
@@ -503,17 +518,14 @@ void ScrollbarController::StartAutoScrollAnimation(
// don't need to create any animation for it.
ScrollTree& scroll_tree =
layer_tree_host_impl_->active_tree()->property_trees()->scroll_tree;
- ScrollNode* scroll_node = scroll_tree.FindNodeFromElementId(element_id);
+ ScrollNode* scroll_node =
+ scroll_tree.FindNodeFromElementId(scrollbar->scroll_element_id());
if (!(scroll_node && scrollbar_scroll_is_active_))
return;
layer_tree_host_impl_->active_tree()->UpdateScrollbarGeometries();
-
- // TODO(arakeri): The animation needs to be readjusted if the scroller length
- // changes. Tracked here: crbug.com/972485
- float scroll_layer_length =
- currently_captured_scrollbar_->scroll_layer_length();
+ float scroll_layer_length = scrollbar->scroll_layer_length();
gfx::ScrollOffset current_offset =
scroll_tree.current_scroll_offset(scroll_node->element_id);
@@ -523,8 +535,7 @@ void ScrollbarController::StartAutoScrollAnimation(
// value indicates forwards scrolling.
const float target_offset = velocity < 0 ? 0 : scroll_layer_length;
const gfx::Vector2dF target_offset_vector =
- currently_captured_scrollbar_->orientation() ==
- ScrollbarOrientation::VERTICAL
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::Vector2dF(current_offset.x(), target_offset)
: gfx::Vector2dF(target_offset, current_offset.y());
@@ -560,8 +571,7 @@ InputHandlerPointerResult ScrollbarController::HandlePointerUp(
cancelable_autoscroll_task_.reset();
}
- drag_state_ = base::nullopt;
- autoscroll_state_ = base::nullopt;
+ ResetState();
return scroll_result;
}
@@ -580,6 +590,7 @@ LayerImpl* ScrollbarController::GetLayerHitByPoint(
}
int ScrollbarController::GetScrollDeltaForScrollbarPart(
+ const ScrollbarLayerImplBase* scrollbar,
const ScrollbarPart scrollbar_part,
const bool shift_modifier) {
int scroll_delta = 0;
@@ -589,20 +600,19 @@ int ScrollbarController::GetScrollDeltaForScrollbarPart(
switch (scrollbar_part) {
case ScrollbarPart::BACK_BUTTON:
case ScrollbarPart::FORWARD_BUTTON:
- scroll_delta = kPixelsPerLineStep;
+ scroll_delta = kPixelsPerLineStep * ScreenSpaceScaleFactor();
break;
case ScrollbarPart::BACK_TRACK:
case ScrollbarPart::FORWARD_TRACK:
if (shift_modifier) {
- scroll_delta = GetScrollDeltaForShiftClick();
+ scroll_delta = GetScrollDeltaForAbsoluteJump(scrollbar);
break;
}
owner_scroll_layer =
layer_tree_host_impl_->active_tree()->ScrollableLayerByElementId(
- currently_captured_scrollbar_->scroll_element_id());
+ scrollbar->scroll_element_id());
viewport_length =
- currently_captured_scrollbar_->orientation() ==
- ScrollbarOrientation::VERTICAL
+ scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? owner_scroll_layer->scroll_container_bounds().height()
: (owner_scroll_layer->scroll_container_bounds().width());
scroll_delta = viewport_length * kMinFractionToStepWhenPaging;
@@ -611,7 +621,7 @@ int ScrollbarController::GetScrollDeltaForScrollbarPart(
scroll_delta = 0;
}
- return scroll_delta * ScreenSpaceScaleFactor();
+ return scroll_delta;
}
float ScrollbarController::ScreenSpaceScaleFactor() const {
@@ -622,11 +632,13 @@ float ScrollbarController::ScreenSpaceScaleFactor() const {
// on arrows would be incorrectly calculated as 80px instead of 40px. This is
// also necessary to ensure that hit testing works as intended.
return layer_tree_host_impl_->settings().use_zoom_for_dsf
- ? layer_tree_host_impl_->active_tree()->device_scale_factor()
+ ? layer_tree_host_impl_->active_tree()
+ ->painted_device_scale_factor()
: 1.f;
}
gfx::PointF ScrollbarController::GetScrollbarRelativePosition(
+ const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF position_in_widget,
bool* clipped) {
gfx::Transform inverse_screen_space_transform(
@@ -639,7 +651,7 @@ gfx::PointF ScrollbarController::GetScrollbarRelativePosition(
? 1.f / layer_tree_host_impl_->active_tree()->device_scale_factor()
: 1.f;
gfx::Transform scaled_screen_space_transform(
- currently_captured_scrollbar_->ScreenSpaceTransform());
+ scrollbar->ScreenSpaceTransform());
scaled_screen_space_transform.PostScale(scale, scale);
if (!scaled_screen_space_transform.GetInverse(
&inverse_screen_space_transform))
@@ -651,60 +663,61 @@ gfx::PointF ScrollbarController::GetScrollbarRelativePosition(
// Determines the ScrollbarPart based on the position_in_widget.
ScrollbarPart ScrollbarController::GetScrollbarPartFromPointerDown(
+ const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF position_in_widget) {
// position_in_widget needs to be transformed and made relative to the
// scrollbar layer because hit testing assumes layer relative coordinates.
bool clipped = false;
const gfx::PointF scroller_relative_position(
- GetScrollbarRelativePosition(position_in_widget, &clipped));
+ GetScrollbarRelativePosition(scrollbar, position_in_widget, &clipped));
if (clipped)
return ScrollbarPart::NO_PART;
- return currently_captured_scrollbar_->IdentifyScrollbarPart(
- scroller_relative_position);
+ return scrollbar->IdentifyScrollbarPart(scroller_relative_position);
}
// Determines the corresponding rect for the given scrollbar part.
gfx::Rect ScrollbarController::GetRectForScrollbarPart(
+ const ScrollbarLayerImplBase* scrollbar,
const ScrollbarPart scrollbar_part) {
if (scrollbar_part == ScrollbarPart::BACK_BUTTON)
- return currently_captured_scrollbar_->BackButtonRect();
+ return scrollbar->BackButtonRect();
if (scrollbar_part == ScrollbarPart::FORWARD_BUTTON)
- return currently_captured_scrollbar_->ForwardButtonRect();
+ return scrollbar->ForwardButtonRect();
if (scrollbar_part == ScrollbarPart::BACK_TRACK)
- return currently_captured_scrollbar_->BackTrackRect();
+ return scrollbar->BackTrackRect();
if (scrollbar_part == ScrollbarPart::FORWARD_TRACK)
- return currently_captured_scrollbar_->ForwardTrackRect();
+ return scrollbar->ForwardTrackRect();
return gfx::Rect(0, 0);
}
// Determines the scroll offsets based on the ScrollbarPart and the scrollbar
// orientation.
gfx::ScrollOffset ScrollbarController::GetScrollOffsetForScrollbarPart(
+ const ScrollbarLayerImplBase* scrollbar,
const ScrollbarPart scrollbar_part,
- const ScrollbarOrientation orientation,
const bool shift_modifier) {
float scroll_delta =
- GetScrollDeltaForScrollbarPart(scrollbar_part, shift_modifier);
+ GetScrollDeltaForScrollbarPart(scrollbar, scrollbar_part, shift_modifier);
// See CreateScrollStateForGesture for more information on how these values
// will be interpreted.
if (scrollbar_part == ScrollbarPart::BACK_BUTTON) {
- return orientation == ScrollbarOrientation::VERTICAL
+ return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, -scroll_delta) // Up arrow
: gfx::ScrollOffset(-scroll_delta, 0); // Left arrow
} else if (scrollbar_part == ScrollbarPart::FORWARD_BUTTON) {
- return orientation == ScrollbarOrientation::VERTICAL
+ return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, scroll_delta) // Down arrow
: gfx::ScrollOffset(scroll_delta, 0); // Right arrow
} else if (scrollbar_part == ScrollbarPart::BACK_TRACK) {
- return orientation == ScrollbarOrientation::VERTICAL
+ return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, -scroll_delta) // Track click up
: gfx::ScrollOffset(-scroll_delta, 0); // Track click left
} else if (scrollbar_part == ScrollbarPart::FORWARD_TRACK) {
- return orientation == ScrollbarOrientation::VERTICAL
+ return scrollbar->orientation() == ScrollbarOrientation::VERTICAL
? gfx::ScrollOffset(0, scroll_delta) // Track click down
: gfx::ScrollOffset(scroll_delta, 0); // Track click right
}
diff --git a/chromium/cc/input/scrollbar_controller.h b/chromium/cc/input/scrollbar_controller.h
index e1b13dc2e03..80a49f3f424 100644
--- a/chromium/cc/input/scrollbar_controller.h
+++ b/chromium/cc/input/scrollbar_controller.h
@@ -32,13 +32,11 @@ class CC_EXPORT ScrollbarController {
// needed to determine whether we should set up the autoscrolling in the
// forwards or the backwards direction.
void StartAutoScrollAnimation(float velocity,
- ElementId element_id,
+ const ScrollbarLayerImplBase* scrollbar,
ScrollbarPart pressed_scrollbar_part);
bool ScrollbarScrollIsActive() { return scrollbar_scroll_is_active_; }
- ScrollbarOrientation orientation() {
- return currently_captured_scrollbar_->orientation();
- }
-
+ void DidUnregisterScrollbar(ElementId element_id);
+ ScrollbarLayerImplBase* ScrollbarLayer();
void WillBeginImplFrame();
private:
@@ -74,44 +72,62 @@ class CC_EXPORT ScrollbarController {
float scroll_position_at_start_;
};
+ struct CC_EXPORT CapturedScrollbarMetadata {
+ // Needed to retrieve the ScrollbarSet for a particular ElementId.
+ ElementId scroll_element_id;
+
+ // Needed to identify the correct scrollbar from the ScrollbarSet.
+ ScrollbarOrientation orientation;
+ };
+
// Returns the DSF based on whether use-zoom-for-dsf is enabled.
float ScreenSpaceScaleFactor() const;
// Helper to convert scroll offset to autoscroll velocity.
- float InitialDeltaToAutoscrollVelocity(gfx::ScrollOffset scroll_offset) const;
+ float InitialDeltaToAutoscrollVelocity(
+ const ScrollbarLayerImplBase* scrollbar,
+ gfx::ScrollOffset scroll_offset) const;
// Returns the hit tested ScrollbarPart based on the position_in_widget.
ScrollbarPart GetScrollbarPartFromPointerDown(
+ const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF position_in_widget);
// Returns scroll offsets based on which ScrollbarPart was hit tested.
gfx::ScrollOffset GetScrollOffsetForScrollbarPart(
+ const ScrollbarLayerImplBase* scrollbar,
const ScrollbarPart scrollbar_part,
- const ScrollbarOrientation orientation,
const bool shift_modifier);
// Returns the rect for the ScrollbarPart.
- gfx::Rect GetRectForScrollbarPart(const ScrollbarPart scrollbar_part);
+ gfx::Rect GetRectForScrollbarPart(const ScrollbarLayerImplBase* scrollbar,
+ const ScrollbarPart scrollbar_part);
LayerImpl* GetLayerHitByPoint(const gfx::PointF position_in_widget);
- int GetScrollDeltaForScrollbarPart(const ScrollbarPart scrollbar_part,
+ int GetScrollDeltaForScrollbarPart(const ScrollbarLayerImplBase* scrollbar,
+ const ScrollbarPart scrollbar_part,
const bool shift_modifier);
// Makes position_in_widget relative to the scrollbar.
- gfx::PointF GetScrollbarRelativePosition(const gfx::PointF position_in_widget,
- bool* clipped);
+ gfx::PointF GetScrollbarRelativePosition(
+ const ScrollbarLayerImplBase* scrollbar,
+ const gfx::PointF position_in_widget,
+ bool* clipped);
// Decides if the scroller should snap to the offset that it was originally at
// (i.e the offset before the thumb drag).
- bool SnapToDragOrigin(const gfx::PointF pointer_position_in_widget);
+ bool SnapToDragOrigin(const ScrollbarLayerImplBase* scrollbar,
+ const gfx::PointF pointer_position_in_widget);
// Decides whether a track autoscroll should be aborted (or restarted) due to
// the thumb reaching the pointer or the pointer leaving (or re-entering) the
// bounds.
void RecomputeAutoscrollStateIfNeeded();
+ void ResetState();
- // Shift + click is expected to do a non-animated jump to a certain offset.
- float GetScrollDeltaForShiftClick();
+ // Shift (or "Option" in case of Mac) + click is expected to do a non-animated
+ // jump to a certain offset.
+ float GetScrollDeltaForAbsoluteJump(const ScrollbarLayerImplBase* scrollbar);
// Determines if the delta needs to be animated.
ui::input_types::ScrollGranularity Granularity(
@@ -121,25 +137,29 @@ class CC_EXPORT ScrollbarController {
// Calculates the scroll_offset based on position_in_widget and
// drag_anchor_relative_to_thumb_.
gfx::ScrollOffset GetScrollOffsetForDragPosition(
+ const ScrollbarLayerImplBase* scrollbar,
const gfx::PointF pointer_position_in_widget);
// Returns a Vector2dF for position_in_widget relative to the scrollbar thumb.
- gfx::Vector2dF GetThumbRelativePoint(const gfx::PointF position_in_widget);
+ gfx::Vector2dF GetThumbRelativePoint(const ScrollbarLayerImplBase* scrollbar,
+ const gfx::PointF position_in_widget);
// Returns the ratio of the scroller length to the scrollbar length. This is
// needed to scale the scroll delta for thumb drag.
- float GetScrollerToScrollbarRatio();
+ float GetScrollerToScrollbarRatio(const ScrollbarLayerImplBase* scrollbar);
LayerTreeHostImpl* layer_tree_host_impl_;
// Used to safeguard against firing GSE without firing GSB and GSU. For
// example, if mouse is pressed outside the scrollbar but released after
// moving inside the scrollbar, a GSE will get queued up without this flag.
bool scrollbar_scroll_is_active_;
- const ScrollbarLayerImplBase* currently_captured_scrollbar_;
// This is relative to the RenderWidget's origin.
gfx::PointF last_known_pointer_position_;
+ // Set only while interacting with the scrollbar (eg: drag, click etc).
+ base::Optional<CapturedScrollbarMetadata> captured_scrollbar_metadata_;
+
// Holds information pertaining to autoscrolling. This member is empty if and
// only if an autoscroll is *not* in progress.
base::Optional<AutoScrollState> autoscroll_state_;
@@ -157,7 +177,7 @@ class CC_EXPORT ScrollbarController {
// pointermoves are not VSync aligned).
bool drag_processed_for_current_frame_;
- std::unique_ptr<base::CancelableClosure> cancelable_autoscroll_task_;
+ std::unique_ptr<base::CancelableOnceClosure> cancelable_autoscroll_task_;
};
} // namespace cc
diff --git a/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc b/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc
index d01e1ac2bcd..8988bf72e65 100644
--- a/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc
+++ b/chromium/cc/input/single_scrollbar_animation_controller_thinning.cc
@@ -173,8 +173,9 @@ void SingleScrollbarAnimationControllerThinning::DidMouseMove(
if (!scrollbar)
return;
- float distance_to_scrollbar_track = DistanceToScrollbarPart(
- device_viewport_point, *scrollbar, ScrollbarPart::TRACK);
+ float distance_to_scrollbar_track =
+ DistanceToScrollbarPart(device_viewport_point, *scrollbar,
+ ScrollbarPart::TRACK_BUTTONS_TICKMARKS);
float distance_to_scrollbar_thumb = DistanceToScrollbarPart(
device_viewport_point, *scrollbar, ScrollbarPart::THUMB);
diff --git a/chromium/cc/input/snap_fling_controller.cc b/chromium/cc/input/snap_fling_controller.cc
index 4c8e485bcff..eba05d722a6 100644
--- a/chromium/cc/input/snap_fling_controller.cc
+++ b/chromium/cc/input/snap_fling_controller.cc
@@ -50,8 +50,8 @@ bool SnapFlingController::HandleGestureScrollUpdate(
SnapFlingCurve::EstimateDisplacement(info.delta);
gfx::Vector2dF target_offset, start_offset;
- if (!client_->GetSnapFlingInfo(ending_displacement, &start_offset,
- &target_offset)) {
+ if (!client_->GetSnapFlingInfoAndSetSnapTarget(
+ ending_displacement, &start_offset, &target_offset)) {
state_ = State::kIgnored;
return false;
}
diff --git a/chromium/cc/input/snap_fling_controller.h b/chromium/cc/input/snap_fling_controller.h
index c5ad511d91c..184d9045d8a 100644
--- a/chromium/cc/input/snap_fling_controller.h
+++ b/chromium/cc/input/snap_fling_controller.h
@@ -23,9 +23,10 @@ class SnapFlingCurve;
// are in the same coordinate space.
class SnapFlingClient {
public:
- virtual bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement,
- gfx::Vector2dF* out_initial_position,
- gfx::Vector2dF* out_target_position) const = 0;
+ virtual bool GetSnapFlingInfoAndSetSnapTarget(
+ const gfx::Vector2dF& natural_displacement,
+ gfx::Vector2dF* out_initial_position,
+ gfx::Vector2dF* out_target_position) const = 0;
virtual gfx::Vector2dF ScrollByForSnapFling(const gfx::Vector2dF& delta) = 0;
virtual void ScrollEndForSnapFling() = 0;
virtual void RequestAnimationForSnapFling() = 0;
diff --git a/chromium/cc/input/snap_fling_controller_unittest.cc b/chromium/cc/input/snap_fling_controller_unittest.cc
index ebbf5b18cfd..aca8075efb5 100644
--- a/chromium/cc/input/snap_fling_controller_unittest.cc
+++ b/chromium/cc/input/snap_fling_controller_unittest.cc
@@ -14,7 +14,7 @@ namespace {
class MockSnapFlingClient : public SnapFlingClient {
public:
- MOCK_CONST_METHOD3(GetSnapFlingInfo,
+ MOCK_CONST_METHOD3(GetSnapFlingInfoAndSetSnapTarget,
bool(const gfx::Vector2dF& natural_displacement,
gfx::Vector2dF* initial_offset,
gfx::Vector2dF* target_offset));
@@ -75,8 +75,8 @@ TEST_F(SnapFlingControllerTest, CreatesAndAnimatesCurveOnFirstInertialGSU) {
gsu.delta = gfx::Vector2dF(0, -10);
gsu.is_in_inertial_phase = true;
- EXPECT_CALL(mock_client_,
- GetSnapFlingInfo(testing::_, testing::_, testing::_))
+ EXPECT_CALL(mock_client_, GetSnapFlingInfoAndSetSnapTarget(
+ testing::_, testing::_, testing::_))
.WillOnce(
testing::DoAll(testing::SetArgPointee<1>(gfx::Vector2dF(0, 0)),
testing::SetArgPointee<2>(gfx::Vector2dF(0, 100)),
@@ -92,8 +92,8 @@ TEST_F(SnapFlingControllerTest, DoesNotHandleNonInertialGSU) {
gsu.delta = gfx::Vector2dF(0, -10);
gsu.is_in_inertial_phase = false;
- EXPECT_CALL(mock_client_,
- GetSnapFlingInfo(testing::_, testing::_, testing::_))
+ EXPECT_CALL(mock_client_, GetSnapFlingInfoAndSetSnapTarget(
+ testing::_, testing::_, testing::_))
.Times(0);
EXPECT_CALL(mock_client_, RequestAnimationForSnapFling()).Times(0);
EXPECT_CALL(mock_client_, ScrollByForSnapFling(testing::_)).Times(0);
diff --git a/chromium/cc/input/snap_selection_strategy.cc b/chromium/cc/input/snap_selection_strategy.cc
index 7ea5fe4d431..e2df143a220 100644
--- a/chromium/cc/input/snap_selection_strategy.cc
+++ b/chromium/cc/input/snap_selection_strategy.cc
@@ -10,9 +10,10 @@ std::unique_ptr<SnapSelectionStrategy>
SnapSelectionStrategy::CreateForEndPosition(
const gfx::ScrollOffset& current_position,
bool scrolled_x,
- bool scrolled_y) {
+ bool scrolled_y,
+ SnapTargetsPrioritization prioritization) {
return std::make_unique<EndPositionStrategy>(current_position, scrolled_x,
- scrolled_y);
+ scrolled_y, prioritization);
}
std::unique_ptr<SnapSelectionStrategy>
@@ -30,6 +31,14 @@ SnapSelectionStrategy::CreateForEndAndDirection(
displacement);
}
+std::unique_ptr<SnapSelectionStrategy>
+SnapSelectionStrategy::CreateForTargetElement(
+ gfx::ScrollOffset current_position) {
+ return std::make_unique<EndPositionStrategy>(
+ current_position, true /* scrolled_x */, true /* scrolled_y */,
+ SnapTargetsPrioritization::kRequire);
+}
+
bool SnapSelectionStrategy::HasIntendedDirection() const {
return true;
}
@@ -45,6 +54,10 @@ bool SnapSelectionStrategy::IsValidSnapArea(SearchAxis axis,
: area.scroll_snap_align.alignment_block != SnapAlignment::kNone;
}
+bool SnapSelectionStrategy::ShouldPrioritizeSnapTargets() const {
+ return false;
+}
+
bool EndPositionStrategy::ShouldSnapOnX() const {
return scrolled_x_;
}
@@ -72,6 +85,10 @@ bool EndPositionStrategy::HasIntendedDirection() const {
return false;
}
+bool EndPositionStrategy::ShouldPrioritizeSnapTargets() const {
+ return snap_targets_prioritization_ == SnapTargetsPrioritization::kRequire;
+}
+
const base::Optional<SnapSearchResult>& EndPositionStrategy::PickBestResult(
const base::Optional<SnapSearchResult>& closest,
const base::Optional<SnapSearchResult>& covering) const {
diff --git a/chromium/cc/input/snap_selection_strategy.h b/chromium/cc/input/snap_selection_strategy.h
index 4b2fc2e38e4..f3dca1fc47f 100644
--- a/chromium/cc/input/snap_selection_strategy.h
+++ b/chromium/cc/input/snap_selection_strategy.h
@@ -12,6 +12,7 @@
namespace cc {
enum class SnapStopAlwaysFilter { kIgnore, kRequire };
+enum class SnapTargetsPrioritization { kIgnore, kRequire };
// This class represents an abstract strategy that decide which snap selection
// should be considered valid. There are concrete implementations for three core
@@ -24,7 +25,9 @@ class CC_EXPORT SnapSelectionStrategy {
static std::unique_ptr<SnapSelectionStrategy> CreateForEndPosition(
const gfx::ScrollOffset& current_position,
bool scrolled_x,
- bool scrolled_y);
+ bool scrolled_y,
+ SnapTargetsPrioritization prioritization =
+ SnapTargetsPrioritization::kIgnore);
static std::unique_ptr<SnapSelectionStrategy> CreateForDirection(
gfx::ScrollOffset current_position,
gfx::ScrollOffset step,
@@ -33,10 +36,20 @@ class CC_EXPORT SnapSelectionStrategy {
gfx::ScrollOffset current_position,
gfx::ScrollOffset displacement);
+ // Creates a selection strategy that attempts to snap to previously snapped
+ // targets if possible, but defaults to finding the closest snap point if
+ // the target no longer exists.
+ static std::unique_ptr<SnapSelectionStrategy> CreateForTargetElement(
+ gfx::ScrollOffset current_position);
+
// Returns whether it's snappable on x or y depending on the scroll performed.
virtual bool ShouldSnapOnX() const = 0;
virtual bool ShouldSnapOnY() const = 0;
+ // Returns whether snapping should attempt to snap to the previously snapped
+ // area if possible.
+ virtual bool ShouldPrioritizeSnapTargets() const;
+
// Returns the end position of the scroll if no snap interferes.
virtual gfx::ScrollOffset intended_position() const = 0;
// Returns the scroll position from which the snap position should minimize
@@ -88,10 +101,12 @@ class EndPositionStrategy : public SnapSelectionStrategy {
public:
EndPositionStrategy(const gfx::ScrollOffset& current_position,
bool scrolled_x,
- bool scrolled_y)
+ bool scrolled_y,
+ SnapTargetsPrioritization snap_targets_prioritization)
: SnapSelectionStrategy(current_position),
scrolled_x_(scrolled_x),
- scrolled_y_(scrolled_y) {}
+ scrolled_y_(scrolled_y),
+ snap_targets_prioritization_(snap_targets_prioritization) {}
~EndPositionStrategy() override = default;
bool ShouldSnapOnX() const override;
@@ -102,6 +117,7 @@ class EndPositionStrategy : public SnapSelectionStrategy {
bool IsValidSnapPosition(SearchAxis axis, float position) const override;
bool HasIntendedDirection() const override;
+ bool ShouldPrioritizeSnapTargets() const override;
const base::Optional<SnapSearchResult>& PickBestResult(
const base::Optional<SnapSearchResult>& closest,
@@ -111,6 +127,7 @@ class EndPositionStrategy : public SnapSelectionStrategy {
// Whether the x axis and y axis have been scrolled in this scroll gesture.
const bool scrolled_x_;
const bool scrolled_y_;
+ SnapTargetsPrioritization snap_targets_prioritization_;
};
// Examples for intended direction scrolls include
diff --git a/chromium/cc/ipc/BUILD.gn b/chromium/cc/ipc/BUILD.gn
new file mode 100644
index 00000000000..8bcef572b7b
--- /dev/null
+++ b/chromium/cc/ipc/BUILD.gn
@@ -0,0 +1,22 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//cc/cc.gni")
+
+cc_component("ipc") {
+ output_name = "cc_ipc"
+
+ sources = [
+ "cc_param_traits.cc",
+ "cc_param_traits_macros.h",
+ ]
+
+ defines = [ "IS_CC_IPC_IMPL" ]
+
+ public_deps = [
+ "//base",
+ "//cc",
+ "//ipc",
+ ]
+}
diff --git a/chromium/cc/ipc/OWNERS b/chromium/cc/ipc/OWNERS
new file mode 100644
index 00000000000..146c3c3cd62
--- /dev/null
+++ b/chromium/cc/ipc/OWNERS
@@ -0,0 +1,2 @@
+per-file *_param_traits*.*=set noparent
+per-file *_param_traits*.*=file://ipc/SECURITY_OWNERS
diff --git a/chromium/cc/ipc/README.md b/chromium/cc/ipc/README.md
new file mode 100644
index 00000000000..0e3e14f1012
--- /dev/null
+++ b/chromium/cc/ipc/README.md
@@ -0,0 +1,12 @@
+# cc/ipc
+
+[TOC]
+
+## Overview
+
+cc/ipc provides Chrome IPC legacy param trait validators. cc based
+structures that are defined in C++ and have mojo based NativeEnum
+definitions require validators. See cc/mojom for the mojo definitions.
+Eventually all cc based structures should be defined solely in
+mojo and then this directory can be removed. However, this will
+not happen until all structures are sent via mojo only.
diff --git a/chromium/cc/ipc/cc_param_traits.cc b/chromium/cc/ipc/cc_param_traits.cc
new file mode 100644
index 00000000000..14560bf0620
--- /dev/null
+++ b/chromium/cc/ipc/cc_param_traits.cc
@@ -0,0 +1,25 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/ipc/cc_param_traits_macros.h"
+#include "ipc/param_traits_write_macros.h"
+
+namespace IPC {
+#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
+#include "cc/ipc/cc_param_traits_macros.h"
+} // namespace IPC
+
+// Generate param traits read methods.
+#include "ipc/param_traits_read_macros.h"
+namespace IPC {
+#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
+#include "cc/ipc/cc_param_traits_macros.h"
+} // namespace IPC
+
+// Generate param traits log methods.
+#include "ipc/param_traits_log_macros.h"
+namespace IPC {
+#undef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
+#include "cc/ipc/cc_param_traits_macros.h"
+} // namespace IPC
diff --git a/chromium/cc/ipc/cc_param_traits_macros.h b/chromium/cc/ipc/cc_param_traits_macros.h
new file mode 100644
index 00000000000..2e76c288790
--- /dev/null
+++ b/chromium/cc/ipc/cc_param_traits_macros.h
@@ -0,0 +1,17 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_IPC_CC_PARAM_TRAITS_MACROS_H_
+#define CC_IPC_CC_PARAM_TRAITS_MACROS_H_
+
+#include "base/component_export.h"
+#include "cc/input/touch_action.h"
+#include "ipc/ipc_message_macros.h"
+
+#undef IPC_MESSAGE_EXPORT
+#define IPC_MESSAGE_EXPORT COMPONENT_EXPORT(CC_IPC)
+
+IPC_ENUM_TRAITS_MAX_VALUE(cc::TouchAction, cc::TouchAction::kTouchActionMax)
+
+#endif // CC_IPC_CC_PARAM_TRAITS_MACROS_H_
diff --git a/chromium/cc/layers/heads_up_display_layer_impl.cc b/chromium/cc/layers/heads_up_display_layer_impl.cc
index 4d82dfede6c..e2863170ba2 100644
--- a/chromium/cc/layers/heads_up_display_layer_impl.cc
+++ b/chromium/cc/layers/heads_up_display_layer_impl.cc
@@ -37,6 +37,7 @@
#include "components/viz/common/quads/texture_draw_quad.h"
#include "components/viz/common/resources/bitmap_allocation.h"
#include "components/viz/common/resources/platform_color.h"
+#include "gpu/GLES2/gl2extchromium.h"
#include "gpu/command_buffer/client/context_support.h"
#include "gpu/command_buffer/client/gles2_interface.h"
#include "gpu/command_buffer/client/raster_interface.h"
@@ -370,7 +371,9 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
} else {
auto* gl = context_provider->ContextGL();
GLuint mailbox_texture_id =
- gl->CreateAndConsumeTextureCHROMIUM(backing->mailbox.name);
+ gl->CreateAndTexStorage2DSharedImageCHROMIUM(backing->mailbox.name);
+ gl->BeginSharedImageAccessDirectCHROMIUM(
+ mailbox_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
{
ScopedGpuRaster scoped_gpu_raster(context_provider);
@@ -389,6 +392,7 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
DrawHudContents(&canvas);
}
+ gl->EndSharedImageAccessDirectCHROMIUM(mailbox_texture_id);
gl->DeleteTextures(1, &mailbox_texture_id);
backing->mailbox_sync_token =
viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
@@ -414,8 +418,12 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
TRACE_EVENT0("cc", "UploadHudTexture");
SkPixmap pixmap;
staging_surface_->peekPixels(&pixmap);
+
GLuint mailbox_texture_id =
- gl->CreateAndConsumeTextureCHROMIUM(backing->mailbox.name);
+ gl->CreateAndTexStorage2DSharedImageCHROMIUM(backing->mailbox.name);
+ gl->BeginSharedImageAccessDirectCHROMIUM(
+ mailbox_texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
+
gl->BindTexture(backing->texture_target, mailbox_texture_id);
DCHECK(GLSupportsFormat(pool_resource.format()));
// We should use gl compatible format for skia SW rasterization.
@@ -424,6 +432,8 @@ void HeadsUpDisplayLayerImpl::UpdateHudTexture(
gl->TexSubImage2D(
backing->texture_target, 0, 0, 0, pool_resource.size().width(),
pool_resource.size().height(), format, type, pixmap.addr());
+
+ gl->EndSharedImageAccessDirectCHROMIUM(mailbox_texture_id);
gl->DeleteTextures(1, &mailbox_texture_id);
backing->mailbox_sync_token =
viz::ClientResourceProvider::GenerateSyncTokenHelper(gl);
@@ -884,10 +894,6 @@ SkRect HeadsUpDisplayLayerImpl::DrawGpuRasterizationStatus(PaintCanvas* canvas,
status = "off (device)";
color = SK_ColorRED;
break;
- case GpuRasterizationStatus::MSAA_CONTENT:
- status = "MSAA (content)";
- color = SK_ColorCYAN;
- break;
}
if (status.empty())
@@ -1031,6 +1037,14 @@ void HeadsUpDisplayLayerImpl::DrawDebugRects(
stroke_width = DebugColors::NonFastScrollableRectBorderWidth();
label_text = "repaints on scroll";
break;
+ case MAIN_THREAD_SCROLLING_REASON_RECT_TYPE:
+ stroke_color = DebugColors::MainThreadScrollingReasonRectBorderColor();
+ fill_color = DebugColors::MainThreadScrollingReasonRectFillColor();
+ stroke_width = DebugColors::MainThreadScrollingReasonRectBorderWidth();
+ label_text = "main thread scrolling: ";
+ label_text.append(base::ToLowerASCII(MainThreadScrollingReason::AsText(
+ debug_rects[i].main_thread_scrolling_reasons)));
+ break;
case ANIMATION_BOUNDS_RECT_TYPE:
stroke_color = DebugColors::LayerAnimationBoundsBorderColor();
fill_color = DebugColors::LayerAnimationBoundsFillColor();
diff --git a/chromium/cc/layers/layer.cc b/chromium/cc/layers/layer.cc
index 063e39f34f7..6abcee0e961 100644
--- a/chromium/cc/layers/layer.cc
+++ b/chromium/cc/layers/layer.cc
@@ -18,10 +18,8 @@
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "cc/base/simple_enclosed_region.h"
-#include "cc/layers/layer_client.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/picture_layer.h"
-#include "cc/tiles/frame_viewer_instrumentation.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/layer_tree_host.h"
@@ -69,17 +67,14 @@ struct SameSizeAsLayer : public base::RefCounted<SameSizeAsLayer> {
Region non_fast_scrollable_region;
TouchActionRegion touch_action_region;
ElementId element_id;
- base::WeakPtr<LayerClient> client;
- std::unique_ptr<base::trace_event::TracedValue> debug_info;
base::RepeatingCallback<void()> did_scroll_callback;
std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests;
} inputs;
- int int_fields[7];
+ int int_fields[6];
gfx::Vector2dF offset;
unsigned bitfields;
SkColor safe_opaque_background_color;
- int owner_node_id;
- uint64_t compositing_reasons;
+ void* debug_info;
};
static_assert(sizeof(Layer) == sizeof(SameSizeAsLayer),
@@ -87,6 +82,10 @@ static_assert(sizeof(Layer) == sizeof(SameSizeAsLayer),
base::AtomicSequenceNumber g_next_layer_id;
+LayerDebugInfo::LayerDebugInfo() = default;
+LayerDebugInfo::LayerDebugInfo(const LayerDebugInfo&) = default;
+LayerDebugInfo::~LayerDebugInfo() = default;
+
Layer::Inputs::Inputs(int layer_id)
: mask_layer(nullptr),
layer_id(layer_id),
@@ -122,7 +121,6 @@ Layer::Layer()
layer_tree_host_(nullptr),
// Layer IDs start from 1.
inputs_(g_next_layer_id.GetNext() + 1),
- paint_count_(0),
num_descendants_that_draw_content_(0),
transform_tree_index_(TransformTree::kInvalidNodeId),
effect_tree_index_(EffectTree::kInvalidNodeId),
@@ -140,9 +138,7 @@ Layer::Layer()
has_transform_node_(false),
has_clip_node_(false),
subtree_has_copy_request_(false),
- safe_opaque_background_color_(0),
- owner_node_id_(0),
- compositing_reasons_(0) {}
+ safe_opaque_background_color_(0) {}
Layer::~Layer() {
// Our parent should be holding a reference to us so there should be no
@@ -977,6 +973,13 @@ void Layer::UpdateScrollOffset(const gfx::ScrollOffset& scroll_offset) {
property_trees.transform_tree.set_needs_update(true);
}
+void Layer::SetDidScrollCallback(
+ base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)>
+ callback) {
+ DCHECK(!layer_tree_host_ || !layer_tree_host_->IsUsingLayerLists());
+ inputs_.did_scroll_callback = std::move(callback);
+}
+
void Layer::SetScrollable(const gfx::Size& bounds) {
DCHECK(IsPropertyChangeAllowed());
if (inputs_.scrollable && inputs_.scroll_container_bounds == bounds)
@@ -1213,18 +1216,33 @@ void Layer::SetPropertyTreesNeedRebuild() {
layer_tree_host_->property_trees()->needs_rebuild = true;
}
-#if DCHECK_IS_ON()
+LayerDebugInfo& Layer::EnsureDebugInfo() {
+ if (!debug_info_) {
+ debug_info_ = std::make_unique<LayerDebugInfo>();
+ // We just enabled debug info collection. Force PushPropertiesTo() to ensure
+ // the first layer tree snapshot contains the debug info. Otherwise we will
+ // push debug_info when we have other changes to push.
+ SetNeedsPushProperties();
+ }
+ return *debug_info_;
+}
+
+void Layer::ClearDebugInfo() {
+ if (!debug_info_)
+ return;
+
+ debug_info_.reset();
+ SetNeedsPushProperties();
+}
+
std::string Layer::DebugName() const {
- return inputs_.client ? inputs_.client->LayerDebugName(this) : "";
+ return debug_info_ ? debug_info_->name : "";
}
-#endif
std::string Layer::ToString() const {
return base::StringPrintf(
"layer_id: %d\n"
-#if DCHECK_IS_ON()
" name: %s\n"
-#endif
" Bounds: %s\n"
" ElementId: %s\n"
" OffsetToTransformParent: %s\n"
@@ -1235,9 +1253,7 @@ std::string Layer::ToString() const {
" scroll_tree_index: %d\n"
" transform_tree_index: %d\n",
id(),
-#if DCHECK_IS_ON()
DebugName().c_str(),
-#endif
bounds().ToString().c_str(), element_id().ToString().c_str(),
offset_to_transform_parent().ToString().c_str(),
position().ToString().c_str(), scrollable(), clip_tree_index(),
@@ -1291,11 +1307,6 @@ void Layer::SetNeedsDisplayRect(const gfx::Rect& dirty_rect) {
layer_tree_host_->SetNeedsUpdateLayers();
}
-void Layer::SetLayerClient(base::WeakPtr<LayerClient> client) {
- inputs_.client = std::move(client);
- inputs_.debug_info = nullptr;
-}
-
bool Layer::IsSnappedToPixelGridInTarget() {
return false;
}
@@ -1318,7 +1329,6 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
layer->SetBackgroundColor(inputs_.background_color);
layer->SetSafeOpaqueBackgroundColor(safe_opaque_background_color_);
layer->SetBounds(inputs_.bounds);
- layer->SetDebugInfo(std::move(inputs_.debug_info));
layer->SetTransformTreeIndex(transform_tree_index());
layer->SetEffectTreeIndex(effect_tree_index());
layer->SetClipTreeIndex(clip_tree_index());
@@ -1372,16 +1382,13 @@ void Layer::PushPropertiesTo(LayerImpl* layer) {
if (needs_show_scrollbars_)
layer->set_needs_show_scrollbars(true);
- // If the main thread commits multiple times before the impl thread actually
- // draws, then damage tracking will become incorrect if we simply clobber the
- // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
- // union) any update changes that have occurred on the main thread.
- inputs_.update_rect.Union(layer->update_rect());
- layer->SetUpdateRect(inputs_.update_rect);
-
+ layer->UnionUpdateRect(inputs_.update_rect);
layer->SetHasWillChangeTransformHint(has_will_change_transform_hint());
layer->SetNeedsPushProperties();
+ // debug_info_->invalidations, if exist, will be cleared in the function.
+ layer->UpdateDebugInfo(debug_info_.get());
+
// Reset any state that should be cleared for the next update.
needs_show_scrollbars_ = false;
subtree_property_changed_ = false;
@@ -1442,20 +1449,6 @@ bool Layer::Update() {
return false;
}
-bool Layer::HasSlowPaths() const {
- return false;
-}
-
-bool Layer::HasNonAAPaint() const {
- return false;
-}
-
-void Layer::UpdateDebugInfo() {
- DCHECK(frame_viewer_instrumentation::IsTracingLayerTreeSnapshots());
- if (inputs_.client)
- inputs_.debug_info = inputs_.client->TakeDebugInfo(this);
-}
-
void Layer::SetSubtreePropertyChanged() {
if (subtree_property_changed_)
return;
@@ -1470,11 +1463,6 @@ void Layer::SetMayContainVideo(bool yes) {
SetNeedsPushProperties();
}
-void Layer::SetScrollbarsHiddenFromImplSide(bool hidden) {
- if (inputs_.client)
- inputs_.client->DidChangeScrollbarsHiddenIfOverlay(hidden);
-}
-
// On<Property>Animated is called due to an ongoing accelerated animation.
// Since this animation is also being run on the compositor thread, there
// is no need to request a commit to push this value over, so the value is
diff --git a/chromium/cc/layers/layer.h b/chromium/cc/layers/layer.h
index 054f3884a38..223ace706af 100644
--- a/chromium/cc/layers/layer.h
+++ b/chromium/cc/layers/layer.h
@@ -39,25 +39,37 @@
#include "ui/gfx/rrect_f.h"
#include "ui/gfx/transform.h"
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-}
-
namespace viz {
class CopyOutputRequest;
}
namespace cc {
-class LayerClient;
class LayerImpl;
class LayerTreeHost;
class LayerTreeHostCommon;
class LayerTreeImpl;
class PictureLayer;
+// For tracing and debugging. The info will be attached to this layer's tracing
+// output.
+struct LayerDebugInfo {
+ LayerDebugInfo();
+ LayerDebugInfo(const LayerDebugInfo&);
+ ~LayerDebugInfo();
+
+ std::string name;
+ NodeId owner_node_id = kInvalidNodeId;
+ int paint_count = 0;
+ std::vector<const char*> compositing_reasons;
+ struct Invalidation {
+ gfx::Rect rect;
+ const char* reason;
+ std::string client;
+ };
+ std::vector<Invalidation> invalidations;
+};
+
// Base class for composited layers. Special layer types are derived from
// this class. Each layer is an independent unit in the compositor, be that
// for transforming or for content. If a layer has content it can be
@@ -79,12 +91,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
Layer(const Layer&) = delete;
Layer& operator=(const Layer&) = delete;
- // Sets an optional client on this layer, that will be called when relevant
- // events happen. The client is a WeakPtr so it can be destroyed without
- // unsetting itself as the client.
- void SetLayerClient(base::WeakPtr<LayerClient> client);
- LayerClient* GetLayerClientForTesting() const { return inputs_.client.get(); }
-
// A unique and stable id for the Layer. Ids are always positive.
int id() const { return inputs_.layer_id; }
@@ -219,6 +225,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// SetNeedsDisplay() that have not been committed to the compositor thread.
const gfx::Rect& update_rect() const { return inputs_.update_rect; }
+ void ResetUpdateRectForTesting() { inputs_.update_rect = gfx::Rect(); }
+
// Set or get the rounded corner radii which is applied to the layer and its
// subtree (as if they are together as a single composited entity) when
// blitting into their target. Setting this makes the layer masked to bounds.
@@ -391,12 +399,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// asked to prepare content with Update(), if the scroll offset for the layer
// was changed by the InputHandlerClient, on the compositor thread (or on the
// main thread in single-thread mode). It may be set to a null callback, in
- // which case nothing is called.
- void set_did_scroll_callback(
- base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)>
- callback) {
- inputs_.did_scroll_callback = std::move(callback);
- }
+ // which case nothing is called. This is for layer tree mode only. Should use
+ // ScrollTree::SetScrollCallbacks() in layer list mode.
+ void SetDidScrollCallback(base::RepeatingCallback<
+ void(const gfx::ScrollOffset&, const ElementId&)>);
// Set or get if the layer and its subtree should be cached as a texture in
// the display compositor. This is used as an optimization when it is known
@@ -545,9 +551,9 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// display.
virtual sk_sp<SkPicture> GetPicture() const;
- // For tracing. Calls out to the LayerClient to get tracing data that will
- // be attached to this layer's tracing outputs under the 'debug_info' key.
- void UpdateDebugInfo();
+ const LayerDebugInfo* debug_info() const { return debug_info_.get(); }
+ LayerDebugInfo& EnsureDebugInfo();
+ void ClearDebugInfo();
// For telemetry testing. Runs a given test behaviour implemented in
// |benchmark| for this layer. The base class does nothing as benchmarks
@@ -574,23 +580,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// if there is anything new to commit. If all layers return false, the commit
// may be aborted.
virtual bool Update();
- // Internal method to be overriden by Layer subclasses that override Update()
- // and require rasterization. After Update() is called, this is immediately
- // called, and should return whether the layer will require rasterization of
- // paths that will be difficult/slow to raster. Only layers that do
- // rasterization via TileManager need to override this, other layers that have
- // content generated in other ways may leave it as the default.
- virtual bool HasSlowPaths() const;
- // Internal method to be overriden by Layer subclasses that override Update()
- // and require rasterization. After Update() is called, this is immediately
- // called, and should return whether the layer will require rasterization of a
- // drawing operation that must not be anti-aliased. In this case using MSAA to
- // antialias the entire layer's content would produce an incorrect result.
- // This result is considered sticky, once a layer returns true, so false
- // positives should be avoided. Only layers that do rasterization via
- // TileManager need to override this, other layers that have content generated
- // in other ways may leave it as the default.
- virtual bool HasNonAAPaint() const;
// Internal to property tree construction. This allows a layer to request that
// its transform should be snapped such that the layer aligns with the pixel
@@ -618,11 +607,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// was called before it.
void SetNeedsPushProperties();
- // Internal method to call the LayerClient, if there is one, to inform it when
- // overlay scrollbars have been completely hidden (due to lack of scrolling by
- // the user).
- void SetScrollbarsHiddenFromImplSide(bool hidden);
-
// Internal to property tree construction. A generation number for the
// property trees, to verify the layer's indices are pointers into the trees
// currently held by the LayerTreeHost. The number is updated when property
@@ -689,10 +673,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
return should_check_backface_visibility_;
}
-#if DCHECK_IS_ON()
// For debugging, containing information about the associated DOM, etc.
std::string DebugName() const;
-#endif
std::string ToString() const;
@@ -703,25 +685,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// in PropertyTreeManager when handling scroll offsets.
void SetNeedsCommit();
- // The following data are for profiling and debugging. They will be displayed
- // e.g. in the Layers panel of DevTools.
-
- // The compositing reasons of the layer. The values are defined in
- // third_party/blink/renderer/platform/graphics/compositing_reasons.h.
- void set_compositing_reasons(uint64_t compositing_reasons) {
- compositing_reasons_ = compositing_reasons;
- }
- uint64_t compositing_reasons() const { return compositing_reasons_; }
-
- // The id of the DOM node that owns this layer.
- void set_owner_node_id(int node_id) { owner_node_id_ = node_id; }
- int owner_node_id() const { return owner_node_id_; }
-
- // How many times this layer has been repainted.
- int paint_count() const { return paint_count_; }
-
- // End of data for profiling and debugging.
-
protected:
friend class LayerImpl;
friend class TreeSynchronizer;
@@ -760,7 +723,10 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
// be changed while the frame is being generated for commit.
bool IsPropertyChangeAllowed() const;
- void IncreasePaintCount() { ++paint_count_; }
+ void IncreasePaintCount() {
+ if (debug_info_)
+ ++debug_info_->paint_count;
+ }
base::AutoReset<bool> IgnoreSetNeedsCommit() {
return base::AutoReset<bool>(&ignore_set_needs_commit_, true);
@@ -885,10 +851,7 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
ElementId element_id;
- // The following elements can not and are not serialized.
- base::WeakPtr<LayerClient> client;
- std::unique_ptr<base::trace_event::TracedValue> debug_info;
-
+ // These for for layer tree mode (ui compositor) only.
base::RepeatingCallback<void(const gfx::ScrollOffset&, const ElementId&)>
did_scroll_callback;
std::vector<std::unique_ptr<viz::CopyOutputRequest>> copy_requests;
@@ -903,7 +866,6 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
Inputs inputs_;
- int paint_count_;
int num_descendants_that_draw_content_;
int transform_tree_index_;
int effect_tree_index_;
@@ -931,8 +893,8 @@ class CC_EXPORT Layer : public base::RefCounted<Layer> {
bool subtree_has_copy_request_ : 1;
SkColor safe_opaque_background_color_;
- int owner_node_id_;
- uint64_t compositing_reasons_;
+
+ std::unique_ptr<LayerDebugInfo> debug_info_;
};
} // namespace cc
diff --git a/chromium/cc/layers/layer_client.h b/chromium/cc/layers/layer_client.h
deleted file mode 100644
index 75aeff13ab6..00000000000
--- a/chromium/cc/layers/layer_client.h
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2013 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_LAYERS_LAYER_CLIENT_H_
-#define CC_LAYERS_LAYER_CLIENT_H_
-
-#include <memory>
-#include <string>
-
-#include "cc/cc_export.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-}
-}
-
-namespace cc {
-
-class Layer;
-
-class CC_EXPORT LayerClient {
- public:
- // Returns a pointer to a debug info object, if one has been computed.
- // If not, returns nullptr.
- // If the returned pointer is non-nullptr, the caller takes
- // ownership of the pointer.
- //
- // A pointer to the layer is provided for the convenience of layer clients
- // which service multiple layers.
- virtual std::unique_ptr<base::trace_event::TracedValue> TakeDebugInfo(
- const Layer* layer) = 0;
-
- virtual std::string LayerDebugName(const Layer* layer) const = 0;
-
- virtual void DidChangeScrollbarsHiddenIfOverlay(bool) = 0;
-
- protected:
- virtual ~LayerClient() {}
-};
-
-} // namespace cc
-
-#endif // CC_LAYERS_LAYER_CLIENT_H_
diff --git a/chromium/cc/layers/layer_impl.cc b/chromium/cc/layers/layer_impl.cc
index 6653d2cfc24..0b8ae026330 100644
--- a/chromium/cc/layers/layer_impl.cc
+++ b/chromium/cc/layers/layer_impl.cc
@@ -69,7 +69,6 @@ LayerImpl::LayerImpl(LayerTreeImpl* tree_impl,
clip_tree_index_(ClipTree::kInvalidNodeId),
scroll_tree_index_(ScrollTree::kInvalidNodeId),
current_draw_mode_(DRAW_MODE_NONE),
- debug_info_(nullptr),
has_will_change_transform_hint_(false),
needs_push_properties_(false),
is_scrollbar_(false),
@@ -102,10 +101,24 @@ ElementListType LayerImpl::GetElementTypeForAnimation() const {
return IsActive() ? ElementListType::ACTIVE : ElementListType::PENDING;
}
-void LayerImpl::SetDebugInfo(
- std::unique_ptr<base::trace_event::TracedValue> debug_info) {
- owned_debug_info_ = std::move(debug_info);
- debug_info_ = owned_debug_info_.get();
+void LayerImpl::UpdateDebugInfo(LayerDebugInfo* debug_info) {
+ // nullptr means we have stopped collecting debug info.
+ if (!debug_info) {
+ debug_info_.reset();
+ return;
+ }
+ auto new_invalidations = std::move(debug_info->invalidations);
+ if (!debug_info_) {
+ debug_info_ = std::make_unique<LayerDebugInfo>(*debug_info);
+ debug_info_->invalidations = std::move(new_invalidations);
+ return;
+ }
+ // Accumulate invalidations until we draw the layer.
+ auto existing_invalidations = std::move(debug_info_->invalidations);
+ *debug_info_ = *debug_info;
+ debug_info_->invalidations.insert(debug_info_->invalidations.begin(),
+ existing_invalidations.begin(),
+ existing_invalidations.end());
}
void LayerImpl::SetTransformTreeIndex(int index) {
@@ -392,22 +405,13 @@ void LayerImpl::PushPropertiesTo(LayerImpl* layer) {
layer->set_is_scrollbar(is_scrollbar_);
- // If the main thread commits multiple times before the impl thread actually
- // draws, then damage tracking will become incorrect if we simply clobber the
- // update_rect here. The LayerImpl's update_rect needs to accumulate (i.e.
- // union) any update changes that have occurred on the main thread.
- update_rect_.Union(layer->update_rect());
- layer->SetUpdateRect(update_rect_);
+ layer->UnionUpdateRect(update_rect_);
- if (owned_debug_info_)
- layer->SetDebugInfo(std::move(owned_debug_info_));
+ layer->UpdateDebugInfo(debug_info_.get());
// Reset any state that should be cleared for the next update.
needs_show_scrollbars_ = false;
- layer_property_changed_not_from_property_trees_ = false;
- layer_property_changed_from_property_trees_ = false;
- needs_push_properties_ = false;
- update_rect_ = gfx::Rect();
+ ResetChangeTracking();
}
bool LayerImpl::IsAffectedByPageScale() const {
@@ -521,6 +525,8 @@ void LayerImpl::ResetChangeTracking() {
needs_push_properties_ = false;
update_rect_.SetRect(0, 0, 0, 0);
+ if (debug_info_)
+ debug_info_->invalidations.clear();
}
bool LayerImpl::IsActive() const {
@@ -641,8 +647,8 @@ void LayerImpl::SetMirrorCount(int mirror_count) {
mirror_count_ = mirror_count;
}
-void LayerImpl::SetUpdateRect(const gfx::Rect& update_rect) {
- update_rect_ = update_rect;
+void LayerImpl::UnionUpdateRect(const gfx::Rect& update_rect) {
+ update_rect_.Union(update_rect);
}
gfx::Rect LayerImpl::GetDamageRect() const {
@@ -713,6 +719,18 @@ void LayerImpl::GetAllPrioritizedTilesForTracing(
}
void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
+ // The output is consumed at least by
+ // 1. DevTools for showing layer tree information for frame snapshots in
+ // performance timeline (third_party/devtools_frontend/src/front_end/
+ // timeline_model/TracingLayerTree.js),
+ // 2. trace_viewer
+ // (third_party/catapult/tracing/tracing/extras/chrome/cc/layer_impl.html)
+ // Note that trace_viewer uses "namingStyle" style instead of
+ // "naming_style". The difference is intentional and the names are
+ // converted automatically, but we need to keep this in mind when we
+ // search trace_viewer code for the usage of the names here.
+ // When making changes here, we need to make sure we won't break these
+ // consumers.
viz::TracedValue::MakeDictIntoImplicitSnapshotWithCategory(
TRACE_DISABLED_BY_DEFAULT("cc.debug"), state, "cc::LayerImpl",
LayerTypeAsString(), this);
@@ -769,8 +787,30 @@ void LayerImpl::AsValueInto(base::trace_event::TracedValue* state) const {
state->SetBoolean("has_will_change_transform_hint",
has_will_change_transform_hint());
- if (debug_info_)
- state->SetValue("debug_info", debug_info_);
+ if (debug_info_) {
+ state->SetString("layer_name", debug_info_->name);
+ if (debug_info_->owner_node_id)
+ state->SetInteger("owner_node", debug_info_->owner_node_id);
+
+ if (debug_info_->compositing_reasons.size()) {
+ state->BeginArray("compositing_reasons");
+ for (const char* reason : debug_info_->compositing_reasons)
+ state->AppendString(reason);
+ state->EndArray();
+ }
+
+ if (debug_info_->invalidations.size()) {
+ state->BeginArray("annotated_invalidation_rects");
+ for (auto& invalidation : debug_info_->invalidations) {
+ state->BeginDictionary();
+ MathUtil::AddToTracedValue("geometry_rect", invalidation.rect, state);
+ state->SetString("reason", invalidation.reason);
+ state->SetString("client", invalidation.client);
+ state->EndDictionary();
+ }
+ state->EndArray();
+ }
+ }
}
std::string LayerImpl::ToString() const {
diff --git a/chromium/cc/layers/layer_impl.h b/chromium/cc/layers/layer_impl.h
index b054f7f196e..a25b86bee09 100644
--- a/chromium/cc/layers/layer_impl.h
+++ b/chromium/cc/layers/layer_impl.h
@@ -40,9 +40,6 @@
#include "ui/gfx/transform.h"
namespace base {
-namespace trace_event {
-class TracedValue;
-}
class DictionaryValue;
}
@@ -54,6 +51,7 @@ class RenderPass;
namespace cc {
class AppendQuadsData;
+struct LayerDebugInfo;
class LayerTreeImpl;
class MicroBenchmarkImpl;
class PrioritizedTile;
@@ -300,8 +298,11 @@ class CC_EXPORT LayerImpl {
return wheel_event_handler_region_;
}
+ // The main thread may commit multiple times before the impl thread actually
+ // draws, so we need to accumulate (i.e. union) any update changes that have
+ // occurred on the main thread until we draw.
// Note this rect is in layer space (not content space).
- void SetUpdateRect(const gfx::Rect& update_rect);
+ void UnionUpdateRect(const gfx::Rect& update_rect);
const gfx::Rect& update_rect() const { return update_rect_; }
// Denotes an area that is damaged and needs redraw. This is in the layer's
@@ -370,7 +371,7 @@ class CC_EXPORT LayerImpl {
virtual void RunMicroBenchmark(MicroBenchmarkImpl* benchmark);
- void SetDebugInfo(std::unique_ptr<base::trace_event::TracedValue> debug_info);
+ void UpdateDebugInfo(LayerDebugInfo* debug_info);
void set_contributes_to_drawn_render_surface(bool is_member) {
contributes_to_drawn_render_surface_ = is_member;
@@ -536,8 +537,7 @@ class CC_EXPORT LayerImpl {
DrawProperties draw_properties_;
PerformanceProperties<LayerImpl> performance_properties_;
- std::unique_ptr<base::trace_event::TracedValue> owned_debug_info_;
- base::trace_event::TracedValue* debug_info_;
+ std::unique_ptr<LayerDebugInfo> debug_info_;
// Cache of all regions represented by any touch action from
// |touch_action_region_|.
diff --git a/chromium/cc/layers/layer_impl_unittest.cc b/chromium/cc/layers/layer_impl_unittest.cc
index 8de7247dd7b..3bc3298f95c 100644
--- a/chromium/cc/layers/layer_impl_unittest.cc
+++ b/chromium/cc/layers/layer_impl_unittest.cc
@@ -119,7 +119,7 @@ TEST_F(LayerImplTest, VerifyPendingLayerChangesAreTrackedProperly) {
// These properties are internal, and should not be considered "change" when
// they are used.
EXECUTE_AND_VERIFY_SUBTREE_DID_NOT_CHANGE(
- root->SetUpdateRect(arbitrary_rect));
+ root->UnionUpdateRect(arbitrary_rect));
EXECUTE_AND_VERIFY_ONLY_LAYER_CHANGED(root->SetBounds(arbitrary_size));
UpdatePendingTreeDrawProperties();
diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer.cc b/chromium/cc/layers/painted_overlay_scrollbar_layer.cc
index d46146ef57d..1b1c4476ba6 100644
--- a/chromium/cc/layers/painted_overlay_scrollbar_layer.cc
+++ b/chromium/cc/layers/painted_overlay_scrollbar_layer.cc
@@ -26,21 +26,20 @@ namespace cc {
std::unique_ptr<LayerImpl> PaintedOverlayScrollbarLayer::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
return PaintedOverlayScrollbarLayerImpl::Create(
- tree_impl, id(), scrollbar_->Orientation(),
- scrollbar_->IsLeftSideVerticalScrollbar());
+ tree_impl, id(), orientation(), is_left_side_vertical_scrollbar());
}
scoped_refptr<PaintedOverlayScrollbarLayer>
-PaintedOverlayScrollbarLayer::Create(std::unique_ptr<Scrollbar> scrollbar) {
+PaintedOverlayScrollbarLayer::Create(scoped_refptr<Scrollbar> scrollbar) {
return base::WrapRefCounted(
new PaintedOverlayScrollbarLayer(std::move(scrollbar)));
}
PaintedOverlayScrollbarLayer::PaintedOverlayScrollbarLayer(
- std::unique_ptr<Scrollbar> scrollbar)
- : scrollbar_(std::move(scrollbar)),
- thumb_thickness_(scrollbar_->ThumbThickness()),
- thumb_length_(scrollbar_->ThumbLength()) {
+ scoped_refptr<Scrollbar> scrollbar)
+ : ScrollbarLayerBase(scrollbar->Orientation(),
+ scrollbar->IsLeftSideVerticalScrollbar()),
+ scrollbar_(std::move(scrollbar)) {
DCHECK(scrollbar_->HasThumb());
DCHECK(scrollbar_->IsOverlay());
DCHECK(scrollbar_->UsesNinePatchThumbResource());
@@ -49,7 +48,7 @@ PaintedOverlayScrollbarLayer::PaintedOverlayScrollbarLayer(
PaintedOverlayScrollbarLayer::~PaintedOverlayScrollbarLayer() = default;
bool PaintedOverlayScrollbarLayer::OpacityCanAnimateOnImplThread() const {
- return scrollbar_->IsOverlay();
+ return true;
}
void PaintedOverlayScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
@@ -58,12 +57,14 @@ void PaintedOverlayScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
PaintedOverlayScrollbarLayerImpl* scrollbar_layer =
static_cast<PaintedOverlayScrollbarLayerImpl*>(layer);
- scrollbar_layer->SetThumbThickness(thumb_thickness_);
- scrollbar_layer->SetThumbLength(thumb_length_);
- if (scrollbar_->Orientation() == HORIZONTAL) {
+ if (orientation() == HORIZONTAL) {
+ scrollbar_layer->SetThumbThickness(thumb_size_.height());
+ scrollbar_layer->SetThumbLength(thumb_size_.width());
scrollbar_layer->SetTrackStart(track_rect_.x());
scrollbar_layer->SetTrackLength(track_rect_.width());
} else {
+ scrollbar_layer->SetThumbThickness(thumb_size_.width());
+ scrollbar_layer->SetThumbLength(thumb_size_.height());
scrollbar_layer->SetTrackStart(track_rect_.y());
scrollbar_layer->SetTrackLength(track_rect_.height());
}
@@ -97,18 +98,22 @@ void PaintedOverlayScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
ScrollbarLayerBase::SetLayerTreeHost(host);
}
-gfx::Rect PaintedOverlayScrollbarLayer::OriginThumbRectForPainting() const {
- return gfx::Rect(gfx::Point(), scrollbar_->NinePatchThumbCanvasSize());
-}
-
bool PaintedOverlayScrollbarLayer::Update() {
+ // These properties should never change.
+ DCHECK_EQ(orientation(), scrollbar_->Orientation());
+ DCHECK_EQ(is_left_side_vertical_scrollbar(),
+ scrollbar_->IsLeftSideVerticalScrollbar());
+ DCHECK(scrollbar_->HasThumb());
+ DCHECK(scrollbar_->IsOverlay());
+ DCHECK(scrollbar_->UsesNinePatchThumbResource());
+
bool updated = false;
updated |= Layer::Update();
updated |= UpdateProperty(scrollbar_->TrackRect(), &track_rect_);
- updated |= UpdateProperty(scrollbar_->Location(), &location_);
- updated |= UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_);
- updated |= UpdateProperty(scrollbar_->ThumbLength(), &thumb_length_);
+ // Ignore ThumbRect's location because the PaintedOverlayScrollbarLayerImpl
+ // will compute it from scroll offset.
+ updated |= UpdateProperty(scrollbar_->ThumbRect().size(), &thumb_size_);
updated |= PaintThumbIfNeeded();
updated |= PaintTickmarks();
@@ -116,21 +121,19 @@ bool PaintedOverlayScrollbarLayer::Update() {
}
bool PaintedOverlayScrollbarLayer::PaintThumbIfNeeded() {
- if (!scrollbar_->NeedsPaintPart(THUMB) && thumb_resource_)
+ if (!scrollbar_->NeedsRepaintPart(THUMB) && thumb_resource_)
return false;
- gfx::Rect paint_rect = OriginThumbRectForPainting();
+ gfx::Size paint_size = scrollbar_->NinePatchThumbCanvasSize();
+ DCHECK(!paint_size.IsEmpty());
aperture_ = scrollbar_->NinePatchThumbAperture();
- DCHECK(!paint_rect.size().IsEmpty());
- DCHECK(paint_rect.origin().IsOrigin());
-
SkBitmap skbitmap;
- skbitmap.allocN32Pixels(paint_rect.width(), paint_rect.height());
+ skbitmap.allocN32Pixels(paint_size.width(), paint_size.height());
SkiaPaintCanvas canvas(skbitmap);
canvas.clear(SK_ColorTRANSPARENT);
- scrollbar_->PaintPart(&canvas, THUMB);
+ scrollbar_->PaintPart(&canvas, THUMB, gfx::Rect(paint_size));
// Make sure that the pixels are no longer mutable to unavoid unnecessary
// allocation and copying.
skbitmap.setImmutable();
@@ -155,16 +158,16 @@ bool PaintedOverlayScrollbarLayer::PaintTickmarks() {
}
}
- gfx::Rect paint_rect = gfx::Rect(gfx::Point(), track_rect_.size());
-
- DCHECK(!paint_rect.size().IsEmpty());
+ gfx::Size paint_size = track_rect_.size();
+ DCHECK(!paint_size.IsEmpty());
SkBitmap skbitmap;
- skbitmap.allocN32Pixels(paint_rect.width(), paint_rect.height());
+ skbitmap.allocN32Pixels(paint_size.width(), paint_size.height());
SkiaPaintCanvas canvas(skbitmap);
canvas.clear(SK_ColorTRANSPARENT);
- scrollbar_->PaintPart(&canvas, TICKMARKS);
+ scrollbar_->PaintPart(&canvas, TRACK_BUTTONS_TICKMARKS,
+ gfx::Rect(paint_size));
// Make sure that the pixels are no longer mutable to unavoid unnecessary
// allocation and copying.
skbitmap.setImmutable();
diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer.h b/chromium/cc/layers/painted_overlay_scrollbar_layer.h
index 4838fb89452..9b0191d627a 100644
--- a/chromium/cc/layers/painted_overlay_scrollbar_layer.h
+++ b/chromium/cc/layers/painted_overlay_scrollbar_layer.h
@@ -23,7 +23,7 @@ class CC_EXPORT PaintedOverlayScrollbarLayer : public ScrollbarLayerBase {
PaintedOverlayScrollbarLayer& operator=(const PaintedOverlayScrollbarLayer&) =
delete;
static scoped_refptr<PaintedOverlayScrollbarLayer> Create(
- std::unique_ptr<Scrollbar> scrollbar);
+ scoped_refptr<Scrollbar> scrollbar);
bool OpacityCanAnimateOnImplThread() const override;
bool Update() override;
@@ -31,12 +31,10 @@ class CC_EXPORT PaintedOverlayScrollbarLayer : public ScrollbarLayerBase {
void PushPropertiesTo(LayerImpl* layer) override;
protected:
- explicit PaintedOverlayScrollbarLayer(std::unique_ptr<Scrollbar> scrollbar);
+ explicit PaintedOverlayScrollbarLayer(scoped_refptr<Scrollbar> scrollbar);
~PaintedOverlayScrollbarLayer() override;
private:
- gfx::Rect OriginThumbRectForPainting() const;
-
template <typename T>
bool UpdateProperty(T value, T* prop) {
if (*prop == value)
@@ -49,13 +47,10 @@ class CC_EXPORT PaintedOverlayScrollbarLayer : public ScrollbarLayerBase {
bool PaintThumbIfNeeded();
bool PaintTickmarks();
- std::unique_ptr<Scrollbar> scrollbar_;
+ scoped_refptr<Scrollbar> scrollbar_;
- int thumb_thickness_;
- int thumb_length_;
- gfx::Point location_;
+ gfx::Size thumb_size_;
gfx::Rect track_rect_;
-
gfx::Rect aperture_;
std::unique_ptr<ScopedUIResource> thumb_resource_;
diff --git a/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc b/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc
index e1a77c3adf2..7940c7bbd0d 100644
--- a/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/painted_overlay_scrollbar_layer_unittest.cc
@@ -19,8 +19,8 @@ class MockScrollbar : public FakeScrollbar {
public:
MockScrollbar() : FakeScrollbar(true, true, true) {}
- void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override {
- if (part == TICKMARKS)
+ void PaintPart(PaintCanvas*, ScrollbarPart part, const gfx::Rect&) override {
+ if (part == TRACK_BUTTONS_TICKMARKS)
paint_tickmarks_called_ = true;
}
@@ -37,6 +37,8 @@ class MockScrollbar : public FakeScrollbar {
}
private:
+ ~MockScrollbar() override = default;
+
bool paint_tickmarks_called_ = false;
};
@@ -48,12 +50,11 @@ TEST(PaintedOverlayScrollbarLayerTest, PaintTickmarks) {
auto layer_tree_host = FakeLayerTreeHost::Create(
&fake_client_, &task_graph_runner_, animation_host.get());
- MockScrollbar* scrollbar = new MockScrollbar();
+ auto scrollbar = base::MakeRefCounted<MockScrollbar>();
scrollbar->set_has_tickmarks(false);
scoped_refptr<PaintedOverlayScrollbarLayer> scrollbar_layer =
- PaintedOverlayScrollbarLayer::Create(
- std::unique_ptr<Scrollbar>(scrollbar));
+ PaintedOverlayScrollbarLayer::Create(scrollbar);
scrollbar_layer->SetIsDrawable(true);
scrollbar_layer->SetBounds(gfx::Size(100, 100));
diff --git a/chromium/cc/layers/painted_scrollbar_layer.cc b/chromium/cc/layers/painted_scrollbar_layer.cc
index eca1517e8a1..2306ae30f56 100644
--- a/chromium/cc/layers/painted_scrollbar_layer.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer.cc
@@ -15,31 +15,30 @@ namespace cc {
std::unique_ptr<LayerImpl> PaintedScrollbarLayer::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
- return PaintedScrollbarLayerImpl::Create(
- tree_impl, id(), scrollbar_->Orientation(),
- scrollbar_->IsLeftSideVerticalScrollbar(), scrollbar_->IsOverlay());
+ return PaintedScrollbarLayerImpl::Create(tree_impl, id(), orientation(),
+ is_left_side_vertical_scrollbar(),
+ is_overlay_);
}
scoped_refptr<PaintedScrollbarLayer> PaintedScrollbarLayer::Create(
- std::unique_ptr<Scrollbar> scrollbar) {
+ scoped_refptr<Scrollbar> scrollbar) {
return base::WrapRefCounted(new PaintedScrollbarLayer(std::move(scrollbar)));
}
-PaintedScrollbarLayer::PaintedScrollbarLayer(
- std::unique_ptr<Scrollbar> scrollbar)
- : scrollbar_(std::move(scrollbar)),
+PaintedScrollbarLayer::PaintedScrollbarLayer(scoped_refptr<Scrollbar> scrollbar)
+ : ScrollbarLayerBase(scrollbar->Orientation(),
+ scrollbar->IsLeftSideVerticalScrollbar()),
+ scrollbar_(std::move(scrollbar)),
internal_contents_scale_(1.f),
- supports_drag_snap_back_(false),
- thumb_thickness_(scrollbar_->ThumbThickness()),
- thumb_length_(scrollbar_->ThumbLength()),
- is_overlay_(scrollbar_->IsOverlay()),
+ thumb_opacity_(scrollbar_->ThumbOpacity()),
has_thumb_(scrollbar_->HasThumb()),
- thumb_opacity_(scrollbar_->ThumbOpacity()) {}
+ supports_drag_snap_back_(scrollbar_->SupportsDragSnapBack()),
+ is_overlay_(scrollbar_->IsOverlay()) {}
PaintedScrollbarLayer::~PaintedScrollbarLayer() = default;
bool PaintedScrollbarLayer::OpacityCanAnimateOnImplThread() const {
- return scrollbar_->IsOverlay();
+ return is_overlay_;
}
void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
@@ -52,16 +51,15 @@ void PaintedScrollbarLayer::PushPropertiesTo(LayerImpl* layer) {
internal_contents_scale_, internal_content_bounds_);
scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_);
- scrollbar_layer->SetThumbThickness(thumb_thickness_);
scrollbar_layer->SetBackButtonRect(back_button_rect_);
scrollbar_layer->SetForwardButtonRect(forward_button_rect_);
- scrollbar_layer->SetThumbLength(thumb_length_);
- if (scrollbar_->Orientation() == HORIZONTAL) {
- scrollbar_layer->SetTrackStart(track_rect_.x());
- scrollbar_layer->SetTrackLength(track_rect_.width());
+ scrollbar_layer->SetTrackRect(track_rect_);
+ if (orientation() == HORIZONTAL) {
+ scrollbar_layer->SetThumbThickness(thumb_size_.height());
+ scrollbar_layer->SetThumbLength(thumb_size_.width());
} else {
- scrollbar_layer->SetTrackStart(track_rect_.y());
- scrollbar_layer->SetTrackLength(track_rect_.height());
+ scrollbar_layer->SetThumbThickness(thumb_size_.width());
+ scrollbar_layer->SetThumbLength(thumb_size_.height());
}
if (track_resource_.get())
@@ -89,45 +87,33 @@ void PaintedScrollbarLayer::SetLayerTreeHost(LayerTreeHost* host) {
ScrollbarLayerBase::SetLayerTreeHost(host);
}
-gfx::Rect PaintedScrollbarLayer::ScrollbarLayerRectToContentRect(
- const gfx::Rect& layer_rect) const {
- // Don't intersect with the bounds as in LayerRectToContentRect() because
- // layer_rect here might be in coordinates of the containing layer.
- gfx::Rect expanded_rect = gfx::ScaleToEnclosingRectSafe(
- layer_rect, internal_contents_scale_, internal_contents_scale_);
+gfx::Size PaintedScrollbarLayer::LayerSizeToContentSize(
+ const gfx::Size& layer_size) const {
+ gfx::Size content_size =
+ gfx::ScaleToCeiledSize(layer_size, internal_contents_scale_);
// We should never return a rect bigger than the content bounds.
- gfx::Size clamped_size = expanded_rect.size();
- clamped_size.SetToMin(internal_content_bounds_);
- expanded_rect.set_size(clamped_size);
- return expanded_rect;
-}
-
-gfx::Rect PaintedScrollbarLayer::OriginThumbRect() const {
- gfx::Size thumb_size;
- if (scrollbar_->Orientation() == HORIZONTAL) {
- thumb_size =
- gfx::Size(scrollbar_->ThumbLength(), scrollbar_->ThumbThickness());
- } else {
- thumb_size =
- gfx::Size(scrollbar_->ThumbThickness(), scrollbar_->ThumbLength());
- }
- return gfx::Rect(thumb_size);
+ content_size.SetToMin(internal_content_bounds_);
+ return content_size;
}
void PaintedScrollbarLayer::UpdateThumbAndTrackGeometry() {
- UpdateProperty(scrollbar_->SupportsDragSnapBack(), &supports_drag_snap_back_);
+ // These properties should never change.
+ DCHECK_EQ(supports_drag_snap_back_, scrollbar_->SupportsDragSnapBack());
+ DCHECK_EQ(is_left_side_vertical_scrollbar(),
+ scrollbar_->IsLeftSideVerticalScrollbar());
+ DCHECK_EQ(is_overlay_, scrollbar_->IsOverlay());
+ DCHECK_EQ(orientation(), scrollbar_->Orientation());
+
UpdateProperty(scrollbar_->TrackRect(), &track_rect_);
UpdateProperty(scrollbar_->BackButtonRect(), &back_button_rect_);
UpdateProperty(scrollbar_->ForwardButtonRect(), &forward_button_rect_);
- UpdateProperty(scrollbar_->Location(), &location_);
- UpdateProperty(scrollbar_->IsOverlay(), &is_overlay_);
UpdateProperty(scrollbar_->HasThumb(), &has_thumb_);
if (has_thumb_) {
- UpdateProperty(scrollbar_->ThumbThickness(), &thumb_thickness_);
- UpdateProperty(scrollbar_->ThumbLength(), &thumb_length_);
+ // Ignore ThumbRect's location because the PaintedScrollbarLayerImpl will
+ // compute it from scroll offset.
+ UpdateProperty(scrollbar_->ThumbRect().size(), &thumb_size_);
} else {
- UpdateProperty(0, &thumb_thickness_);
- UpdateProperty(0, &thumb_length_);
+ UpdateProperty(gfx::Size(), &thumb_size_);
}
}
@@ -160,13 +146,12 @@ bool PaintedScrollbarLayer::Update() {
UpdateThumbAndTrackGeometry();
- gfx::Rect track_layer_rect = gfx::Rect(location_, bounds());
- gfx::Rect scaled_track_rect = ScrollbarLayerRectToContentRect(
- track_layer_rect);
+ gfx::Size size = bounds();
+ gfx::Size scaled_size = internal_content_bounds_;
bool updated = false;
- if (scaled_track_rect.IsEmpty()) {
+ if (scaled_size.IsEmpty()) {
if (track_resource_) {
track_resource_ = nullptr;
thumb_resource_ = nullptr;
@@ -185,22 +170,20 @@ bool PaintedScrollbarLayer::Update() {
if (update_rect().IsEmpty() && track_resource_)
return updated;
- if (!track_resource_ || scrollbar_->NeedsPaintPart(TRACK)) {
+ if (!track_resource_ ||
+ scrollbar_->NeedsRepaintPart(TRACK_BUTTONS_TICKMARKS)) {
track_resource_ = ScopedUIResource::Create(
layer_tree_host()->GetUIResourceManager(),
- RasterizeScrollbarPart(track_layer_rect, scaled_track_rect, TRACK));
+ RasterizeScrollbarPart(size, scaled_size, TRACK_BUTTONS_TICKMARKS));
}
- gfx::Rect thumb_layer_rect = OriginThumbRect();
- gfx::Rect scaled_thumb_rect =
- ScrollbarLayerRectToContentRect(thumb_layer_rect);
- if (has_thumb_ && !scaled_thumb_rect.IsEmpty()) {
- if (!thumb_resource_ || scrollbar_->NeedsPaintPart(THUMB) ||
- scaled_thumb_rect.size() !=
- thumb_resource_->GetBitmap(0, false).GetSize()) {
+ gfx::Size scaled_thumb_size = LayerSizeToContentSize(thumb_size_);
+ if (has_thumb_ && !scaled_thumb_size.IsEmpty()) {
+ if (!thumb_resource_ || scrollbar_->NeedsRepaintPart(THUMB) ||
+ scaled_thumb_size != thumb_resource_->GetBitmap(0, false).GetSize()) {
thumb_resource_ = ScopedUIResource::Create(
layer_tree_host()->GetUIResourceManager(),
- RasterizeScrollbarPart(thumb_layer_rect, scaled_thumb_rect, THUMB));
+ RasterizeScrollbarPart(thumb_size_, scaled_thumb_size, THUMB));
}
thumb_opacity_ = scrollbar_->ThumbOpacity();
}
@@ -212,28 +195,26 @@ bool PaintedScrollbarLayer::Update() {
}
UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart(
- const gfx::Rect& layer_rect,
- const gfx::Rect& requested_content_rect,
+ const gfx::Size& size,
+ const gfx::Size& requested_content_size,
ScrollbarPart part) {
- DCHECK(!requested_content_rect.size().IsEmpty());
- DCHECK(!layer_rect.size().IsEmpty());
+ DCHECK(!requested_content_size.IsEmpty());
+ DCHECK(!size.IsEmpty());
- gfx::Rect content_rect = requested_content_rect;
+ gfx::Size content_size = requested_content_size;
// Pages can end up requesting arbitrarily large scrollbars. Prevent this
// from crashing due to OOM and try something smaller.
SkBitmap skbitmap;
bool allocation_succeeded =
- skbitmap.tryAllocN32Pixels(content_rect.width(), content_rect.height());
+ skbitmap.tryAllocN32Pixels(content_size.width(), content_size.height());
// Assuming 4bpp, caps at 4M.
constexpr int kMinScrollbarDimension = 1024;
- int dimension = std::max(content_rect.width(), content_rect.height()) / 2;
+ int dimension = std::max(content_size.width(), content_size.height()) / 2;
while (!allocation_succeeded && dimension >= kMinScrollbarDimension) {
- content_rect.Intersect(gfx::Rect(requested_content_rect.x(),
- requested_content_rect.y(), dimension,
- dimension));
+ content_size.SetToMin(gfx::Size(dimension, dimension));
allocation_succeeded =
- skbitmap.tryAllocN32Pixels(content_rect.width(), content_rect.height());
+ skbitmap.tryAllocN32Pixels(content_size.width(), content_size.height());
if (!allocation_succeeded)
dimension = dimension / 2;
}
@@ -243,13 +224,11 @@ UIResourceBitmap PaintedScrollbarLayer::RasterizeScrollbarPart(
SkiaPaintCanvas canvas(skbitmap);
canvas.clear(SK_ColorTRANSPARENT);
- float scale_x =
- content_rect.width() / static_cast<float>(layer_rect.width());
- float scale_y =
- content_rect.height() / static_cast<float>(layer_rect.height());
+ float scale_x = content_size.width() / static_cast<float>(size.width());
+ float scale_y = content_size.height() / static_cast<float>(size.height());
canvas.scale(SkFloatToScalar(scale_x), SkFloatToScalar(scale_y));
- scrollbar_->PaintPart(&canvas, part);
+ scrollbar_->PaintPart(&canvas, part, gfx::Rect(size));
// Make sure that the pixels are no longer mutable to unavoid unnecessary
// allocation and copying.
skbitmap.setImmutable();
diff --git a/chromium/cc/layers/painted_scrollbar_layer.h b/chromium/cc/layers/painted_scrollbar_layer.h
index 444c042d0d3..444a3531263 100644
--- a/chromium/cc/layers/painted_scrollbar_layer.h
+++ b/chromium/cc/layers/painted_scrollbar_layer.h
@@ -18,7 +18,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerBase {
std::unique_ptr<LayerImpl> CreateLayerImpl(LayerTreeImpl* tree_impl) override;
static scoped_refptr<PaintedScrollbarLayer> Create(
- std::unique_ptr<Scrollbar> scrollbar);
+ scoped_refptr<Scrollbar> scrollbar);
PaintedScrollbarLayer(const PaintedScrollbarLayer&) = delete;
PaintedScrollbarLayer& operator=(const PaintedScrollbarLayer&) = delete;
@@ -33,7 +33,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerBase {
}
protected:
- explicit PaintedScrollbarLayer(std::unique_ptr<Scrollbar> scrollbar);
+ explicit PaintedScrollbarLayer(scoped_refptr<Scrollbar> scrollbar);
~PaintedScrollbarLayer() override;
// For unit tests
@@ -47,8 +47,7 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerBase {
void UpdateThumbAndTrackGeometry();
private:
- gfx::Rect ScrollbarLayerRectToContentRect(const gfx::Rect& layer_rect) const;
- gfx::Rect OriginThumbRect() const;
+ gfx::Size LayerSizeToContentSize(const gfx::Size& layer_size) const;
template <typename T>
bool UpdateProperty(T value, T* prop) {
@@ -59,11 +58,12 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerBase {
return true;
}
- UIResourceBitmap RasterizeScrollbarPart(const gfx::Rect& layer_rect,
- const gfx::Rect& content_rect,
- ScrollbarPart part);
+ UIResourceBitmap RasterizeScrollbarPart(
+ const gfx::Size& size,
+ const gfx::Size& requested_content_size,
+ ScrollbarPart part);
- std::unique_ptr<Scrollbar> scrollbar_;
+ scoped_refptr<Scrollbar> scrollbar_;
ElementId scroll_element_id_;
float internal_contents_scale_;
@@ -71,20 +71,18 @@ class CC_EXPORT PaintedScrollbarLayer : public ScrollbarLayerBase {
// Snapshot of properties taken in UpdateThumbAndTrackGeometry and used in
// PushPropertiesTo.
- bool supports_drag_snap_back_;
- int thumb_thickness_;
- int thumb_length_;
- gfx::Point location_;
+ gfx::Size thumb_size_;
gfx::Rect track_rect_;
gfx::Rect back_button_rect_;
gfx::Rect forward_button_rect_;
- bool is_overlay_;
+ float thumb_opacity_;
bool has_thumb_;
+ const bool supports_drag_snap_back_;
+ const bool is_overlay_;
+
std::unique_ptr<ScopedUIResource> track_resource_;
std::unique_ptr<ScopedUIResource> thumb_resource_;
-
- float thumb_opacity_;
};
} // namespace cc
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.cc b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
index 6b9d5829ba5..45400bfac2d 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl.cc
@@ -45,11 +45,7 @@ PaintedScrollbarLayerImpl::PaintedScrollbarLayerImpl(
internal_contents_scale_(1.f),
supports_drag_snap_back_(false),
thumb_thickness_(0),
- thumb_length_(0),
- track_start_(0),
- track_length_(0),
- back_button_rect_(gfx::Rect(0, 0)),
- forward_button_rect_(gfx::Rect(0, 0)) {}
+ thumb_length_(0) {}
PaintedScrollbarLayerImpl::~PaintedScrollbarLayerImpl() = default;
@@ -72,10 +68,9 @@ void PaintedScrollbarLayerImpl::PushPropertiesTo(LayerImpl* layer) {
scrollbar_layer->SetSupportsDragSnapBack(supports_drag_snap_back_);
scrollbar_layer->SetThumbThickness(thumb_thickness_);
scrollbar_layer->SetThumbLength(thumb_length_);
- scrollbar_layer->SetTrackStart(track_start_);
- scrollbar_layer->SetTrackLength(track_length_);
scrollbar_layer->SetBackButtonRect(back_button_rect_);
scrollbar_layer->SetForwardButtonRect(forward_button_rect_);
+ scrollbar_layer->SetTrackRect(track_rect_);
scrollbar_layer->set_track_ui_resource_id(track_ui_resource_id_);
scrollbar_layer->set_thumb_ui_resource_id(thumb_ui_resource_id_);
@@ -197,15 +192,8 @@ int PaintedScrollbarLayerImpl::ThumbLength() const {
return thumb_length_;
}
-void PaintedScrollbarLayerImpl::SetTrackStart(int track_start) {
- if (track_start_ == track_start)
- return;
- track_start_ = track_start;
- NoteLayerPropertyChanged();
-}
-
int PaintedScrollbarLayerImpl::TrackStart() const {
- return track_start_;
+ return orientation() == VERTICAL ? track_rect_.y() : track_rect_.x();
}
void PaintedScrollbarLayerImpl::SetBackButtonRect(gfx::Rect back_button_rect) {
@@ -232,44 +220,50 @@ gfx::Rect PaintedScrollbarLayerImpl::ForwardButtonRect() const {
}
gfx::Rect PaintedScrollbarLayerImpl::BackTrackRect() const {
- gfx::Rect thumb_rect = ComputeThumbQuadRect();
+ const gfx::Rect thumb_rect = ComputeThumbQuadRect();
+ const int rect_x = track_rect_.x();
+ const int rect_y = track_rect_.y();
if (orientation() == HORIZONTAL) {
- int rect_x = back_button_rect_.x() + back_button_rect_.width();
- int rect_y = back_button_rect_.y();
- return gfx::Rect(rect_x, rect_y, thumb_rect.x() - rect_x,
- back_button_rect_.height());
+ int width = thumb_rect.x() - rect_x;
+ int height = track_rect_.height();
+ return gfx::Rect(rect_x, rect_y, width, height);
} else {
- int rect_x = back_button_rect_.x();
- int rect_y = back_button_rect_.y() + back_button_rect_.height();
- return gfx::Rect(rect_x, rect_y, back_button_rect_.width(),
- thumb_rect.y() - rect_y);
+ int width = track_rect_.width();
+ int height = thumb_rect.y() - rect_y;
+ return gfx::Rect(rect_x, rect_y, width, height);
}
}
gfx::Rect PaintedScrollbarLayerImpl::ForwardTrackRect() const {
- gfx::Rect thumb_rect = ComputeThumbQuadRect();
+ const gfx::Rect thumb_rect = ComputeThumbQuadRect();
+ const int track_end = TrackStart() + TrackLength();
if (orientation() == HORIZONTAL) {
- int rect_x = thumb_rect.x() + thumb_rect.width();
- int rect_y = thumb_rect.y();
- return gfx::Rect(rect_x, rect_y, forward_button_rect_.x() - rect_x,
- forward_button_rect_.height());
+ int rect_x = thumb_rect.right();
+ int rect_y = track_rect_.y();
+ int width = track_end - rect_x;
+ int height = track_rect_.height();
+ return gfx::Rect(rect_x, rect_y, width, height);
} else {
- int rect_x = thumb_rect.x();
- int rect_y = thumb_rect.y() + thumb_rect.height();
- return gfx::Rect(rect_x, rect_y, forward_button_rect_.width(),
- forward_button_rect_.y() - rect_y);
+ int rect_x = track_rect_.x();
+ int rect_y = thumb_rect.bottom();
+ int width = track_rect_.width();
+ int height = track_end - rect_y;
+ return gfx::Rect(rect_x, rect_y, width, height);
}
}
-void PaintedScrollbarLayerImpl::SetTrackLength(int track_length) {
- if (track_length_ == track_length)
+void PaintedScrollbarLayerImpl::SetTrackRect(gfx::Rect track_rect) {
+ if (track_rect_ == track_rect)
return;
- track_length_ = track_length;
+ track_rect_ = track_rect;
NoteLayerPropertyChanged();
}
float PaintedScrollbarLayerImpl::TrackLength() const {
- return track_length_ + (orientation() == VERTICAL ? vertical_adjust() : 0);
+ if (orientation() == VERTICAL)
+ return track_rect_.height() + vertical_adjust();
+ else
+ return track_rect_.width();
}
bool PaintedScrollbarLayerImpl::IsThumbResizable() const {
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl.h b/chromium/cc/layers/painted_scrollbar_layer_impl.h
index 75f22053b8e..8c0ffd398ca 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl.h
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl.h
@@ -43,8 +43,7 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase {
void SetForwardButtonRect(gfx::Rect forward_button_rect);
void SetThumbThickness(int thumb_thickness);
void SetThumbLength(int thumb_length);
- void SetTrackStart(int track_start);
- void SetTrackLength(int track_length);
+ void SetTrackRect(gfx::Rect track_rect);
void set_track_ui_resource_id(UIResourceId uid) {
track_ui_resource_id_ = uid;
@@ -97,10 +96,9 @@ class CC_EXPORT PaintedScrollbarLayerImpl : public ScrollbarLayerImplBase {
bool supports_drag_snap_back_;
int thumb_thickness_;
int thumb_length_;
- int track_start_;
- int track_length_;
gfx::Rect back_button_rect_;
gfx::Rect forward_button_rect_;
+ gfx::Rect track_rect_;
};
} // namespace cc
diff --git a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
index 3115841e84d..951126295d0 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_impl_unittest.cc
@@ -49,7 +49,7 @@ TEST(PaintedScrollbarLayerImplTest, Occlusion) {
scrollbar_layer_impl->SetDrawsContent(true);
scrollbar_layer_impl->SetThumbThickness(layer_size.width());
scrollbar_layer_impl->SetThumbLength(500);
- scrollbar_layer_impl->SetTrackLength(layer_size.height());
+ scrollbar_layer_impl->SetTrackRect(gfx::Rect(0, 0, 15, layer_size.height()));
scrollbar_layer_impl->SetCurrentPos(100.f / 4);
scrollbar_layer_impl->SetClipLayerLength(100.f);
scrollbar_layer_impl->SetScrollLayerLength(200.f);
diff --git a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc
index 1852f6417f5..1c5684f51b8 100644
--- a/chromium/cc/layers/painted_scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/painted_scrollbar_layer_unittest.cc
@@ -25,7 +25,13 @@ class MockScrollbar : public FakeScrollbar {
: FakeScrollbar(/*paint*/ true,
/*has_thumb*/ true,
/*is_overlay*/ false) {}
- MOCK_METHOD2(PaintPart, void(PaintCanvas* canvas, ScrollbarPart part));
+ MOCK_METHOD3(PaintPart,
+ void(PaintCanvas* canvas,
+ ScrollbarPart part,
+ const gfx::Rect& rect));
+
+ private:
+ ~MockScrollbar() override = default;
};
TEST(PaintedScrollbarLayerTest, NeedsPaint) {
@@ -36,9 +42,9 @@ TEST(PaintedScrollbarLayerTest, NeedsPaint) {
auto layer_tree_host = FakeLayerTreeHost::Create(
&fake_client_, &task_graph_runner_, animation_host.get());
- MockScrollbar* scrollbar = new MockScrollbar();
+ auto scrollbar = base::MakeRefCounted<MockScrollbar>();
scoped_refptr<PaintedScrollbarLayer> scrollbar_layer =
- PaintedScrollbarLayer::Create(std::unique_ptr<Scrollbar>(scrollbar));
+ PaintedScrollbarLayer::Create(scrollbar);
scrollbar_layer->SetIsDrawable(true);
scrollbar_layer->SetBounds(gfx::Size(100, 100));
@@ -50,34 +56,34 @@ TEST(PaintedScrollbarLayerTest, NeedsPaint) {
// Request no paint, but expect them to be painted because they have not
// yet been initialized.
- scrollbar->set_needs_paint_thumb(false);
- scrollbar->set_needs_paint_track(false);
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(1);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(1);
+ scrollbar->set_needs_repaint_thumb(false);
+ scrollbar->set_needs_repaint_track(false);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(1);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK_BUTTONS_TICKMARKS, _)).Times(1);
scrollbar_layer->Update();
- Mock::VerifyAndClearExpectations(scrollbar);
+ Mock::VerifyAndClearExpectations(scrollbar.get());
// The next update will paint nothing because the first update caused a paint.
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(0);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(0);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(0);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK_BUTTONS_TICKMARKS, _)).Times(0);
scrollbar_layer->Update();
- Mock::VerifyAndClearExpectations(scrollbar);
+ Mock::VerifyAndClearExpectations(scrollbar.get());
// Enable the thumb.
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(1);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(0);
- scrollbar->set_needs_paint_thumb(true);
- scrollbar->set_needs_paint_track(false);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(1);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK_BUTTONS_TICKMARKS, _)).Times(0);
+ scrollbar->set_needs_repaint_thumb(true);
+ scrollbar->set_needs_repaint_track(false);
scrollbar_layer->Update();
- Mock::VerifyAndClearExpectations(scrollbar);
+ Mock::VerifyAndClearExpectations(scrollbar.get());
// Enable the track.
- EXPECT_CALL(*scrollbar, PaintPart(_, THUMB)).Times(0);
- EXPECT_CALL(*scrollbar, PaintPart(_, TRACK)).Times(1);
- scrollbar->set_needs_paint_thumb(false);
- scrollbar->set_needs_paint_track(true);
+ EXPECT_CALL(*scrollbar, PaintPart(_, THUMB, _)).Times(0);
+ EXPECT_CALL(*scrollbar, PaintPart(_, TRACK_BUTTONS_TICKMARKS, _)).Times(1);
+ scrollbar->set_needs_repaint_thumb(false);
+ scrollbar->set_needs_repaint_track(true);
scrollbar_layer->Update();
- Mock::VerifyAndClearExpectations(scrollbar);
+ Mock::VerifyAndClearExpectations(scrollbar.get());
}
} // namespace
diff --git a/chromium/cc/layers/picture_layer.cc b/chromium/cc/layers/picture_layer.cc
index d6c2c095d20..d13ed640807 100644
--- a/chromium/cc/layers/picture_layer.cc
+++ b/chromium/cc/layers/picture_layer.cc
@@ -17,8 +17,6 @@
#include "cc/trees/transform_node.h"
#include "ui/gfx/geometry/rect_conversions.h"
-static constexpr int kMaxNumberOfSlowPathsBeforeReporting = 5;
-
namespace cc {
PictureLayer::PictureLayerInputs::PictureLayerInputs() = default;
@@ -189,22 +187,6 @@ sk_sp<SkPicture> PictureLayer::GetPicture() const {
return raster_source->GetFlattenedPicture();
}
-bool PictureLayer::HasSlowPaths() const {
- // The display list needs to be created (see: UpdateAndExpandInvalidation)
- // before checking for slow paths. There are cases where an update will not
- // create a display list (e.g., if the size is empty). We return false in
- // these cases because the slow paths bit sticks true.
- return picture_layer_inputs_.display_list &&
- picture_layer_inputs_.display_list->NumSlowPaths() >
- kMaxNumberOfSlowPathsBeforeReporting;
-}
-
-bool PictureLayer::HasNonAAPaint() const {
- // We return false by default, as this bit sticks true.
- return picture_layer_inputs_.display_list &&
- picture_layer_inputs_.display_list->HasNonAAPaint();
-}
-
void PictureLayer::ClearClient() {
picture_layer_inputs_.client = nullptr;
UpdateDrawsContent(HasDrawableContent());
diff --git a/chromium/cc/layers/picture_layer.h b/chromium/cc/layers/picture_layer.h
index 8150e1514fc..05e41d7be84 100644
--- a/chromium/cc/layers/picture_layer.h
+++ b/chromium/cc/layers/picture_layer.h
@@ -49,8 +49,6 @@ class CC_EXPORT PictureLayer : public Layer {
void SetNeedsDisplayRect(const gfx::Rect& layer_rect) override;
sk_sp<SkPicture> GetPicture() const override;
bool Update() override;
- bool HasSlowPaths() const override;
- bool HasNonAAPaint() const override;
void RunMicroBenchmark(MicroBenchmark* benchmark) override;
void CaptureContent(const gfx::Rect& rect,
std::vector<NodeId>* content) override;
diff --git a/chromium/cc/layers/picture_layer_impl.cc b/chromium/cc/layers/picture_layer_impl.cc
index 2369a6610ef..e4c8eb90abd 100644
--- a/chromium/cc/layers/picture_layer_impl.cc
+++ b/chromium/cc/layers/picture_layer_impl.cc
@@ -680,6 +680,17 @@ void PictureLayerImpl::UpdateRasterSource(
SetPaintWorkletInputs({});
}
}
+
+ // If the MSAA sample count has changed, we need to re-raster the complete
+ // layer.
+ if (raster_source_ && raster_source_->GetDisplayItemList() &&
+ raster_source->GetDisplayItemList() &&
+ layer_tree_impl()->GetMSAASampleCountForRaster(
+ raster_source_->GetDisplayItemList()) !=
+ layer_tree_impl()->GetMSAASampleCountForRaster(
+ raster_source->GetDisplayItemList())) {
+ new_invalidation->Union(gfx::Rect(raster_source->GetSize()));
+ }
}
// The |raster_source_| is initially null, so have to check for that for the
@@ -747,7 +758,7 @@ bool PictureLayerImpl::UpdateCanUseLCDTextAfterCommit() {
gfx::Rect bounds_rect(bounds());
invalidation_ = Region(bounds_rect);
tilings_->Invalidate(invalidation_);
- SetUpdateRect(bounds_rect);
+ UnionUpdateRect(bounds_rect);
return true;
}
@@ -1573,14 +1584,9 @@ PictureLayerImpl::InvalidateRegionForImages(
if (invalidation.IsEmpty())
return ImageInvalidationResult::kNoInvalidation;
- // Make sure to union the rect from this invalidation with the update_rect
- // instead of over-writing it. We don't want to reset the update that came
- // from the main thread.
// Note: We can use a rect here since this is only used to track damage for a
// frame and not raster invalidation.
- gfx::Rect new_update_rect = invalidation.bounds();
- new_update_rect.Union(update_rect());
- SetUpdateRect(new_update_rect);
+ UnionUpdateRect(invalidation.bounds());
invalidation_.Union(invalidation);
tilings_->Invalidate(invalidation);
diff --git a/chromium/cc/layers/picture_layer_impl_unittest.cc b/chromium/cc/layers/picture_layer_impl_unittest.cc
index 77fb24781a6..67e1df67e5a 100644
--- a/chromium/cc/layers/picture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/picture_layer_impl_unittest.cc
@@ -2491,73 +2491,6 @@ TEST_F(LegacySWPictureLayerImplTest, RecreateInvalidPendingTreeTiles) {
EXPECT_NE(active_tiling->TileAt(0, 0), pending_tiling->TileAt(0, 0));
}
-class MSAAEnabledPictureLayerImplTest : public PictureLayerImplTest {
- public:
- LayerTreeSettings CreateSettings() override {
- LayerTreeSettings settings = PictureLayerImplTest::CreateSettings();
- settings.gpu_rasterization_msaa_sample_count = 1;
- return settings;
- }
-};
-
-TEST_F(MSAAEnabledPictureLayerImplTest, SyncTilingAfterMSAAToggles) {
- host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
-
- gfx::Size layer_bounds(10, 10);
-
- scoped_refptr<FakeRasterSource> pending_raster_source =
- FakeRasterSource::CreateFilled(layer_bounds);
- scoped_refptr<FakeRasterSource> active_raster_source =
- FakeRasterSource::CreateFilled(layer_bounds);
-
- SetupTrees(pending_raster_source, active_raster_source);
-
- EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));
- EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f));
-
- // MSAA is disabled by default.
- EXPECT_FALSE(host_impl()->use_msaa());
- EXPECT_EQ(0u, pending_layer()->release_tile_resources_count());
- EXPECT_EQ(0u, active_layer()->release_tile_resources_count());
- EXPECT_EQ(0u, pending_layer()->release_resources_count());
- EXPECT_EQ(0u, active_layer()->release_resources_count());
- // Toggling MSAA clears all tilings on both trees.
- host_impl()->SetContentHasSlowPaths(true);
- host_impl()->CommitComplete();
- EXPECT_TRUE(host_impl()->use_msaa());
- EXPECT_EQ(1u, pending_layer()->release_tile_resources_count());
- EXPECT_EQ(1u, active_layer()->release_tile_resources_count());
- EXPECT_EQ(1u, pending_layer()->release_resources_count());
- 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()->FindTilingWithScaleKey(1.f));
- EXPECT_EQ(0u, active_layer()->tilings()->num_tilings());
-
- host_impl()->NotifyReadyToActivate();
- ActivateTree();
- EXPECT_TRUE(active_layer()->tilings()->FindTilingWithScaleKey(1.f));
-
- SetupPendingTree(pending_raster_source);
- EXPECT_TRUE(pending_layer()->tilings()->FindTilingWithScaleKey(1.f));
-
- // Toggling msaa clears all tilings on both trees.
- host_impl()->SetContentHasSlowPaths(false);
- EXPECT_TRUE(host_impl()->use_msaa());
- host_impl()->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::ON,
- host_impl()->gpu_rasterization_status());
- EXPECT_EQ(2u, pending_layer()->release_tile_resources_count());
- EXPECT_EQ(2u, active_layer()->release_tile_resources_count());
- EXPECT_EQ(2u, pending_layer()->release_resources_count());
- EXPECT_EQ(2u, active_layer()->release_resources_count());
- host_impl()->NotifyReadyToActivate();
-
- host_impl()->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::ON,
- host_impl()->gpu_rasterization_status());
-}
-
TEST_F(LegacySWPictureLayerImplTest, HighResCreatedWhenBoundsShrink) {
// Put 0.5 as high res.
SetInitialDeviceScaleFactor(0.5f);
diff --git a/chromium/cc/layers/picture_layer_unittest.cc b/chromium/cc/layers/picture_layer_unittest.cc
index 9f8feabe10d..daf36769d2b 100644
--- a/chromium/cc/layers/picture_layer_unittest.cc
+++ b/chromium/cc/layers/picture_layer_unittest.cc
@@ -227,76 +227,6 @@ TEST(PictureLayerTest, ClearVisibleRectWhenNoTiling) {
host_impl.active_tree()->root_layer()->DidDraw(nullptr);
}
-TEST(PictureLayerTest, HasSlowPaths) {
- std::unique_ptr<FakeRecordingSource> recording_source_owned(
- new FakeRecordingSource);
- FakeRecordingSource* recording_source = recording_source_owned.get();
-
- gfx::Size layer_bounds(200, 200);
- gfx::Rect layer_rect(layer_bounds);
- Region invalidation(layer_rect);
-
- FakeContentLayerClient client;
- client.set_bounds(layer_bounds);
- scoped_refptr<FakePictureLayer> layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client, std::move(recording_source_owned));
-
- FakeLayerTreeHostClient host_client;
- TestTaskGraphRunner 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);
-
- recording_source->SetNeedsDisplayRect(layer_rect);
- layer->Update();
-
- // Layer does not have slow paths by default.
- EXPECT_FALSE(layer->HasSlowPaths());
-
- // Add slow-path content to the client.
- client.set_contains_slow_paths(true);
- recording_source->SetNeedsDisplayRect(layer_rect);
- layer->Update();
- EXPECT_TRUE(layer->HasSlowPaths());
-}
-
-TEST(PictureLayerTest, HasNonAAPaint) {
- std::unique_ptr<FakeRecordingSource> recording_source_owned(
- new FakeRecordingSource);
- FakeRecordingSource* recording_source = recording_source_owned.get();
-
- gfx::Size layer_bounds(200, 200);
- gfx::Rect layer_rect(layer_bounds);
- Region invalidation(layer_rect);
-
- FakeContentLayerClient client;
- client.set_bounds(layer_bounds);
- scoped_refptr<FakePictureLayer> layer =
- FakePictureLayer::CreateWithRecordingSource(
- &client, std::move(recording_source_owned));
-
- FakeLayerTreeHostClient host_client;
- TestTaskGraphRunner 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);
-
- recording_source->SetNeedsDisplayRect(layer_rect);
- layer->Update();
-
- // Layer does not have non-aa paint by default.
- EXPECT_FALSE(layer->HasNonAAPaint());
-
- // Add non-aa content to the client.
- client.add_draw_rect(layer_rect, PaintFlags());
- recording_source->SetNeedsDisplayRect(layer_rect);
- layer->Update();
- EXPECT_TRUE(layer->HasNonAAPaint());
-}
-
// PicturePile uses the source frame number as a unit for measuring invalidation
// frequency. When a pile moves between compositors, the frame number increases
// non-monotonically. This executes that code path under this scenario allowing
diff --git a/chromium/cc/layers/scrollbar_layer_base.cc b/chromium/cc/layers/scrollbar_layer_base.cc
index 14c743b9eb9..e676c3eed1e 100644
--- a/chromium/cc/layers/scrollbar_layer_base.cc
+++ b/chromium/cc/layers/scrollbar_layer_base.cc
@@ -8,7 +8,10 @@
namespace cc {
-ScrollbarLayerBase::ScrollbarLayerBase() {
+ScrollbarLayerBase::ScrollbarLayerBase(ScrollbarOrientation orientation,
+ bool is_left_side_vertical_scrollbar)
+ : orientation_(orientation),
+ is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar) {
SetIsScrollbar(true);
}
@@ -24,8 +27,12 @@ void ScrollbarLayerBase::SetScrollElementId(ElementId element_id) {
void ScrollbarLayerBase::PushPropertiesTo(LayerImpl* layer) {
Layer::PushPropertiesTo(layer);
- static_cast<ScrollbarLayerImplBase*>(layer)->SetScrollElementId(
- scroll_element_id_);
+
+ auto* scrollbar_layer_impl = static_cast<ScrollbarLayerImplBase*>(layer);
+ DCHECK_EQ(scrollbar_layer_impl->orientation(), orientation_);
+ DCHECK_EQ(scrollbar_layer_impl->is_left_side_vertical_scrollbar(),
+ is_left_side_vertical_scrollbar_);
+ scrollbar_layer_impl->SetScrollElementId(scroll_element_id_);
}
} // namespace cc
diff --git a/chromium/cc/layers/scrollbar_layer_base.h b/chromium/cc/layers/scrollbar_layer_base.h
index 00c5dfa3491..ad783c3dd87 100644
--- a/chromium/cc/layers/scrollbar_layer_base.h
+++ b/chromium/cc/layers/scrollbar_layer_base.h
@@ -13,14 +13,23 @@ namespace cc {
class CC_EXPORT ScrollbarLayerBase : public Layer {
public:
void SetScrollElementId(ElementId element_id);
+ ElementId scroll_element_id() const { return scroll_element_id_; }
+
+ ScrollbarOrientation orientation() const { return orientation_; }
+ bool is_left_side_vertical_scrollbar() const {
+ return is_left_side_vertical_scrollbar_;
+ }
void PushPropertiesTo(LayerImpl* layer) override;
protected:
- ScrollbarLayerBase();
+ ScrollbarLayerBase(ScrollbarOrientation orientation,
+ bool is_left_side_vertical_scrollbar);
~ScrollbarLayerBase() override;
private:
+ const ScrollbarOrientation orientation_;
+ const bool is_left_side_vertical_scrollbar_;
ElementId scroll_element_id_;
};
diff --git a/chromium/cc/layers/scrollbar_layer_unittest.cc b/chromium/cc/layers/scrollbar_layer_unittest.cc
index 98a5011c0c3..da855d4f9cd 100644
--- a/chromium/cc/layers/scrollbar_layer_unittest.cc
+++ b/chromium/cc/layers/scrollbar_layer_unittest.cc
@@ -137,7 +137,7 @@ class BaseScrollbarLayerTest : public testing::Test {
LayerImpl* LayerImplForScrollAreaAndScrollbar(
FakeLayerTreeHost* host,
- std::unique_ptr<Scrollbar> scrollbar,
+ scoped_refptr<Scrollbar> scrollbar,
bool reverse_order,
bool use_solid_color_scrollbar,
int thumb_thickness,
@@ -195,6 +195,9 @@ class FakePaintedOverlayScrollbar : public FakeScrollbar {
gfx::Rect NinePatchThumbAperture() const override {
return gfx::Rect(1, 1, 1, 1);
}
+
+ private:
+ ~FakePaintedOverlayScrollbar() override = default;
};
// Test that a painted overlay scrollbar will repaint and recrate its resource
@@ -203,11 +206,9 @@ class FakePaintedOverlayScrollbar : public FakeScrollbar {
TEST_F(ScrollbarLayerTest, RepaintOverlayWhenResourceDisposed) {
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> content_layer = Layer::Create();
- std::unique_ptr<FakePaintedOverlayScrollbar> scrollbar(
- new FakePaintedOverlayScrollbar);
- FakePaintedOverlayScrollbar* fake_scrollbar = scrollbar.get();
+ auto fake_scrollbar = base::MakeRefCounted<FakePaintedOverlayScrollbar>();
scoped_refptr<PaintedOverlayScrollbarLayer> scrollbar_layer =
- PaintedOverlayScrollbarLayer::Create(std::move(scrollbar));
+ PaintedOverlayScrollbarLayer::Create(fake_scrollbar);
scrollbar_layer->SetScrollElementId(layer_tree_root->element_id());
// Setup.
@@ -224,7 +225,7 @@ TEST_F(ScrollbarLayerTest, RepaintOverlayWhenResourceDisposed) {
// First call to update should create a resource. The scrollbar itself thinks
// it needs a repaint.
{
- fake_scrollbar->set_needs_paint_thumb(true);
+ fake_scrollbar->set_needs_repaint_thumb(true);
EXPECT_EQ(0u, fake_ui_resource_manager_->UIResourceCount());
EXPECT_TRUE(scrollbar_layer->Update());
EXPECT_EQ(1u, fake_ui_resource_manager_->UIResourceCount());
@@ -233,7 +234,7 @@ TEST_F(ScrollbarLayerTest, RepaintOverlayWhenResourceDisposed) {
// Now the scrollbar has been painted and nothing else has changed, calling
// Update() shouldn't have an effect.
{
- fake_scrollbar->set_needs_paint_thumb(false);
+ fake_scrollbar->set_needs_repaint_thumb(false);
EXPECT_FALSE(scrollbar_layer->Update());
EXPECT_EQ(1u, fake_ui_resource_manager_->UIResourceCount());
}
@@ -258,11 +259,12 @@ class FakeNinePatchScrollbar : public FakeScrollbar {
: FakeScrollbar(/*paint*/ true, /*has_thumb*/ true, /*is_overlay*/ true) {
}
bool UsesNinePatchThumbResource() const override { return true; }
+
+ private:
+ ~FakeNinePatchScrollbar() override = default;
};
TEST_F(ScrollbarLayerTest, ScrollElementIdPushedAcrossCommit) {
- std::unique_ptr<Scrollbar> scrollbar1(new FakeScrollbar);
- std::unique_ptr<Scrollbar> scrollbar2(new FakeNinePatchScrollbar);
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> layer_a = Layer::Create();
scoped_refptr<Layer> layer_b = Layer::Create();
@@ -270,10 +272,11 @@ TEST_F(ScrollbarLayerTest, ScrollElementIdPushedAcrossCommit) {
layer_b->SetElementId(LayerIdToElementIdForTesting(layer_b->id()));
scoped_refptr<PaintedScrollbarLayer> painted_scrollbar_layer =
- PaintedScrollbarLayer::Create(std::move(scrollbar1));
+ PaintedScrollbarLayer::Create(base::MakeRefCounted<FakeScrollbar>());
painted_scrollbar_layer->SetScrollElementId(layer_a->element_id());
scoped_refptr<PaintedOverlayScrollbarLayer> painted_overlay_scrollbar_layer =
- PaintedOverlayScrollbarLayer::Create(std::move(scrollbar2));
+ PaintedOverlayScrollbarLayer::Create(
+ base::MakeRefCounted<FakeNinePatchScrollbar>());
painted_overlay_scrollbar_layer->SetScrollElementId(layer_a->element_id());
scoped_refptr<SolidColorScrollbarLayer> solid_color_scrollbar_layer =
SolidColorScrollbarLayer::Create(VERTICAL, 1, 1, false);
@@ -331,13 +334,12 @@ TEST_F(ScrollbarLayerTest, ScrollElementIdPushedAcrossCommit) {
}
TEST_F(ScrollbarLayerTest, ScrollOffsetSynchronization) {
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar);
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> scroll_layer = Layer::Create();
scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id()));
scoped_refptr<Layer> content_layer = Layer::Create();
scoped_refptr<PaintedScrollbarLayer> scrollbar_layer =
- PaintedScrollbarLayer::Create(std::move(scrollbar));
+ PaintedScrollbarLayer::Create(base::MakeRefCounted<FakeScrollbar>());
scrollbar_layer->SetScrollElementId(scroll_layer->element_id());
// Choose bounds to give max_scroll_offset = (30, 50).
@@ -420,10 +422,8 @@ TEST_F(ScrollbarLayerTest, UpdatePropertiesOfScrollBarWhenThumbRemoved) {
scrollbar_layer->SetScrollElementId(root_layer->element_id());
// The track_rect should be relative to the scrollbar's origin.
- scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10));
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(10, 10, 50, 10));
- scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10);
- scrollbar_layer->fake_scrollbar()->set_thumb_length(4);
+ scrollbar_layer->fake_scrollbar()->set_thumb_size(gfx::Size(4, 10));
LayerImpl* root_layer_impl = nullptr;
PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr;
@@ -461,10 +461,8 @@ TEST_F(ScrollbarLayerTest, ThumbRect) {
scrollbar_layer->SetScrollElementId(root_layer->element_id());
// The track_rect should be relative to the scrollbar's origin.
- scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(20, 10));
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(10, 10, 50, 10));
- scrollbar_layer->fake_scrollbar()->set_thumb_thickness(10);
- scrollbar_layer->fake_scrollbar()->set_thumb_length(4);
+ scrollbar_layer->fake_scrollbar()->set_thumb_size(gfx::Size(4, 10));
layer_tree_host_->UpdateLayers();
LayerImpl* root_layer_impl = nullptr;
@@ -493,8 +491,7 @@ TEST_F(ScrollbarLayerTest, ThumbRect) {
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);
+ scrollbar_layer->fake_scrollbar()->set_thumb_size(gfx::Size(6, 4));
UPDATE_AND_EXTRACT_LAYER_POINTERS();
EXPECT_EQ(gfx::Rect(54, 0, 6, 4).ToString(),
@@ -502,7 +499,6 @@ TEST_F(ScrollbarLayerTest, ThumbRect) {
// Shrink the scrollbar layer to cover only the track.
scrollbar_layer->SetBounds(gfx::Size(50, 10));
- scrollbar_layer->fake_scrollbar()->set_location(gfx::Point(30, 10));
scrollbar_layer->fake_scrollbar()->set_track_rect(gfx::Rect(0, 10, 50, 10));
UPDATE_AND_EXTRACT_LAYER_POINTERS();
@@ -535,8 +531,7 @@ TEST_F(ScrollbarLayerTest, ThumbRectForOverlayLeftSideVerticalScrollbar) {
scrollbar_layer->SetBounds(gfx::Size(10, 20));
scrollbar_layer->SetScrollElementId(root_layer->element_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);
+ scrollbar_layer->fake_scrollbar()->set_thumb_size(gfx::Size(10, 4));
layer_tree_host_->UpdateLayers();
LayerImpl* root_layer_impl = nullptr;
PaintedScrollbarLayerImpl* scrollbar_layer_impl = nullptr;
@@ -557,8 +552,7 @@ TEST_F(ScrollbarLayerTest, ThumbRectForOverlayLeftSideVerticalScrollbar) {
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);
+ scrollbar_layer->fake_scrollbar()->set_thumb_size(gfx::Size(4, 6));
UPDATE_AND_EXTRACT_LAYER_POINTERS();
// For left side vertical scrollbars thumb_rect.x = bounds.width() -
// thumb_thickness.
@@ -571,9 +565,9 @@ TEST_F(ScrollbarLayerTest, SolidColorDrawQuads) {
const int kTrackStart = 1;
const int kTrackLength = 100;
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
LayerImpl* layer_impl_tree_root = LayerImplForScrollAreaAndScrollbar(
- layer_tree_host_.get(), std::move(scrollbar), false, true,
+ layer_tree_host_.get(),
+ base::MakeRefCounted<FakeScrollbar>(false, true, true), false, true,
kThumbThickness, kTrackStart);
ScrollbarLayerImplBase* scrollbar_layer_impl =
static_cast<SolidColorScrollbarLayerImpl*>(
@@ -632,16 +626,13 @@ TEST_F(ScrollbarLayerTest, LayerDrivenSolidColorDrawQuads) {
const int kTrackStart = 0;
const int kTrackLength = 10;
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
-
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> scroll_layer = Layer::Create();
scroll_layer->SetElementId(LayerIdToElementIdForTesting(scroll_layer->id()));
scoped_refptr<Layer> child1 = Layer::Create();
const bool kIsLeftSideVerticalScrollbar = false;
scoped_refptr<SolidColorScrollbarLayer> child2 =
- SolidColorScrollbarLayer::Create(scrollbar->Orientation(),
- kThumbThickness, kTrackStart,
+ SolidColorScrollbarLayer::Create(HORIZONTAL, kThumbThickness, kTrackStart,
kIsLeftSideVerticalScrollbar);
child2->SetScrollElementId(scroll_layer->element_id());
scroll_layer->AddChild(child1);
@@ -689,8 +680,6 @@ TEST_F(ScrollbarLayerTest, ScrollbarLayerOpacity) {
const int kThumbThickness = 3;
const int kTrackStart = 0;
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
-
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> scroll_layer = Layer::Create();
scroll_layer->SetElementId(ElementId(200));
@@ -698,8 +687,7 @@ TEST_F(ScrollbarLayerTest, ScrollbarLayerOpacity) {
scoped_refptr<SolidColorScrollbarLayer> scrollbar_layer;
const bool kIsLeftSideVerticalScrollbar = false;
scrollbar_layer = SolidColorScrollbarLayer::Create(
- scrollbar->Orientation(), kThumbThickness, kTrackStart,
- kIsLeftSideVerticalScrollbar);
+ HORIZONTAL, kThumbThickness, kTrackStart, kIsLeftSideVerticalScrollbar);
scrollbar_layer->SetScrollElementId(scroll_layer->element_id());
scrollbar_layer->SetElementId(ElementId(300));
scroll_layer->AddChild(child1);
@@ -767,7 +755,6 @@ TEST_F(ScrollbarLayerTest, ScrollbarLayerPushProperties) {
// its properties after scroll layer.
const int kThumbThickness = 3;
const int kTrackStart = 0;
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> scroll_layer = Layer::Create();
@@ -775,8 +762,7 @@ TEST_F(ScrollbarLayerTest, ScrollbarLayerPushProperties) {
scoped_refptr<Layer> child1 = Layer::Create();
const bool kIsLeftSideVerticalScrollbar = false;
scoped_refptr<SolidColorScrollbarLayer> scrollbar_layer =
- SolidColorScrollbarLayer::Create(scrollbar->Orientation(),
- kThumbThickness, kTrackStart,
+ SolidColorScrollbarLayer::Create(HORIZONTAL, kThumbThickness, kTrackStart,
kIsLeftSideVerticalScrollbar);
scrollbar_layer->SetScrollElementId(scroll_layer->element_id());
scroll_layer->AddChild(child1);
@@ -915,10 +901,8 @@ TEST_F(AuraScrollbarLayerTest, ScrollbarLayerCreateAfterSetScrollable) {
layer_tree_host_->CommitAndCreatePendingTree();
host_impl->ActivateSyncTree();
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, true));
scoped_refptr<SolidColorScrollbarLayer> scrollbar_layer =
- SolidColorScrollbarLayer::Create(scrollbar->Orientation(),
- kThumbThickness, kTrackStart,
+ SolidColorScrollbarLayer::Create(HORIZONTAL, kThumbThickness, kTrackStart,
kIsLeftSideVerticalScrollbar);
scrollbar_layer->SetScrollElementId(scroll_layer->element_id());
scroll_layer->InsertChild(scrollbar_layer, 1);
@@ -1035,7 +1019,6 @@ class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest {
int expected_created,
int expected_deleted,
bool use_solid_color_scrollbar) {
- std::unique_ptr<Scrollbar> scrollbar(new FakeScrollbar(false, true, false));
scoped_refptr<Layer> layer_tree_root = Layer::Create();
scoped_refptr<Layer> content_layer = Layer::Create();
scoped_refptr<ScrollbarLayerBase> scrollbar_layer;
@@ -1044,10 +1027,11 @@ class ScrollbarLayerTestResourceCreationAndRelease : public ScrollbarLayerTest {
const int kTrackStart = 0;
const bool kIsLeftSideVerticalScrollbar = false;
scrollbar_layer = SolidColorScrollbarLayer::Create(
- scrollbar->Orientation(), kThumbThickness, kTrackStart,
+ HORIZONTAL, kThumbThickness, kTrackStart,
kIsLeftSideVerticalScrollbar);
} else {
- scrollbar_layer = PaintedScrollbarLayer::Create(std::move(scrollbar));
+ scrollbar_layer = PaintedScrollbarLayer::Create(
+ base::MakeRefCounted<FakeScrollbar>(false, true, false));
}
scrollbar_layer->SetScrollElementId(layer_tree_root->element_id());
layer_tree_root->AddChild(content_layer);
@@ -1349,7 +1333,6 @@ class ScaledScrollbarLayerTestScaledRasterization : public ScrollbarLayerTest {
scrollbar_layer->SetBounds(scrollbar_rect.size());
scrollbar_layer->SetPosition(gfx::PointF(scrollbar_rect.origin()));
- scrollbar_layer->fake_scrollbar()->set_location(scrollbar_rect.origin());
scrollbar_layer->fake_scrollbar()->set_track_rect(
gfx::Rect(scrollbar_rect.size()));
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.cc b/chromium/cc/layers/solid_color_scrollbar_layer.cc
index 92e321f2d67..caf3a0aee84 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer.cc
+++ b/chromium/cc/layers/solid_color_scrollbar_layer.cc
@@ -13,9 +13,9 @@ namespace cc {
std::unique_ptr<LayerImpl> SolidColorScrollbarLayer::CreateLayerImpl(
LayerTreeImpl* tree_impl) {
- return SolidColorScrollbarLayerImpl::Create(tree_impl, id(), orientation_,
- thumb_thickness_, track_start_,
- is_left_side_vertical_scrollbar_);
+ return SolidColorScrollbarLayerImpl::Create(
+ tree_impl, id(), orientation(), thumb_thickness_, track_start_,
+ is_left_side_vertical_scrollbar());
}
scoped_refptr<SolidColorScrollbarLayer> SolidColorScrollbarLayer::Create(
@@ -33,10 +33,9 @@ SolidColorScrollbarLayer::SolidColorScrollbarLayer(
int thumb_thickness,
int track_start,
bool is_left_side_vertical_scrollbar)
- : orientation_(orientation),
+ : ScrollbarLayerBase(orientation, is_left_side_vertical_scrollbar),
thumb_thickness_(thumb_thickness),
- track_start_(track_start),
- is_left_side_vertical_scrollbar_(is_left_side_vertical_scrollbar) {
+ track_start_(track_start) {
Layer::SetOpacity(0.f);
}
diff --git a/chromium/cc/layers/solid_color_scrollbar_layer.h b/chromium/cc/layers/solid_color_scrollbar_layer.h
index 8aed2f50026..6bb1615e312 100644
--- a/chromium/cc/layers/solid_color_scrollbar_layer.h
+++ b/chromium/cc/layers/solid_color_scrollbar_layer.h
@@ -37,10 +37,8 @@ class CC_EXPORT SolidColorScrollbarLayer : public ScrollbarLayerBase {
bool is_left_side_vertical_scrollbar);
~SolidColorScrollbarLayer() override;
- ScrollbarOrientation orientation_;
int thumb_thickness_;
int track_start_;
- bool is_left_side_vertical_scrollbar_;
};
} // namespace cc
diff --git a/chromium/cc/layers/surface_layer_impl.cc b/chromium/cc/layers/surface_layer_impl.cc
index 6ef4249c51e..ea7c454d540 100644
--- a/chromium/cc/layers/surface_layer_impl.cc
+++ b/chromium/cc/layers/surface_layer_impl.cc
@@ -149,7 +149,7 @@ void SurfaceLayerImpl::AppendQuads(viz::RenderPass* render_pass,
auto* quad = render_pass->CreateAndAppendDrawQuad<viz::SurfaceDrawQuad>();
quad->SetNew(shared_quad_state, quad_rect, visible_quad_rect,
surface_range_, background_color(),
- stretch_content_to_fill_bounds_, has_pointer_events_none_);
+ stretch_content_to_fill_bounds_);
quad->is_reflection = is_reflection_;
// Add the primary surface ID as a dependency.
append_quads_data->activation_dependencies.push_back(surface_range_.end());
diff --git a/chromium/cc/layers/texture_layer_impl_unittest.cc b/chromium/cc/layers/texture_layer_impl_unittest.cc
index dad52054171..0e46ca0ae60 100644
--- a/chromium/cc/layers/texture_layer_impl_unittest.cc
+++ b/chromium/cc/layers/texture_layer_impl_unittest.cc
@@ -102,41 +102,5 @@ TEST(TextureLayerImplTest, Occlusion) {
}
}
-TEST(TextureLayerImplTest, ResourceNotFreedOnMSAAToggle) {
- bool released = false;
- LayerTreeImplTestBase impl(
- FakeLayerTreeFrameSink::Create3dForGpuRasterization());
- impl.host_impl()->AdvanceToNextFrame(base::TimeDelta::FromMilliseconds(1));
-
- gfx::Size layer_size(1000, 1000);
- gfx::Size viewport_size(1000, 1000);
-
- viz::TransferableResource resource;
- resource.is_software = false;
- resource.mailbox_holder.mailbox = gpu::Mailbox::Generate();
- resource.mailbox_holder.sync_token =
- gpu::SyncToken(gpu::CommandBufferNamespace::GPU_IO,
- gpu::CommandBufferId::FromUnsafeValue(0x234), 0x456);
- resource.mailbox_holder.texture_target = GL_TEXTURE_2D;
-
- TextureLayerImpl* texture_layer_impl = impl.AddLayer<TextureLayerImpl>();
- texture_layer_impl->SetBounds(layer_size);
- texture_layer_impl->SetDrawsContent(true);
- texture_layer_impl->SetTransferableResource(
- resource, viz::SingleReleaseCallback::Create(base::BindOnce(
- [](bool* released, const gpu::SyncToken& sync_token,
- bool lost) { *released = true; },
- base::Unretained(&released))));
- CopyProperties(impl.root_layer(), texture_layer_impl);
-
- impl.CalcDrawProps(viewport_size);
-
- EXPECT_FALSE(released);
- // Toggling MSAA clears all tilings on both trees.
- impl.host_impl()->SetContentHasSlowPaths(true);
- impl.host_impl()->CommitComplete();
- EXPECT_FALSE(released);
-}
-
} // namespace
} // namespace cc
diff --git a/chromium/cc/layers/tile_size_calculator.cc b/chromium/cc/layers/tile_size_calculator.cc
index eacb897a12f..b6397bcaf1b 100644
--- a/chromium/cc/layers/tile_size_calculator.cc
+++ b/chromium/cc/layers/tile_size_calculator.cc
@@ -10,10 +10,6 @@
namespace cc {
namespace {
-// Even for really wide viewports, at some point GPU raster should use
-// less than 4 tiles to fill the viewport. This is set to 256 as a
-// sane minimum for now, but we might want to tune this for low-end.
-const int kMinHeightForGpuRasteredTile = 256;
// When making odd-sized tiles, round them up to increase the chances
// of using the same tile size.
@@ -44,7 +40,8 @@ gfx::Size ApplyDsfAdjustment(const gfx::Size& device_pixels_size, float dsf) {
// viewport vertically.
gfx::Size CalculateGpuTileSize(const gfx::Size& base_tile_size,
const gfx::Size& content_bounds,
- const gfx::Size& max_tile_size) {
+ const gfx::Size& max_tile_size,
+ int min_height_for_gpu_raster_tile) {
int tile_width = base_tile_size.width();
// Increase the height proportionally as the width decreases, and pad by our
@@ -66,7 +63,7 @@ gfx::Size CalculateGpuTileSize(const gfx::Size& base_tile_size,
tile_width = MathUtil::UncheckedRoundUp(tile_width, kGpuDefaultTileRoundUp);
tile_height = MathUtil::UncheckedRoundUp(tile_height, kGpuDefaultTileRoundUp);
- tile_height = std::max(tile_height, kMinHeightForGpuRasteredTile);
+ tile_height = std::max(tile_height, min_height_for_gpu_raster_tile);
if (!max_tile_size.IsEmpty()) {
tile_width = std::min(tile_width, max_tile_size.width());
@@ -111,6 +108,8 @@ TileSizeCalculator::AffectingParams TileSizeCalculator::GetAffectingParams() {
params.max_texture_size = layer_tree_impl->max_texture_size();
params.use_gpu_rasterization = layer_tree_impl->use_gpu_rasterization();
params.max_tile_size = layer_tree_impl->settings().max_gpu_raster_tile_size;
+ params.min_height_for_gpu_raster_tile =
+ layer_tree_impl->settings().min_height_for_gpu_raster_tile;
params.gpu_raster_max_texture_size =
layer_impl()->gpu_raster_max_texture_size();
params.device_scale_factor = layer_tree_impl->device_scale_factor();
@@ -153,15 +152,17 @@ gfx::Size TileSizeCalculator::CalculateTileSize() {
// Set our initial size assuming a |base_tile_size| equal to our
// |viewport_size|.
gfx::Size default_tile_size =
- CalculateGpuTileSize(base_tile_size, content_bounds, max_tile_size);
+ CalculateGpuTileSize(base_tile_size, content_bounds, max_tile_size,
+ affecting_params_.min_height_for_gpu_raster_tile);
// Use half-width GPU tiles when the content_width is greater than our
// calculated tile size.
if (content_bounds.width() > default_tile_size.width()) {
// Divide width by 2 and round up.
base_tile_size.set_width((base_tile_size.width() + 1) / 2);
- default_tile_size =
- CalculateGpuTileSize(base_tile_size, content_bounds, max_tile_size);
+ default_tile_size = CalculateGpuTileSize(
+ base_tile_size, content_bounds, max_tile_size,
+ affecting_params_.min_height_for_gpu_raster_tile);
}
default_tile_width = default_tile_size.width();
diff --git a/chromium/cc/layers/tile_size_calculator.h b/chromium/cc/layers/tile_size_calculator.h
index cd455b922d2..ab00258e193 100644
--- a/chromium/cc/layers/tile_size_calculator.h
+++ b/chromium/cc/layers/tile_size_calculator.h
@@ -26,6 +26,7 @@ class CC_EXPORT TileSizeCalculator {
bool use_gpu_rasterization = false;
float device_scale_factor = 0.0f;
gfx::Size max_tile_size;
+ int min_height_for_gpu_raster_tile;
gfx::Size gpu_raster_max_texture_size;
gfx::Size max_untiled_layer_size;
gfx::Size default_tile_size;
diff --git a/chromium/cc/layers/video_layer_impl.cc b/chromium/cc/layers/video_layer_impl.cc
index b76baeb77e0..905a0a5a024 100644
--- a/chromium/cc/layers/video_layer_impl.cc
+++ b/chromium/cc/layers/video_layer_impl.cc
@@ -188,7 +188,7 @@ void VideoLayerImpl::ReleaseResources() {
}
void VideoLayerImpl::SetNeedsRedraw() {
- SetUpdateRect(gfx::UnionRects(update_rect(), gfx::Rect(bounds())));
+ UnionUpdateRect(gfx::Rect(bounds()));
layer_tree_impl()->SetNeedsRedraw();
}
diff --git a/chromium/cc/layers/viewport.cc b/chromium/cc/layers/viewport.cc
index 5a50ee6b010..635d9996ccd 100644
--- a/chromium/cc/layers/viewport.cc
+++ b/chromium/cc/layers/viewport.cc
@@ -69,18 +69,19 @@ Viewport::ScrollResult Viewport::ScrollBy(const gfx::Vector2dF& physical_delta,
return result;
}
-bool Viewport::CanScroll(const ScrollState& scroll_state) const {
- auto* outer_node = OuterScrollNode();
+bool Viewport::CanScroll(const ScrollNode& node,
+ const ScrollState& scroll_state) const {
+ DCHECK(ShouldScroll(node));
- if (!outer_node)
- return false;
+ bool result = host_impl_->CanConsumeDelta(*InnerScrollNode(), scroll_state);
- bool result = false;
- if (auto* inner_node = InnerScrollNode())
- result |= host_impl_->CanConsumeDelta(*inner_node, scroll_state);
-
- result |= host_impl_->CanConsumeDelta(*outer_node, scroll_state);
+ // If the passed in node is the inner viewport, we're not interested in the
+ // scrollability of the outer viewport. See LTHI::GetNodeToScroll for how the
+ // scroll chain is constructed.
+ if (node.scrolls_inner_viewport)
+ return result;
+ result |= host_impl_->CanConsumeDelta(*OuterScrollNode(), scroll_state);
return result;
}
@@ -229,15 +230,20 @@ void Viewport::PinchEnd(const gfx::Point& anchor, bool snap_to_min) {
pinch_zoom_active_ = false;
}
-bool Viewport::ShouldScroll(const ScrollNode& scroll_node) {
+bool Viewport::ShouldScroll(const ScrollNode& scroll_node) const {
+ // Non-main frame renderers and the UI compositor will not have viewport
+ // scrolling nodes and should thus never scroll with the Viewport object.
+ if (!InnerScrollNode() || !OuterScrollNode()) {
+ DCHECK(!InnerScrollNode());
+ DCHECK(!OuterScrollNode());
+ DCHECK(!scroll_node.scrolls_inner_viewport);
+ DCHECK(!scroll_node.scrolls_outer_viewport);
+ return false;
+ }
return scroll_node.scrolls_inner_viewport ||
scroll_node.scrolls_outer_viewport;
}
-ScrollNode* Viewport::MainScrollNode() const {
- return host_impl_->OuterViewportScrollNode();
-}
-
gfx::Vector2dF Viewport::ScrollBrowserControls(const gfx::Vector2dF& delta) {
gfx::Vector2dF excess_delta =
host_impl_->browser_controls_manager()->ScrollBy(delta);
diff --git a/chromium/cc/layers/viewport.h b/chromium/cc/layers/viewport.h
index ac17140f513..55a64b7ee4e 100644
--- a/chromium/cc/layers/viewport.h
+++ b/chromium/cc/layers/viewport.h
@@ -21,6 +21,15 @@ struct ScrollNode;
// outer viewport (layout) scroll layers. These layers have different scroll
// bubbling behavior from the rest of the layer tree which is encoded in this
// class.
+//
+// When performing any kind of scroll operations on either the inner or outer
+// scroll node, they must be done using this class. Typically, the outer
+// viewport's scroll node will be used in the scroll chain to represent a full
+// viewport scroll (i.e. one that will use this class to scroll both inner and
+// outer viewports, as appropriate). However, in some situations (see comments
+// in LayerTreeHostImpl::GetNodeToScroll) we may wish to scroll only the inner
+// viewport. In that case, the inner viewport is used in the scroll chain, but
+// we should still scroll using this class.
class CC_EXPORT Viewport {
public:
// If the pinch zoom anchor on the first PinchUpdate is within this length
@@ -55,8 +64,6 @@ class CC_EXPORT Viewport {
bool affect_browser_controls,
bool scroll_outer_viewport);
- bool CanScroll(const ScrollState& scroll_state) const;
-
// TODO(bokan): Callers can now be replaced by ScrollBy.
void ScrollByInnerFirst(const gfx::Vector2dF& delta);
@@ -71,12 +78,18 @@ class CC_EXPORT Viewport {
void PinchEnd(const gfx::Point& anchor, bool snap_to_min);
// Returns true if the given scroll node should be scrolled via this class,
- // false if it should be scrolled directly.
- bool ShouldScroll(const ScrollNode& scroll_node);
-
- // Returns the "representative" viewport scroll node. That is, the one that's
- // set as the currently scrolling node when the viewport scrolls.
- ScrollNode* MainScrollNode() const;
+ // false if it should be scrolled directly. Scrolling either the inner or
+ // outer viewport nodes must be done using this class.
+ bool ShouldScroll(const ScrollNode& scroll_node) const;
+
+ // Returns true if the viewport can consume any of the delta for the given
+ // the |scroll_state|. This method takes a ScrollNode because viewport
+ // scrolling can occur for either the inner or outer scroll nodes. If it
+ // outer is used, we do a combined scroll that distributes the scroll among
+ // the inner and outer viewports. If the inner is used, only the inner
+ // viewport is scrolled. It is an error to pass any other node to this
+ // method.
+ bool CanScroll(const ScrollNode& node, const ScrollState& scroll_state) const;
private:
explicit Viewport(LayerTreeHostImpl* host_impl);
diff --git a/chromium/cc/metrics/begin_main_frame_metrics.cc b/chromium/cc/metrics/begin_main_frame_metrics.cc
index d4e83ead0c0..04b6d8bbf3d 100644
--- a/chromium/cc/metrics/begin_main_frame_metrics.cc
+++ b/chromium/cc/metrics/begin_main_frame_metrics.cc
@@ -8,4 +8,7 @@ namespace cc {
BeginMainFrameMetrics::BeginMainFrameMetrics() = default;
+BeginMainFrameMetrics::BeginMainFrameMetrics(
+ const BeginMainFrameMetrics& other) = default;
+
} // namespace cc
diff --git a/chromium/cc/metrics/begin_main_frame_metrics.h b/chromium/cc/metrics/begin_main_frame_metrics.h
index 2927360a849..bcd40714215 100644
--- a/chromium/cc/metrics/begin_main_frame_metrics.h
+++ b/chromium/cc/metrics/begin_main_frame_metrics.h
@@ -28,6 +28,8 @@ struct CC_EXPORT BeginMainFrameMetrics {
base::TimeDelta update_layers;
BeginMainFrameMetrics();
+
+ BeginMainFrameMetrics(const BeginMainFrameMetrics& other);
};
} // namespace cc
diff --git a/chromium/cc/metrics/compositor_frame_reporter.cc b/chromium/cc/metrics/compositor_frame_reporter.cc
index cb494e657b7..e6586c87ce2 100644
--- a/chromium/cc/metrics/compositor_frame_reporter.cc
+++ b/chromium/cc/metrics/compositor_frame_reporter.cc
@@ -16,6 +16,7 @@ namespace cc {
namespace {
using StageType = CompositorFrameReporter::StageType;
+using BlinkBreakdown = CompositorFrameReporter::BlinkBreakdown;
using VizBreakdown = CompositorFrameReporter::VizBreakdown;
constexpr int kMissedFrameReportTypeCount =
@@ -23,7 +24,13 @@ constexpr int kMissedFrameReportTypeCount =
kMissedFrameReportTypeCount);
constexpr int kStageTypeCount = static_cast<int>(StageType::kStageTypeCount);
constexpr int kAllBreakdownCount =
- static_cast<int>(VizBreakdown::kBreakdownCount);
+ static_cast<int>(VizBreakdown::kBreakdownCount) +
+ static_cast<int>(BlinkBreakdown::kBreakdownCount);
+
+constexpr int kVizBreakdownInitialIndex = kStageTypeCount;
+constexpr int kBlinkBreakdownInitialIndex =
+ kVizBreakdownInitialIndex + static_cast<int>(VizBreakdown::kBreakdownCount);
+
// For each possible FrameSequenceTrackerType there will be a UMA histogram
// plus one for general case.
constexpr int kFrameSequenceTrackerTypeCount =
@@ -31,38 +38,74 @@ constexpr int kFrameSequenceTrackerTypeCount =
// Names for CompositorFrameReporter::StageType, which should be updated in case
// of changes to the enum.
-constexpr const char* kStageNames[] = {
- [static_cast<int>(StageType::kBeginImplFrameToSendBeginMainFrame)] =
- "BeginImplFrameToSendBeginMainFrame",
- [static_cast<int>(StageType::kSendBeginMainFrameToCommit)] =
- "SendBeginMainFrameToCommit",
- [static_cast<int>(StageType::kCommit)] = "Commit",
- [static_cast<int>(StageType::kEndCommitToActivation)] =
- "EndCommitToActivation",
- [static_cast<int>(StageType::kActivation)] = "Activation",
- [static_cast<int>(StageType::kEndActivateToSubmitCompositorFrame)] =
- "EndActivateToSubmitCompositorFrame",
- [static_cast<int>(
- StageType::kSubmitCompositorFrameToPresentationCompositorFrame)] =
- "SubmitCompositorFrameToPresentationCompositorFrame",
- [static_cast<int>(StageType::kTotalLatency)] = "TotalLatency",
- [static_cast<int>(VizBreakdown::kSubmitToReceiveCompositorFrame) +
- kStageTypeCount] =
- "SubmitCompositorFrameToPresentationCompositorFrame."
- "SubmitToReceiveCompositorFrame",
- [static_cast<int>(VizBreakdown::kReceivedCompositorFrameToStartDraw) +
- kStageTypeCount] =
- "SubmitCompositorFrameToPresentationCompositorFrame."
- "ReceivedCompositorFrameToStartDraw",
- [static_cast<int>(VizBreakdown::kStartDrawToSwapEnd) + kStageTypeCount] =
- "SubmitCompositorFrameToPresentationCompositorFrame.StartDrawToSwapEnd",
- [static_cast<int>(VizBreakdown::kSwapEndToPresentationCompositorFrame) +
- kStageTypeCount] =
- "SubmitCompositorFrameToPresentationCompositorFrame."
- "SwapEndToPresentationCompositorFrame"};
-static_assert(sizeof(kStageNames) / sizeof(kStageNames[0]) ==
- kStageTypeCount + kAllBreakdownCount,
- "Compositor latency stages has changed.");
+constexpr const char* GetStageName(int stage_type_index) {
+ switch (stage_type_index) {
+ case static_cast<int>(StageType::kBeginImplFrameToSendBeginMainFrame):
+ return "BeginImplFrameToSendBeginMainFrame";
+ case static_cast<int>(StageType::kSendBeginMainFrameToCommit):
+ return "SendBeginMainFrameToCommit";
+ case static_cast<int>(StageType::kCommit):
+ return "Commit";
+ case static_cast<int>(StageType::kEndCommitToActivation):
+ return "EndCommitToActivation";
+ case static_cast<int>(StageType::kActivation):
+ return "Activation";
+ case static_cast<int>(StageType::kEndActivateToSubmitCompositorFrame):
+ return "EndActivateToSubmitCompositorFrame";
+ case static_cast<int>(
+ StageType::kSubmitCompositorFrameToPresentationCompositorFrame):
+ return "SubmitCompositorFrameToPresentationCompositorFrame";
+ case static_cast<int>(StageType::kTotalLatency):
+ return "TotalLatency";
+ case static_cast<int>(VizBreakdown::kSubmitToReceiveCompositorFrame) +
+ kVizBreakdownInitialIndex:
+ return "SubmitCompositorFrameToPresentationCompositorFrame."
+ "SubmitToReceiveCompositorFrame";
+ case static_cast<int>(VizBreakdown::kReceivedCompositorFrameToStartDraw) +
+ kVizBreakdownInitialIndex:
+ return "SubmitCompositorFrameToPresentationCompositorFrame."
+ "ReceivedCompositorFrameToStartDraw";
+ case static_cast<int>(VizBreakdown::kStartDrawToSwapEnd) +
+ kVizBreakdownInitialIndex:
+ return "SubmitCompositorFrameToPresentationCompositorFrame."
+ "StartDrawToSwapEnd";
+ case static_cast<int>(VizBreakdown::kSwapEndToPresentationCompositorFrame) +
+ kVizBreakdownInitialIndex:
+ return "SubmitCompositorFrameToPresentationCompositorFrame."
+ "SwapEndToPresentationCompositorFrame";
+ case static_cast<int>(BlinkBreakdown::kHandleInputEvents) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.HandleInputEvents";
+ case static_cast<int>(BlinkBreakdown::kAnimate) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.Animate";
+ case static_cast<int>(BlinkBreakdown::kStyleUpdate) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.StyleUpdate";
+ case static_cast<int>(BlinkBreakdown::kLayoutUpdate) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.LayoutUpdate";
+ case static_cast<int>(BlinkBreakdown::kPrepaint) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.Prepaint";
+ case static_cast<int>(BlinkBreakdown::kComposite) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.Composite";
+ case static_cast<int>(BlinkBreakdown::kPaint) + kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.Paint";
+ case static_cast<int>(BlinkBreakdown::kScrollingCoordinator) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.ScrollingCoordinator";
+ case static_cast<int>(BlinkBreakdown::kCompositeCommit) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.CompositeCommit";
+ case static_cast<int>(BlinkBreakdown::kUpdateLayers) +
+ kBlinkBreakdownInitialIndex:
+ return "SendBeginMainFrameToCommit.UpdateLayers";
+ default:
+ return "";
+ }
+}
// Names for CompositorFrameReporter::MissedFrameReportTypes, which should be
// updated in case of changes to the enum.
@@ -88,13 +131,14 @@ std::string HistogramName(const int report_type_index,
const int stage_type_index) {
DCHECK_LE(frame_sequence_tracker_type_index,
FrameSequenceTrackerType::kMaxType);
- const char* tracker_type_name = FrameSequenceTracker::
- kFrameSequenceTrackerTypeNames[frame_sequence_tracker_type_index];
+ const char* tracker_type_name =
+ FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
+ frame_sequence_tracker_type_index);
DCHECK(tracker_type_name);
return base::StrCat({"CompositorLatency.",
kReportTypeNames[report_type_index], tracker_type_name,
*tracker_type_name ? "." : "",
- kStageNames[stage_type_index]});
+ GetStageName(stage_type_index)});
}
} // namespace
@@ -129,8 +173,8 @@ void CompositorFrameReporter::StartStage(
CHECK_LT(stage_type_index, static_cast<int>(StageType::kStageTypeCount));
CHECK_GE(stage_type_index, 0);
TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
- "cc,benchmark", "PipelineReporter", this,
- TRACE_STR_COPY(kStageNames[stage_type_index]), start_time);
+ "cc,benchmark", "PipelineReporter", this, GetStageName(stage_type_index),
+ start_time);
}
void CompositorFrameReporter::EndCurrentStage(base::TimeTicks end_time) {
@@ -164,11 +208,19 @@ void CompositorFrameReporter::OnAbortBeginMainFrame() {
did_abort_main_frame_ = false;
}
+void CompositorFrameReporter::SetBlinkBreakdown(
+ std::unique_ptr<BeginMainFrameMetrics> blink_breakdown) {
+ DCHECK(blink_breakdown_.paint.is_zero());
+ if (blink_breakdown)
+ blink_breakdown_ = *blink_breakdown;
+ else
+ blink_breakdown_ = BeginMainFrameMetrics();
+}
+
void CompositorFrameReporter::SetVizBreakdown(
const viz::FrameTimingDetails& viz_breakdown) {
- DCHECK(current_stage_.viz_breakdown.received_compositor_frame_timestamp
- .is_null());
- current_stage_.viz_breakdown = viz_breakdown;
+ DCHECK(viz_breakdown_.received_compositor_frame_timestamp.is_null());
+ viz_breakdown_ = viz_breakdown;
}
void CompositorFrameReporter::TerminateReporter() {
@@ -205,9 +257,8 @@ void CompositorFrameReporter::TerminateReporter() {
submitted_frame_missed_deadline_ ? "missed_frame" : "non_missed_frame";
TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2(
"cc,benchmark", "PipelineReporter", this, frame_termination_time_,
- "termination_status", TRACE_STR_COPY(termination_status_str),
- "compositor_frame_submission_status",
- TRACE_STR_COPY(submission_status_str));
+ "termination_status", termination_status_str,
+ "compositor_frame_submission_status", submission_status_str);
// Only report histograms if the frame was presented.
if (report_latency) {
@@ -226,27 +277,31 @@ void CompositorFrameReporter::ReportStageHistograms(bool missed_frame) const {
: CompositorFrameReporter::MissedFrameReportTypes::kNonMissedFrame;
for (const StageData& stage : stage_history_) {
- ReportStageHistogramWithBreakdown(
- report_type, FrameSequenceTrackerType::kMaxType, stage);
+ ReportStageHistogramWithBreakdown(report_type, stage);
for (const auto& frame_sequence_tracker_type : *active_trackers_) {
// Report stage breakdowns.
- ReportStageHistogramWithBreakdown(report_type,
- frame_sequence_tracker_type, stage);
+ ReportStageHistogramWithBreakdown(report_type, stage,
+ frame_sequence_tracker_type);
}
}
}
void CompositorFrameReporter::ReportStageHistogramWithBreakdown(
CompositorFrameReporter::MissedFrameReportTypes report_type,
- FrameSequenceTrackerType frame_sequence_tracker_type,
- CompositorFrameReporter::StageData stage) const {
+ const CompositorFrameReporter::StageData& stage,
+ FrameSequenceTrackerType frame_sequence_tracker_type) const {
base::TimeDelta stage_delta = stage.end_time - stage.start_time;
ReportHistogram(report_type, frame_sequence_tracker_type,
static_cast<int>(stage.stage_type), stage_delta);
switch (stage.stage_type) {
+ case StageType::kSendBeginMainFrameToCommit: {
+ ReportBlinkBreakdowns(report_type, frame_sequence_tracker_type);
+ break;
+ }
case StageType::kSubmitCompositorFrameToPresentationCompositorFrame: {
- ReportVizBreakdown(report_type, frame_sequence_tracker_type, stage);
+ ReportVizBreakdowns(report_type, stage.start_time,
+ frame_sequence_tracker_type);
break;
}
default:
@@ -254,43 +309,76 @@ void CompositorFrameReporter::ReportStageHistogramWithBreakdown(
}
}
-void CompositorFrameReporter::ReportVizBreakdown(
+void CompositorFrameReporter::ReportBlinkBreakdowns(
CompositorFrameReporter::MissedFrameReportTypes report_type,
- FrameSequenceTrackerType frame_sequence_tracker_type,
- CompositorFrameReporter::StageData stage) const {
+ FrameSequenceTrackerType frame_sequence_tracker_type) const {
+ std::vector<std::pair<BlinkBreakdown, base::TimeDelta>> breakdowns = {
+ {BlinkBreakdown::kHandleInputEvents,
+ blink_breakdown_.handle_input_events},
+ {BlinkBreakdown::kAnimate, blink_breakdown_.animate},
+ {BlinkBreakdown::kStyleUpdate, blink_breakdown_.style_update},
+ {BlinkBreakdown::kLayoutUpdate, blink_breakdown_.layout_update},
+ {BlinkBreakdown::kPrepaint, blink_breakdown_.prepaint},
+ {BlinkBreakdown::kComposite, blink_breakdown_.composite},
+ {BlinkBreakdown::kPaint, blink_breakdown_.paint},
+ {BlinkBreakdown::kScrollingCoordinator,
+ blink_breakdown_.scrolling_coordinator},
+ {BlinkBreakdown::kCompositeCommit, blink_breakdown_.composite_commit},
+ {BlinkBreakdown::kUpdateLayers, blink_breakdown_.update_layers}};
+
+ for (const auto& pair : breakdowns) {
+ ReportHistogram(report_type, frame_sequence_tracker_type,
+ kBlinkBreakdownInitialIndex + static_cast<int>(pair.first),
+ pair.second);
+ }
+}
+
+void CompositorFrameReporter::ReportVizBreakdowns(
+ CompositorFrameReporter::MissedFrameReportTypes report_type,
+ base::TimeTicks start_time,
+ FrameSequenceTrackerType frame_sequence_tracker_type) const {
// Check if viz_breakdown is set.
- if (stage.viz_breakdown.received_compositor_frame_timestamp.is_null())
+ if (viz_breakdown_.received_compositor_frame_timestamp.is_null())
return;
-
- int index_origin = static_cast<int>(StageType::kStageTypeCount);
base::TimeDelta submit_to_receive_compositor_frame_delta =
- stage.viz_breakdown.received_compositor_frame_timestamp -
- stage.start_time;
- ReportHistogram(report_type, frame_sequence_tracker_type, index_origin,
- submit_to_receive_compositor_frame_delta);
-
- if (stage.viz_breakdown.draw_start_timestamp.is_null())
+ viz_breakdown_.received_compositor_frame_timestamp - start_time;
+ ReportHistogram(
+ report_type, frame_sequence_tracker_type,
+ kVizBreakdownInitialIndex +
+ static_cast<int>(VizBreakdown::kSubmitToReceiveCompositorFrame),
+ submit_to_receive_compositor_frame_delta);
+
+ if (viz_breakdown_.draw_start_timestamp.is_null())
return;
base::TimeDelta received_compositor_frame_to_start_draw_delta =
- stage.viz_breakdown.draw_start_timestamp -
- stage.viz_breakdown.received_compositor_frame_timestamp;
- ReportHistogram(report_type, frame_sequence_tracker_type, index_origin + 1,
- received_compositor_frame_to_start_draw_delta);
-
- if (stage.viz_breakdown.swap_timings.is_null())
+ viz_breakdown_.draw_start_timestamp -
+ viz_breakdown_.received_compositor_frame_timestamp;
+ ReportHistogram(
+ report_type, frame_sequence_tracker_type,
+ kVizBreakdownInitialIndex +
+ static_cast<int>(VizBreakdown::kReceivedCompositorFrameToStartDraw),
+ received_compositor_frame_to_start_draw_delta);
+
+ if (viz_breakdown_.swap_timings.is_null())
return;
base::TimeDelta start_draw_to_swap_end_delta =
- stage.viz_breakdown.swap_timings.swap_end -
- stage.viz_breakdown.draw_start_timestamp;
+ viz_breakdown_.swap_timings.swap_end -
+ viz_breakdown_.draw_start_timestamp;
- ReportHistogram(report_type, frame_sequence_tracker_type, index_origin + 2,
+ ReportHistogram(report_type, frame_sequence_tracker_type,
+ kVizBreakdownInitialIndex +
+ static_cast<int>(VizBreakdown::kStartDrawToSwapEnd),
start_draw_to_swap_end_delta);
base::TimeDelta swap_end_to_presentation_compositor_frame_delta =
- stage.end_time - stage.viz_breakdown.swap_timings.swap_end;
-
- ReportHistogram(report_type, frame_sequence_tracker_type, index_origin + 3,
- swap_end_to_presentation_compositor_frame_delta);
+ viz_breakdown_.presentation_feedback.timestamp -
+ viz_breakdown_.swap_timings.swap_end;
+
+ ReportHistogram(
+ report_type, frame_sequence_tracker_type,
+ kVizBreakdownInitialIndex +
+ static_cast<int>(VizBreakdown::kSwapEndToPresentationCompositorFrame),
+ swap_end_to_presentation_compositor_frame_delta);
}
void CompositorFrameReporter::ReportHistogram(
diff --git a/chromium/cc/metrics/compositor_frame_reporter.h b/chromium/cc/metrics/compositor_frame_reporter.h
index 79cbd089e46..d938249e58a 100644
--- a/chromium/cc/metrics/compositor_frame_reporter.h
+++ b/chromium/cc/metrics/compositor_frame_reporter.h
@@ -11,6 +11,7 @@
#include "base/time/time.h"
#include "cc/base/base_export.h"
#include "cc/cc_export.h"
+#include "cc/metrics/begin_main_frame_metrics.h"
#include "cc/metrics/frame_sequence_tracker.h"
#include "components/viz/common/frame_timing_details.h"
@@ -91,6 +92,20 @@ class CC_EXPORT CompositorFrameReporter {
kBreakdownCount
};
+ enum class BlinkBreakdown {
+ kHandleInputEvents = 0,
+ kAnimate = 1,
+ kStyleUpdate = 2,
+ kLayoutUpdate = 3,
+ kPrepaint = 4,
+ kComposite = 5,
+ kPaint = 6,
+ kScrollingCoordinator = 7,
+ kCompositeCommit = 8,
+ kUpdateLayers = 9,
+ kBreakdownCount
+ };
+
CompositorFrameReporter(
const base::flat_set<FrameSequenceTrackerType>* active_trackers,
bool is_single_threaded = false);
@@ -107,6 +122,8 @@ class CC_EXPORT CompositorFrameReporter {
void StartStage(StageType stage_type, base::TimeTicks start_time);
void TerminateFrame(FrameTerminationStatus termination_status,
base::TimeTicks termination_time);
+ void SetBlinkBreakdown(
+ std::unique_ptr<BeginMainFrameMetrics> blink_breakdown);
void SetVizBreakdown(const viz::FrameTimingDetails& viz_breakdown);
int StageHistorySizeForTesting() { return stage_history_.size(); }
@@ -119,12 +136,11 @@ class CC_EXPORT CompositorFrameReporter {
return impl_frame_finish_time_;
}
- protected:
+ private:
struct StageData {
StageType stage_type;
base::TimeTicks start_time;
base::TimeTicks end_time;
- viz::FrameTimingDetails viz_breakdown;
StageData();
StageData(StageType stage_type,
base::TimeTicks start_time,
@@ -133,31 +149,35 @@ class CC_EXPORT CompositorFrameReporter {
~StageData();
};
+ void TerminateReporter();
+ void EndCurrentStage(base::TimeTicks end_time);
+ void ReportStageHistograms(bool missed_frame) const;
+ void ReportStageHistogramWithBreakdown(
+ MissedFrameReportTypes report_type,
+ const StageData& stage,
+ FrameSequenceTrackerType frame_sequence_tracker_type =
+ FrameSequenceTrackerType::kMaxType) const;
+ void ReportBlinkBreakdowns(
+ MissedFrameReportTypes report_type,
+ FrameSequenceTrackerType frame_sequence_tracker_type) const;
+ void ReportVizBreakdowns(
+ MissedFrameReportTypes report_type,
+ const base::TimeTicks start_time,
+ FrameSequenceTrackerType frame_sequence_tracker_type) const;
+ void ReportHistogram(MissedFrameReportTypes report_type,
+ FrameSequenceTrackerType intraction_type,
+ const int stage_type_index,
+ base::TimeDelta time_delta) const;
+
StageData current_stage_;
+ BeginMainFrameMetrics blink_breakdown_;
+ viz::FrameTimingDetails viz_breakdown_;
// Stage data is recorded here. On destruction these stages will be reported
// to UMA if the termination status is |kPresentedFrame|. Reported data will
// be divided based on the frame submission status.
std::vector<StageData> stage_history_;
- private:
- void TerminateReporter();
- void EndCurrentStage(base::TimeTicks end_time);
- void ReportStageHistograms(bool missed_frame) const;
- void ReportStageHistogramWithBreakdown(
- CompositorFrameReporter::MissedFrameReportTypes report_type,
- FrameSequenceTrackerType frame_sequence_tracker_type,
- CompositorFrameReporter::StageData stage) const;
- void ReportVizBreakdown(
- CompositorFrameReporter::MissedFrameReportTypes report_type,
- FrameSequenceTrackerType frame_sequence_tracker_type,
- CompositorFrameReporter::StageData stage) const;
- void ReportHistogram(
- CompositorFrameReporter::MissedFrameReportTypes report_type,
- FrameSequenceTrackerType intraction_type,
- const int stage_type_index,
- base::TimeDelta time_delta) const;
-
// Returns true if the stage duration is greater than |kAbnormalityPercentile|
// of its RollingTimeDeltaHistory.
base::TimeDelta GetStateNormalUpperLimit(const StageData& stage) const;
diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller.cc b/chromium/cc/metrics/compositor_frame_reporting_controller.cc
index 760207b87f0..13a575ff211 100644
--- a/chromium/cc/metrics/compositor_frame_reporting_controller.cc
+++ b/chromium/cc/metrics/compositor_frame_reporting_controller.cc
@@ -52,8 +52,10 @@ base::TimeTicks CompositorFrameReportingController::Now() const {
void CompositorFrameReportingController::WillBeginImplFrame() {
base::TimeTicks begin_time = Now();
if (reporters_[PipelineStage::kBeginImplFrame]) {
+ // If the the reporter is replaced in this stage, it means that Impl frame
+ // caused no damage.
reporters_[PipelineStage::kBeginImplFrame]->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kReplacedByNewReporter,
+ CompositorFrameReporter::FrameTerminationStatus::kDidNotProduceFrame,
begin_time);
}
std::unique_ptr<CompositorFrameReporter> reporter =
@@ -207,6 +209,13 @@ void CompositorFrameReportingController::DidPresentCompositorFrame(
}
}
+void CompositorFrameReportingController::SetBlinkBreakdown(
+ std::unique_ptr<BeginMainFrameMetrics> details) {
+ DCHECK(reporters_[PipelineStage::kBeginMainFrame]);
+ reporters_[PipelineStage::kBeginMainFrame]->SetBlinkBreakdown(
+ std::move(details));
+}
+
void CompositorFrameReportingController::AddActiveTracker(
FrameSequenceTrackerType type) {
active_trackers_.insert(type);
diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller.h b/chromium/cc/metrics/compositor_frame_reporting_controller.h
index 80254c1dc64..eda48867076 100644
--- a/chromium/cc/metrics/compositor_frame_reporting_controller.h
+++ b/chromium/cc/metrics/compositor_frame_reporting_controller.h
@@ -20,6 +20,7 @@ struct FrameTimingDetails;
}
namespace cc {
+struct BeginMainFrameMetrics;
class RollingTimeDeltaHistory;
// This is used for managing simultaneous CompositorFrameReporter instances
@@ -62,6 +63,8 @@ class CC_EXPORT CompositorFrameReportingController {
uint32_t frame_token,
const viz::FrameTimingDetails& details);
+ void SetBlinkBreakdown(std::unique_ptr<BeginMainFrameMetrics> details);
+
virtual void AddActiveTracker(FrameSequenceTrackerType type);
virtual void RemoveActiveTracker(FrameSequenceTrackerType type);
diff --git a/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc b/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc
index 6fd89c4a30a..7d4884c1e49 100644
--- a/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc
+++ b/chromium/cc/metrics/compositor_frame_reporting_controller_unittest.cc
@@ -61,13 +61,14 @@ class CompositorFrameReportingControllerTest : public testing::Test {
reporting_controller_.WillBeginMainFrame();
}
- void SimulateCommit() {
+ void SimulateCommit(std::unique_ptr<BeginMainFrameMetrics> blink_breakdown) {
if (!reporting_controller_.reporters()[CompositorFrameReportingController::
PipelineStage::kBeginMainFrame])
SimulateBeginMainFrame();
CHECK(
reporting_controller_.reporters()[CompositorFrameReportingController::
PipelineStage::kBeginMainFrame]);
+ reporting_controller_.SetBlinkBreakdown(std::move(blink_breakdown));
reporting_controller_.WillCommit();
reporting_controller_.DidCommit();
}
@@ -75,7 +76,7 @@ class CompositorFrameReportingControllerTest : public testing::Test {
void SimulateActivate() {
if (!reporting_controller_.reporters()
[CompositorFrameReportingController::PipelineStage::kCommit])
- SimulateCommit();
+ SimulateCommit(nullptr);
CHECK(reporting_controller_.reporters()
[CompositorFrameReportingController::PipelineStage::kCommit]);
reporting_controller_.WillActivate();
@@ -155,7 +156,7 @@ TEST_F(CompositorFrameReportingControllerTest, ActiveReporterCounts) {
// 4 simultaneous reporters active.
SimulateActivate();
- SimulateCommit();
+ SimulateCommit(nullptr);
SimulateBeginMainFrame();
@@ -173,7 +174,7 @@ TEST_F(CompositorFrameReportingControllerTest,
// 2 reporters active.
SimulateActivate();
- SimulateCommit();
+ SimulateCommit(nullptr);
// Submitting and Presenting the next reporter which will be a normal frame.
SimulatePresentCompositorFrame();
@@ -202,7 +203,7 @@ TEST_F(CompositorFrameReportingControllerTest,
// Submitting the next reporter will be replaced as a result of a new commit.
// And this will be reported for all stage before activate as a missed frame.
- SimulateCommit();
+ SimulateCommit(nullptr);
// Non Missed frame histogram counts should not change.
histogram_tester.ExpectTotalCount(
"CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
@@ -228,5 +229,69 @@ TEST_F(CompositorFrameReportingControllerTest,
histogram_tester.ExpectTotalCount(
"CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 0);
}
+
+TEST_F(CompositorFrameReportingControllerTest, ImplFrameCausedNoDamage) {
+ base::HistogramTester histogram_tester;
+
+ SimulateBeginImplFrame();
+ SimulateBeginImplFrame();
+ histogram_tester.ExpectTotalCount(
+ "CompositorLatency.MissedFrame.BeginImplFrameToSendBeginMainFrame", 0);
+}
+
+TEST_F(CompositorFrameReportingControllerTest, BlinkBreakdown) {
+ base::HistogramTester histogram_tester;
+
+ std::unique_ptr<BeginMainFrameMetrics> blink_breakdown =
+ std::make_unique<BeginMainFrameMetrics>();
+ blink_breakdown->handle_input_events = base::TimeDelta::FromMicroseconds(10);
+ blink_breakdown->animate = base::TimeDelta::FromMicroseconds(9);
+ blink_breakdown->style_update = base::TimeDelta::FromMicroseconds(8);
+ blink_breakdown->layout_update = base::TimeDelta::FromMicroseconds(7);
+ blink_breakdown->prepaint = base::TimeDelta::FromMicroseconds(6);
+ blink_breakdown->composite = base::TimeDelta::FromMicroseconds(5);
+ blink_breakdown->paint = base::TimeDelta::FromMicroseconds(4);
+ blink_breakdown->scrolling_coordinator = base::TimeDelta::FromMicroseconds(3);
+ blink_breakdown->composite_commit = base::TimeDelta::FromMicroseconds(2);
+ blink_breakdown->update_layers = base::TimeDelta::FromMicroseconds(1);
+
+ SimulateActivate();
+ SimulateCommit(std::move(blink_breakdown));
+ SimulatePresentCompositorFrame();
+
+ histogram_tester.ExpectTotalCount(
+ "CompositorLatency.SendBeginMainFrameToCommit", 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.HandleInputEvents",
+ base::TimeDelta::FromMicroseconds(10).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.Animate",
+ base::TimeDelta::FromMicroseconds(9).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.StyleUpdate",
+ base::TimeDelta::FromMicroseconds(8).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.LayoutUpdate",
+ base::TimeDelta::FromMicroseconds(7).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.Prepaint",
+ base::TimeDelta::FromMicroseconds(6).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.Composite",
+ base::TimeDelta::FromMicroseconds(5).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.Paint",
+ base::TimeDelta::FromMicroseconds(4).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.ScrollingCoordinator",
+ base::TimeDelta::FromMicroseconds(3).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.CompositeCommit",
+ base::TimeDelta::FromMicroseconds(2).InMilliseconds(), 1);
+ histogram_tester.ExpectUniqueSample(
+ "CompositorLatency.SendBeginMainFrameToCommit.UpdateLayers",
+ base::TimeDelta::FromMicroseconds(1).InMilliseconds(), 1);
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/metrics/compositor_timing_history.cc b/chromium/cc/metrics/compositor_timing_history.cc
index d244237b7e9..d2bf9e2c354 100644
--- a/chromium/cc/metrics/compositor_timing_history.cc
+++ b/chromium/cc/metrics/compositor_timing_history.cc
@@ -13,6 +13,7 @@
#include "base/trace_event/trace_event.h"
#include "cc/debug/rendering_stats_instrumentation.h"
#include "cc/metrics/compositor_frame_reporting_controller.h"
+#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h"
namespace cc {
@@ -593,25 +594,21 @@ CompositorTimingHistory::CreateUMAReporter(UMACategory category) {
return base::WrapUnique<CompositorTimingHistory::UMAReporter>(nullptr);
}
-void CompositorTimingHistory::AsValueInto(
- base::trace_event::TracedValue* state) const {
- state->SetDouble(
- "begin_main_frame_queue_critical_estimate_ms",
- BeginMainFrameQueueDurationCriticalEstimate().InMillisecondsF());
- state->SetDouble(
- "begin_main_frame_queue_not_critical_estimate_ms",
- BeginMainFrameQueueDurationNotCriticalEstimate().InMillisecondsF());
- state->SetDouble(
- "begin_main_frame_start_to_ready_to_commit_estimate_ms",
- BeginMainFrameStartToReadyToCommitDurationEstimate().InMillisecondsF());
- state->SetDouble("commit_to_ready_to_activate_estimate_ms",
- CommitToReadyToActivateDurationEstimate().InMillisecondsF());
- state->SetDouble("prepare_tiles_estimate_ms",
- PrepareTilesDurationEstimate().InMillisecondsF());
- state->SetDouble("activate_estimate_ms",
- ActivateDurationEstimate().InMillisecondsF());
- state->SetDouble("draw_estimate_ms",
- DrawDurationEstimate().InMillisecondsF());
+void CompositorTimingHistory::AsProtozeroInto(
+ perfetto::protos::pbzero::CompositorTimingHistory* state) const {
+ state->set_begin_main_frame_queue_critical_estimate_delta_us(
+ BeginMainFrameQueueDurationCriticalEstimate().InMicroseconds());
+ state->set_begin_main_frame_queue_not_critical_estimate_delta_us(
+ BeginMainFrameQueueDurationNotCriticalEstimate().InMicroseconds());
+ state->set_begin_main_frame_start_to_ready_to_commit_estimate_delta_us(
+ BeginMainFrameStartToReadyToCommitDurationEstimate().InMicroseconds());
+ state->set_commit_to_ready_to_activate_estimate_delta_us(
+ CommitToReadyToActivateDurationEstimate().InMicroseconds());
+ state->set_prepare_tiles_estimate_delta_us(
+ PrepareTilesDurationEstimate().InMicroseconds());
+ state->set_activate_estimate_delta_us(
+ ActivateDurationEstimate().InMicroseconds());
+ state->set_draw_estimate_delta_us(DrawDurationEstimate().InMicroseconds());
}
base::TimeTicks CompositorTimingHistory::Now() const {
@@ -776,8 +773,10 @@ void CompositorTimingHistory::BeginMainFrameAborted() {
begin_main_frame_frame_time_ = base::TimeTicks();
}
-void CompositorTimingHistory::NotifyReadyToCommit() {
+void CompositorTimingHistory::NotifyReadyToCommit(
+ std::unique_ptr<BeginMainFrameMetrics> details) {
DCHECK_NE(begin_main_frame_start_time_, base::TimeTicks());
+ compositor_frame_reporting_controller_->SetBlinkBreakdown(std::move(details));
begin_main_frame_start_to_ready_to_commit_duration_history_.InsertSample(
Now() - begin_main_frame_start_time_);
}
diff --git a/chromium/cc/metrics/compositor_timing_history.h b/chromium/cc/metrics/compositor_timing_history.h
index c39f69ad071..57b8c115f86 100644
--- a/chromium/cc/metrics/compositor_timing_history.h
+++ b/chromium/cc/metrics/compositor_timing_history.h
@@ -12,18 +12,20 @@
#include "cc/tiles/tile_priority.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
-namespace base {
-namespace trace_event {
-class TracedValue;
-} // namespace trace_event
-} // namespace base
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class CompositorTimingHistory;
+}
+} // namespace protos
+} // namespace perfetto
namespace viz {
struct FrameTimingDetails;
}
namespace cc {
-
+struct BeginMainFrameMetrics;
class CompositorFrameReportingController;
class RenderingStatsInstrumentation;
@@ -47,7 +49,8 @@ class CC_EXPORT CompositorTimingHistory {
CompositorTimingHistory& operator=(const CompositorTimingHistory&) = delete;
- void AsValueInto(base::trace_event::TracedValue* state) const;
+ void AsProtozeroInto(
+ perfetto::protos::pbzero::CompositorTimingHistory* state) const;
// The main thread responsiveness depends heavily on whether or not the
// on_critical_path flag is set, so we record response times separately.
@@ -76,7 +79,7 @@ class CC_EXPORT CompositorTimingHistory {
base::TimeTicks main_frame_time);
void BeginMainFrameStarted(base::TimeTicks main_thread_start_time);
void BeginMainFrameAborted();
- void NotifyReadyToCommit();
+ void NotifyReadyToCommit(std::unique_ptr<BeginMainFrameMetrics> details);
void WillCommit();
void DidCommit();
void WillPrepareTiles();
diff --git a/chromium/cc/metrics/compositor_timing_history_unittest.cc b/chromium/cc/metrics/compositor_timing_history_unittest.cc
index 81f72e61733..695217c62df 100644
--- a/chromium/cc/metrics/compositor_timing_history_unittest.cc
+++ b/chromium/cc/metrics/compositor_timing_history_unittest.cc
@@ -122,7 +122,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_Commit) {
AdvanceNowBy(begin_main_frame_queue_duration);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- timing_history_.NotifyReadyToCommit();
+ timing_history_.NotifyReadyToCommit(nullptr);
timing_history_.WillCommit();
AdvanceNowBy(commit_duration);
timing_history_.DidCommit();
diff --git a/chromium/cc/metrics/frame_sequence_metrics_unittest.cc b/chromium/cc/metrics/frame_sequence_metrics_unittest.cc
new file mode 100644
index 00000000000..a41eb1cdf43
--- /dev/null
+++ b/chromium/cc/metrics/frame_sequence_metrics_unittest.cc
@@ -0,0 +1,75 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/metrics/frame_sequence_tracker.h"
+
+#include "base/macros.h"
+#include "base/test/metrics/histogram_tester.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace cc {
+
+TEST(FrameSequenceMetricsTest, MergeMetrics) {
+ // Create a metric with only a small number of frames. It shouldn't report any
+ // metrics.
+ FrameSequenceMetrics first(FrameSequenceTrackerType::kTouchScroll, nullptr,
+ nullptr);
+ first.impl_throughput().frames_expected = 20;
+ first.impl_throughput().frames_produced = 10;
+ EXPECT_FALSE(first.HasEnoughDataForReporting());
+
+ // Create a second metric with too few frames to report any metrics.
+ auto second = std::make_unique<FrameSequenceMetrics>(
+ FrameSequenceTrackerType::kTouchScroll, nullptr, nullptr);
+ second->impl_throughput().frames_expected = 90;
+ second->impl_throughput().frames_produced = 60;
+ EXPECT_FALSE(second->HasEnoughDataForReporting());
+
+ // Merge the two metrics. The result should have enough frames to report
+ // metrics.
+ first.Merge(std::move(second));
+ EXPECT_TRUE(first.HasEnoughDataForReporting());
+}
+
+TEST(FrameSequenceMetricsTest, AllMetricsReported) {
+ base::HistogramTester histograms;
+
+ // Create a metric with enough frames on impl to be reported, but not enough
+ // on main.
+ FrameSequenceMetrics first(FrameSequenceTrackerType::kTouchScroll, nullptr,
+ nullptr);
+ first.impl_throughput().frames_expected = 120;
+ first.impl_throughput().frames_produced = 80;
+ first.main_throughput().frames_expected = 20;
+ first.main_throughput().frames_produced = 10;
+ EXPECT_TRUE(first.HasEnoughDataForReporting());
+ first.ReportMetrics();
+
+ // The compositor-thread metric should be reported, but not the main-thread
+ // metric.
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 1u);
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.Throughput.MainThread.TouchScroll", 0u);
+
+ // There should still be data left over for the main-thread.
+ EXPECT_TRUE(first.HasDataLeftForReporting());
+
+ auto second = std::make_unique<FrameSequenceMetrics>(
+ FrameSequenceTrackerType::kTouchScroll, nullptr, nullptr);
+ second->impl_throughput().frames_expected = 110;
+ second->impl_throughput().frames_produced = 100;
+ second->main_throughput().frames_expected = 90;
+ first.Merge(std::move(second));
+ EXPECT_TRUE(first.HasEnoughDataForReporting());
+ first.ReportMetrics();
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 2u);
+ histograms.ExpectTotalCount(
+ "Graphics.Smoothness.Throughput.MainThread.TouchScroll", 1u);
+ // All the metrics have now been reported. No data should be left over.
+ EXPECT_FALSE(first.HasDataLeftForReporting());
+}
+
+} // namespace cc
diff --git a/chromium/cc/metrics/frame_sequence_tracker.cc b/chromium/cc/metrics/frame_sequence_tracker.cc
index 5ba4bf9f95b..5d8cfab6e99 100644
--- a/chromium/cc/metrics/frame_sequence_tracker.cc
+++ b/chromium/cc/metrics/frame_sequence_tracker.cc
@@ -11,70 +11,200 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "cc/metrics/compositor_frame_reporting_controller.h"
+#include "cc/metrics/throughput_ukm_reporter.h"
+#include "cc/trees/ukm_manager.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/quads/compositor_frame_metadata.h"
#include "ui/gfx/presentation_feedback.h"
+// This macro is used with DCHECK to provide addition debug info.
+#if DCHECK_IS_ON()
+#define TRACKER_TRACE_STREAM frame_sequence_trace_
+#define TRACKER_DCHECK_MSG \
+ " in " << GetFrameSequenceTrackerTypeName(static_cast<int>(this->type_)) \
+ << " tracker: " << frame_sequence_trace_.str() << " (" \
+ << frame_sequence_trace_.str().size() << ")";
+#else
+#define TRACKER_TRACE_STREAM EAT_STREAM_PARAMETERS
+#define TRACKER_DCHECK_MSG ""
+#endif
+
namespace cc {
-constexpr const char* FrameSequenceTracker::kFrameSequenceTrackerTypeNames[] = {
- [FrameSequenceTrackerType::kCompositorAnimation] = "CompositorAnimation",
- [FrameSequenceTrackerType::kMainThreadAnimation] = "MainThreadAnimation",
- [FrameSequenceTrackerType::kPinchZoom] = "PinchZoom",
- [FrameSequenceTrackerType::kRAF] = "RAF",
- [FrameSequenceTrackerType::kTouchScroll] = "TouchScroll",
- [FrameSequenceTrackerType::kUniversal] = "Universal",
- [FrameSequenceTrackerType::kVideo] = "Video",
- [FrameSequenceTrackerType::kWheelScroll] = "WheelScroll",
- [FrameSequenceTrackerType::kMaxType] = "",
-};
+const char* FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
+ int type_index) {
+ switch (type_index) {
+ case static_cast<int>(FrameSequenceTrackerType::kCompositorAnimation):
+ return "CompositorAnimation";
+ case static_cast<int>(FrameSequenceTrackerType::kMainThreadAnimation):
+ return "MainThreadAnimation";
+ case static_cast<int>(FrameSequenceTrackerType::kPinchZoom):
+ return "PinchZoom";
+ case static_cast<int>(FrameSequenceTrackerType::kRAF):
+ return "RAF";
+ case static_cast<int>(FrameSequenceTrackerType::kTouchScroll):
+ return "TouchScroll";
+ case static_cast<int>(FrameSequenceTrackerType::kUniversal):
+ return "Universal";
+ case static_cast<int>(FrameSequenceTrackerType::kVideo):
+ return "Video";
+ case static_cast<int>(FrameSequenceTrackerType::kWheelScroll):
+ return "WheelScroll";
+ default:
+ return "";
+ }
+}
namespace {
-// Avoid reporting any throughput metric for sequences that had a small amount
-// of frames.
-constexpr int kMinFramesForThroughputMetric = 4;
-
-enum class ThreadType {
- kMain,
- kCompositor,
- kSlower,
-};
+// Avoid reporting any throughput metric for sequences that do not have a
+// sufficient number of frames.
+constexpr int kMinFramesForThroughputMetric = 100;
-constexpr int kBuiltinSequenceNum =
- base::size(FrameSequenceTracker::kFrameSequenceTrackerTypeNames);
+constexpr int kBuiltinSequenceNum = FrameSequenceTrackerType::kMaxType + 1;
constexpr int kMaximumHistogramIndex = 3 * kBuiltinSequenceNum;
-int GetIndexForMetric(ThreadType thread_type, FrameSequenceTrackerType type) {
- if (thread_type == ThreadType::kMain)
+int GetIndexForMetric(FrameSequenceTracker::ThreadType thread_type,
+ FrameSequenceTrackerType type) {
+ if (thread_type == FrameSequenceTracker::ThreadType::kMain)
return static_cast<int>(type);
- if (thread_type == ThreadType::kCompositor)
+ if (thread_type == FrameSequenceTracker::ThreadType::kCompositor)
return static_cast<int>(type + kBuiltinSequenceNum);
return static_cast<int>(type + 2 * kBuiltinSequenceNum);
}
std::string GetCheckerboardingHistogramName(FrameSequenceTrackerType type) {
- return base::StrCat(
- {"Graphics.Smoothness.Checkerboarding.",
- FrameSequenceTracker::kFrameSequenceTrackerTypeNames[type]});
+ return base::StrCat({"Graphics.Smoothness.Checkerboarding.",
+ FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
+ static_cast<int>(type))});
}
std::string GetThroughputHistogramName(FrameSequenceTrackerType type,
const char* thread_name) {
- return base::StrCat(
- {"Graphics.Smoothness.Throughput.", thread_name, ".",
- FrameSequenceTracker::kFrameSequenceTrackerTypeNames[type]});
+ return base::StrCat({"Graphics.Smoothness.Throughput.", thread_name, ".",
+ FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
+ static_cast<int>(type))});
}
std::string GetFrameSequenceLengthHistogramName(FrameSequenceTrackerType type) {
- return base::StrCat(
- {"Graphics.Smoothness.FrameSequenceLength.",
- FrameSequenceTracker::kFrameSequenceTrackerTypeNames[type]});
+ return base::StrCat({"Graphics.Smoothness.FrameSequenceLength.",
+ FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
+ static_cast<int>(type))});
}
} // namespace
////////////////////////////////////////////////////////////////////////////////
+// FrameSequenceMetrics
+
+FrameSequenceMetrics::FrameSequenceMetrics(FrameSequenceTrackerType type,
+ UkmManager* ukm_manager,
+ ThroughputUkmReporter* ukm_reporter)
+ : type_(type),
+ ukm_manager_(ukm_manager),
+ throughput_ukm_reporter_(ukm_reporter) {
+ TRACE_EVENT_ASYNC_BEGIN1(
+ "cc,benchmark", "FrameSequenceTracker", this, "name",
+ FrameSequenceTracker::GetFrameSequenceTrackerTypeName(
+ static_cast<int>(type_)));
+}
+
+FrameSequenceMetrics::~FrameSequenceMetrics() {
+ if (HasDataLeftForReporting())
+ ReportMetrics();
+}
+
+void FrameSequenceMetrics::Merge(
+ std::unique_ptr<FrameSequenceMetrics> metrics) {
+ DCHECK_EQ(type_, metrics->type_);
+ impl_throughput_.Merge(metrics->impl_throughput_);
+ main_throughput_.Merge(metrics->main_throughput_);
+ frames_checkerboarded_ += metrics->frames_checkerboarded_;
+
+ // Reset the state of |metrics| before destroying it, so that it doesn't end
+ // up reporting the metrics.
+ metrics->impl_throughput_ = {};
+ metrics->main_throughput_ = {};
+ metrics->frames_checkerboarded_ = 0;
+}
+
+bool FrameSequenceMetrics::HasEnoughDataForReporting() const {
+ return impl_throughput_.frames_expected >= kMinFramesForThroughputMetric ||
+ main_throughput_.frames_expected >= kMinFramesForThroughputMetric;
+}
+
+bool FrameSequenceMetrics::HasDataLeftForReporting() const {
+ return impl_throughput_.frames_expected > 0 ||
+ main_throughput_.frames_expected > 0;
+}
+
+void FrameSequenceMetrics::ReportMetrics() {
+ DCHECK_LE(impl_throughput_.frames_produced, impl_throughput_.frames_expected);
+ DCHECK_LE(main_throughput_.frames_produced, main_throughput_.frames_expected);
+ TRACE_EVENT_ASYNC_END2(
+ "cc,benchmark", "FrameSequenceTracker", this, "args",
+ ThroughputData::ToTracedValue(impl_throughput_, main_throughput_),
+ "checkerboard", frames_checkerboarded_);
+
+ // Report the throughput metrics.
+ base::Optional<int> impl_throughput_percent = ThroughputData::ReportHistogram(
+ type_, "CompositorThread",
+ GetIndexForMetric(FrameSequenceTracker::ThreadType::kCompositor, type_),
+ impl_throughput_);
+ base::Optional<int> main_throughput_percent = ThroughputData::ReportHistogram(
+ type_, "MainThread",
+ GetIndexForMetric(FrameSequenceTracker::ThreadType::kMain, type_),
+ main_throughput_);
+
+ base::Optional<ThroughputData> slower_throughput;
+ base::Optional<int> slower_throughput_percent;
+ if (impl_throughput_percent &&
+ (!main_throughput_percent ||
+ impl_throughput_percent.value() <= main_throughput_percent.value())) {
+ slower_throughput = impl_throughput_;
+ }
+ if (main_throughput_percent &&
+ (!impl_throughput_percent ||
+ main_throughput_percent.value() < impl_throughput_percent.value())) {
+ slower_throughput = main_throughput_;
+ }
+ if (slower_throughput.has_value()) {
+ slower_throughput_percent = ThroughputData::ReportHistogram(
+ type_, "SlowerThread",
+ GetIndexForMetric(FrameSequenceTracker::ThreadType::kSlower, type_),
+ slower_throughput.value());
+ DCHECK(slower_throughput_percent.has_value());
+ }
+
+ // slower_throughput has value indicates that we have reported UMA.
+ if (slower_throughput.has_value() && ukm_manager_ &&
+ throughput_ukm_reporter_) {
+ throughput_ukm_reporter_->ReportThroughputUkm(
+ ukm_manager_, slower_throughput_percent, impl_throughput_percent,
+ main_throughput_percent, type_);
+ }
+
+ // Report the checkerboarding metrics.
+ if (impl_throughput_.frames_expected >= kMinFramesForThroughputMetric) {
+ const int checkerboarding_percent = static_cast<int>(
+ 100 * frames_checkerboarded_ / impl_throughput_.frames_expected);
+ STATIC_HISTOGRAM_POINTER_GROUP(
+ GetCheckerboardingHistogramName(type_), type_,
+ FrameSequenceTrackerType::kMaxType, Add(checkerboarding_percent),
+ base::LinearHistogram::FactoryGet(
+ GetCheckerboardingHistogramName(type_), 1, 100, 101,
+ base::HistogramBase::kUmaTargetedHistogramFlag));
+ frames_checkerboarded_ = 0;
+ }
+
+ // Reset the metrics that have already been reported.
+ if (impl_throughput_percent.has_value())
+ impl_throughput_ = {};
+ if (main_throughput_percent.has_value())
+ main_throughput_ = {};
+}
+
+////////////////////////////////////////////////////////////////////////////////
// FrameSequenceTrackerCollection
FrameSequenceTrackerCollection::FrameSequenceTrackerCollection(
@@ -82,7 +212,8 @@ FrameSequenceTrackerCollection::FrameSequenceTrackerCollection(
CompositorFrameReportingController* compositor_frame_reporting_controller)
: is_single_threaded_(is_single_threaded),
compositor_frame_reporting_controller_(
- compositor_frame_reporting_controller) {}
+ compositor_frame_reporting_controller),
+ throughput_ukm_reporter_(std::make_unique<ThroughputUkmReporter>()) {}
FrameSequenceTrackerCollection::~FrameSequenceTrackerCollection() {
frame_trackers_.clear();
@@ -95,7 +226,8 @@ void FrameSequenceTrackerCollection::StartSequence(
return;
if (frame_trackers_.contains(type))
return;
- auto tracker = base::WrapUnique(new FrameSequenceTracker(type));
+ auto tracker = base::WrapUnique(new FrameSequenceTracker(
+ type, ukm_manager_, throughput_ukm_reporter_.get()));
frame_trackers_[type] = std::move(tracker);
if (compositor_frame_reporting_controller_)
@@ -175,6 +307,26 @@ void FrameSequenceTrackerCollection::NotifyFramePresented(
for (auto& tracker : removal_trackers_)
tracker->ReportFramePresented(frame_token, feedback);
+ for (auto& tracker : removal_trackers_) {
+ if (tracker->termination_status() ==
+ FrameSequenceTracker::TerminationStatus::kReadyForTermination) {
+ // The tracker is ready to be terminated. Take the metrics from the
+ // tracker, merge with any outstanding metrics from previous trackers of
+ // the same type. If there are enough frames to report the metrics, then
+ // report the metrics and destroy it. Otherwise, retain it to be merged
+ // with follow-up sequences.
+ auto metrics = tracker->TakeMetrics();
+ if (accumulated_metrics_.contains(tracker->type())) {
+ metrics->Merge(std::move(accumulated_metrics_[tracker->type()]));
+ accumulated_metrics_.erase(tracker->type());
+ }
+ if (metrics->HasEnoughDataForReporting())
+ metrics->ReportMetrics();
+ if (metrics->HasDataLeftForReporting())
+ accumulated_metrics_[tracker->type()] = std::move(metrics);
+ }
+ }
+
// Destroy the trackers that are ready to be terminated.
base::EraseIf(
removal_trackers_,
@@ -209,67 +361,31 @@ FrameSequenceTracker* FrameSequenceTrackerCollection::GetTrackerForTesting(
return frame_trackers_[type].get();
}
+void FrameSequenceTrackerCollection::SetUkmManager(UkmManager* manager) {
+ DCHECK(frame_trackers_.empty());
+ ukm_manager_ = manager;
+}
+
////////////////////////////////////////////////////////////////////////////////
// FrameSequenceTracker
-FrameSequenceTracker::FrameSequenceTracker(FrameSequenceTrackerType type)
- : type_(type) {
+FrameSequenceTracker::FrameSequenceTracker(
+ FrameSequenceTrackerType type,
+ UkmManager* manager,
+ ThroughputUkmReporter* throughput_ukm_reporter)
+ : type_(type),
+ metrics_(
+ std::make_unique<FrameSequenceMetrics>(type,
+ manager,
+ throughput_ukm_reporter)) {
DCHECK_LT(type_, FrameSequenceTrackerType::kMaxType);
- TRACE_EVENT_ASYNC_BEGIN1(
- "cc,benchmark", "FrameSequenceTracker", this, "name",
- TRACE_STR_COPY(
- FrameSequenceTracker::kFrameSequenceTrackerTypeNames[type_]));
}
FrameSequenceTracker::~FrameSequenceTracker() {
- DCHECK_LE(impl_throughput_.frames_produced, impl_throughput_.frames_expected);
- DCHECK_LE(main_throughput_.frames_produced, main_throughput_.frames_expected);
- DCHECK_LE(main_throughput_.frames_produced, impl_throughput_.frames_produced);
- TRACE_EVENT_ASYNC_END2(
- "cc,benchmark", "FrameSequenceTracker", this, "args",
- ThroughputData::ToTracedValue(impl_throughput_, main_throughput_),
- "checkerboard", checkerboarding_.frames_checkerboarded);
- ReportMetrics();
}
void FrameSequenceTracker::ReportMetrics() {
- // Report the throughput metrics.
- base::Optional<int> impl_throughput_percent = ThroughputData::ReportHistogram(
- type_, "CompositorThread",
- GetIndexForMetric(ThreadType::kCompositor, type_), impl_throughput_);
- base::Optional<int> main_throughput_percent = ThroughputData::ReportHistogram(
- type_, "MainThread", GetIndexForMetric(ThreadType::kMain, type_),
- main_throughput_);
-
- base::Optional<ThroughputData> slower_throughput;
- if (impl_throughput_percent &&
- (!main_throughput_percent ||
- impl_throughput_percent.value() <= main_throughput_percent.value())) {
- slower_throughput = impl_throughput_;
- }
- if (main_throughput_percent &&
- (!impl_throughput_percent ||
- main_throughput_percent.value() < impl_throughput_percent.value())) {
- slower_throughput = main_throughput_;
- }
- if (slower_throughput.has_value()) {
- ThroughputData::ReportHistogram(
- type_, "SlowerThread", GetIndexForMetric(ThreadType::kSlower, type_),
- slower_throughput.value());
- }
-
- // Report the checkerboarding metrics.
- if (impl_throughput_.frames_expected >= kMinFramesForThroughputMetric) {
- const int checkerboarding_percent =
- static_cast<int>(100 * checkerboarding_.frames_checkerboarded /
- impl_throughput_.frames_expected);
- STATIC_HISTOGRAM_POINTER_GROUP(
- GetCheckerboardingHistogramName(type_), type_,
- FrameSequenceTrackerType::kMaxType, Add(checkerboarding_percent),
- base::LinearHistogram::FactoryGet(
- GetCheckerboardingHistogramName(type_), 1, 100, 101,
- base::HistogramBase::kUmaTargetedHistogramFlag));
- }
+ metrics_->ReportMetrics();
}
void FrameSequenceTracker::ReportBeginImplFrame(
@@ -280,9 +396,14 @@ void FrameSequenceTracker::ReportBeginImplFrame(
if (ShouldIgnoreBeginFrameSource(args.source_id))
return;
+#if DCHECK_IS_ON()
+ if (args.type == viz::BeginFrameArgs::NORMAL)
+ impl_frames_.insert(std::make_pair(args.source_id, args.sequence_number));
+#endif
+ TRACKER_TRACE_STREAM << 'b';
UpdateTrackedFrameData(&begin_impl_frame_data_, args.source_id,
args.sequence_number);
- impl_throughput_.frames_expected +=
+ impl_throughput().frames_expected +=
begin_impl_frame_data_.previous_sequence_delta;
if (first_frame_timestamp_.is_null())
@@ -297,11 +418,24 @@ void FrameSequenceTracker::ReportBeginMainFrame(
if (ShouldIgnoreBeginFrameSource(args.source_id))
return;
+ if (ShouldIgnoreSequence(args.sequence_number))
+ return;
+
+#if DCHECK_IS_ON()
+ if (args.type == viz::BeginFrameArgs::NORMAL) {
+ DCHECK(impl_frames_.contains(
+ std::make_pair(args.source_id, args.sequence_number)));
+ }
+#endif
+
+ TRACKER_TRACE_STREAM << 'B';
+ TRACKER_TRACE_STREAM << "(" << begin_main_frame_data_.previous_sequence << ","
+ << args.sequence_number << ")";
UpdateTrackedFrameData(&begin_main_frame_data_, args.source_id,
args.sequence_number);
if (first_received_main_sequence_ == 0)
first_received_main_sequence_ = args.sequence_number;
- main_throughput_.frames_expected +=
+ main_throughput().frames_expected +=
begin_main_frame_data_.previous_sequence_delta;
}
@@ -310,14 +444,10 @@ void FrameSequenceTracker::ReportSubmitFrame(
bool has_missing_content,
const viz::BeginFrameAck& ack,
const viz::BeginFrameArgs& origin_args) {
- if (termination_status_ != TerminationStatus::kActive)
- return;
-
- if (ShouldIgnoreBeginFrameSource(ack.source_id))
- return;
-
- if (begin_impl_frame_data_.previous_sequence == 0 ||
- ack.sequence_number < begin_impl_frame_data_.previous_sequence) {
+ if (termination_status_ != TerminationStatus::kActive ||
+ ShouldIgnoreBeginFrameSource(ack.source_id) ||
+ ShouldIgnoreSequence(ack.sequence_number)) {
+ ignored_frame_tokens_.insert(frame_token);
return;
}
@@ -330,9 +460,12 @@ void FrameSequenceTracker::ReportSubmitFrame(
origin_args.sequence_number >= first_received_main_sequence_) {
if (last_submitted_main_sequence_ == 0 ||
origin_args.sequence_number > last_submitted_main_sequence_) {
+ TRACKER_TRACE_STREAM << 'S';
+
last_submitted_main_sequence_ = origin_args.sequence_number;
main_frames_.push_back(frame_token);
- DCHECK_GE(main_throughput_.frames_expected, main_frames_.size());
+ DCHECK_GE(main_throughput().frames_expected, main_frames_.size())
+ << TRACKER_DCHECK_MSG;
}
}
@@ -363,14 +496,20 @@ void FrameSequenceTracker::ReportFramePresented(
return;
}
+ if (ignored_frame_tokens_.contains(frame_token))
+ return;
+
+ TRACKER_TRACE_STREAM << 'P';
+
TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
- "cc,benchmark", "FrameSequenceTracker", this, "FramePresented",
+ "cc,benchmark", "FrameSequenceTracker", metrics_.get(), "FramePresented",
feedback.timestamp);
const bool was_presented = !feedback.timestamp.is_null();
if (was_presented && last_submitted_frame_) {
- DCHECK_LT(impl_throughput_.frames_produced,
- impl_throughput_.frames_expected);
- ++impl_throughput_.frames_produced;
+ DCHECK_LT(impl_throughput().frames_produced,
+ impl_throughput().frames_expected)
+ << TRACKER_DCHECK_MSG;
+ ++impl_throughput().frames_produced;
if (frame_token_acks_last_frame)
last_submitted_frame_ = 0;
@@ -379,17 +518,19 @@ void FrameSequenceTracker::ReportFramePresented(
while (!main_frames_.empty() &&
!viz::FrameTokenGT(main_frames_.front(), frame_token)) {
if (was_presented && main_frames_.front() == frame_token) {
- DCHECK_LT(main_throughput_.frames_produced,
- main_throughput_.frames_expected);
- ++main_throughput_.frames_produced;
+ DCHECK_LT(main_throughput().frames_produced,
+ main_throughput().frames_expected)
+ << TRACKER_DCHECK_MSG;
+ ++main_throughput().frames_produced;
}
main_frames_.pop_front();
}
if (was_presented) {
if (checkerboarding_.last_frame_had_checkerboarding) {
- DCHECK(!checkerboarding_.last_frame_timestamp.is_null());
- DCHECK(!feedback.timestamp.is_null());
+ DCHECK(!checkerboarding_.last_frame_timestamp.is_null())
+ << TRACKER_DCHECK_MSG;
+ DCHECK(!feedback.timestamp.is_null()) << TRACKER_DCHECK_MSG;
// |feedback.timestamp| is the timestamp when the latest frame was
// presented. |checkerboarding_.last_frame_timestamp| is the timestamp
@@ -402,10 +543,10 @@ void FrameSequenceTracker::ReportFramePresented(
const auto& interval = feedback.interval.is_zero()
? viz::BeginFrameArgs::DefaultInterval()
: feedback.interval;
- DCHECK(!interval.is_zero());
+ DCHECK(!interval.is_zero()) << TRACKER_DCHECK_MSG;
constexpr base::TimeDelta kEpsilon = base::TimeDelta::FromMilliseconds(1);
int64_t frames = (difference + kEpsilon) / interval;
- checkerboarding_.frames_checkerboarded += frames;
+ metrics_->add_checkerboarded_frames(frames);
}
const bool frame_had_checkerboarding =
@@ -430,13 +571,15 @@ void FrameSequenceTracker::ReportImplFrameCausedNoDamage(
// It is possible that this is called before a begin-impl-frame has been
// dispatched for this frame-sequence. In such cases, ignore this call.
- if (begin_impl_frame_data_.previous_sequence == 0 ||
- ack.sequence_number < begin_impl_frame_data_.previous_sequence) {
+ if (ShouldIgnoreSequence(ack.sequence_number))
return;
- }
- DCHECK_GT(impl_throughput_.frames_expected, 0u);
- DCHECK_GT(impl_throughput_.frames_expected, impl_throughput_.frames_produced);
- --impl_throughput_.frames_expected;
+
+ TRACKER_TRACE_STREAM << 'n';
+ DCHECK_GT(impl_throughput().frames_expected, 0u) << TRACKER_DCHECK_MSG;
+ DCHECK_GT(impl_throughput().frames_expected,
+ impl_throughput().frames_produced)
+ << TRACKER_DCHECK_MSG;
+ --impl_throughput().frames_expected;
if (begin_impl_frame_data_.previous_sequence == ack.sequence_number)
begin_impl_frame_data_.previous_sequence = 0;
@@ -450,6 +593,10 @@ void FrameSequenceTracker::ReportMainFrameCausedNoDamage(
if (ShouldIgnoreBeginFrameSource(args.source_id))
return;
+ // ReportBeginMainFrame could be called without ReportBeginImplFrame, in that
+ // case we should ignore this call.
+ if (ShouldIgnoreSequence(args.sequence_number))
+ return;
// It is possible that this is called before a begin-main-frame has been
// dispatched for this frame-sequence. In such cases, ignore this call.
if (begin_main_frame_data_.previous_sequence == 0 ||
@@ -457,10 +604,16 @@ void FrameSequenceTracker::ReportMainFrameCausedNoDamage(
return;
}
- DCHECK_GT(main_throughput_.frames_expected, 0u);
- DCHECK_GT(main_throughput_.frames_expected, main_throughput_.frames_produced);
- --main_throughput_.frames_expected;
- DCHECK_GE(main_throughput_.frames_expected, main_frames_.size());
+ TRACKER_TRACE_STREAM << 'N';
+ TRACKER_TRACE_STREAM << "(" << begin_main_frame_data_.previous_sequence << ","
+ << args.sequence_number << ")";
+ DCHECK_GT(main_throughput().frames_expected, 0u) << TRACKER_DCHECK_MSG;
+ DCHECK_GT(main_throughput().frames_expected,
+ main_throughput().frames_produced)
+ << TRACKER_DCHECK_MSG;
+ --main_throughput().frames_expected;
+ DCHECK_GE(main_throughput().frames_expected, main_frames_.size())
+ << TRACKER_DCHECK_MSG;
if (begin_main_frame_data_.previous_sequence == args.sequence_number)
begin_main_frame_data_.previous_sequence = 0;
@@ -478,7 +631,7 @@ void FrameSequenceTracker::UpdateTrackedFrameData(TrackedFrameData* frame_data,
uint64_t sequence_number) {
if (frame_data->previous_sequence &&
frame_data->previous_source == source_id) {
- uint8_t current_latency = sequence_number - frame_data->previous_sequence;
+ uint32_t current_latency = sequence_number - frame_data->previous_sequence;
frame_data->previous_sequence_delta = current_latency;
} else {
frame_data->previous_sequence_delta = 1;
@@ -494,8 +647,17 @@ bool FrameSequenceTracker::ShouldIgnoreBeginFrameSource(
return source_id != begin_impl_frame_data_.previous_source;
}
+// This check ensures that when ReportBeginMainFrame, or ReportSubmitFrame, or
+// ReportFramePresented is called for a particular arg, the ReportBeginImplFrame
+// is been called already.
+bool FrameSequenceTracker::ShouldIgnoreSequence(
+ uint64_t sequence_number) const {
+ return begin_impl_frame_data_.previous_sequence == 0 ||
+ sequence_number < begin_impl_frame_data_.previous_sequence;
+}
+
std::unique_ptr<base::trace_event::TracedValue>
-FrameSequenceTracker::ThroughputData::ToTracedValue(
+FrameSequenceMetrics::ThroughputData::ToTracedValue(
const ThroughputData& impl,
const ThroughputData& main) {
auto dict = std::make_unique<base::trace_event::TracedValue>();
@@ -508,13 +670,16 @@ FrameSequenceTracker::ThroughputData::ToTracedValue(
bool FrameSequenceTracker::ShouldReportMetricsNow(
const viz::BeginFrameArgs& args) const {
- if (!first_frame_timestamp_.is_null() &&
- args.frame_time - first_frame_timestamp_ >= time_delta_to_report_)
- return true;
- return false;
+ return metrics_->HasEnoughDataForReporting() &&
+ !first_frame_timestamp_.is_null() &&
+ args.frame_time - first_frame_timestamp_ >= time_delta_to_report_;
+}
+
+std::unique_ptr<FrameSequenceMetrics> FrameSequenceTracker::TakeMetrics() {
+ return std::move(metrics_);
}
-base::Optional<int> FrameSequenceTracker::ThroughputData::ReportHistogram(
+base::Optional<int> FrameSequenceMetrics::ThroughputData::ReportHistogram(
FrameSequenceTrackerType sequence_type,
const char* thread_name,
int metric_index,
diff --git a/chromium/cc/metrics/frame_sequence_tracker.h b/chromium/cc/metrics/frame_sequence_tracker.h
index 5004aa001c5..ac18280b445 100644
--- a/chromium/cc/metrics/frame_sequence_tracker.h
+++ b/chromium/cc/metrics/frame_sequence_tracker.h
@@ -14,6 +14,7 @@
#include "base/callback_helpers.h"
#include "base/containers/circular_deque.h"
#include "base/containers/flat_map.h"
+#include "base/containers/flat_set.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/trace_event/traced_value.h"
@@ -31,6 +32,8 @@ struct BeginFrameArgs;
namespace cc {
class FrameSequenceTracker;
class CompositorFrameReportingController;
+class ThroughputUkmReporter;
+class UkmManager;
enum FrameSequenceTrackerType {
kCompositorAnimation = 0,
@@ -44,6 +47,73 @@ enum FrameSequenceTrackerType {
kMaxType
};
+class CC_EXPORT FrameSequenceMetrics {
+ public:
+ FrameSequenceMetrics(FrameSequenceTrackerType type,
+ UkmManager* ukm_manager,
+ ThroughputUkmReporter* ukm_reporter);
+ ~FrameSequenceMetrics();
+
+ FrameSequenceMetrics(const FrameSequenceMetrics&) = delete;
+ FrameSequenceMetrics& operator=(const FrameSequenceMetrics&) = delete;
+
+ struct ThroughputData {
+ static std::unique_ptr<base::trace_event::TracedValue> ToTracedValue(
+ const ThroughputData& impl,
+ const ThroughputData& main);
+
+ // Returns the throughput in percent, a return value of base::nullopt
+ // indicates that no throughput metric is reported.
+ static base::Optional<int> ReportHistogram(
+ FrameSequenceTrackerType sequence_type,
+ const char* thread_name,
+ int metric_index,
+ const ThroughputData& data);
+
+ void Merge(const ThroughputData& data) {
+ frames_expected += data.frames_expected;
+ frames_produced += data.frames_produced;
+ }
+
+ // Tracks the number of frames that were expected to be shown during this
+ // frame-sequence.
+ uint32_t frames_expected = 0;
+
+ // Tracks the number of frames that were actually presented to the user
+ // during this frame-sequence.
+ uint32_t frames_produced = 0;
+ };
+
+ void Merge(std::unique_ptr<FrameSequenceMetrics> metrics);
+ bool HasEnoughDataForReporting() const;
+ bool HasDataLeftForReporting() const;
+ void ReportMetrics();
+
+ ThroughputData& impl_throughput() { return impl_throughput_; }
+ ThroughputData& main_throughput() { return main_throughput_; }
+ void add_checkerboarded_frames(int64_t frames) {
+ frames_checkerboarded_ += frames;
+ }
+ uint32_t frames_checkerboarded() const { return frames_checkerboarded_; }
+
+ private:
+ const FrameSequenceTrackerType type_;
+
+ // Please refer to the comments in FrameSequenceTrackerCollection's
+ // ukm_manager_.
+ UkmManager* const ukm_manager_;
+
+ // Pointer to the reporter owned by the FrameSequenceTrackerCollection.
+ ThroughputUkmReporter* const throughput_ukm_reporter_;
+
+ ThroughputData impl_throughput_;
+ ThroughputData main_throughput_;
+
+ // Tracks the number of produced frames that had some amount of
+ // checkerboarding, and how many frames showed such checkerboarded frames.
+ uint32_t frames_checkerboarded_ = 0;
+};
+
// Used for notifying attached FrameSequenceTracker's of begin-frames and
// submitted frames.
class CC_EXPORT FrameSequenceTrackerCollection {
@@ -93,6 +163,8 @@ class CC_EXPORT FrameSequenceTrackerCollection {
FrameSequenceTracker* GetTrackerForTesting(FrameSequenceTrackerType type);
+ void SetUkmManager(UkmManager* manager);
+
private:
friend class FrameSequenceTrackerTest;
@@ -106,6 +178,20 @@ class CC_EXPORT FrameSequenceTrackerCollection {
std::vector<std::unique_ptr<FrameSequenceTracker>> removal_trackers_;
CompositorFrameReportingController* const
compositor_frame_reporting_controller_;
+
+ // The reporter takes throughput data and connect to UkmManager to report it.
+ std::unique_ptr<ThroughputUkmReporter> throughput_ukm_reporter_;
+
+ // This is pointing to the LayerTreeHostImpl::ukm_manager_, which is
+ // initialized right after the LayerTreeHostImpl is created. So when this
+ // pointer is initialized, there should be no trackers yet. Moreover, the
+ // LayerTreeHostImpl::ukm_manager_ lives as long as the LayerTreeHostImpl, so
+ // this pointer should never be null as long as LayerTreeHostImpl is alive.
+ UkmManager* ukm_manager_ = nullptr;
+
+ base::flat_map<FrameSequenceTrackerType,
+ std::unique_ptr<FrameSequenceMetrics>>
+ accumulated_metrics_;
};
// Tracks a sequence of frames to determine the throughput. It tracks this by
@@ -123,7 +209,13 @@ class CC_EXPORT FrameSequenceTracker {
kReadyForTermination,
};
- static const char* const kFrameSequenceTrackerTypeNames[];
+ enum class ThreadType {
+ kMain,
+ kCompositor,
+ kSlower,
+ };
+
+ static const char* GetFrameSequenceTrackerTypeName(int type_index);
~FrameSequenceTracker();
@@ -172,11 +264,25 @@ class CC_EXPORT FrameSequenceTracker {
// Returns true if we should ask this tracker to report its throughput data.
bool ShouldReportMetricsNow(const viz::BeginFrameArgs& args) const;
+ FrameSequenceMetrics* metrics() { return metrics_.get(); }
+ FrameSequenceTrackerType type() const { return type_; }
+
+ std::unique_ptr<FrameSequenceMetrics> TakeMetrics();
+
private:
friend class FrameSequenceTrackerCollection;
friend class FrameSequenceTrackerTest;
- explicit FrameSequenceTracker(FrameSequenceTrackerType type);
+ FrameSequenceTracker(FrameSequenceTrackerType type,
+ UkmManager* manager,
+ ThroughputUkmReporter* throughput_ukm_reporter);
+
+ FrameSequenceMetrics::ThroughputData& impl_throughput() {
+ return metrics_->impl_throughput();
+ }
+ FrameSequenceMetrics::ThroughputData& main_throughput() {
+ return metrics_->main_throughput();
+ }
void ScheduleTerminate() {
termination_status_ = TerminationStatus::kScheduledForTermination;
@@ -191,37 +297,13 @@ class CC_EXPORT FrameSequenceTracker {
// The difference in |BeginFrameArgs::sequence_number| fields of the last
// two processed BeginFrameArgs.
- uint8_t previous_sequence_delta = 0;
- };
-
- struct ThroughputData {
- static std::unique_ptr<base::trace_event::TracedValue> ToTracedValue(
- const ThroughputData& impl,
- const ThroughputData& main);
- // Returns the throughput in percent, a return value of base::nullopt
- // indicates that no throughput metric is reported.
- static base::Optional<int> ReportHistogram(
- FrameSequenceTrackerType sequence_type,
- const char* thread_name,
- int metric_index,
- const ThroughputData& data);
- // Tracks the number of frames that were expected to be shown during this
- // frame-sequence.
- uint32_t frames_expected = 0;
-
- // Tracks the number of frames that were actually presented to the user
- // during this frame-sequence.
- uint32_t frames_produced = 0;
+ uint32_t previous_sequence_delta = 0;
};
struct CheckerboardingData {
CheckerboardingData();
~CheckerboardingData();
- // Tracks the number of produced frames that had some amount of
- // checkerboarding, and how many frames showed such checkerboarded frames.
- uint32_t frames_checkerboarded = 0;
-
// Tracks whether the last presented frame had checkerboarding. This is used
// to track how many vsyncs showed frames with checkerboarding.
bool last_frame_had_checkerboarding = false;
@@ -238,6 +320,8 @@ class CC_EXPORT FrameSequenceTracker {
bool ShouldIgnoreBeginFrameSource(uint64_t source_id) const;
+ bool ShouldIgnoreSequence(uint64_t sequence_number) const;
+
// Report related metrics: throughput, checkboarding...
void ReportMetrics();
@@ -248,8 +332,7 @@ class CC_EXPORT FrameSequenceTracker {
TrackedFrameData begin_impl_frame_data_;
TrackedFrameData begin_main_frame_data_;
- ThroughputData impl_throughput_;
- ThroughputData main_throughput_;
+ std::unique_ptr<FrameSequenceMetrics> metrics_;
CheckerboardingData checkerboarding_;
@@ -282,8 +365,29 @@ class CC_EXPORT FrameSequenceTracker {
// scheduled to report histogram.
base::TimeTicks first_frame_timestamp_;
+ // A frame that is ignored at ReportSubmitFrame should never be presented.
+ // TODO(xidachen): this should not be necessary. Some webview tests seem to
+ // present a frame even if it is ignored by ReportSubmitFrame.
+ base::flat_set<uint32_t> ignored_frame_tokens_;
+
// Report the throughput metrics every 5 seconds.
const base::TimeDelta time_delta_to_report_ = base::TimeDelta::FromSeconds(5);
+
+#if DCHECK_IS_ON()
+ // This stringstream represents a sequence of frame reporting activities on
+ // the current tracker. Each letter can be one of the following:
+ // {'B', 'N', 'b', 'n', 'S', 'P'}, where
+ // 'B' = ReportBeginMainFrame(), 'N' = ReportMainFrameCausedNoDamage(),
+ // 'b' = ReportBeginImplFrame(), 'n' = ReportMainFrameCausedNoDamage(),
+ // 'S' = ReportSubmitFrame() and 'P' = ReportFramePresented().
+ // Note that |frame_sequence_trace_| is only defined and populated
+ // when DCHECK is on.
+ std::stringstream frame_sequence_trace_;
+
+ // If ReportBeginImplFrame is never called on a arg, then ReportBeginMainFrame
+ // should ignore that arg.
+ base::flat_set<std::pair<uint64_t, uint64_t>> impl_frames_;
+#endif
};
} // namespace cc
diff --git a/chromium/cc/metrics/frame_sequence_tracker_unittest.cc b/chromium/cc/metrics/frame_sequence_tracker_unittest.cc
index 53d9b62a8d3..d2c1fa482fc 100644
--- a/chromium/cc/metrics/frame_sequence_tracker_unittest.cc
+++ b/chromium/cc/metrics/frame_sequence_tracker_unittest.cc
@@ -117,8 +117,8 @@ class FrameSequenceTrackerTest : public testing::Test {
base::HistogramTester histogram_tester;
// Test that there is no main thread frames expected.
- tracker_->impl_throughput_.frames_expected = 100u;
- tracker_->impl_throughput_.frames_produced = 85u;
+ tracker_->impl_throughput().frames_expected = 100u;
+ tracker_->impl_throughput().frames_produced = 85u;
tracker_->ReportMetrics();
histogram_tester.ExpectTotalCount(
"Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 1u);
@@ -128,8 +128,10 @@ class FrameSequenceTrackerTest : public testing::Test {
"Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 1u);
// Test that both are reported.
- tracker_->main_throughput_.frames_expected = 50u;
- tracker_->main_throughput_.frames_produced = 25u;
+ tracker_->impl_throughput().frames_expected = 100u;
+ tracker_->impl_throughput().frames_produced = 85u;
+ tracker_->main_throughput().frames_expected = 150u;
+ tracker_->main_throughput().frames_produced = 25u;
tracker_->ReportMetrics();
histogram_tester.ExpectTotalCount(
"Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 2u);
@@ -139,10 +141,10 @@ class FrameSequenceTrackerTest : public testing::Test {
"Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 2u);
// Test that none is reported.
- tracker_->main_throughput_.frames_expected = 2u;
- tracker_->main_throughput_.frames_produced = 1u;
- tracker_->impl_throughput_.frames_expected = 2u;
- tracker_->impl_throughput_.frames_produced = 1u;
+ tracker_->main_throughput().frames_expected = 2u;
+ tracker_->main_throughput().frames_produced = 1u;
+ tracker_->impl_throughput().frames_expected = 2u;
+ tracker_->impl_throughput().frames_produced = 1u;
tracker_->ReportMetrics();
histogram_tester.ExpectTotalCount(
"Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 2u);
@@ -152,10 +154,10 @@ class FrameSequenceTrackerTest : public testing::Test {
"Graphics.Smoothness.Throughput.SlowerThread.TouchScroll", 2u);
// Test the case where compositor and main thread have the same throughput.
- tracker_->impl_throughput_.frames_expected = 20u;
- tracker_->impl_throughput_.frames_produced = 18u;
- tracker_->main_throughput_.frames_expected = 20u;
- tracker_->main_throughput_.frames_produced = 18u;
+ tracker_->impl_throughput().frames_expected = 120u;
+ tracker_->impl_throughput().frames_produced = 118u;
+ tracker_->main_throughput().frames_expected = 120u;
+ tracker_->main_throughput().frames_produced = 118u;
tracker_->ReportMetrics();
histogram_tester.ExpectTotalCount(
"Graphics.Smoothness.Throughput.CompositorThread.TouchScroll", 3u);
@@ -176,9 +178,27 @@ class FrameSequenceTrackerTest : public testing::Test {
return collection_.removal_trackers_.size();
}
+ uint64_t BeginImplFrameDataPreviousSequence() const {
+ return tracker_->begin_impl_frame_data_.previous_sequence;
+ }
+ uint64_t BeginMainFrameDataPreviousSequence() const {
+ return tracker_->begin_main_frame_data_.previous_sequence;
+ }
+
+ base::flat_set<uint32_t> IgnoredFrameTokens() const {
+ return tracker_->ignored_frame_tokens_;
+ }
+
+ FrameSequenceMetrics::ThroughputData& ImplThroughput() const {
+ return tracker_->impl_throughput();
+ }
+ FrameSequenceMetrics::ThroughputData& MainThroughput() const {
+ return tracker_->main_throughput();
+ }
+
protected:
uint32_t number_of_frames_checkerboarded() const {
- return tracker_->checkerboarding_.frames_checkerboarded;
+ return tracker_->metrics_->frames_checkerboarded();
}
std::unique_ptr<CompositorFrameReportingController>
@@ -356,6 +376,7 @@ TEST_F(FrameSequenceTrackerTest, ReportMetricsAtFixedInterval) {
EXPECT_EQ(NumberOfTrackers(), 1u);
EXPECT_EQ(NumberOfRemovalTrackers(), 0u);
+ ImplThroughput().frames_expected += 100;
// Now args.frame_time is 5s since the tracker creation time, so this tracker
// should be scheduled to report its throughput.
args = CreateBeginFrameArgs(source, ++sequence,
@@ -365,4 +386,28 @@ TEST_F(FrameSequenceTrackerTest, ReportMetricsAtFixedInterval) {
EXPECT_EQ(NumberOfRemovalTrackers(), 1u);
}
+TEST_F(FrameSequenceTrackerTest, ReportWithoutBeginImplFrame) {
+ const uint64_t source = 1;
+ uint64_t sequence = 0;
+
+ auto args = CreateBeginFrameArgs(source, ++sequence);
+ collection_.NotifyBeginMainFrame(args);
+
+ EXPECT_EQ(BeginImplFrameDataPreviousSequence(), 0u);
+ // Call to ReportBeginMainFrame should early exit.
+ EXPECT_EQ(BeginMainFrameDataPreviousSequence(), 0u);
+
+ uint32_t frame_token = NextFrameToken();
+ collection_.NotifySubmitFrame(frame_token, false,
+ viz::BeginFrameAck(args, true), args);
+
+ // Call to ReportSubmitFrame should early exit.
+ EXPECT_TRUE(IgnoredFrameTokens().contains(frame_token));
+
+ gfx::PresentationFeedback feedback;
+ collection_.NotifyFramePresented(frame_token, feedback);
+ EXPECT_EQ(ImplThroughput().frames_produced, 0u);
+ EXPECT_EQ(MainThroughput().frames_produced, 0u);
+}
+
} // namespace cc
diff --git a/chromium/cc/metrics/throughput_ukm_reporter.cc b/chromium/cc/metrics/throughput_ukm_reporter.cc
new file mode 100644
index 00000000000..796cd184b32
--- /dev/null
+++ b/chromium/cc/metrics/throughput_ukm_reporter.cc
@@ -0,0 +1,51 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/metrics/throughput_ukm_reporter.h"
+
+#include "cc/trees/ukm_manager.h"
+
+namespace cc {
+
+namespace {
+// Collect UKM once per kNumberOfSamplesToReport UMA reports.
+constexpr unsigned kNumberOfSamplesToReport = 2000u;
+} // namespace
+
+void ThroughputUkmReporter::ReportThroughputUkm(
+ const UkmManager* ukm_manager,
+ const base::Optional<int>& slower_throughput_percent,
+ const base::Optional<int>& impl_throughput_percent,
+ const base::Optional<int>& main_throughput_percent,
+ FrameSequenceTrackerType type) {
+ // Sampling control. We sample the event here to not throttle the UKM system.
+ // Currently, the same sampling rate is applied to all existing trackers. We
+ // might want to iterate on this based on the collected data.
+ static uint32_t samples_to_next_event = 0;
+
+ if (samples_to_next_event == 0) {
+ // Sample every 2000 events. Using the Universal tracker as an example
+ // which reports UMA every 5s, then the system collects UKM once per
+ // 2000*5 = 10000 seconds, which is about 3 hours. This number may need to
+ // be tuned to not throttle the UKM system.
+ samples_to_next_event = kNumberOfSamplesToReport;
+ if (impl_throughput_percent) {
+ ukm_manager->RecordThroughputUKM(
+ type, FrameSequenceTracker::ThreadType::kCompositor,
+ impl_throughput_percent.value());
+ }
+ if (main_throughput_percent) {
+ ukm_manager->RecordThroughputUKM(type,
+ FrameSequenceTracker::ThreadType::kMain,
+ main_throughput_percent.value());
+ }
+ ukm_manager->RecordThroughputUKM(type,
+ FrameSequenceTracker::ThreadType::kSlower,
+ slower_throughput_percent.value());
+ }
+ DCHECK_GT(samples_to_next_event, 0u);
+ samples_to_next_event--;
+}
+
+} // namespace cc
diff --git a/chromium/cc/metrics/throughput_ukm_reporter.h b/chromium/cc/metrics/throughput_ukm_reporter.h
new file mode 100644
index 00000000000..defa8703ee8
--- /dev/null
+++ b/chromium/cc/metrics/throughput_ukm_reporter.h
@@ -0,0 +1,31 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_METRICS_THROUGHPUT_UKM_REPORTER_H_
+#define CC_METRICS_THROUGHPUT_UKM_REPORTER_H_
+
+#include "base/optional.h"
+#include "cc/cc_export.h"
+#include "cc/metrics/frame_sequence_tracker.h"
+
+namespace cc {
+class UkmManager;
+
+// A helper class that takes throughput data from a FrameSequenceTracker and
+// talk to UkmManager to report it.
+class CC_EXPORT ThroughputUkmReporter {
+ public:
+ ThroughputUkmReporter() = default;
+ ~ThroughputUkmReporter() = default;
+
+ void ReportThroughputUkm(const UkmManager* ukm_manager,
+ const base::Optional<int>& slower_throughput_percent,
+ const base::Optional<int>& impl_throughput_percent,
+ const base::Optional<int>& main_throughput_percent,
+ FrameSequenceTrackerType type);
+};
+
+} // namespace cc
+
+#endif // CC_METRICS_THROUGHPUT_UKM_REPORTER_H_
diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
index 72c13d9231f..401958e0bcb 100644
--- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
+++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.cc
@@ -14,7 +14,6 @@
#include "base/trace_event/trace_event.h"
#include "cc/base/histograms.h"
#include "cc/trees/layer_tree_frame_sink_client.h"
-#include "components/viz/client/hit_test_data_provider.h"
#include "components/viz/common/features.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/common/hit_test/hit_test_region_list.h"
@@ -82,7 +81,6 @@ AsyncLayerTreeFrameSink::AsyncLayerTreeFrameSink(
std::move(worker_context_provider),
std::move(params->compositor_task_runner),
params->gpu_memory_buffer_manager),
- hit_test_data_provider_(std::move(params->hit_test_data_provider)),
synthetic_begin_frame_source_(
std::move(params->synthetic_begin_frame_source)),
pipes_(std::move(params->pipes)),
@@ -93,10 +91,6 @@ AsyncLayerTreeFrameSink::AsyncLayerTreeFrameSink(
submit_begin_frame_histogram_(GetHistogramNamed(
"GraphicsPipeline.%s.SubmitCompositorFrameAfterBeginFrame",
params->client_name)) {
- // We should not create hit test data provider if we want to use cc layer tree
- // to generated data.
- if (features::IsVizHitTestingSurfaceLayerEnabled())
- DCHECK(!params->hit_test_data_provider);
DETACH_FROM_THREAD(thread_checker_);
}
@@ -186,11 +180,8 @@ void AsyncLayerTreeFrameSink::SubmitCompositorFrame(
frame.size_in_pixels().width());
}
- base::Optional<viz::HitTestRegionList> hit_test_region_list;
- if (hit_test_data_provider_)
- hit_test_region_list = hit_test_data_provider_->GetHitTestData(frame);
- else
- hit_test_region_list = client_->BuildHitTestData();
+ base::Optional<viz::HitTestRegionList> hit_test_region_list =
+ client_->BuildHitTestData();
if (show_hit_test_borders && hit_test_region_list)
hit_test_region_list->flags |= viz::HitTestRegionFlags::kHitTestDebug;
diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
index 236d792b4b0..076f3428163 100644
--- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
+++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink.h
@@ -31,10 +31,6 @@ namespace base {
class HistogramBase;
} // namespace base
-namespace viz {
-class HitTestDataProvider;
-} // namespace viz
-
namespace cc {
namespace mojo_embedder {
@@ -97,7 +93,6 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink
gpu::GpuMemoryBufferManager* gpu_memory_buffer_manager = nullptr;
std::unique_ptr<viz::SyntheticBeginFrameSource>
synthetic_begin_frame_source;
- std::unique_ptr<viz::HitTestDataProvider> hit_test_data_provider;
UnboundMessagePipes pipes;
bool wants_animate_only_begin_frames = false;
const char* client_name = nullptr;
@@ -112,10 +107,6 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink
AsyncLayerTreeFrameSink& operator=(const AsyncLayerTreeFrameSink&) = delete;
- const viz::HitTestDataProvider* hit_test_data_provider() const {
- return hit_test_data_provider_.get();
- }
-
const viz::LocalSurfaceId& local_surface_id() const {
return local_surface_id_;
}
@@ -155,7 +146,6 @@ class CC_MOJO_EMBEDDER_EXPORT AsyncLayerTreeFrameSink
bool begin_frames_paused_ = false;
bool needs_begin_frames_ = false;
viz::LocalSurfaceId local_surface_id_;
- std::unique_ptr<viz::HitTestDataProvider> hit_test_data_provider_;
std::unique_ptr<viz::ExternalBeginFrameSource> begin_frame_source_;
std::unique_ptr<viz::SyntheticBeginFrameSource> synthetic_begin_frame_source_;
diff --git a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc
index 82984c11006..2a4ba2e5906 100644
--- a/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc
+++ b/chromium/cc/mojo_embedder/async_layer_tree_frame_sink_unittest.cc
@@ -13,7 +13,6 @@
#include "base/test/test_mock_time_task_runner.h"
#include "base/threading/thread.h"
#include "cc/test/fake_layer_tree_frame_sink_client.h"
-#include "components/viz/client/hit_test_data_provider_draw_quad.h"
#include "components/viz/common/quads/render_pass_draw_quad.h"
#include "components/viz/common/quads/solid_color_draw_quad.h"
#include "components/viz/common/quads/surface_draw_quad.h"
@@ -141,9 +140,6 @@ class AsyncLayerTreeFrameSinkSimpleTest : public testing::Test {
init_params_.pipes.compositor_frame_sink_remote = std::move(sink_remote);
init_params_.pipes.client_receiver =
client.InitWithNewPipeAndPassReceiver();
- init_params_.hit_test_data_provider =
- std::make_unique<viz::HitTestDataProviderDrawQuad>(
- /*should_ask_for_child_region=*/true, /*root_accepts_events=*/true);
layer_tree_frame_sink_ = std::make_unique<AsyncLayerTreeFrameSink>(
std::move(context_provider), nullptr, &init_params_);
@@ -177,27 +173,33 @@ class AsyncLayerTreeFrameSinkSimpleTest : public testing::Test {
FakeLayerTreeFrameSinkClient layer_tree_frame_sink_client_;
};
-TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
+TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListEmpty) {
viz::RenderPassList pass_list;
+ auto pass = viz::RenderPass::Create();
+ pass->id = 1;
+ pass->output_rect = display_rect_;
+ pass_list.push_back(move(pass));
+
+ SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
+ task_runner_->RunUntilIdle();
+
+ EXPECT_TRUE(viz::HitTestRegionList::IsEqual(viz::HitTestRegionList(),
+ GetHitTestData()));
+}
+TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
+ viz::RenderPassList pass_list;
// Initial submission.
auto pass1 = viz::RenderPass::Create();
pass1->id = 1;
pass1->output_rect = display_rect_;
- auto* shared_quad_state1 = pass1->CreateAndAppendSharedQuadState();
- gfx::Rect rect1(display_rect_);
- shared_quad_state1->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect1,
- /*visible_quad_layer_rect=*/rect1,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect1,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad1 =
- pass1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
- quad1->SetNew(shared_quad_state1, /*rect=*/rect1,
- /*visible_rect=*/rect1, SK_ColorBLACK,
- /*force_anti_aliasing_off=*/false);
pass_list.push_back(move(pass1));
+
+ viz::HitTestRegionList region_list1;
+ region_list1.flags = viz::HitTestRegionFlags::kHitTestMine;
+ region_list1.bounds.SetRect(0, 0, 1024, 768);
+ layer_tree_frame_sink_client_.set_hit_test_region_list(region_list1);
+
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
task_runner_->RunUntilIdle();
const viz::HitTestRegionList hit_test_region_list = GetHitTestData();
@@ -206,20 +208,8 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
auto pass2 = viz::RenderPass::Create();
pass2->id = 2;
pass2->output_rect = display_rect_;
- auto* shared_quad_state2 = pass2->CreateAndAppendSharedQuadState();
- gfx::Rect rect2(display_rect_);
- shared_quad_state2->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect2,
- /*visible_quad_layer_rect=*/rect2,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad2 =
- pass2->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
- quad2->SetNew(shared_quad_state2, /*rect=*/rect2,
- /*visible_rect=*/rect2, SK_ColorBLACK,
- /*force_anti_aliasing_off=*/false);
pass_list.push_back(move(pass2));
+
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
task_runner_->RunUntilIdle();
@@ -227,76 +217,15 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest, HitTestRegionListDuplicate) {
viz::HitTestRegionList::IsEqual(hit_test_region_list, GetHitTestData()));
// Different submission.
- const viz::SurfaceId child_surface_id(
- viz::FrameSinkId(1, 1),
- viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
- auto pass3_0 = viz::RenderPass::Create();
- pass3_0->output_rect = display_rect_;
- pass3_0->id = 3;
- auto* shared_quad_state3_0 = pass3_0->CreateAndAppendSharedQuadState();
- gfx::Rect rect3_0(display_rect_);
- gfx::Transform transform3_0;
- transform3_0.Translate(-200, -100);
- shared_quad_state3_0->SetAll(
- transform3_0, /*quad_layer_rect=*/rect3_0,
- /*visible_quad_layer_rect=*/rect3_0,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3_0,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad3_0 =
- pass3_0->quad_list.AllocateAndConstruct<viz::SurfaceDrawQuad>();
- quad3_0->SetNew(shared_quad_state3_0, /*rect=*/rect3_0,
- /*visible_rect=*/rect3_0,
- viz::SurfaceRange(base::nullopt, child_surface_id),
- SK_ColorBLACK,
- /*stretch_content_to_fill_bounds=*/false,
- /*ignores_input_event=*/false);
- pass_list.push_back(std::move(pass3_0));
-
- auto pass3_1 = viz::RenderPass::Create();
- pass3_1->output_rect = display_rect_;
- pass3_1->id = 4;
- auto* shared_quad_state3_1 = pass3_1->CreateAndAppendSharedQuadState();
- gfx::Rect rect3_1(display_rect_);
- shared_quad_state3_1->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect3_1,
- /*visible_quad_layer_rect=*/rect3_1,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3_1,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad3_1 =
- pass3_1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
- quad3_1->SetNew(shared_quad_state3_1, /*rect=*/rect3_1,
- /*visible_rect=*/rect3_1, SK_ColorBLACK,
- /*force_anti_aliasing_off=*/false);
- pass_list.push_back(std::move(pass3_1));
-
- auto pass3_root = viz::RenderPass::Create();
- pass3_root->output_rect = display_rect_;
- pass3_root->id = 5;
- auto* shared_quad_state3_root = pass3_root->CreateAndAppendSharedQuadState();
- gfx::Rect rect3_root(display_rect_);
- shared_quad_state3_root->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect3_root,
- /*visible_quad_layer_rect=*/rect3_root,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3_root,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad3_root_1 =
- pass3_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
- quad3_root_1->SetNew(shared_quad_state3_root, /*rect=*/rect3_root,
- /*visible_rect=*/rect3_root, /*render_pass_id=*/3,
- /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
- gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
- 1.0f);
- auto* quad3_root_2 =
- pass3_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
- quad3_root_2->SetNew(shared_quad_state3_root, /*rect=*/rect3_root,
- /*visible_rect=*/rect3_root, /*render_pass_id=*/4,
- /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
- gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
- 1.0f);
- pass_list.push_back(std::move(pass3_root));
+ auto pass3 = viz::RenderPass::Create();
+ pass3->id = 3;
+ pass3->output_rect = display_rect_;
+ pass_list.push_back(move(pass3));
+
+ viz::HitTestRegionList region_list2;
+ region_list2.flags = viz::HitTestRegionFlags::kHitTestMine;
+ region_list2.bounds.SetRect(0, 0, 800, 600);
+ layer_tree_frame_sink_client_.set_hit_test_region_list(region_list2);
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
task_runner_->RunUntilIdle();
@@ -312,95 +241,27 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest,
auto pass1 = viz::RenderPass::Create();
pass1->id = 1;
pass1->output_rect = display_rect_;
- auto* shared_quad_state1 = pass1->CreateAndAppendSharedQuadState();
- gfx::Rect rect1(display_rect_);
- shared_quad_state1->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect1,
- /*visible_quad_layer_rect=*/rect1,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect1,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad1 =
- pass1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
- quad1->SetNew(shared_quad_state1, /*rect=*/rect1,
- /*visible_rect=*/rect1, SK_ColorBLACK,
- /*force_anti_aliasing_off=*/false);
pass_list.push_back(move(pass1));
+
+ viz::HitTestRegionList region_list1;
+ region_list1.flags = viz::HitTestRegionFlags::kHitTestMine;
+ region_list1.bounds.SetRect(0, 0, 1024, 768);
+ layer_tree_frame_sink_client_.set_hit_test_region_list(region_list1);
+
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
task_runner_->RunUntilIdle();
viz::HitTestRegionList hit_test_region_list = GetHitTestData();
// Different submission with |hit_test_data_changed| set to true.
- const viz::SurfaceId child_surface_id(
- viz::FrameSinkId(1, 1),
- viz::LocalSurfaceId(2, base::UnguessableToken::Create()));
- auto pass2_0 = viz::RenderPass::Create();
- pass2_0->output_rect = display_rect_;
- pass2_0->id = 2;
- auto* shared_quad_state2_0 = pass2_0->CreateAndAppendSharedQuadState();
- gfx::Rect rect2_0(display_rect_);
- gfx::Transform transform2_0;
- transform2_0.Translate(-200, -100);
- shared_quad_state2_0->SetAll(
- transform2_0, /*quad_layer_rect=*/rect2_0,
- /*visible_quad_layer_rect=*/rect2_0,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2_0,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad2_0 =
- pass2_0->quad_list.AllocateAndConstruct<viz::SurfaceDrawQuad>();
- quad2_0->SetNew(shared_quad_state2_0, /*rect=*/rect2_0,
- /*visible_rect=*/rect2_0,
- viz::SurfaceRange(base::nullopt, child_surface_id),
- SK_ColorBLACK,
- /*stretch_content_to_fill_bounds=*/false,
- /*ignores_input_event=*/false);
- pass_list.push_back(std::move(pass2_0));
-
- auto pass2_1 = viz::RenderPass::Create();
- pass2_1->output_rect = display_rect_;
- pass2_1->id = 3;
- auto* shared_quad_state2_1 = pass2_1->CreateAndAppendSharedQuadState();
- gfx::Rect rect2_1(display_rect_);
- shared_quad_state2_1->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect2_1,
- /*visible_quad_layer_rect=*/rect2_1,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2_1,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad2_1 =
- pass2_1->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
- quad2_1->SetNew(shared_quad_state2_1, /*rect=*/rect2_1,
- /*visible_rect=*/rect2_1, SK_ColorBLACK,
- /*force_anti_aliasing_off=*/false);
- pass_list.push_back(std::move(pass2_1));
-
- auto pass2_root = viz::RenderPass::Create();
- pass2_root->output_rect = display_rect_;
- pass2_root->id = 4;
- auto* shared_quad_state2_root = pass2_root->CreateAndAppendSharedQuadState();
- gfx::Rect rect2_root(display_rect_);
- shared_quad_state2_root->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect2_root,
- /*visible_quad_layer_rect=*/rect2_root,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect2_root,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad2_root_1 =
- pass2_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
- quad2_root_1->SetNew(shared_quad_state2_root, /*rect=*/rect2_root,
- /*visible_rect=*/rect2_root, /*render_pass_id=*/2,
- /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
- gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
- 1.0f);
- auto* quad2_root_2 =
- pass2_root->quad_list.AllocateAndConstruct<viz::RenderPassDrawQuad>();
- quad2_root_2->SetNew(shared_quad_state2_root, /*rect=*/rect2_root,
- /*visible_rect=*/rect2_root, /*render_pass_id=*/3,
- /*mask_resource_id=*/0, gfx::RectF(), gfx::Size(),
- gfx::Vector2dF(1, 1), gfx::PointF(), gfx::RectF(), false,
- 1.0f);
- pass_list.push_back(std::move(pass2_root));
+ auto pass2 = viz::RenderPass::Create();
+ pass2->id = 2;
+ pass2->output_rect = display_rect_;
+ pass_list.push_back(std::move(pass2));
+
+ viz::HitTestRegionList region_list2;
+ region_list2.flags = viz::HitTestRegionFlags::kHitTestMine;
+ region_list2.bounds.SetRect(0, 0, 800, 600);
+ layer_tree_frame_sink_client_.set_hit_test_region_list(region_list2);
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/true);
task_runner_->RunUntilIdle();
@@ -409,25 +270,18 @@ TEST_F(AsyncLayerTreeFrameSinkSimpleTest,
viz::HitTestRegionList::IsEqual(hit_test_region_list, GetHitTestData()));
hit_test_region_list = GetHitTestData();
- // Identical submission with |hit_test_data_changed| set back to false. We
+ // Different submission with |hit_test_data_changed| set back to false. We
// expect the hit-data to still have been sent.
auto pass3 = viz::RenderPass::Create();
- pass3->id = 4;
+ pass3->id = 3;
pass3->output_rect = display_rect_;
- auto* shared_quad_state3 = pass3->CreateAndAppendSharedQuadState();
- gfx::Rect rect3(display_rect_);
- shared_quad_state3->SetAll(
- gfx::Transform(), /*quad_layer_rect=*/rect3,
- /*visible_quad_layer_rect=*/rect3,
- /*rounded_corner_bounds=*/gfx::RRectF(), /*clip_rect=*/rect3,
- /*is_clipped=*/false, /*are_contents_opaque=*/false,
- /*opacity=*/0.5f, SkBlendMode::kSrcOver, /*sorting_context_id=*/0);
- auto* quad3 =
- pass3->quad_list.AllocateAndConstruct<viz::SolidColorDrawQuad>();
- quad3->SetNew(shared_quad_state3, /*rect=*/rect3,
- /*visible_rect=*/rect3, SK_ColorBLACK,
- /*force_anti_aliasing_off=*/false);
pass_list.push_back(move(pass3));
+
+ viz::HitTestRegionList region_list3;
+ region_list3.flags = viz::HitTestRegionFlags::kHitTestChildSurface;
+ region_list3.bounds.SetRect(0, 0, 800, 600);
+ layer_tree_frame_sink_client_.set_hit_test_region_list(region_list3);
+
SendRenderPassList(&pass_list, /*hit_test_data_changed=*/false);
task_runner_->RunUntilIdle();
diff --git a/chromium/cc/mojom/BUILD.gn b/chromium/cc/mojom/BUILD.gn
new file mode 100644
index 00000000000..7f648e69f14
--- /dev/null
+++ b/chromium/cc/mojom/BUILD.gn
@@ -0,0 +1,16 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import("//mojo/public/tools/bindings/mojom.gni")
+
+mojom("mojom") {
+ generate_java = true
+ sources = [
+ "touch_action.mojom",
+ ]
+
+ public_deps = [
+ "//mojo/public/mojom/base",
+ ]
+}
diff --git a/chromium/cc/mojom/OWNERS b/chromium/cc/mojom/OWNERS
new file mode 100644
index 00000000000..d28aad21794
--- /dev/null
+++ b/chromium/cc/mojom/OWNERS
@@ -0,0 +1,5 @@
+per-file *.mojom=set noparent
+per-file *.mojom=file://ipc/SECURITY_OWNERS
+
+per-file *.typemap=set noparent
+per-file *.typemap=file://ipc/SECURITY_OWNERS
diff --git a/chromium/cc/mojom/README.md b/chromium/cc/mojom/README.md
new file mode 100644
index 00000000000..ec9c22f8c27
--- /dev/null
+++ b/chromium/cc/mojom/README.md
@@ -0,0 +1,10 @@
+# cc/mojom
+
+[TOC]
+
+## Overview
+
+cc/mojom provides the mojom typemaps for cc types. This directory is where
+cc types that appear as part of mojo APIs should be placed. Structures that
+are defined in C++ and have mojo based NativeEnum definitions will
+require legacy Chrome IPC validators, see cc/ipc.
diff --git a/chromium/cc/mojom/touch_action.mojom b/chromium/cc/mojom/touch_action.mojom
new file mode 100644
index 00000000000..00084ffff29
--- /dev/null
+++ b/chromium/cc/mojom/touch_action.mojom
@@ -0,0 +1,8 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+module cc.mojom;
+
+[Native]
+enum TouchAction;
diff --git a/chromium/cc/mojom/touch_action.typemap b/chromium/cc/mojom/touch_action.typemap
new file mode 100644
index 00000000000..0ca823399df
--- /dev/null
+++ b/chromium/cc/mojom/touch_action.typemap
@@ -0,0 +1,12 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+mojom = "//cc/mojom/touch_action.mojom"
+public_headers = [ "//cc/input/touch_action.h" ]
+traits_headers = [ "//cc/ipc/cc_param_traits_macros.h" ]
+public_deps = [
+ "//cc",
+ "//cc/ipc",
+]
+type_mappings = [ "cc.mojom.TouchAction=::cc::TouchAction" ]
diff --git a/chromium/cc/paint/discardable_image_map.cc b/chromium/cc/paint/discardable_image_map.cc
index ddc1c7d3347..47b0c7b4f2c 100644
--- a/chromium/cc/paint/discardable_image_map.cc
+++ b/chromium/cc/paint/discardable_image_map.cc
@@ -30,60 +30,26 @@ SkRect MapRect(const SkMatrix& matrix, const SkRect& src) {
return dst;
}
-// This canvas is used only for tracking transform/clip/filter state from the
-// non-drawing ops.
-class PaintTrackingCanvas final : public SkNoDrawCanvas {
- public:
- PaintTrackingCanvas(int width, int height) : SkNoDrawCanvas(width, height) {}
- ~PaintTrackingCanvas() override = default;
-
- bool ComputePaintBounds(const SkRect& rect,
- const SkPaint* current_paint,
- SkRect* paint_bounds) {
- *paint_bounds = rect;
- if (current_paint) {
- if (!current_paint->canComputeFastBounds())
- return false;
- *paint_bounds =
- current_paint->computeFastBounds(*paint_bounds, paint_bounds);
- }
-
- for (const auto& paint : base::Reversed(saved_paints_)) {
- if (!paint.canComputeFastBounds())
- return false;
- *paint_bounds = paint.computeFastBounds(*paint_bounds, paint_bounds);
- }
-
- return true;
- }
-
- private:
- // SkNoDrawCanvas overrides.
- SaveLayerStrategy getSaveLayerStrategy(const SaveLayerRec& rec) override {
- saved_paints_.push_back(rec.fPaint ? *rec.fPaint : SkPaint());
- return SkNoDrawCanvas::getSaveLayerStrategy(rec);
- }
-
- void willSave() override {
- saved_paints_.push_back(SkPaint());
- return SkNoDrawCanvas::willSave();
+bool ComputePaintBounds(const SkRect& rect,
+ const SkPaint* current_paint,
+ SkRect* paint_bounds) {
+ *paint_bounds = rect;
+ if (current_paint) {
+ if (!current_paint->canComputeFastBounds())
+ return false;
+ *paint_bounds =
+ current_paint->computeFastBounds(*paint_bounds, paint_bounds);
}
- void willRestore() override {
- DCHECK_GT(saved_paints_.size(), 0u);
- saved_paints_.pop_back();
- SkNoDrawCanvas::willRestore();
- }
-
- std::vector<SkPaint> saved_paints_;
-};
+ return true;
+}
class DiscardableImageGenerator {
public:
DiscardableImageGenerator(int width,
int height,
const PaintOpBuffer* buffer) {
- PaintTrackingCanvas canvas(width, height);
+ SkNoDrawCanvas canvas(width, height);
GatherDiscardableImages(buffer, nullptr, &canvas);
}
~DiscardableImageGenerator() = default;
@@ -157,7 +123,7 @@ class DiscardableImageGenerator {
// this image in the top-level buffer.
void GatherDiscardableImages(const PaintOpBuffer* buffer,
const gfx::Rect* top_level_op_rect,
- PaintTrackingCanvas* canvas) {
+ SkNoDrawCanvas* canvas) {
if (!buffer->HasDiscardableImages())
return;
@@ -221,7 +187,7 @@ class DiscardableImageGenerator {
// Given the |op_rect|, which is the rect for the draw op, returns the
// transformed rect accounting for the current transform, clip and paint
// state on |canvas_|.
- gfx::Rect ComputePaintRect(const PaintOp* op, PaintTrackingCanvas* canvas) {
+ gfx::Rect ComputePaintRect(const PaintOp* op, SkNoDrawCanvas* canvas) {
const SkRect& clip_rect = SkRect::Make(canvas->getDeviceClipBounds());
const SkMatrix& ctm = canvas->getTotalMatrix();
@@ -243,7 +209,7 @@ class DiscardableImageGenerator {
SkRect paint_rect = MapRect(ctm, op_rect);
bool computed_paint_bounds =
- canvas->ComputePaintBounds(paint_rect, &paint, &paint_rect);
+ ComputePaintBounds(paint_rect, &paint, &paint_rect);
if (!computed_paint_bounds) {
// TODO(vmpstr): UMA this case.
paint_rect = clip_rect;
@@ -308,8 +274,8 @@ class DiscardableImageGenerator {
return;
}
- PaintTrackingCanvas canvas(scaled_tile_rect.width(),
- scaled_tile_rect.height());
+ SkNoDrawCanvas canvas(scaled_tile_rect.width(),
+ scaled_tile_rect.height());
canvas.setMatrix(SkMatrix::MakeRectToRect(
shader->tile(), scaled_tile_rect, SkMatrix::kFill_ScaleToFit));
base::AutoReset<bool> auto_reset(&only_gather_animated_images_, true);
diff --git a/chromium/cc/paint/discardable_image_map_unittest.cc b/chromium/cc/paint/discardable_image_map_unittest.cc
index 28a86bfcebe..23e9c990175 100644
--- a/chromium/cc/paint/discardable_image_map_unittest.cc
+++ b/chromium/cc/paint/discardable_image_map_unittest.cc
@@ -30,6 +30,7 @@
namespace cc {
namespace {
+using Rects = base::StackVector<gfx::Rect, 1>;
struct PositionScaleDrawImage {
PositionScaleDrawImage(const PaintImage& image,
@@ -378,6 +379,65 @@ TEST_F(DiscardableImageMapTest, PaintDestroyedWhileImageIsDrawn) {
EXPECT_TRUE(images[0].image == discardable_image);
}
+// Check if SkNoDrawCanvas does not crash for large layers.
+TEST_F(DiscardableImageMapTest, RestoreSavedBigLayers) {
+ PaintFlags flags;
+ SkRect rect = SkRect::MakeWH(INT_MAX, INT_MAX);
+ scoped_refptr<DisplayItemList> display_list = new DisplayItemList;
+ display_list->StartPaint();
+ display_list->push<DrawRectOp>(rect, flags);
+ display_list->EndPaintOfUnpaired(gfx::Rect(INT_MAX, INT_MAX));
+ display_list->Finalize();
+ display_list->GenerateDiscardableImagesMetadata();
+}
+
+// Test if SaveLayer and Restore work together.
+// 1. Move cursor to (25, 25) draw a black rect of size 25x25.
+// 2. save layer, move the cursor by (100, 100) or to point (125, 125), draw a
+// red rect of size 25x25.
+// 3. Restore layer, so the cursor moved back to (25, 25), move cursor by (100,
+// 0) or at the point (125, 25), draw a yellow rect of size 25x25.
+// (25, 25)
+// +---+
+// | |
+// +---+
+// (25, 125) (125, 125)
+// +---+ +---+
+// | | | |
+// +---+ +---+
+TEST_F(DiscardableImageMapTest, RestoreSavedTransformedLayers) {
+ scoped_refptr<DisplayItemList> display_list = new DisplayItemList;
+ PaintFlags paint;
+ gfx::Rect visible_rect(200, 200);
+ display_list->StartPaint();
+
+ PaintImage discardable_image1 =
+ CreateDiscardablePaintImage(gfx::Size(25, 25));
+ PaintImage discardable_image2 =
+ CreateDiscardablePaintImage(gfx::Size(25, 25));
+ PaintImage discardable_image3 =
+ CreateDiscardablePaintImage(gfx::Size(25, 25));
+ display_list->push<TranslateOp>(25, 25);
+ display_list->push<DrawImageOp>(discardable_image1, 0.f, 0.f, nullptr);
+ display_list->push<SaveLayerOp>(nullptr, &paint);
+ display_list->push<TranslateOp>(100, 100);
+ display_list->push<DrawImageOp>(discardable_image2, 0.f, 0.f, nullptr);
+ display_list->push<RestoreOp>();
+ display_list->push<TranslateOp>(0, 100);
+ display_list->push<DrawImageOp>(discardable_image3, 0.f, 0.f, nullptr);
+ display_list->EndPaintOfUnpaired(visible_rect);
+ display_list->Finalize();
+
+ display_list->GenerateDiscardableImagesMetadata();
+ const DiscardableImageMap& image_map = display_list->discardable_image_map();
+ std::vector<PositionScaleDrawImage> images =
+ GetDiscardableImagesInRect(image_map, gfx::Rect(0, 0, 200, 200));
+ EXPECT_EQ(3u, images.size());
+ EXPECT_EQ(gfx::Rect(25, 25, 25, 25), InsetImageRects(images)[0]);
+ EXPECT_EQ(gfx::Rect(125, 125, 25, 25), InsetImageRects(images)[1]);
+ EXPECT_EQ(gfx::Rect(25, 125, 25, 25), InsetImageRects(images)[2]);
+}
+
TEST_F(DiscardableImageMapTest, NullPaintOnSaveLayer) {
gfx::Rect visible_rect(2048, 2048);
FakeContentLayerClient content_layer_client;
diff --git a/chromium/cc/paint/display_item_list.h b/chromium/cc/paint/display_item_list.h
index af922d371b7..bb297dc88bf 100644
--- a/chromium/cc/paint/display_item_list.h
+++ b/chromium/cc/paint/display_item_list.h
@@ -90,6 +90,8 @@ class CC_PAINT_EXPORT DisplayItemList
return offset;
}
+ UsageHint GetUsageHint() const { return usage_hint_; }
+
// Called by blink::PaintChunksToCcLayer when an effect ends, to update the
// bounds of a SaveLayer[Alpha]Op which was emitted when the effect started.
// This is needed because blink doesn't know the bounds when an effect starts.
diff --git a/chromium/cc/paint/filter_operations.cc b/chromium/cc/paint/filter_operations.cc
index 332bca8f9de..0d79dfa793f 100644
--- a/chromium/cc/paint/filter_operations.cc
+++ b/chromium/cc/paint/filter_operations.cc
@@ -235,7 +235,7 @@ void FilterOperations::AsValueInto(
}
std::string FilterOperations::ToString() const {
- base::trace_event::TracedValue value;
+ base::trace_event::TracedValue value(0, /*force_json=*/true);
value.BeginArray("FilterOperations");
AsValueInto(&value);
value.EndArray();
diff --git a/chromium/cc/paint/image_transfer_cache_entry.cc b/chromium/cc/paint/image_transfer_cache_entry.cc
index 5939e789bb8..7041d9d8487 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.cc
+++ b/chromium/cc/paint/image_transfer_cache_entry.cc
@@ -174,6 +174,7 @@ ClientImageTransferCacheEntry::ClientImageTransferCacheEntry(
safe_size += sizeof(uint32_t); // height
safe_size += sizeof(uint32_t); // has mips
safe_size += sizeof(uint64_t) + align; // pixels size + alignment
+ safe_size += sizeof(uint64_t) + align; // row bytes + alignment
safe_size += target_color_space_size + sizeof(uint64_t) + align;
safe_size += pixmap_color_space_size + sizeof(uint64_t) + align;
// Include 4 bytes of padding so we can always align our data pointer to a
@@ -216,6 +217,7 @@ ClientImageTransferCacheEntry::ClientImageTransferCacheEntry(
safe_size += decoded_color_space_size + align;
safe_size += num_planes_ * sizeof(uint64_t); // plane widths
safe_size += num_planes_ * sizeof(uint64_t); // plane heights
+ safe_size += num_planes_ * sizeof(uint64_t); // plane strides
safe_size +=
num_planes_ * (sizeof(uint64_t) + align); // pixels size + alignment
// Include 4 bytes of padding before each plane data chunk so we can always
@@ -249,8 +251,8 @@ void ClientImageTransferCacheEntry::ValidateYUVDataBeforeSerializing() const {
const SkPixmap* plane = yuv_pixmaps_->at(i);
DCHECK_GT(plane->width(), 0);
DCHECK_GT(plane->height(), 0);
+ DCHECK_GT(plane->rowBytes(), 0u);
}
- DCHECK(yuv_color_space_);
}
bool ClientImageTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
@@ -273,6 +275,7 @@ bool ClientImageTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
const SkPixmap* plane = yuv_pixmaps_->at(i);
writer.Write(plane->width());
writer.Write(plane->height());
+ writer.WriteSize(plane->rowBytes());
size_t plane_size = plane->computeByteSize();
if (plane_size == SIZE_MAX)
return false;
@@ -299,7 +302,7 @@ bool ClientImageTransferCacheEntry::Serialize(base::span<uint8_t> data) const {
if (pixmap_size == SIZE_MAX)
return false;
writer.WriteSize(pixmap_size);
- // TODO(enne): we should consider caching these in some form.
+ writer.WriteSize(pixmap_->rowBytes());
writer.Write(pixmap_->colorSpace());
writer.Write(target_color_space_);
writer.AlignMemory(4);
@@ -403,6 +406,8 @@ bool ServiceImageTransferCacheEntry::Deserialize(
reader.Read(&plane_width);
uint32_t plane_height = 0;
reader.Read(&plane_height);
+ size_t plane_stride = 0;
+ reader.ReadSize(&plane_stride);
// Because Skia does not support YUV rasterization from software planes,
// we require that each pixmap fits in a GPU texture. In the
// GpuImageDecodeCache, we veto YUV decoding if the planes would be too
@@ -411,7 +416,8 @@ bool ServiceImageTransferCacheEntry::Deserialize(
// We compute this for each plane in case a malicious renderer tries to
// send very large U or V planes.
fits_on_gpu_ = plane_width <= max_size && plane_height <= max_size;
- if (!fits_on_gpu_ || plane_width == 0 || plane_height == 0)
+ if (!fits_on_gpu_ || plane_width == 0 || plane_height == 0 ||
+ plane_stride == 0)
return false;
size_t plane_bytes;
@@ -435,7 +441,9 @@ bool ServiceImageTransferCacheEntry::Deserialize(
// are OK with this as the worst case scenario is visual corruption.
SkPixmap plane_pixmap(plane_pixmap_info,
const_cast<const void*>(plane_pixel_data),
- plane_pixmap_info.minRowBytes());
+ plane_stride);
+ if (plane_pixmap.computeByteSize() > plane_bytes)
+ return false;
// Nothing should read the colorspace of individual planes because that
// information is stored in image_, so we pass nullptr.
@@ -478,6 +486,8 @@ bool ServiceImageTransferCacheEntry::Deserialize(
has_mips_ = needs_mips;
size_t pixel_size;
reader.ReadSize(&pixel_size);
+ size_t row_bytes;
+ reader.ReadSize(&row_bytes);
sk_sp<SkColorSpace> pixmap_color_space;
reader.Read(&pixmap_color_space);
sk_sp<SkColorSpace> target_color_space;
@@ -488,8 +498,10 @@ bool ServiceImageTransferCacheEntry::Deserialize(
SkImageInfo image_info = SkImageInfo::Make(
width, height, color_type, kPremul_SkAlphaType, pixmap_color_space);
- if (image_info.computeMinByteSize() > pixel_size)
+ if (row_bytes < image_info.minRowBytes() ||
+ image_info.computeByteSize(row_bytes) > pixel_size) {
return false;
+ }
// Align data to a 4-byte boundry, to match what we did when writing.
reader.AlignMemory(4);
@@ -505,8 +517,7 @@ bool ServiceImageTransferCacheEntry::Deserialize(
// Const-cast away the "volatile" on |pixel_data|. We specifically understand
// that a malicious caller may change our pixels under us, and are OK with
// this as the worst case scenario is visual corruption.
- SkPixmap pixmap(image_info, const_cast<const void*>(pixel_data),
- image_info.minRowBytes());
+ SkPixmap pixmap(image_info, const_cast<const void*>(pixel_data), row_bytes);
image_ = MakeSkImage(pixmap, width, height, target_color_space);
if (image_) {
@@ -537,6 +548,8 @@ sk_sp<SkImage> ServiceImageTransferCacheEntry::MakeSkImage(
image = MakeTextureImage(context_, std::move(image), target_color_space,
has_mips_ ? GrMipMapped::kYes : GrMipMapped::kNo);
} else {
+ // If the image is on the CPU, no work is needed to generate mips.
+ has_mips_ = true;
sk_sp<SkImage> original =
SkImage::MakeFromRaster(pixmap, [](const void*, void*) {}, nullptr);
if (!original)
@@ -571,6 +584,7 @@ void ServiceImageTransferCacheEntry::EnsureMips() {
if (has_mips_)
return;
+ DCHECK(fits_on_gpu_);
if (is_yuv()) {
DCHECK(image_);
DCHECK(yuv_color_space_.has_value());
diff --git a/chromium/cc/paint/image_transfer_cache_entry.h b/chromium/cc/paint/image_transfer_cache_entry.h
index f4975a5c16e..12eb917e91c 100644
--- a/chromium/cc/paint/image_transfer_cache_entry.h
+++ b/chromium/cc/paint/image_transfer_cache_entry.h
@@ -132,6 +132,7 @@ class CC_PAINT_EXPORT ServiceImageTransferCacheEntry
// Ensures the cached image has mips.
void EnsureMips();
+ bool has_mips() const { return has_mips_; }
// Used in tests and for registering each texture for memory dumps.
const sk_sp<SkImage>& GetPlaneImage(size_t index) const;
diff --git a/chromium/cc/paint/image_transfer_cache_entry_unittest.cc b/chromium/cc/paint/image_transfer_cache_entry_unittest.cc
index ac1819daf31..4c03a544e4f 100644
--- a/chromium/cc/paint/image_transfer_cache_entry_unittest.cc
+++ b/chromium/cc/paint/image_transfer_cache_entry_unittest.cc
@@ -46,9 +46,10 @@ void MarkTextureAsReleased(SkImage::ReleaseContext context) {
*released = true;
}
-// Checks if all the pixels in |image| are |expected_color|.
-bool CheckImageIsSolidColor(const sk_sp<SkImage>& image,
- SkColor expected_color) {
+// Checks if all the pixels in the |subset| of |image| are |expected_color|.
+bool CheckRectIsSolidColor(const sk_sp<SkImage>& image,
+ SkColor expected_color,
+ const SkIRect& subset) {
DCHECK_GE(image->width(), 1);
DCHECK_GE(image->height(), 1);
SkBitmap bitmap;
@@ -59,8 +60,8 @@ bool CheckImageIsSolidColor(const sk_sp<SkImage>& image,
return false;
if (!image->readPixels(pixmap, 0 /* srcX */, 0 /* srcY */))
return false;
- for (int y = 0; y < image->height(); y++) {
- for (int x = 0; x < image->width(); x++) {
+ for (int y = subset.fTop; y < subset.fBottom; y++) {
+ for (int x = subset.fLeft; x < subset.fRight; x++) {
if (bitmap.getColor(x, y) != expected_color)
return false;
}
@@ -68,6 +69,13 @@ bool CheckImageIsSolidColor(const sk_sp<SkImage>& image,
return true;
}
+// Checks if all the pixels in |image| are |expected_color|.
+bool CheckImageIsSolidColor(const sk_sp<SkImage>& image,
+ SkColor expected_color) {
+ return CheckRectIsSolidColor(
+ image, expected_color, SkIRect::MakeWH(image->width(), image->height()));
+}
+
class ImageTransferCacheEntryTest
: public testing::TestWithParam<YUVDecodeFormat> {
public:
@@ -196,8 +204,77 @@ class ImageTransferCacheEntryTest
scoped_refptr<gl::GLShareGroup> share_group_;
scoped_refptr<gl::GLContext> gl_context_;
sk_sp<GrContext> gr_context_;
+ gl::DisableNullDrawGLBindings enable_pixel_output_;
};
+TEST_P(ImageTransferCacheEntryTest, Deserialize) {
+#if defined(OS_ANDROID)
+ // TODO(crbug.com/985458): this test is failing on Android for NV12 and we
+ // don't understand why yet. Revisit this once Skia supports an RG8
+ // SkColorType.
+ if (GetParam() == YUVDecodeFormat::kYUV2)
+ return;
+#endif
+
+ // Create a client-side entry from YUV planes. Use a different stride than the
+ // width to test that alignment works correctly.
+ const int image_width = 12;
+ const int image_height = 10;
+ const size_t y_stride = 16;
+ const size_t uv_stride = 8;
+
+ const size_t y_bytes = y_stride * image_height;
+ const size_t uv_bytes = uv_stride * image_height / 2;
+ const size_t planes_size = y_bytes + 2 * uv_bytes;
+ std::unique_ptr<char[]> planes_data(new char[planes_size]);
+
+ void* planes[3];
+ planes[0] = reinterpret_cast<void*>(planes_data.get());
+ planes[1] = ((char*)planes[0]) + y_bytes;
+ planes[2] = ((char*)planes[1]) + uv_bytes;
+
+ auto info = SkImageInfo::Make(image_width, image_height, kGray_8_SkColorType,
+ kUnknown_SkAlphaType);
+ SkPixmap y_pixmap(info, planes[0], y_stride);
+ SkPixmap u_pixmap(info.makeWH(image_width / 2, image_height / 2), planes[1],
+ uv_stride);
+ SkPixmap v_pixmap(info.makeWH(image_width / 2, image_height / 2), planes[2],
+ uv_stride);
+
+ // rgb (255, 121, 255) -> yuv (255, 255, 255)
+ const SkIRect bottom_color_rect =
+ SkIRect::MakeXYWH(0, image_height / 2, image_width, image_height / 2);
+ ASSERT_TRUE(y_pixmap.erase(SkColors::kWhite));
+ ASSERT_TRUE(u_pixmap.erase(SkColors::kWhite));
+ ASSERT_TRUE(v_pixmap.erase(SkColors::kWhite));
+ // rgb (178, 0, 225) -> yuv (0, 255, 255)
+ const SkIRect top_color_rect = SkIRect::MakeWH(image_width, image_height / 2);
+ ASSERT_TRUE(y_pixmap.erase(SkColors::kBlack, &top_color_rect));
+
+ auto client_entry(std::make_unique<ClientImageTransferCacheEntry>(
+ &y_pixmap, &u_pixmap, &v_pixmap, nullptr, kJpegYUVColorSpace,
+ true /* needs_mips */));
+ uint32_t size = client_entry->SerializedSize();
+ std::vector<uint8_t> data(size);
+ ASSERT_TRUE(client_entry->Serialize(
+ base::make_span(static_cast<uint8_t*>(data.data()), size)));
+
+ // Create service-side entry from the client-side serialize info
+ auto entry(std::make_unique<ServiceImageTransferCacheEntry>());
+ ASSERT_TRUE(entry->Deserialize(
+ gr_context(), base::make_span(static_cast<uint8_t*>(data.data()), size)));
+ ASSERT_TRUE(entry->is_yuv());
+
+ // Check color of pixels
+ ASSERT_TRUE(CheckRectIsSolidColor(entry->image(), SkColorSetRGB(178, 0, 225),
+ top_color_rect));
+ ASSERT_TRUE(CheckRectIsSolidColor(
+ entry->image(), SkColorSetRGB(255, 121, 255), bottom_color_rect));
+
+ client_entry.reset();
+ entry.reset();
+}
+
TEST_P(ImageTransferCacheEntryTest, HardwareDecodedNoMipsAtCreation) {
std::unique_ptr<bool[]> release_flags;
std::vector<sk_sp<SkImage>> plane_images = CreateTestYUVImage(&release_flags);
@@ -320,12 +397,64 @@ std::string TestParamToString(
}
}
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
ImageTransferCacheEntryTest,
::testing::Values(YUVDecodeFormat::kYUV3,
YUVDecodeFormat::kYVU3,
YUVDecodeFormat::kYUV2),
TestParamToString);
+TEST(ImageTransferCacheEntryTestNoYUV, CPUImageWithMips) {
+ GrMockOptions options;
+ auto gr_context = GrContext::MakeMock(&options);
+
+ SkBitmap bitmap;
+ bitmap.allocPixels(
+ SkImageInfo::MakeN32Premul(gr_context->maxTextureSize() + 1, 10));
+ ClientImageTransferCacheEntry client_entry(&bitmap.pixmap(), nullptr, true);
+ std::vector<uint8_t> storage(client_entry.SerializedSize());
+ client_entry.Serialize(base::make_span(storage.data(), storage.size()));
+
+ ServiceImageTransferCacheEntry service_entry;
+ service_entry.Deserialize(gr_context.get(),
+ base::make_span(storage.data(), storage.size()));
+ ASSERT_TRUE(service_entry.image());
+ auto pre_mip_image = service_entry.image();
+ EXPECT_FALSE(pre_mip_image->isTextureBacked());
+ EXPECT_TRUE(service_entry.has_mips());
+
+ service_entry.EnsureMips();
+ ASSERT_TRUE(service_entry.image());
+ EXPECT_FALSE(service_entry.image()->isTextureBacked());
+ EXPECT_TRUE(service_entry.has_mips());
+ EXPECT_EQ(pre_mip_image, service_entry.image());
+}
+
+TEST(ImageTransferCacheEntryTestNoYUV, CPUImageAddMipsLater) {
+ GrMockOptions options;
+ auto gr_context = GrContext::MakeMock(&options);
+
+ SkBitmap bitmap;
+ bitmap.allocPixels(
+ SkImageInfo::MakeN32Premul(gr_context->maxTextureSize() + 1, 10));
+ ClientImageTransferCacheEntry client_entry(&bitmap.pixmap(), nullptr, false);
+ std::vector<uint8_t> storage(client_entry.SerializedSize());
+ client_entry.Serialize(base::make_span(storage.data(), storage.size()));
+
+ ServiceImageTransferCacheEntry service_entry;
+ service_entry.Deserialize(gr_context.get(),
+ base::make_span(storage.data(), storage.size()));
+ ASSERT_TRUE(service_entry.image());
+ auto pre_mip_image = service_entry.image();
+ EXPECT_FALSE(pre_mip_image->isTextureBacked());
+ EXPECT_TRUE(service_entry.has_mips());
+
+ service_entry.EnsureMips();
+ ASSERT_TRUE(service_entry.image());
+ EXPECT_FALSE(service_entry.image()->isTextureBacked());
+ EXPECT_TRUE(service_entry.has_mips());
+ EXPECT_EQ(pre_mip_image, service_entry.image());
+}
+
} // namespace
} // namespace cc
diff --git a/chromium/cc/paint/paint_canvas.h b/chromium/cc/paint/paint_canvas.h
index 32918efd58a..31a736d7dc3 100644
--- a/chromium/cc/paint/paint_canvas.h
+++ b/chromium/cc/paint/paint_canvas.h
@@ -18,6 +18,10 @@ namespace printing {
class MetafileSkia;
} // namespace printing
+namespace paint_preview {
+class PaintPreviewTracker;
+} // namespace paint_preview
+
namespace cc {
class SkottieWrapper;
class PaintFlags;
@@ -191,12 +195,19 @@ class CC_PAINT_EXPORT PaintCanvas {
void SetPrintingMetafile(printing::MetafileSkia* metafile) {
metafile_ = metafile;
}
+ paint_preview::PaintPreviewTracker* GetPaintPreviewTracker() const {
+ return tracker_;
+ }
+ void SetPaintPreviewTracker(paint_preview::PaintPreviewTracker* tracker) {
+ tracker_ = tracker;
+ }
// Subclasses can override to handle custom data.
virtual void recordCustomData(uint32_t id) {}
private:
printing::MetafileSkia* metafile_ = nullptr;
+ paint_preview::PaintPreviewTracker* tracker_ = nullptr;
};
class CC_PAINT_EXPORT PaintCanvasAutoRestore {
diff --git a/chromium/cc/paint/paint_image.cc b/chromium/cc/paint/paint_image.cc
index c601c016c78..f9b3d0e0798 100644
--- a/chromium/cc/paint/paint_image.cc
+++ b/chromium/cc/paint/paint_image.cc
@@ -193,19 +193,17 @@ bool PaintImage::Decode(void* memory,
client_id);
}
-bool PaintImage::DecodeYuv(void* planes[SkYUVASizeInfo::kMaxCount],
- size_t frame_index,
- GeneratorClientId client_id,
- const SkYUVASizeInfo& yuva_size_info) const {
- SkYUVAIndex indices[SkYUVAIndex::kIndexCount];
- // Passing nullptr for the SkYUVASizeInfo forces IsYuv to create and fill out
- // a temporary object instead because |yuva_size_info| is const.
- bool is_yuv = IsYuv(nullptr, indices);
- DCHECK(is_yuv);
+bool PaintImage::DecodeYuv(
+ void* planes[SkYUVASizeInfo::kMaxCount],
+ size_t frame_index,
+ GeneratorClientId client_id,
+ const SkYUVASizeInfo& yuva_size_info,
+ SkYUVAIndex plane_indices[SkYUVAIndex::kIndexCount]) const {
+ DCHECK(plane_indices != nullptr);
DCHECK(CanDecodeFromGenerator());
const uint32_t lazy_pixel_ref = unique_id();
- return paint_image_generator_->GetYUVA8Planes(yuva_size_info, indices, planes,
- frame_index, lazy_pixel_ref);
+ return paint_image_generator_->GetYUVA8Planes(
+ yuva_size_info, plane_indices, planes, frame_index, lazy_pixel_ref);
}
bool PaintImage::DecodeFromGenerator(void* memory,
diff --git a/chromium/cc/paint/paint_image.h b/chromium/cc/paint/paint_image.h
index df01c1086f9..00c74fcc1f3 100644
--- a/chromium/cc/paint/paint_image.h
+++ b/chromium/cc/paint/paint_image.h
@@ -51,6 +51,7 @@ struct CC_PAINT_EXPORT ImageHeaderMetadata {
// The size of the area containing coded data, if known. For example, if the
// |image_size| for a 4:2:0 JPEG is 12x31, its coded size should be 16x32
// because the size of a minimum-coded unit for 4:2:0 is 16x16.
+ // A zero-initialized |coded_size| indicates an invalid image.
base::Optional<gfx::Size> coded_size;
// Whether the image embeds an ICC color profile.
@@ -218,10 +219,14 @@ class CC_PAINT_EXPORT PaintImage {
// - The |frame_index| parameter will be passed along to
// ImageDecoder::DecodeToYUV but for multi-frame YUV support, ImageDecoder
// needs a separate YUV frame buffer cache.
+ // - The mapping of source planes to channels is tracked by |plane_indices|.
+ // This struct is initialized by QueryYUVA8 in calls to
+ // PaintImage::IsYuv(), including within this method.
bool DecodeYuv(void* planes[SkYUVASizeInfo::kMaxCount],
size_t frame_index,
GeneratorClientId client_id,
- const SkYUVASizeInfo& yuva_size_info) const;
+ const SkYUVASizeInfo& yuva_size_info,
+ SkYUVAIndex* plane_indices) const;
Id stable_id() const { return id_; }
const sk_sp<SkImage>& GetSkImage() const;
diff --git a/chromium/cc/paint/paint_image_unittest.cc b/chromium/cc/paint/paint_image_unittest.cc
index bc1a06d80ac..3837d80ef2a 100644
--- a/chromium/cc/paint/paint_image_unittest.cc
+++ b/chromium/cc/paint/paint_image_unittest.cc
@@ -150,8 +150,10 @@ TEST(PaintImageTest, DecodeToYuv420NoAlpha) {
ASSERT_TRUE(image.IsYuv(&image_yuv_size_info, image_plane_indices));
ASSERT_EQ(yuva_size_info, image_yuv_size_info);
+ SkYUVAIndex plane_indices[SkYUVAIndex::kIndexCount];
image.DecodeYuv(planes, 1u /* frame_index */,
- PaintImage::kDefaultGeneratorClientId, yuva_size_info);
+ PaintImage::kDefaultGeneratorClientId, yuva_size_info,
+ plane_indices);
ASSERT_EQ(yuv_generator->frames_decoded().size(), 1u);
EXPECT_EQ(yuv_generator->frames_decoded().count(1u), 1u);
yuv_generator->reset_frames_decoded();
diff --git a/chromium/cc/paint/paint_op_buffer.cc b/chromium/cc/paint/paint_op_buffer.cc
index 02915f75f95..20afc9bc84f 100644
--- a/chromium/cc/paint/paint_op_buffer.cc
+++ b/chromium/cc/paint/paint_op_buffer.cc
@@ -2480,14 +2480,10 @@ void PaintOpBuffer::Playback(SkCanvas* canvas,
}
}
-sk_sp<PaintOpBuffer> PaintOpBuffer::MakeFromMemory(
- const volatile void* input,
- size_t input_size,
- const PaintOp::DeserializeOptions& options) {
- auto buffer = sk_make_sp<PaintOpBuffer>();
- if (input_size == 0)
- return buffer;
-
+bool PaintOpBuffer::Deserialize(const volatile void* input,
+ size_t input_size,
+ const PaintOp::DeserializeOptions& options) {
+ Reset();
size_t total_bytes_read = 0u;
while (total_bytes_read < input_size) {
const volatile void* next_op =
@@ -2497,26 +2493,39 @@ sk_sp<PaintOpBuffer> PaintOpBuffer::MakeFromMemory(
uint32_t skip;
if (!PaintOpReader::ReadAndValidateOpHeader(
next_op, input_size - total_bytes_read, &type, &skip)) {
- return nullptr;
+ return false;
}
size_t op_skip = ComputeOpSkip(g_type_to_size[type]);
const auto* op = g_deserialize_functions[type](
- next_op, skip, buffer->AllocatePaintOp(op_skip), op_skip, options);
+ next_op, skip, AllocatePaintOp(op_skip), op_skip, options);
if (!op) {
// The last allocated op has already been destroyed if it failed to
// deserialize. Update the buffer's op tracking to exclude it to avoid
// access during cleanup at destruction.
- buffer->used_ -= op_skip;
- buffer->op_count_--;
- return nullptr;
+ used_ -= op_skip;
+ op_count_--;
+ return false;
}
- g_analyze_op_functions[type](buffer.get(), op);
+ g_analyze_op_functions[type](this, op);
total_bytes_read += skip;
}
- DCHECK_GT(buffer->size(), 0u);
+ DCHECK_GT(size(), 0u);
+ return true;
+}
+
+// static
+sk_sp<PaintOpBuffer> PaintOpBuffer::MakeFromMemory(
+ const volatile void* input,
+ size_t input_size,
+ const PaintOp::DeserializeOptions& options) {
+ auto buffer = sk_make_sp<PaintOpBuffer>();
+ if (input_size == 0)
+ return buffer;
+ if (!buffer->Deserialize(input, input_size, options))
+ return nullptr;
return buffer;
}
diff --git a/chromium/cc/paint/paint_op_buffer.h b/chromium/cc/paint/paint_op_buffer.h
index 11615ac3697..cd3ac1c50ca 100644
--- a/chromium/cc/paint/paint_op_buffer.h
+++ b/chromium/cc/paint/paint_op_buffer.h
@@ -937,6 +937,12 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt {
void Playback(SkCanvas* canvas) const;
void Playback(SkCanvas* canvas, const PlaybackParams& params) const;
+ // Deserialize PaintOps from |input|. The original content will be
+ // overwritten.
+ bool Deserialize(const volatile void* input,
+ size_t input_size,
+ const PaintOp::DeserializeOptions& options);
+
static sk_sp<PaintOpBuffer> MakeFromMemory(
const volatile void* input,
size_t input_size,
@@ -949,6 +955,8 @@ class CC_PAINT_EXPORT PaintOpBuffer : public SkRefCnt {
size_t bytes_used() const {
return sizeof(*this) + reserved_ + subrecord_bytes_used_;
}
+ // Returns the number of bytes used by paint ops.
+ size_t paint_ops_size() const { return used_ + subrecord_bytes_used_; }
// Returns the total number of ops including sub-records.
size_t total_op_count() const { return op_count_ + subrecord_op_count_; }
diff --git a/chromium/cc/paint/paint_recorder.h b/chromium/cc/paint/paint_recorder.h
index 58b26fa3fb5..4dce74a70e2 100644
--- a/chromium/cc/paint/paint_recorder.h
+++ b/chromium/cc/paint/paint_recorder.h
@@ -30,7 +30,7 @@ class CC_PAINT_EXPORT PaintRecorder {
return beginRecording(SkRect::MakeWH(width, height));
}
- // Only valid between between and finish recording.
+ // Only valid while recording.
ALWAYS_INLINE RecordPaintCanvas* getRecordingCanvas() {
return canvas_.has_value() ? &canvas_.value() : nullptr;
}
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.cc b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
index db625272e7c..a2bbd75c2c9 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.cc
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.cc
@@ -99,7 +99,10 @@ std::unique_ptr<RasterBuffer>
BitmapRasterBufferProvider::AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) {
DCHECK_EQ(resource.format(), viz::RGBA_8888);
const gfx::Size& size = resource.size();
diff --git a/chromium/cc/raster/bitmap_raster_buffer_provider.h b/chromium/cc/raster/bitmap_raster_buffer_provider.h
index bdf1fc8d06d..b8c18b6c428 100644
--- a/chromium/cc/raster/bitmap_raster_buffer_provider.h
+++ b/chromium/cc/raster/bitmap_raster_buffer_provider.h
@@ -33,7 +33,10 @@ class CC_EXPORT BitmapRasterBufferProvider : public RasterBufferProvider {
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override;
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
bool IsResourcePremultiplied() const override;
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.cc b/chromium/cc/raster/gpu_raster_buffer_provider.cc
index cbe878b7e1c..ae560bafe01 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.cc
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.cc
@@ -31,7 +31,6 @@
#include "gpu/command_buffer/client/shared_image_interface.h"
#include "gpu/command_buffer/common/shared_image_trace_utils.h"
#include "gpu/command_buffer/common/shared_image_usage.h"
-#include "third_party/skia/include/core/SkMultiPictureDraw.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/gpu/GrContext.h"
@@ -128,8 +127,7 @@ static void RasterizeSourceOOP(
const gfx::Rect& playback_rect,
const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
- viz::RasterContextProvider* context_provider,
- int msaa_sample_count) {
+ viz::RasterContextProvider* context_provider) {
gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
if (mailbox->IsZero()) {
DCHECK(!sync_token.HasData());
@@ -146,9 +144,9 @@ static void RasterizeSourceOOP(
ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
}
- ri->BeginRasterCHROMIUM(raster_source->background_color(), msaa_sample_count,
- playback_settings.use_lcd_text, color_space,
- mailbox->name);
+ ri->BeginRasterCHROMIUM(
+ raster_source->background_color(), playback_settings.msaa_sample_count,
+ playback_settings.use_lcd_text, color_space, mailbox->name);
float recording_to_raster_scale =
transform.scale() / raster_source->recording_scale_factor();
gfx::Size content_size = raster_source->GetContentSize(transform.scale());
@@ -183,7 +181,6 @@ static void RasterizeSource(
const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
viz::RasterContextProvider* context_provider,
- int msaa_sample_count,
bool unpremultiply_and_dither,
const gfx::Size& max_tile_size) {
gpu::raster::RasterInterface* ri = context_provider->RasterInterface();
@@ -203,7 +200,9 @@ static void RasterizeSource(
// valid by the time the consume command executes.
ri->WaitSyncTokenCHROMIUM(sync_token.GetConstData());
}
- GLuint texture_id = ri->CreateAndConsumeForGpuRaster(mailbox->name);
+ GLuint texture_id = ri->CreateAndConsumeForGpuRaster(*mailbox);
+ ri->BeginSharedImageAccessDirectCHROMIUM(
+ texture_id, GL_SHARED_IMAGE_ACCESS_MODE_READWRITE_CHROMIUM);
{
ScopedGrContextAccess gr_context_access(context_provider);
base::Optional<viz::ClientResourceProvider::ScopedSkSurface> scoped_surface;
@@ -215,13 +214,13 @@ static void RasterizeSource(
scoped_surface.emplace(context_provider->GrContext(), sk_color_space,
texture_id, texture_target, resource_size,
resource_format, playback_settings.use_lcd_text,
- msaa_sample_count);
+ playback_settings.msaa_sample_count);
surface = scoped_surface->surface();
} else {
scoped_dither_surface.emplace(
context_provider, sk_color_space, playback_rect, raster_full_rect,
max_tile_size, texture_id, resource_size,
- playback_settings.use_lcd_text, msaa_sample_count);
+ playback_settings.use_lcd_text, playback_settings.msaa_sample_count);
surface = scoped_dither_surface->surface();
}
@@ -243,7 +242,7 @@ static void RasterizeSource(
playback_rect, transform,
playback_settings);
}
-
+ ri->EndSharedImageAccessDirectCHROMIUM(texture_id);
ri->DeleteGpuRasterTexture(texture_id);
}
@@ -285,13 +284,21 @@ GpuRasterBufferProvider::RasterBufferImpl::RasterBufferImpl(
GpuRasterBufferProvider* client,
const ResourcePool::InUsePoolResource& in_use_resource,
GpuRasterBacking* backing,
- bool resource_has_previous_content)
+ bool resource_has_previous_content,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates)
: client_(client),
backing_(backing),
resource_size_(in_use_resource.size()),
resource_format_(in_use_resource.format()),
color_space_(in_use_resource.color_space()),
resource_has_previous_content_(resource_has_previous_content),
+ depends_on_at_raster_decodes_(depends_on_at_raster_decodes),
+ depends_on_hardware_accelerated_jpeg_candidates_(
+ depends_on_hardware_accelerated_jpeg_candidates),
+ depends_on_hardware_accelerated_webp_candidates_(
+ depends_on_hardware_accelerated_webp_candidates),
before_raster_sync_token_(backing->returned_sync_token),
texture_target_(backing->texture_target),
texture_is_overlay_candidate_(backing->overlay_candidate),
@@ -339,14 +346,15 @@ void GpuRasterBufferProvider::RasterBufferImpl::Playback(
before_raster_sync_token_, resource_size_, resource_format_, color_space_,
resource_has_previous_content_, raster_source, raster_full_rect,
raster_dirty_rect, new_content_id, transform, playback_settings, url,
- creation_time_);
+ creation_time_, depends_on_at_raster_decodes_,
+ depends_on_hardware_accelerated_jpeg_candidates_,
+ depends_on_hardware_accelerated_webp_candidates_);
}
GpuRasterBufferProvider::GpuRasterBufferProvider(
viz::ContextProvider* compositor_context_provider,
viz::RasterContextProvider* worker_context_provider,
bool use_gpu_memory_buffer_resources,
- int gpu_rasterization_msaa_sample_count,
viz::ResourceFormat tile_format,
const gfx::Size& max_tile_size,
bool unpremultiply_and_dither_low_bit_depth_tiles,
@@ -355,7 +363,6 @@ GpuRasterBufferProvider::GpuRasterBufferProvider(
: compositor_context_provider_(compositor_context_provider),
worker_context_provider_(worker_context_provider),
use_gpu_memory_buffer_resources_(use_gpu_memory_buffer_resources),
- msaa_sample_count_(gpu_rasterization_msaa_sample_count),
tile_format_(tile_format),
max_tile_size_(max_tile_size),
unpremultiply_and_dither_low_bit_depth_tiles_(
@@ -373,7 +380,10 @@ GpuRasterBufferProvider::~GpuRasterBufferProvider() {
std::unique_ptr<RasterBuffer> GpuRasterBufferProvider::AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) {
if (!resource.gpu_backing()) {
auto backing = std::make_unique<GpuRasterBacking>();
backing->worker_context_provider = worker_context_provider_;
@@ -386,8 +396,11 @@ std::unique_ptr<RasterBuffer> GpuRasterBufferProvider::AcquireBufferForRaster(
static_cast<GpuRasterBacking*>(resource.gpu_backing());
bool resource_has_previous_content =
resource_content_id && resource_content_id == previous_content_id;
- return std::make_unique<RasterBufferImpl>(this, resource, backing,
- resource_has_previous_content);
+ return std::make_unique<RasterBufferImpl>(
+ this, resource, backing, resource_has_previous_content,
+ depends_on_at_raster_decodes,
+ depends_on_hardware_accelerated_jpeg_candidates,
+ depends_on_hardware_accelerated_webp_candidates);
}
void GpuRasterBufferProvider::Flush() {
@@ -402,13 +415,6 @@ bool GpuRasterBufferProvider::IsResourcePremultiplied() const {
return !ShouldUnpremultiplyAndDitherResource(GetResourceFormat());
}
-bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const {
- // Partial raster doesn't support MSAA, as the MSAA resolve is unaware of clip
- // rects.
- // TODO(crbug.com/629683): See if we can work around this limitation.
- return msaa_sample_count_ == 0;
-}
-
bool GpuRasterBufferProvider::IsResourceReadyToDraw(
const ResourcePool::InUsePoolResource& resource) const {
const gpu::SyncToken& sync_token = resource.gpu_backing()->mailbox_sync_token;
@@ -421,6 +427,10 @@ bool GpuRasterBufferProvider::IsResourceReadyToDraw(
sync_token);
}
+bool GpuRasterBufferProvider::CanPartialRasterIntoProvidedResource() const {
+ return true;
+}
+
uint64_t GpuRasterBufferProvider::SetReadyToDrawCallback(
const std::vector<const ResourcePool::InUsePoolResource*>& resources,
base::OnceClosure callback,
@@ -467,14 +477,21 @@ gpu::SyncToken GpuRasterBufferProvider::PlaybackOnWorkerThread(
const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
const GURL& url,
- base::TimeTicks raster_buffer_creation_time) {
+ base::TimeTicks raster_buffer_creation_time,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) {
PendingRasterQuery query;
+ query.depends_on_hardware_accelerated_jpeg_candidates =
+ depends_on_hardware_accelerated_jpeg_candidates;
+ query.depends_on_hardware_accelerated_webp_candidates =
+ depends_on_hardware_accelerated_webp_candidates;
gpu::SyncToken raster_finished_token = PlaybackOnWorkerThreadInternal(
mailbox, texture_target, texture_is_overlay_candidate, sync_token,
resource_size, resource_format, color_space,
resource_has_previous_content, raster_source, raster_full_rect,
raster_dirty_rect, new_content_id, transform, playback_settings, url,
- &query);
+ depends_on_at_raster_decodes, &query);
if (query.raster_duration_query_id) {
if (query.raster_start_query_id)
@@ -508,6 +525,7 @@ gpu::SyncToken GpuRasterBufferProvider::PlaybackOnWorkerThreadInternal(
const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
const GURL& url,
+ bool depends_on_at_raster_decodes,
PendingRasterQuery* query) {
viz::RasterContextProvider::ScopedRasterContextLock scoped_context(
worker_context_provider_, url.possibly_invalid_spec().c_str());
@@ -545,8 +563,11 @@ gpu::SyncToken GpuRasterBufferProvider::PlaybackOnWorkerThreadInternal(
// enabled because we will use this timestamp to measure raster scheduling
// delay and we only need to collect that data to assess the impact of
// hardware acceleration of image decodes which work only in Chrome OS with
- // OOP-R.
- if (enable_oop_rasterization_) {
+ // OOP-R. Furthermore, we don't count raster work that depends on at-raster
+ // image decodes. This is because we want the delay to always include
+ // image decoding and uploading time, and at-raster decodes should be
+ // relatively rare.
+ if (enable_oop_rasterization_ && !depends_on_at_raster_decodes) {
ri->GenQueriesEXT(1, &query->raster_start_query_id);
DCHECK_GT(query->raster_start_query_id, 0u);
ri->QueryCounterEXT(query->raster_start_query_id,
@@ -566,19 +587,17 @@ gpu::SyncToken GpuRasterBufferProvider::PlaybackOnWorkerThreadInternal(
if (measure_raster_metric)
timer.emplace();
if (enable_oop_rasterization_) {
- RasterizeSourceOOP(raster_source, resource_has_previous_content, mailbox,
- sync_token, texture_target,
- texture_is_overlay_candidate, resource_size,
- resource_format, color_space, raster_full_rect,
- playback_rect, transform, playback_settings,
- worker_context_provider_, msaa_sample_count_);
+ RasterizeSourceOOP(
+ raster_source, resource_has_previous_content, mailbox, sync_token,
+ texture_target, texture_is_overlay_candidate, resource_size,
+ resource_format, color_space, raster_full_rect, playback_rect,
+ transform, playback_settings, worker_context_provider_);
} else {
RasterizeSource(raster_source, resource_has_previous_content, mailbox,
sync_token, texture_target, texture_is_overlay_candidate,
resource_size, resource_format, color_space,
raster_full_rect, playback_rect, transform,
playback_settings, worker_context_provider_,
- msaa_sample_count_,
ShouldUnpremultiplyAndDitherResource(resource_format),
max_tile_size_);
}
@@ -671,9 +690,26 @@ bool GpuRasterBufferProvider::CheckRasterFinishedQueries() {
// negative scheduling delay.
DCHECK_GE(raster_scheduling_delay.InMicroseconds(), 0u);
UMA_HISTOGRAM_RASTER_TIME_CUSTOM_MICROSECONDS(
- base::StringPrintf("Renderer4.%s.RasterTaskSchedulingDelay.All",
- client_name),
+ base::StringPrintf(
+ "Renderer4.%s.RasterTaskSchedulingDelayNoAtRasterDecodes.All",
+ client_name),
raster_scheduling_delay);
+ if (it->depends_on_hardware_accelerated_jpeg_candidates) {
+ UMA_HISTOGRAM_RASTER_TIME_CUSTOM_MICROSECONDS(
+ base::StringPrintf(
+ "Renderer4.%s.RasterTaskSchedulingDelayNoAtRasterDecodes."
+ "TilesWithJpegHwDecodeCandidates",
+ client_name),
+ raster_scheduling_delay);
+ }
+ if (it->depends_on_hardware_accelerated_webp_candidates) {
+ UMA_HISTOGRAM_RASTER_TIME_CUSTOM_MICROSECONDS(
+ base::StringPrintf(
+ "Renderer4.%s.RasterTaskSchedulingDelayNoAtRasterDecodes."
+ "TilesWithWebPHwDecodeCandidates",
+ client_name),
+ raster_scheduling_delay);
+ }
}
if (enable_oop_rasterization_) {
diff --git a/chromium/cc/raster/gpu_raster_buffer_provider.h b/chromium/cc/raster/gpu_raster_buffer_provider.h
index 2f54037b443..4a442a3b6a1 100644
--- a/chromium/cc/raster/gpu_raster_buffer_provider.h
+++ b/chromium/cc/raster/gpu_raster_buffer_provider.h
@@ -32,7 +32,6 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
viz::ContextProvider* compositor_context_provider,
viz::RasterContextProvider* worker_context_provider,
bool use_gpu_memory_buffer_resources,
- int gpu_rasterization_msaa_sample_count,
viz::ResourceFormat tile_format,
const gfx::Size& max_tile_size,
bool unpremultiply_and_dither_low_bit_depth_tiles,
@@ -47,7 +46,10 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override;
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
bool IsResourcePremultiplied() const override;
@@ -77,7 +79,10 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
const GURL& url,
- base::TimeTicks raster_buffer_creation_time);
+ base::TimeTicks raster_buffer_creation_time,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates);
private:
class GpuRasterBacking;
@@ -87,7 +92,10 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
RasterBufferImpl(GpuRasterBufferProvider* client,
const ResourcePool::InUsePoolResource& in_use_resource,
GpuRasterBacking* backing,
- bool resource_has_previous_content);
+ bool resource_has_previous_content,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates);
RasterBufferImpl(const RasterBufferImpl&) = delete;
~RasterBufferImpl() override;
@@ -112,6 +120,9 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
const viz::ResourceFormat resource_format_;
const gfx::ColorSpace color_space_;
const bool resource_has_previous_content_;
+ const bool depends_on_at_raster_decodes_;
+ const bool depends_on_hardware_accelerated_jpeg_candidates_;
+ const bool depends_on_hardware_accelerated_webp_candidates_;
const gpu::SyncToken before_raster_sync_token_;
const GLenum texture_target_;
const bool texture_is_overlay_candidate_;
@@ -137,6 +148,11 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
// The time at which the raster buffer was created.
base::TimeTicks raster_buffer_creation_time;
+
+ // Whether the raster work depends on candidates for hardware accelerated
+ // JPEG or WebP decodes.
+ bool depends_on_hardware_accelerated_jpeg_candidates = false;
+ bool depends_on_hardware_accelerated_webp_candidates = false;
};
bool ShouldUnpremultiplyAndDitherResource(viz::ResourceFormat format) const;
@@ -156,12 +172,12 @@ class CC_EXPORT GpuRasterBufferProvider : public RasterBufferProvider {
const gfx::AxisTransform2d& transform,
const RasterSource::PlaybackSettings& playback_settings,
const GURL& url,
+ bool depends_on_at_raster_decodes,
PendingRasterQuery* query);
viz::ContextProvider* const compositor_context_provider_;
viz::RasterContextProvider* const worker_context_provider_;
const bool use_gpu_memory_buffer_resources_;
- const int msaa_sample_count_;
const viz::ResourceFormat tile_format_;
const gfx::Size max_tile_size_;
const bool unpremultiply_and_dither_low_bit_depth_tiles_;
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.cc b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
index 6a40f4e513e..6c0c9d9e0b1 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.cc
@@ -159,7 +159,10 @@ std::unique_ptr<RasterBuffer>
OneCopyRasterBufferProvider::AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) {
if (!resource.gpu_backing()) {
auto backing = std::make_unique<OneCopyGpuBacking>();
backing->worker_context_provider = worker_context_provider_;
@@ -377,21 +380,20 @@ gpu::SyncToken OneCopyRasterBufferProvider::CopyOnWorkerThread(
}
if (mailbox->IsZero()) {
- uint32_t flags =
+ uint32_t usage =
gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_RASTER;
if (mailbox_texture_is_overlay_candidate)
- flags |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
+ usage |= gpu::SHARED_IMAGE_USAGE_SCANOUT;
*mailbox = sii->CreateSharedImage(resource_format, resource_size,
- color_space, flags);
+ color_space, usage);
}
// Create staging shared image.
if (staging_buffer->mailbox.IsZero()) {
- uint32_t flags =
- gpu::SHARED_IMAGE_USAGE_DISPLAY | gpu::SHARED_IMAGE_USAGE_RASTER;
+ const uint32_t usage = gpu::SHARED_IMAGE_USAGE_RASTER;
staging_buffer->mailbox =
sii->CreateSharedImage(staging_buffer->gpu_memory_buffer.get(),
- gpu_memory_buffer_manager_, color_space, flags);
+ gpu_memory_buffer_manager_, color_space, usage);
} else {
sii->UpdateSharedImage(staging_buffer->sync_token, staging_buffer->mailbox);
}
diff --git a/chromium/cc/raster/one_copy_raster_buffer_provider.h b/chromium/cc/raster/one_copy_raster_buffer_provider.h
index 370e6cbf43c..0d2a7d0dbe7 100644
--- a/chromium/cc/raster/one_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/one_copy_raster_buffer_provider.h
@@ -48,7 +48,10 @@ class CC_EXPORT OneCopyRasterBufferProvider : public RasterBufferProvider {
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override;
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
bool IsResourcePremultiplied() const override;
diff --git a/chromium/cc/raster/raster_buffer_provider.h b/chromium/cc/raster/raster_buffer_provider.h
index a23befca140..7b4937373ff 100644
--- a/chromium/cc/raster/raster_buffer_provider.h
+++ b/chromium/cc/raster/raster_buffer_provider.h
@@ -50,7 +50,10 @@ class CC_EXPORT RasterBufferProvider {
virtual std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) = 0;
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) = 0;
// Flush pending work from writing the content of the RasterBuffer, so that
// queries to tell if the backing is ready to draw from will get the right
diff --git a/chromium/cc/raster/raster_buffer_provider_perftest.cc b/chromium/cc/raster/raster_buffer_provider_perftest.cc
index 66391be769d..e6a0a2aa825 100644
--- a/chromium/cc/raster/raster_buffer_provider_perftest.cc
+++ b/chromium/cc/raster/raster_buffer_provider_perftest.cc
@@ -202,7 +202,8 @@ class PerfRasterBufferProviderHelper {
virtual std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) = 0;
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes) = 0;
};
class PerfRasterTaskImpl : public PerfTileTask {
@@ -277,7 +278,8 @@ class RasterBufferProviderPerfTestBase {
// No tile ids are given to support partial updates.
std::unique_ptr<RasterBuffer> raster_buffer;
if (helper)
- raster_buffer = helper->AcquireBufferForRaster(in_use_resource, 0, 0);
+ raster_buffer =
+ helper->AcquireBufferForRaster(in_use_resource, 0, 0, false);
TileTask::Vector dependencies = image_decode_tasks;
raster_tasks->push_back(new PerfRasterTaskImpl(
resource_pool_.get(), std::move(in_use_resource),
@@ -371,7 +373,7 @@ class RasterBufferProviderPerfTest
Create3dResourceProvider();
raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
compositor_context_provider_.get(), worker_context_provider_.get(),
- false, 0, viz::RGBA_8888, gfx::Size(), true, false);
+ false, viz::RGBA_8888, gfx::Size(), true, false);
break;
case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
CreateSoftwareResourceProvider();
@@ -398,9 +400,13 @@ class RasterBufferProviderPerfTest
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes) override {
return raster_buffer_provider_->AcquireBufferForRaster(
- resource, resource_content_id, previous_content_id);
+ resource, resource_content_id, previous_content_id,
+ depends_on_at_raster_decodes,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
}
void RunMessageLoopUntilAllTasksHaveCompleted() {
diff --git a/chromium/cc/raster/raster_buffer_provider_unittest.cc b/chromium/cc/raster/raster_buffer_provider_unittest.cc
index 391ee0eb52d..9953e5b19aa 100644
--- a/chromium/cc/raster/raster_buffer_provider_unittest.cc
+++ b/chromium/cc/raster/raster_buffer_provider_unittest.cc
@@ -225,13 +225,13 @@ class RasterBufferProviderTest
case RASTER_BUFFER_PROVIDER_TYPE_GPU:
Create3dResourceProvider();
raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
- context_provider_.get(), worker_context_provider_.get(), false, 0,
+ context_provider_.get(), worker_context_provider_.get(), false,
viz::RGBA_8888, gfx::Size(), true, false, 1);
break;
case RASTER_BUFFER_PROVIDER_TYPE_GPU_OOPR:
Create3dResourceProvider();
raster_buffer_provider_ = std::make_unique<GpuRasterBufferProvider>(
- context_provider_.get(), worker_context_provider_.get(), false, 0,
+ context_provider_.get(), worker_context_provider_.get(), false,
viz::RGBA_8888, gfx::Size(), true, true, 1);
break;
case RASTER_BUFFER_PROVIDER_TYPE_BITMAP:
@@ -289,25 +289,39 @@ class RasterBufferProviderTest
return pool_->AcquireResource(size, viz::RGBA_8888, gfx::ColorSpace());
}
- void AppendTask(unsigned id, const gfx::Size& size) {
+ void AppendTask(unsigned id,
+ const gfx::Size& size,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) {
ResourcePool::InUsePoolResource resource = AllocateResource(size);
// The raster buffer has no tile ids associated with it for partial update,
// so doesn't need to provide a valid dirty rect.
std::unique_ptr<RasterBuffer> raster_buffer =
- raster_buffer_provider_->AcquireBufferForRaster(resource, 0, 0);
+ raster_buffer_provider_->AcquireBufferForRaster(
+ resource, 0, 0, depends_on_at_raster_decodes,
+ depends_on_hardware_accelerated_jpeg_candidates,
+ depends_on_hardware_accelerated_webp_candidates);
TileTask::Vector empty;
tasks_.push_back(
new TestRasterTaskImpl(this, id, std::move(raster_buffer), &empty));
resources_.push_back(std::move(resource));
}
- void AppendTask(unsigned id) { AppendTask(id, gfx::Size(1, 1)); }
+ void AppendTask(unsigned id) {
+ AppendTask(id, gfx::Size(1, 1), false /* depends_on_at_raster_decodes */,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
+ }
void AppendBlockingTask(unsigned id, base::Lock* lock) {
ResourcePool::InUsePoolResource resource =
AllocateResource(gfx::Size(1, 1));
std::unique_ptr<RasterBuffer> raster_buffer =
- raster_buffer_provider_->AcquireBufferForRaster(resource, 0, 0);
+ raster_buffer_provider_->AcquireBufferForRaster(
+ resource, 0, 0, false /* depends_on_at_raster_decodes */,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
TileTask::Vector empty;
tasks_.push_back(new BlockingTestRasterTaskImpl(
this, id, std::move(raster_buffer), lock, &empty));
@@ -317,7 +331,10 @@ class RasterBufferProviderTest
void AppendTaskWithResource(unsigned id,
const ResourcePool::InUsePoolResource* resource) {
std::unique_ptr<RasterBuffer> raster_buffer =
- raster_buffer_provider_->AcquireBufferForRaster(*resource, 0, 0);
+ raster_buffer_provider_->AcquireBufferForRaster(
+ *resource, 0, 0, false /* depends_on_at_raster_decodes */,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
TileTask::Vector empty;
tasks_.push_back(
new TestRasterTaskImpl(this, id, std::move(raster_buffer), &empty));
@@ -571,8 +588,35 @@ TEST_P(RasterBufferProviderTest, MeasureGpuRasterDuration) {
return;
}
- // Schedule a task.
- AppendTask(0u);
+ // Schedule a few tasks.
+ constexpr gfx::Size size(1, 1);
+ AppendTask(0u, size, false /* depends_on_at_raster_decodes */,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(1u, size, false /* depends_on_at_raster_decodes */,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ true /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(2u, size, false /* depends_on_at_raster_decodes */,
+ true /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(3u, size, false /* depends_on_at_raster_decodes */,
+ true /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(4u, size, false /* depends_on_at_raster_decodes */,
+ true /* depends_on_hardware_accelerated_jpeg_candidates */,
+ true /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(5u, size, true /* depends_on_at_raster_decodes */,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(6u, size, true /* depends_on_at_raster_decodes */,
+ false /* depends_on_hardware_accelerated_jpeg_candidates */,
+ true /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(7u, size, true /* depends_on_at_raster_decodes */,
+ true /* depends_on_hardware_accelerated_jpeg_candidates */,
+ false /* depends_on_hardware_accelerated_webp_candidates */);
+ AppendTask(8u, size, true /* depends_on_at_raster_decodes */,
+ true /* depends_on_hardware_accelerated_jpeg_candidates */,
+ true /* depends_on_hardware_accelerated_webp_candidates */);
ScheduleTasks();
RunMessageLoopUntilAllTasksHaveCompleted();
@@ -591,24 +635,41 @@ TEST_P(RasterBufferProviderTest, MeasureGpuRasterDuration) {
std::string duration_histogram("Renderer4.Renderer.RasterTaskTotalDuration.");
duration_histogram +=
GetParam() == RASTER_BUFFER_PROVIDER_TYPE_GPU_OOPR ? "Oop" : "Gpu";
- std::string delay_histogram(
- "Renderer4.Renderer.RasterTaskSchedulingDelay.All");
+ std::string delay_histogram_all_tiles(
+ "Renderer4.Renderer.RasterTaskSchedulingDelayNoAtRasterDecodes.All");
+ std::string delay_histogram_jpeg_tiles(
+ "Renderer4.Renderer.RasterTaskSchedulingDelayNoAtRasterDecodes."
+ "TilesWithJpegHwDecodeCandidates");
+ std::string delay_histogram_webp_tiles(
+ "Renderer4.Renderer.RasterTaskSchedulingDelayNoAtRasterDecodes."
+ "TilesWithWebPHwDecodeCandidates");
histogram_tester.ExpectTotalCount(duration_histogram, 0);
- histogram_tester.ExpectTotalCount(delay_histogram, 0);
+ histogram_tester.ExpectTotalCount(delay_histogram_all_tiles, 0);
+ histogram_tester.ExpectTotalCount(delay_histogram_jpeg_tiles, 0);
+ histogram_tester.ExpectTotalCount(delay_histogram_webp_tiles, 0);
bool has_pending_queries =
raster_buffer_provider_->CheckRasterFinishedQueries();
EXPECT_FALSE(has_pending_queries);
- histogram_tester.ExpectTotalCount(duration_histogram, 1);
+ histogram_tester.ExpectTotalCount(duration_histogram, 9);
// Only in Chrome OS with OOP-R, we should be measuring raster scheduling
- // delay.
- base::HistogramBase::Count expected_delay_histogram_count = 0;
+ // delay (and only for tasks that don't depend on at-raster image decodes).
+ base::HistogramBase::Count expected_delay_histogram_all_tiles_count = 0;
+ base::HistogramBase::Count expected_delay_histogram_jpeg_tiles_count = 0;
+ base::HistogramBase::Count expected_delay_histogram_webp_tiles_count = 0;
#if defined(OS_CHROMEOS)
- if (GetParam() == RASTER_BUFFER_PROVIDER_TYPE_GPU_OOPR)
- expected_delay_histogram_count = 1;
+ if (GetParam() == RASTER_BUFFER_PROVIDER_TYPE_GPU_OOPR) {
+ expected_delay_histogram_all_tiles_count = 5;
+ expected_delay_histogram_jpeg_tiles_count = 3;
+ expected_delay_histogram_webp_tiles_count = 2;
+ }
#endif
- histogram_tester.ExpectTotalCount(delay_histogram,
- expected_delay_histogram_count);
+ histogram_tester.ExpectTotalCount(delay_histogram_all_tiles,
+ expected_delay_histogram_all_tiles_count);
+ histogram_tester.ExpectTotalCount(delay_histogram_jpeg_tiles,
+ expected_delay_histogram_jpeg_tiles_count);
+ histogram_tester.ExpectTotalCount(delay_histogram_webp_tiles,
+ expected_delay_histogram_webp_tiles_count);
}
INSTANTIATE_TEST_SUITE_P(
diff --git a/chromium/cc/raster/raster_source.h b/chromium/cc/raster/raster_source.h
index bbf9f1490a4..33b3564055a 100644
--- a/chromium/cc/raster/raster_source.h
+++ b/chromium/cc/raster/raster_source.h
@@ -38,6 +38,9 @@ class CC_EXPORT RasterSource : public base::RefCountedThreadSafe<RasterSource> {
// If set to true, we should use LCD text.
bool use_lcd_text = true;
+ // Specifies the sample count if MSAA is enabled for this tile.
+ int msaa_sample_count = 0;
+
ImageProvider* image_provider = nullptr;
};
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
index ef6c2c73433..b364de68c58 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.cc
@@ -174,7 +174,10 @@ std::unique_ptr<RasterBuffer>
ZeroCopyRasterBufferProvider::AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) {
if (!resource.gpu_backing()) {
auto backing = std::make_unique<ZeroCopyGpuBacking>();
const gpu::Capabilities& caps =
diff --git a/chromium/cc/raster/zero_copy_raster_buffer_provider.h b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
index 653228c7c65..e34376f4aec 100644
--- a/chromium/cc/raster/zero_copy_raster_buffer_provider.h
+++ b/chromium/cc/raster/zero_copy_raster_buffer_provider.h
@@ -39,7 +39,10 @@ class CC_EXPORT ZeroCopyRasterBufferProvider : public RasterBufferProvider {
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override;
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override;
void Flush() override;
viz::ResourceFormat GetResourceFormat() const override;
bool IsResourcePremultiplied() const override;
diff --git a/chromium/cc/resources/resource_pool.cc b/chromium/cc/resources/resource_pool.cc
index e169cac0f0f..ceb4d5ffd27 100644
--- a/chromium/cc/resources/resource_pool.cc
+++ b/chromium/cc/resources/resource_pool.cc
@@ -13,7 +13,6 @@
#include "base/atomic_sequence_num.h"
#include "base/bind.h"
#include "base/format_macros.h"
-#include "base/memory/shared_memory_handle.h"
#include "base/single_thread_task_runner.h"
#include "base/strings/stringprintf.h"
#include "base/threading/thread_task_runner_handle.h"
diff --git a/chromium/cc/scheduler/begin_frame_tracker.cc b/chromium/cc/scheduler/begin_frame_tracker.cc
index 19d106e0f1d..fe8f84012ad 100644
--- a/chromium/cc/scheduler/begin_frame_tracker.cc
+++ b/chromium/cc/scheduler/begin_frame_tracker.cc
@@ -4,6 +4,8 @@
#include "cc/scheduler/begin_frame_tracker.h"
+#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h"
+
namespace cc {
BeginFrameTracker::BeginFrameTracker(const base::Location& location)
@@ -77,36 +79,35 @@ base::TimeDelta BeginFrameTracker::Interval() const {
return interval;
}
-void BeginFrameTracker::AsValueInto(
+void BeginFrameTracker::AsProtozeroInto(
base::TimeTicks now,
- base::trace_event::TracedValue* state) const {
- state->SetDouble("updated_at_ms",
- current_updated_at_.since_origin().InMillisecondsF());
- state->SetDouble("finished_at_ms",
- current_finished_at_.since_origin().InMillisecondsF());
+ perfetto::protos::pbzero::BeginImplFrameArgs* state) const {
+ state->set_updated_at_us(current_updated_at_.since_origin().InMicroseconds());
+ state->set_finished_at_us(
+ current_finished_at_.since_origin().InMicroseconds());
if (HasFinished()) {
- state->SetString("state", "FINISHED");
- state->BeginDictionary("current_args_");
+ state->set_state(
+ perfetto::protos::pbzero::BeginImplFrameArgs::BEGIN_FRAME_FINISHED);
+ current_args_.AsProtozeroInto(state->set_current_args());
} else {
- state->SetString("state", "USING");
- state->BeginDictionary("last_args_");
+ state->set_state(
+ perfetto::protos::pbzero::BeginImplFrameArgs::BEGIN_FRAME_USING);
+ current_args_.AsProtozeroInto(state->set_last_args());
}
- current_args_.AsValueInto(state);
- state->EndDictionary();
base::TimeTicks frame_time = current_args_.frame_time;
base::TimeTicks deadline = current_args_.deadline;
base::TimeDelta interval = current_args_.interval;
- state->BeginDictionary("major_timestamps_in_ms");
- state->SetDouble("0_interval", interval.InMillisecondsF());
- state->SetDouble("1_now_to_deadline", (deadline - now).InMillisecondsF());
- state->SetDouble("2_frame_time_to_now", (now - frame_time).InMillisecondsF());
- state->SetDouble("3_frame_time_to_deadline",
- (deadline - frame_time).InMillisecondsF());
- state->SetDouble("4_now", now.since_origin().InMillisecondsF());
- state->SetDouble("5_frame_time", frame_time.since_origin().InMillisecondsF());
- state->SetDouble("6_deadline", deadline.since_origin().InMillisecondsF());
- state->EndDictionary();
+
+ auto* timestamps = state->set_timestamps_in_us();
+ timestamps->set_interval_delta(interval.InMicroseconds());
+ timestamps->set_now_to_deadline_delta((deadline - now).InMicroseconds());
+ timestamps->set_frame_time_to_now_delta((now - frame_time).InMicroseconds());
+ timestamps->set_frame_time_to_deadline_delta(
+ (deadline - frame_time).InMicroseconds());
+ timestamps->set_now(now.since_origin().InMicroseconds());
+ timestamps->set_frame_time(frame_time.since_origin().InMicroseconds());
+ timestamps->set_deadline(deadline.since_origin().InMicroseconds());
}
const viz::BeginFrameArgs& BeginFrameTracker::DangerousMethodCurrentOrLast()
diff --git a/chromium/cc/scheduler/begin_frame_tracker.h b/chromium/cc/scheduler/begin_frame_tracker.h
index e80f7383768..81c27d5a115 100644
--- a/chromium/cc/scheduler/begin_frame_tracker.h
+++ b/chromium/cc/scheduler/begin_frame_tracker.h
@@ -16,6 +16,13 @@
#define BEGINFRAMETRACKER_FROM_HERE FROM_HERE_WITH_EXPLICIT_FUNCTION("")
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class BeginImplFrameArgs;
+}
+} // namespace protos
+} // namespace perfetto
namespace cc {
// Microclass to trace and check properties for correct BeginFrameArgs (BFA)
@@ -68,8 +75,9 @@ class CC_EXPORT BeginFrameTracker {
// any time.
base::TimeDelta Interval() const;
- void AsValueInto(base::TimeTicks now,
- base::trace_event::TracedValue* dict) const;
+ void AsProtozeroInto(
+ base::TimeTicks now,
+ perfetto::protos::pbzero::BeginImplFrameArgs* dict) const;
// The following methods violate principles of how viz::BeginFrameArgs should
// be used. These methods should only be used when there is no other choice.
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index 523b09c2e4f..04a285de7ee 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -13,8 +13,11 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "cc/base/devtools_instrumentation.h"
+#include "cc/metrics/begin_main_frame_metrics.h"
#include "cc/metrics/compositor_timing_history.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
+#include "services/tracing/public/cpp/perfetto/macros.h"
+#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h"
namespace cc {
@@ -153,7 +156,7 @@ void Scheduler::DidSubmitCompositorFrame(uint32_t frame_token) {
}
void Scheduler::DidReceiveCompositorFrameAck() {
- DCHECK_GT(state_machine_.pending_submit_frames(), 0) << AsValue()->ToString();
+ DCHECK_GT(state_machine_.pending_submit_frames(), 0);
compositor_timing_history_->DidReceiveCompositorFrameAck();
state_machine_.DidReceiveCompositorFrameAck();
ProcessScheduledActions();
@@ -168,9 +171,10 @@ void Scheduler::SetTreePrioritiesAndScrollState(
ProcessScheduledActions();
}
-void Scheduler::NotifyReadyToCommit() {
+void Scheduler::NotifyReadyToCommit(
+ std::unique_ptr<BeginMainFrameMetrics> details) {
TRACE_EVENT0("cc", "Scheduler::NotifyReadyToCommit");
- compositor_timing_history_->NotifyReadyToCommit();
+ compositor_timing_history_->NotifyReadyToCommit(std::move(details));
state_machine_.NotifyReadyToCommit();
ProcessScheduledActions();
}
@@ -782,8 +786,10 @@ void Scheduler::ProcessScheduledActions() {
SchedulerStateMachine::Action action;
do {
action = state_machine_.NextAction();
- TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
- "SchedulerStateMachine", "state", AsValue());
+ TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler"),
+ "SchedulerStateMachine", [this](perfetto::EventContext ctx) {
+ this->AsProtozeroInto(ctx.event()->set_cc_scheduler_state());
+ });
base::AutoReset<SchedulerStateMachine::Action> mark_inside_action(
&inside_action_, action);
switch (action) {
@@ -864,62 +870,47 @@ void Scheduler::ProcessScheduledActions() {
StartOrStopBeginFrames();
}
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-Scheduler::AsValue() const {
- auto state = std::make_unique<base::trace_event::TracedValue>();
- AsValueInto(state.get());
- return std::move(state);
-}
-
-void Scheduler::AsValueInto(base::trace_event::TracedValue* state) const {
+void Scheduler::AsProtozeroInto(
+ perfetto::protos::pbzero::ChromeCompositorSchedulerState* state) const {
base::TimeTicks now = Now();
- state->BeginDictionary("state_machine");
- state_machine_.AsValueInto(state);
- state->EndDictionary();
-
- state->SetBoolean("observing_begin_frame_source",
- observing_begin_frame_source_);
- state->SetBoolean("begin_impl_frame_deadline_task",
- !begin_impl_frame_deadline_task_.IsCancelled());
- state->SetBoolean("pending_begin_frame_task",
- !pending_begin_frame_task_.IsCancelled());
- state->SetBoolean("skipped_last_frame_missed_exceeded_deadline",
- skipped_last_frame_missed_exceeded_deadline_);
- state->SetBoolean("skipped_last_frame_to_reduce_latency",
- skipped_last_frame_to_reduce_latency_);
- state->SetString("inside_action",
- SchedulerStateMachine::ActionToString(inside_action_));
- state->SetString("deadline_mode",
- SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
- deadline_mode_));
-
- state->SetDouble("deadline_ms", deadline_.since_origin().InMillisecondsF());
- state->SetDouble("deadline_scheduled_at_ms",
- deadline_scheduled_at_.since_origin().InMillisecondsF());
-
- state->SetDouble("now_ms", Now().since_origin().InMillisecondsF());
- state->SetDouble("now_to_deadline_ms", (deadline_ - Now()).InMillisecondsF());
- state->SetDouble("now_to_deadline_scheduled_at_ms",
- (deadline_scheduled_at_ - Now()).InMillisecondsF());
-
- state->BeginDictionary("begin_impl_frame_args");
- begin_impl_frame_tracker_.AsValueInto(now, state);
- state->EndDictionary();
-
- state->BeginDictionary("begin_frame_observer_state");
- BeginFrameObserverBase::AsValueInto(state);
- state->EndDictionary();
+ state_machine_.AsProtozeroInto(state->set_state_machine());
+
+ state->set_observing_begin_frame_source(observing_begin_frame_source_);
+ state->set_begin_impl_frame_deadline_task(
+ !begin_impl_frame_deadline_task_.IsCancelled());
+ state->set_pending_begin_frame_task(!pending_begin_frame_task_.IsCancelled());
+ state->set_skipped_last_frame_missed_exceeded_deadline(
+ skipped_last_frame_missed_exceeded_deadline_);
+ state->set_skipped_last_frame_to_reduce_latency(
+ skipped_last_frame_to_reduce_latency_);
+ state->set_inside_action(
+ SchedulerStateMachine::ActionToProtozeroEnum(inside_action_));
+ state->set_deadline_mode(
+ SchedulerStateMachine::BeginImplFrameDeadlineModeToProtozeroEnum(
+ deadline_mode_));
+
+ state->set_deadline_us(deadline_.since_origin().InMicroseconds());
+ state->set_deadline_scheduled_at_us(
+ deadline_scheduled_at_.since_origin().InMicroseconds());
+
+ state->set_now_us(Now().since_origin().InMicroseconds());
+ state->set_now_to_deadline_delta_us((deadline_ - Now()).InMicroseconds());
+ state->set_now_to_deadline_scheduled_at_delta_us(
+ (deadline_scheduled_at_ - Now()).InMicroseconds());
+
+ begin_impl_frame_tracker_.AsProtozeroInto(now,
+ state->set_begin_impl_frame_args());
+
+ BeginFrameObserverBase::AsProtozeroInto(
+ state->set_begin_frame_observer_state());
if (begin_frame_source_) {
- state->BeginDictionary("begin_frame_source_state");
- begin_frame_source_->AsValueInto(state);
- state->EndDictionary();
+ begin_frame_source_->AsProtozeroInto(state->set_begin_frame_source_state());
}
- state->BeginDictionary("compositor_timing_history");
- compositor_timing_history_->AsValueInto(state);
- state->EndDictionary();
+ compositor_timing_history_->AsProtozeroInto(
+ state->set_compositor_timing_history());
}
void Scheduler::UpdateCompositorTimingHistoryRecordingEnabled() {
diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h
index 23571c15023..fe99ee0fcac 100644
--- a/chromium/cc/scheduler/scheduler.h
+++ b/chromium/cc/scheduler/scheduler.h
@@ -20,10 +20,14 @@
#include "components/viz/common/frame_sinks/begin_frame_source.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
+namespace perfetto {
+namespace protos {
+namespace pbzero {
+class ChromeCompositorSchedulerState;
}
+} // namespace protos
+} // namespace perfetto
+namespace base {
class SingleThreadTaskRunner;
}
@@ -32,7 +36,7 @@ struct FrameTimingDetails;
}
namespace cc {
-
+struct BeginMainFrameMetrics;
class CompositorTimingHistory;
class SchedulerClient {
@@ -170,7 +174,7 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
// BeginMainFrame request from the compositor, and blocks the main thread
// to copy the layer tree to the compositor thread. Call this method when the
// main thread updates are completed to signal it is ready for the commmit.
- void NotifyReadyToCommit();
+ void NotifyReadyToCommit(std::unique_ptr<BeginMainFrameMetrics> details);
void BeginMainFrameAborted(CommitEarlyOutReason reason);
void DidCommit();
@@ -224,9 +228,8 @@ class CC_EXPORT Scheduler : public viz::BeginFrameObserverBase {
// the main thread by the cc scheduler.
void SetMainThreadWantsBeginMainFrameNotExpected(bool new_state);
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
-
- void AsValueInto(base::trace_event::TracedValue* state) const;
+ void AsProtozeroInto(
+ perfetto::protos::pbzero::ChromeCompositorSchedulerState* state) const;
void SetVideoNeedsBeginFrames(bool video_needs_begin_frames);
diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc
index dbbe56848fa..042772481bd 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine.cc
@@ -15,6 +15,7 @@ namespace cc {
namespace {
// Surfaces and CompositorTimingHistory don't support more than 1 pending swap.
const int kMaxPendingSubmitFrames = 1;
+
} // namespace
SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
@@ -22,36 +23,44 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
SchedulerStateMachine::~SchedulerStateMachine() = default;
-const char* SchedulerStateMachine::LayerTreeFrameSinkStateToString(
- LayerTreeFrameSinkState state) {
+perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ LayerTreeFrameSinkState
+ SchedulerStateMachine::LayerTreeFrameSinkStateToProtozeroEnum(
+ LayerTreeFrameSinkState state) {
+ using pbzeroMajorState =
+ perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
switch (state) {
case LayerTreeFrameSinkState::NONE:
- return "LayerTreeFrameSinkState::NONE";
+ return pbzeroMajorState::LAYER_TREE_FRAME_NONE;
case LayerTreeFrameSinkState::ACTIVE:
- return "LayerTreeFrameSinkState::ACTIVE";
+ return pbzeroMajorState::LAYER_TREE_FRAME_ACTIVE;
case LayerTreeFrameSinkState::CREATING:
- return "LayerTreeFrameSinkState::CREATING";
+ return pbzeroMajorState::LAYER_TREE_FRAME_CREATING;
case LayerTreeFrameSinkState::WAITING_FOR_FIRST_COMMIT:
- return "LayerTreeFrameSinkState::WAITING_FOR_FIRST_COMMIT";
+ return pbzeroMajorState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_COMMIT;
case LayerTreeFrameSinkState::WAITING_FOR_FIRST_ACTIVATION:
- return "LayerTreeFrameSinkState::WAITING_FOR_FIRST_ACTIVATION";
+ return pbzeroMajorState::LAYER_TREE_FRAME_WAITING_FOR_FIRST_ACTIVATION;
}
NOTREACHED();
- return "???";
+ return pbzeroMajorState::LAYER_TREE_FRAME_UNSPECIFIED;
}
-const char* SchedulerStateMachine::BeginImplFrameStateToString(
- BeginImplFrameState state) {
+perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ BeginImplFrameState
+ SchedulerStateMachine::BeginImplFrameStateToProtozeroEnum(
+ BeginImplFrameState state) {
+ using pbzeroMajorState =
+ perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
switch (state) {
case BeginImplFrameState::IDLE:
- return "BeginImplFrameState::IDLE";
+ return pbzeroMajorState::BEGIN_IMPL_FRAME_IDLE;
case BeginImplFrameState::INSIDE_BEGIN_FRAME:
- return "BeginImplFrameState::INSIDE_BEGIN_FRAME";
+ return pbzeroMajorState::BEGIN_IMPL_FRAME_INSIDE_BEGIN_FRAME;
case BeginImplFrameState::INSIDE_DEADLINE:
- return "BeginImplFrameState::INSIDE_DEADLINE";
+ return pbzeroMajorState::BEGIN_IMPL_FRAME_INSIDE_DEADLINE;
}
NOTREACHED();
- return "???";
+ return pbzeroMajorState::BEGIN_IMPL_FRAME_UNSPECIFIED;
}
const char* SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
@@ -72,176 +81,204 @@ const char* SchedulerStateMachine::BeginImplFrameDeadlineModeToString(
return "???";
}
-const char* SchedulerStateMachine::BeginMainFrameStateToString(
- BeginMainFrameState state) {
+perfetto::protos::pbzero::ChromeCompositorSchedulerState::
+ BeginImplFrameDeadlineMode
+ SchedulerStateMachine::BeginImplFrameDeadlineModeToProtozeroEnum(
+ BeginImplFrameDeadlineMode mode) {
+ using pbzeroSchedulerState =
+ perfetto::protos::pbzero::ChromeCompositorSchedulerState;
+ switch (mode) {
+ case BeginImplFrameDeadlineMode::NONE:
+ return pbzeroSchedulerState::DEADLINE_MODE_NONE;
+ case BeginImplFrameDeadlineMode::IMMEDIATE:
+ return pbzeroSchedulerState::DEADLINE_MODE_IMMEDIATE;
+ case BeginImplFrameDeadlineMode::REGULAR:
+ return pbzeroSchedulerState::DEADLINE_MODE_REGULAR;
+ case BeginImplFrameDeadlineMode::LATE:
+ return pbzeroSchedulerState::DEADLINE_MODE_LATE;
+ case BeginImplFrameDeadlineMode::BLOCKED:
+ return pbzeroSchedulerState::DEADLINE_MODE_BLOCKED;
+ }
+ NOTREACHED();
+ return pbzeroSchedulerState::DEADLINE_MODE_UNSPECIFIED;
+}
+
+perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ BeginMainFrameState
+ SchedulerStateMachine::BeginMainFrameStateToProtozeroEnum(
+ BeginMainFrameState state) {
+ using pbzeroMajorState =
+ perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
switch (state) {
case BeginMainFrameState::IDLE:
- return "BeginMainFrameState::IDLE";
+ return pbzeroMajorState::BEGIN_MAIN_FRAME_IDLE;
case BeginMainFrameState::SENT:
- return "BeginMainFrameState::SENT";
+ return pbzeroMajorState::BEGIN_MAIN_FRAME_SENT;
case BeginMainFrameState::READY_TO_COMMIT:
- return "BeginMainFrameState::READY_TO_COMMIT";
+ return pbzeroMajorState::BEGIN_MAIN_FRAME_READY_TO_COMMIT;
}
NOTREACHED();
- return "???";
+ return pbzeroMajorState::BEGIN_MAIN_FRAME_UNSPECIFIED;
}
-const char* SchedulerStateMachine::ForcedRedrawOnTimeoutStateToString(
- ForcedRedrawOnTimeoutState state) {
+perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ ForcedRedrawOnTimeoutState
+ SchedulerStateMachine::ForcedRedrawOnTimeoutStateToProtozeroEnum(
+ ForcedRedrawOnTimeoutState state) {
+ using pbzeroMajorState =
+ perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState;
switch (state) {
case ForcedRedrawOnTimeoutState::IDLE:
- return "ForcedRedrawOnTimeoutState::IDLE";
+ return pbzeroMajorState::FORCED_REDRAW_IDLE;
case ForcedRedrawOnTimeoutState::WAITING_FOR_COMMIT:
- return "ForcedRedrawOnTimeoutState::WAITING_FOR_COMMIT";
+ return pbzeroMajorState::FORCED_REDRAW_WAITING_FOR_COMMIT;
case ForcedRedrawOnTimeoutState::WAITING_FOR_ACTIVATION:
- return "ForcedRedrawOnTimeoutState::WAITING_FOR_ACTIVATION";
+ return pbzeroMajorState::FORCED_REDRAW_WAITING_FOR_ACTIVATION;
case ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW:
- return "ForcedRedrawOnTimeoutState::WAITING_FOR_DRAW";
+ return pbzeroMajorState::FORCED_REDRAW_WAITING_FOR_DRAW;
}
NOTREACHED();
- return "???";
+ return pbzeroMajorState::FORCED_REDRAW_UNSPECIFIED;
}
-const char* ScrollHandlerStateToString(ScrollHandlerState state) {
+perfetto::protos::pbzero::ChromeCompositorStateMachine::MinorState::
+ ScrollHandlerState
+ ScrollHandlerStateToProtozeroEnum(ScrollHandlerState state) {
+ using pbzeroMinorState =
+ perfetto::protos::pbzero::ChromeCompositorStateMachine::MinorState;
switch (state) {
case ScrollHandlerState::SCROLL_AFFECTS_SCROLL_HANDLER:
- return "SCROLL_AFFECTS_SCROLL_HANDLER";
+ return pbzeroMinorState::SCROLL_AFFECTS_SCROLL_HANDLER;
case ScrollHandlerState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER:
- return "SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER";
+ return pbzeroMinorState::SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER;
}
NOTREACHED();
- return "???";
+ return pbzeroMinorState::SCROLL_HANDLER_UNSPECIFIED;
}
-const char* SchedulerStateMachine::ActionToString(Action action) {
+perfetto::protos::pbzero::ChromeCompositorSchedulerAction
+SchedulerStateMachine::ActionToProtozeroEnum(Action action) {
+ using pbzeroSchedulerAction =
+ perfetto::protos::pbzero::ChromeCompositorSchedulerAction;
switch (action) {
case Action::NONE:
- return "Action::NONE";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_NONE;
case Action::SEND_BEGIN_MAIN_FRAME:
- return "Action::SEND_BEGIN_MAIN_FRAME";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_SEND_BEGIN_MAIN_FRAME;
case Action::COMMIT:
- return "Action::COMMIT";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_COMMIT;
case Action::ACTIVATE_SYNC_TREE:
- return "Action::ACTIVATE_SYNC_TREE";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_ACTIVATE_SYNC_TREE;
case Action::DRAW_IF_POSSIBLE:
- return "Action::DRAW_IF_POSSIBLE";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_DRAW_IF_POSSIBLE;
case Action::DRAW_FORCED:
- return "Action::DRAW_FORCED";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_DRAW_FORCED;
case Action::DRAW_ABORT:
- return "Action::DRAW_ABORT";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_DRAW_ABORT;
case Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION:
- return "Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION";
+ return pbzeroSchedulerAction::
+ CC_SCHEDULER_ACTION_BEGIN_LAYER_TREE_FRAME_SINK_CREATION;
case Action::PREPARE_TILES:
- return "Action::PREPARE_TILES";
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_PREPARE_TILES;
case Action::INVALIDATE_LAYER_TREE_FRAME_SINK:
- return "Action::INVALIDATE_LAYER_TREE_FRAME_SINK";
+ return pbzeroSchedulerAction::
+ CC_SCHEDULER_ACTION_INVALIDATE_LAYER_TREE_FRAME_SINK;
case Action::PERFORM_IMPL_SIDE_INVALIDATION:
- return "Action::PERFORM_IMPL_SIDE_INVALIDATION";
+ return pbzeroSchedulerAction::
+ CC_SCHEDULER_ACTION_PERFORM_IMPL_SIDE_INVALIDATION;
case Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL:
- return "Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL";
+ return pbzeroSchedulerAction::
+ CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL;
case Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON:
- return "Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON";
+ return pbzeroSchedulerAction::
+ CC_SCHEDULER_ACTION_NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON;
}
NOTREACHED();
- return "???";
-}
-
-std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
-SchedulerStateMachine::AsValue() const {
- std::unique_ptr<base::trace_event::TracedValue> state(
- new base::trace_event::TracedValue());
- AsValueInto(state.get());
- return std::move(state);
-}
-
-void SchedulerStateMachine::AsValueInto(
- base::trace_event::TracedValue* state) const {
- state->BeginDictionary("major_state");
- state->SetString("next_action", ActionToString(NextAction()));
- state->SetString("begin_impl_frame_state",
- BeginImplFrameStateToString(begin_impl_frame_state_));
- state->SetString("begin_main_frame_state",
- BeginMainFrameStateToString(begin_main_frame_state_));
- state->SetString(
- "layer_tree_frame_sink_state",
- LayerTreeFrameSinkStateToString(layer_tree_frame_sink_state_));
- state->SetString("forced_redraw_state",
- ForcedRedrawOnTimeoutStateToString(forced_redraw_state_));
- state->EndDictionary();
-
- state->BeginDictionary("minor_state");
- state->SetInteger("commit_count", commit_count_);
- state->SetInteger("current_frame_number", current_frame_number_);
- 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",
- last_frame_number_begin_main_frame_sent_);
- state->SetBoolean("did_draw", did_draw_);
- state->SetBoolean("did_send_begin_main_frame_for_current_frame",
- did_send_begin_main_frame_for_current_frame_);
- state->SetBoolean("did_notify_begin_main_frame_not_expected_until",
- did_notify_begin_main_frame_not_expected_until_);
- state->SetBoolean("did_notify_begin_main_frame_not_expected_soon",
- did_notify_begin_main_frame_not_expected_soon_);
- state->SetBoolean("wants_begin_main_frame_not_expected",
- wants_begin_main_frame_not_expected_);
- state->SetBoolean("did_commit_during_frame", did_commit_during_frame_);
- state->SetBoolean("did_invalidate_layer_tree_frame_sink",
- did_invalidate_layer_tree_frame_sink_);
- state->SetBoolean("did_perform_impl_side_invalidaion",
- did_perform_impl_side_invalidation_);
- state->SetBoolean("did_prepare_tiles", did_prepare_tiles_);
- state->SetInteger("consecutive_checkerboard_animations",
- consecutive_checkerboard_animations_);
- state->SetInteger("pending_submit_frames", pending_submit_frames_);
- state->SetInteger("submit_frames_with_current_layer_tree_frame_sink",
- submit_frames_with_current_layer_tree_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_);
- state->SetBoolean("needs_one_begin_impl_frame", needs_one_begin_impl_frame_);
- state->SetBoolean("visible", visible_);
- state->SetBoolean("begin_frame_source_paused", begin_frame_source_paused_);
- state->SetBoolean("can_draw", can_draw_);
- state->SetBoolean("resourceless_draw", resourceless_draw_);
- state->SetBoolean("has_pending_tree", has_pending_tree_);
- state->SetBoolean("pending_tree_is_ready_for_activation",
- pending_tree_is_ready_for_activation_);
- state->SetBoolean("active_tree_needs_first_draw",
- active_tree_needs_first_draw_);
- state->SetBoolean("active_tree_is_ready_to_draw",
- active_tree_is_ready_to_draw_);
- state->SetBoolean("did_create_and_initialize_first_layer_tree_frame_sink",
- did_create_and_initialize_first_layer_tree_frame_sink_);
- state->SetString("tree_priority", TreePriorityToString(tree_priority_));
- state->SetString("scroll_handler_state",
- ScrollHandlerStateToString(scroll_handler_state_));
- state->SetBoolean("critical_begin_main_frame_to_activate_is_fast",
- critical_begin_main_frame_to_activate_is_fast_);
- state->SetBoolean("main_thread_missed_last_deadline",
- main_thread_missed_last_deadline_);
- state->SetBoolean("skip_next_begin_main_frame_to_reduce_latency",
- skip_next_begin_main_frame_to_reduce_latency_);
- state->SetBoolean("video_needs_begin_frames", video_needs_begin_frames_);
- state->SetBoolean("defer_begin_main_frame", defer_begin_main_frame_);
- 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_submit_in_last_frame", did_submit_in_last_frame_);
- state->SetBoolean("needs_impl_side_invalidation",
- needs_impl_side_invalidation_);
- state->SetBoolean("current_pending_tree_is_impl_side",
- current_pending_tree_is_impl_side_);
- state->SetBoolean("previous_pending_tree_was_impl_side",
- previous_pending_tree_was_impl_side_);
- state->SetBoolean("processing_animation_worklets_for_active_tree",
- processing_animation_worklets_for_active_tree_);
- state->SetBoolean("processing_animation_worklets_for_pending_tree",
- processing_animation_worklets_for_pending_tree_);
- state->SetBoolean("processing_paint_worklets_for_pending_tree",
- processing_paint_worklets_for_pending_tree_);
- state->EndDictionary();
+ return pbzeroSchedulerAction::CC_SCHEDULER_ACTION_UNSPECIFIED;
+}
+
+void SchedulerStateMachine::AsProtozeroInto(
+ perfetto::protos::pbzero::ChromeCompositorStateMachine* state) const {
+ auto* major_state = state->set_major_state();
+ major_state->set_next_action(ActionToProtozeroEnum(NextAction()));
+ major_state->set_begin_impl_frame_state(
+ BeginImplFrameStateToProtozeroEnum(begin_impl_frame_state_));
+ major_state->set_begin_main_frame_state(
+ BeginMainFrameStateToProtozeroEnum(begin_main_frame_state_));
+ major_state->set_layer_tree_frame_sink_state(
+ LayerTreeFrameSinkStateToProtozeroEnum(layer_tree_frame_sink_state_));
+ major_state->set_forced_redraw_state(
+ ForcedRedrawOnTimeoutStateToProtozeroEnum(forced_redraw_state_));
+
+ auto* minor_state = state->set_minor_state();
+ minor_state->set_commit_count(commit_count_);
+ minor_state->set_current_frame_number(current_frame_number_);
+ minor_state->set_last_frame_number_submit_performed(
+ last_frame_number_submit_performed_);
+ minor_state->set_last_frame_number_draw_performed(
+ last_frame_number_draw_performed_);
+ minor_state->set_last_frame_number_begin_main_frame_sent(
+ last_frame_number_begin_main_frame_sent_);
+ minor_state->set_did_draw(did_draw_);
+ minor_state->set_did_send_begin_main_frame_for_current_frame(
+ did_send_begin_main_frame_for_current_frame_);
+ minor_state->set_did_notify_begin_main_frame_not_expected_until(
+ did_notify_begin_main_frame_not_expected_until_);
+ minor_state->set_did_notify_begin_main_frame_not_expected_soon(
+ did_notify_begin_main_frame_not_expected_soon_);
+ minor_state->set_wants_begin_main_frame_not_expected(
+ wants_begin_main_frame_not_expected_);
+ minor_state->set_did_commit_during_frame(did_commit_during_frame_);
+ minor_state->set_did_invalidate_layer_tree_frame_sink(
+ did_invalidate_layer_tree_frame_sink_);
+ minor_state->set_did_perform_impl_side_invalidaion(
+ did_perform_impl_side_invalidation_);
+ minor_state->set_did_prepare_tiles(did_prepare_tiles_);
+ minor_state->set_consecutive_checkerboard_animations(
+ consecutive_checkerboard_animations_);
+ minor_state->set_pending_submit_frames(pending_submit_frames_);
+ minor_state->set_submit_frames_with_current_layer_tree_frame_sink(
+ submit_frames_with_current_layer_tree_frame_sink_);
+ minor_state->set_needs_redraw(needs_redraw_);
+ minor_state->set_needs_prepare_tiles(needs_prepare_tiles_);
+ minor_state->set_needs_begin_main_frame(needs_begin_main_frame_);
+ minor_state->set_needs_one_begin_impl_frame(needs_one_begin_impl_frame_);
+ minor_state->set_visible(visible_);
+ minor_state->set_begin_frame_source_paused(begin_frame_source_paused_);
+ minor_state->set_can_draw(can_draw_);
+ minor_state->set_resourceless_draw(resourceless_draw_);
+ minor_state->set_has_pending_tree(has_pending_tree_);
+ minor_state->set_pending_tree_is_ready_for_activation(
+ pending_tree_is_ready_for_activation_);
+ minor_state->set_active_tree_needs_first_draw(active_tree_needs_first_draw_);
+ minor_state->set_active_tree_is_ready_to_draw(active_tree_is_ready_to_draw_);
+ minor_state->set_did_create_and_initialize_first_layer_tree_frame_sink(
+ did_create_and_initialize_first_layer_tree_frame_sink_);
+ minor_state->set_tree_priority(TreePriorityToProtozeroEnum(tree_priority_));
+ minor_state->set_scroll_handler_state(
+ ScrollHandlerStateToProtozeroEnum(scroll_handler_state_));
+ minor_state->set_critical_begin_main_frame_to_activate_is_fast(
+ critical_begin_main_frame_to_activate_is_fast_);
+ minor_state->set_main_thread_missed_last_deadline(
+ main_thread_missed_last_deadline_);
+ minor_state->set_skip_next_begin_main_frame_to_reduce_latency(
+ skip_next_begin_main_frame_to_reduce_latency_);
+ minor_state->set_video_needs_begin_frames(video_needs_begin_frames_);
+ minor_state->set_defer_begin_main_frame(defer_begin_main_frame_);
+ minor_state->set_last_commit_had_no_updates(last_commit_had_no_updates_);
+ minor_state->set_did_draw_in_last_frame(did_draw_in_last_frame_);
+ minor_state->set_did_submit_in_last_frame(did_submit_in_last_frame_);
+ minor_state->set_needs_impl_side_invalidation(needs_impl_side_invalidation_);
+ minor_state->set_current_pending_tree_is_impl_side(
+ current_pending_tree_is_impl_side_);
+ minor_state->set_previous_pending_tree_was_impl_side(
+ previous_pending_tree_was_impl_side_);
+ minor_state->set_processing_animation_worklets_for_active_tree(
+ processing_animation_worklets_for_active_tree_);
+ minor_state->set_processing_animation_worklets_for_pending_tree(
+ processing_animation_worklets_for_pending_tree_);
+ minor_state->set_processing_paint_worklets_for_pending_tree(
+ processing_paint_worklets_for_pending_tree_);
}
bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
@@ -1373,8 +1410,7 @@ void SchedulerStateMachine::SetNeedsOneBeginImplFrame() {
}
void SchedulerStateMachine::NotifyReadyToCommit() {
- DCHECK_EQ(begin_main_frame_state_, BeginMainFrameState::SENT)
- << AsValue()->ToString();
+ DCHECK_EQ(begin_main_frame_state_, BeginMainFrameState::SENT);
begin_main_frame_state_ = BeginMainFrameState::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.
diff --git a/chromium/cc/scheduler/scheduler_state_machine.h b/chromium/cc/scheduler/scheduler_state_machine.h
index 198e2ff1749..fe25d098c34 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.h
+++ b/chromium/cc/scheduler/scheduler_state_machine.h
@@ -16,13 +16,7 @@
#include "cc/scheduler/scheduler_settings.h"
#include "cc/tiles/tile_priority.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
-
-namespace base {
-namespace trace_event {
-class ConvertableToTraceFormat;
-class TracedValue;
-}
-}
+#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h"
namespace cc {
@@ -30,7 +24,6 @@ enum class ScrollHandlerState {
SCROLL_AFFECTS_SCROLL_HANDLER,
SCROLL_DOES_NOT_AFFECT_SCROLL_HANDLER,
};
-const char* ScrollHandlerStateToString(ScrollHandlerState state);
// The SchedulerStateMachine decides how to coordinate main thread activites
// like painting/running javascript with rendering and input activities on the
@@ -59,8 +52,9 @@ class CC_EXPORT SchedulerStateMachine {
WAITING_FOR_FIRST_COMMIT,
WAITING_FOR_FIRST_ACTIVATION,
};
- static const char* LayerTreeFrameSinkStateToString(
- LayerTreeFrameSinkState state);
+ static perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ LayerTreeFrameSinkState
+ LayerTreeFrameSinkStateToProtozeroEnum(LayerTreeFrameSinkState state);
// Note: BeginImplFrameState does not cycle through these states in a fixed
// order on all platforms. It's up to the scheduler to set these correctly.
@@ -69,7 +63,9 @@ class CC_EXPORT SchedulerStateMachine {
INSIDE_BEGIN_FRAME,
INSIDE_DEADLINE,
};
- static const char* BeginImplFrameStateToString(BeginImplFrameState state);
+ static perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ BeginImplFrameState
+ BeginImplFrameStateToProtozeroEnum(BeginImplFrameState state);
// The scheduler uses a deadline to wait for main thread updates before
// submitting a compositor frame. BeginImplFrameDeadlineMode specifies when
@@ -84,8 +80,14 @@ class CC_EXPORT SchedulerStateMachine {
BLOCKED, // Deadline should be blocked indefinitely until the next frame
// arrives.
};
+ // TODO(nuskos): Update Scheduler::ScheduleBeginImplFrameDeadline event to
+ // used typed macros so we can remove this ToString function.
static const char* BeginImplFrameDeadlineModeToString(
BeginImplFrameDeadlineMode mode);
+ static perfetto::protos::pbzero::ChromeCompositorSchedulerState::
+ BeginImplFrameDeadlineMode
+ BeginImplFrameDeadlineModeToProtozeroEnum(
+ BeginImplFrameDeadlineMode mode);
enum class BeginMainFrameState {
IDLE, // A new BeginMainFrame can start.
@@ -93,7 +95,9 @@ class CC_EXPORT SchedulerStateMachine {
READY_TO_COMMIT, // A previously issued BeginMainFrame has been processed,
// and is ready to commit.
};
- static const char* BeginMainFrameStateToString(BeginMainFrameState state);
+ static perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ BeginMainFrameState
+ BeginMainFrameStateToProtozeroEnum(BeginMainFrameState state);
// When a redraw is forced, it goes through a complete commit -> activation ->
// draw cycle. Until a redraw has been forced, it remains in IDLE state.
@@ -103,8 +107,10 @@ class CC_EXPORT SchedulerStateMachine {
WAITING_FOR_ACTIVATION,
WAITING_FOR_DRAW,
};
- static const char* ForcedRedrawOnTimeoutStateToString(
- ForcedRedrawOnTimeoutState state);
+ static perfetto::protos::pbzero::ChromeCompositorStateMachine::MajorState::
+ ForcedRedrawOnTimeoutState
+ ForcedRedrawOnTimeoutStateToProtozeroEnum(
+ ForcedRedrawOnTimeoutState state);
BeginMainFrameState begin_main_frame_state() const {
return begin_main_frame_state_;
@@ -136,10 +142,11 @@ class CC_EXPORT SchedulerStateMachine {
NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL,
NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON,
};
- static const char* ActionToString(Action action);
+ static perfetto::protos::pbzero::ChromeCompositorSchedulerAction
+ ActionToProtozeroEnum(Action action);
- std::unique_ptr<base::trace_event::ConvertableToTraceFormat> AsValue() const;
- void AsValueInto(base::trace_event::TracedValue* dict) const;
+ void AsProtozeroInto(
+ perfetto::protos::pbzero::ChromeCompositorStateMachine* state) const;
Action NextAction() const;
void WillSendBeginMainFrame();
diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
index 6e080e666fe..ec84d72a398 100644
--- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -20,22 +20,19 @@
// With:
// 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), \
- SchedulerStateMachine::enum_tostring(actual))
+#define EXPECT_ENUM_EQ(enum_tostring, expected, actual) \
+ EXPECT_EQ(enum_tostring(expected), enum_tostring(actual))
#define EXPECT_IMPL_FRAME_STATE(expected) \
EXPECT_ENUM_EQ(BeginImplFrameStateToString, expected, \
- state.begin_impl_frame_state()) \
- << state.AsValue()->ToString()
+ state.begin_impl_frame_state())
#define EXPECT_MAIN_FRAME_STATE(expected) \
EXPECT_ENUM_EQ(BeginMainFrameStateToString, expected, \
state.BeginMainFrameState())
-#define EXPECT_ACTION(expected) \
- EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction()) \
- << state.AsValue()->ToString()
+#define EXPECT_ACTION(expected) \
+ EXPECT_ENUM_EQ(ActionToString, expected, state.NextAction())
#define EXPECT_ACTION_UPDATE_STATE(action) \
EXPECT_ACTION(action); \
@@ -63,6 +60,69 @@ namespace cc {
namespace {
+const char* BeginImplFrameStateToString(
+ SchedulerStateMachine::BeginImplFrameState state) {
+ using BeginImplFrameState = SchedulerStateMachine::BeginImplFrameState;
+ switch (state) {
+ case BeginImplFrameState::IDLE:
+ return "BeginImplFrameState::IDLE";
+ case BeginImplFrameState::INSIDE_BEGIN_FRAME:
+ return "BeginImplFrameState::INSIDE_BEGIN_FRAME";
+ case BeginImplFrameState::INSIDE_DEADLINE:
+ return "BeginImplFrameState::INSIDE_DEADLINE";
+ }
+ NOTREACHED();
+ return "???";
+}
+const char* BeginMainFrameStateToString(
+ SchedulerStateMachine::BeginMainFrameState state) {
+ using BeginMainFrameState = SchedulerStateMachine::BeginMainFrameState;
+ switch (state) {
+ case BeginMainFrameState::IDLE:
+ return "BeginMainFrameState::IDLE";
+ case BeginMainFrameState::SENT:
+ return "BeginMainFrameState::SENT";
+ case BeginMainFrameState::READY_TO_COMMIT:
+ return "BeginMainFrameState::READY_TO_COMMIT";
+ }
+ NOTREACHED();
+ return "???";
+}
+
+const char* ActionToString(SchedulerStateMachine::Action action) {
+ using Action = SchedulerStateMachine::Action;
+ switch (action) {
+ case Action::NONE:
+ return "Action::NONE";
+ case Action::SEND_BEGIN_MAIN_FRAME:
+ return "Action::SEND_BEGIN_MAIN_FRAME";
+ case Action::COMMIT:
+ return "Action::COMMIT";
+ case Action::ACTIVATE_SYNC_TREE:
+ return "Action::ACTIVATE_SYNC_TREE";
+ 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_LAYER_TREE_FRAME_SINK_CREATION:
+ return "Action::BEGIN_LAYER_TREE_FRAME_SINK_CREATION";
+ case Action::PREPARE_TILES:
+ return "Action::PREPARE_TILES";
+ case Action::INVALIDATE_LAYER_TREE_FRAME_SINK:
+ return "Action::INVALIDATE_LAYER_TREE_FRAME_SINK";
+ case Action::PERFORM_IMPL_SIDE_INVALIDATION:
+ return "Action::PERFORM_IMPL_SIDE_INVALIDATION";
+ case Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL:
+ return "Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_UNTIL";
+ case Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON:
+ return "Action::NOTIFY_BEGIN_MAIN_FRAME_NOT_EXPECTED_SOON";
+ }
+ NOTREACHED();
+ return "???";
+}
+
const bool kAnimateOnly = false;
const SchedulerStateMachine::BeginImplFrameState all_begin_impl_frame_states[] =
@@ -799,8 +859,7 @@ TEST(SchedulerStateMachineTest, TestNextActionDrawsOnBeginImplFrame) {
// Case 2: needs_begin_main_frame=true
state.SetNeedsBeginMainFrame();
EXPECT_NE(SchedulerStateMachine::Action::DRAW_IF_POSSIBLE,
- state.NextAction())
- << state.AsValue()->ToString();
+ state.NextAction());
}
}
@@ -867,8 +926,7 @@ TEST(SchedulerStateMachineTest, TestNoBeginMainFrameStatesRedrawWhenInvisible) {
// Case 2: needs_begin_main_frame=true.
state.SetNeedsBeginMainFrame();
EXPECT_NE(SchedulerStateMachine::Action::DRAW_IF_POSSIBLE,
- state.NextAction())
- << state.AsValue()->ToString();
+ state.NextAction());
}
}
}
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index 5437a540cd1..7d1c8d81aa0 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -18,6 +18,7 @@
#include "base/test/test_mock_time_task_runner.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
+#include "cc/metrics/begin_main_frame_metrics.h"
#include "cc/test/scheduler_test_common.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
#include "components/viz/test/begin_frame_args_test.h"
@@ -50,7 +51,6 @@ class FakeSchedulerClient : public SchedulerClient,
void Reset() {
actions_.clear();
- states_.clear();
will_begin_impl_frame_causes_redraw_ = false;
will_begin_impl_frame_requests_one_begin_impl_frame_ = false;
invalidate_needs_redraw_ = true;
@@ -69,7 +69,6 @@ class FakeSchedulerClient : public SchedulerClient,
const std::vector<std::string> Actions() const {
return std::vector<std::string>(actions_.begin(), actions_.end());
}
- std::string StateForAction(int i) const { return states_[i]->ToString(); }
base::TimeTicks posted_begin_impl_frame_deadline() const {
return posted_begin_impl_frame_deadline_;
}
@@ -205,7 +204,6 @@ class FakeSchedulerClient : public SchedulerClient,
base::AutoReset<bool> mark_inside(&inside_action_, true);
invalidate_needs_redraw_ = needs_redraw;
actions_.push_back("ScheduledActionInvalidateLayerTreeFrameSink");
- states_.push_back(scheduler_->AsValue());
}
void ScheduledActionPerformImplSideInvalidation() override {
EXPECT_FALSE(inside_action_);
@@ -246,7 +244,6 @@ class FakeSchedulerClient : public SchedulerClient,
void PushAction(const char* description) {
actions_.push_back(description);
- states_.push_back(scheduler_->AsValue());
}
// FakeExternalBeginFrameSource::Client implementation.
@@ -282,8 +279,6 @@ class FakeSchedulerClient : public SchedulerClient,
viz::BeginFrameAck last_begin_frame_ack_;
base::TimeTicks posted_begin_impl_frame_deadline_;
std::vector<const char*> actions_;
- std::vector<std::unique_ptr<base::trace_event::ConvertableToTraceFormat>>
- states_;
TestScheduler* scheduler_ = nullptr;
base::TimeDelta frame_interval_;
};
@@ -455,7 +450,7 @@ class SchedulerTest : public testing::Test {
task_runner_->AdvanceMockTickClock(base::TimeDelta::FromMilliseconds(1));
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
scheduler_->NotifyReadyToDraw();
@@ -663,7 +658,7 @@ TEST_F(SchedulerTest, RequestCommit) {
// NotifyReadyToCommit should trigger the commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
EXPECT_TRUE(scheduler_->begin_frames_expected());
client_->Reset();
@@ -778,7 +773,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
// Finish the first commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
client_->Reset();
@@ -807,7 +802,7 @@ TEST_F(SchedulerTest, RequestCommitAfterBeginMainFrameSent) {
// Finishing the commit before the deadline should post a new deadline task
// to trigger the deadline early.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
client_->Reset();
@@ -985,7 +980,7 @@ TEST_F(SchedulerTest, RequestCommitInsideDraw) {
EXPECT_TRUE(scheduler_->CommitPending());
EXPECT_TRUE(client->needs_begin_frames());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_SCOPED(AdvanceFrame());
@@ -1380,7 +1375,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawDoNotPostDeadline) {
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
client_->Reset();
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -1418,7 +1413,7 @@ TEST_F(SchedulerTest, WaitForReadyToDrawCancelledWhenLostLayerTreeFrameSink) {
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
client_->Reset();
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -1450,7 +1445,7 @@ void SchedulerTest::AdvanceAndMissOneFrame() {
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_ACTIONS("AddObserver(this)", "WillBeginImplFrame",
"ScheduledActionSendBeginMainFrame", "ScheduledActionCommit",
@@ -1714,7 +1709,7 @@ TEST_F(SchedulerTest, MainFrameNotSkippedAfterCanDrawChanges) {
// Make us abort the upcoming draw.
client_->Reset();
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
@@ -1759,7 +1754,7 @@ TEST_F(SchedulerTest, MainFrameNotSkippedWhenNoTimingHistory) {
// Commit after the deadline.
client_->Reset();
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
@@ -1789,7 +1784,7 @@ void SchedulerTest::ImplFrameSkippedAfterLateAck(
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -1834,7 +1829,7 @@ void SchedulerTest::ImplFrameSkippedAfterLateAck(
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
@@ -1963,7 +1958,7 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateAck() {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -1987,7 +1982,7 @@ void SchedulerTest::ImplFrameNotSkippedAfterLateAck() {
client_->Reset();
scheduler_->DidReceiveCompositorFrameAck();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -2061,7 +2056,7 @@ TEST_F(SchedulerTest, MainFrameThenImplFrameSkippedAfterLateCommitAndLateAck) {
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
@@ -2077,7 +2072,7 @@ TEST_F(SchedulerTest, MainFrameThenImplFrameSkippedAfterLateCommitAndLateAck) {
EXPECT_TRUE(scheduler_->MainThreadMissedLastDeadline());
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
@@ -2142,7 +2137,7 @@ TEST_F(SchedulerTest, MainFrameThenImplFrameSkippedAfterLateCommitAndLateAck) {
SendNextBeginFrame();
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
EXPECT_FALSE(scheduler_->MainThreadMissedLastDeadline());
@@ -2177,7 +2172,7 @@ void SchedulerTest::BeginFramesNotFromClient(BeginFrameSourceType bfs_type) {
// NotifyReadyToCommit should trigger the commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -2231,7 +2226,7 @@ void SchedulerTest::BeginFramesNotFromClient_IsDrawThrottled(
// NotifyReadyToCommit should trigger the pending commit.
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -2337,7 +2332,7 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterBeginFrameStarted) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree");
client_->Reset();
@@ -2383,7 +2378,7 @@ TEST_F(SchedulerTest,
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit", "ScheduledActionActivateSyncTree",
"ScheduledActionBeginLayerTreeFrameSinkCreation");
}
@@ -2402,7 +2397,7 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkAfterReadyToCommit) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -2458,7 +2453,7 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWithDelayBasedBeginFrameSource) {
// NotifyReadyToCommit should trigger the commit.
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
EXPECT_TRUE(scheduler_->begin_frames_expected());
@@ -2494,7 +2489,7 @@ TEST_F(SchedulerTest, DidLoseLayerTreeFrameSinkWhenIdle) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -2526,7 +2521,7 @@ TEST_F(SchedulerTest, ScheduledActionActivateAfterBecomingInvisible) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
@@ -2552,7 +2547,7 @@ TEST_F(SchedulerTest, ScheduledActionActivateAfterBeginFrameSourcePaused) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
@@ -2739,7 +2734,7 @@ TEST_F(SchedulerTest, SwitchFrameSourceWhenNotObserving) {
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame");
client_->Reset();
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -2830,7 +2825,7 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Requested) {
// Trigger a frame draw.
EXPECT_SCOPED(AdvanceFrame());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
@@ -2866,7 +2861,7 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_Unrequested) {
// Trigger a frame draw.
EXPECT_SCOPED(AdvanceFrame());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
@@ -2904,7 +2899,7 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoonOnlyOncePerFrame) {
// Trigger a frame draw.
EXPECT_SCOPED(AdvanceFrame());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
@@ -2945,7 +2940,7 @@ TEST_F(SchedulerTest, SendBeginMainFrameNotExpectedSoon_AlreadyIdle) {
// Trigger a frame draw.
EXPECT_SCOPED(AdvanceFrame());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunPendingTasks();
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionSendBeginMainFrame",
@@ -3303,7 +3298,7 @@ TEST_F(SchedulerTest, SynchronousCompositorCommitAndVerifyBeginFrameAcks) {
client_->last_begin_frame_ack());
client_->Reset();
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -3457,7 +3452,7 @@ TEST_F(SchedulerTest, SynchronousCompositorSendBeginMainFrameWhileIdle) {
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
client_->Reset();
@@ -3515,7 +3510,7 @@ TEST_F(SchedulerTest, AuthoritativeVSyncInterval) {
EXPECT_EQ(initial_interval, scheduler_->BeginImplFrameInterval());
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
scheduler_->NotifyReadyToActivate();
task_runner_->RunTasksWhile(client_->InsideBeginImplFrame(true));
@@ -3626,7 +3621,7 @@ TEST_F(SchedulerTest, ImplSideInvalidationsMergedWithCommit) {
// commit.
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
EXPECT_FALSE(scheduler_->needs_impl_side_invalidation());
}
@@ -4166,7 +4161,7 @@ TEST_F(SchedulerTest,
// Commit before deadline but not ready to activate.
client_->Reset();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("ScheduledActionCommit");
// Draw deadline.
@@ -4215,7 +4210,7 @@ TEST_F(SchedulerTest, DontSkipMainFrameAfterClearingHistory) {
EXPECT_SCOPED(AdvanceFrame());
scheduler_->SetNeedsBeginMainFrame();
scheduler_->NotifyBeginMainFrameStarted(task_runner_->NowTicks());
- scheduler_->NotifyReadyToCommit();
+ scheduler_->NotifyReadyToCommit(nullptr);
EXPECT_ACTIONS("WillBeginImplFrame", "ScheduledActionCommit");
// But during the commit, the history is cleared. So the main frame should not
diff --git a/chromium/cc/tiles/frame_viewer_instrumentation.h b/chromium/cc/tiles/frame_viewer_instrumentation.h
index 7c4ad9df52f..38f1ed1811e 100644
--- a/chromium/cc/tiles/frame_viewer_instrumentation.h
+++ b/chromium/cc/tiles/frame_viewer_instrumentation.h
@@ -6,6 +6,7 @@
#define CC_TILES_FRAME_VIEWER_INSTRUMENTATION_H_
#include "base/trace_event/trace_event.h"
+#include "cc/cc_export.h"
#include "cc/tiles/tile_priority.h"
namespace cc {
@@ -42,7 +43,7 @@ class ScopedRasterTask {
ScopedRasterTask& operator=(const ScopedRasterTask&) = delete;
};
-bool IsTracingLayerTreeSnapshots();
+bool CC_EXPORT IsTracingLayerTreeSnapshots();
} // namespace frame_viewer_instrumentation
} // namespace cc
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.cc b/chromium/cc/tiles/gpu_image_decode_cache.cc
index 198f910967d..17c49d2d3ae 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache.cc
@@ -186,23 +186,26 @@ void SetYuvPixmapsFromSizeInfo(SkPixmap* pixmap_y,
DCHECK(pixmap_y);
DCHECK(pixmap_u);
DCHECK(pixmap_v);
- const size_t y_width = yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index];
+ const size_t y_width_bytes =
+ yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index];
+ const size_t y_width = yuva_size_info.fSizes[SkYUVAIndex::kY_Index].width();
const size_t y_height = yuva_size_info.fSizes[SkYUVAIndex::kY_Index].height();
- const size_t u_width = yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index];
+ const size_t u_width_bytes =
+ yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index];
+ const size_t u_width = yuva_size_info.fSizes[SkYUVAIndex::kU_Index].width();
const size_t u_height = yuva_size_info.fSizes[SkYUVAIndex::kU_Index].height();
- const size_t v_width = yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index];
+ const size_t v_width_bytes =
+ yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index];
+ const size_t v_width = yuva_size_info.fSizes[SkYUVAIndex::kV_Index].width();
const size_t v_height = yuva_size_info.fSizes[SkYUVAIndex::kV_Index].height();
const SkImageInfo y_decode_info =
info.makeColorType(kGray_8_SkColorType).makeWH(y_width, y_height);
const SkImageInfo u_decode_info = y_decode_info.makeWH(u_width, u_height);
const SkImageInfo v_decode_info = y_decode_info.makeWH(v_width, v_height);
yuva_size_info.computePlanes(memory_ptr, planes);
- pixmap_y->reset(y_decode_info, planes[SkYUVAIndex::kY_Index],
- y_decode_info.minRowBytes());
- pixmap_u->reset(u_decode_info, planes[SkYUVAIndex::kU_Index],
- u_decode_info.minRowBytes());
- pixmap_v->reset(v_decode_info, planes[SkYUVAIndex::kV_Index],
- v_decode_info.minRowBytes());
+ pixmap_y->reset(y_decode_info, planes[SkYUVAIndex::kY_Index], y_width_bytes);
+ pixmap_u->reset(u_decode_info, planes[SkYUVAIndex::kU_Index], u_width_bytes);
+ pixmap_v->reset(v_decode_info, planes[SkYUVAIndex::kV_Index], v_width_bytes);
}
// Helper method to fill in |scaled_u_size| and |scaled_v_size| by computing
@@ -280,8 +283,10 @@ bool DrawAndScaleImage(const DrawImage& draw_image,
draw_image.filter_quality() == kNone_SkFilterQuality;
SkImageInfo info = pixmap.info();
SkYUVASizeInfo yuva_size_info;
+ SkYUVAIndex plane_indices[SkYUVAIndex::kIndexCount];
if (do_yuv_decode) {
- const bool yuva_info_initialized = paint_image.IsYuv(&yuva_size_info);
+ const bool yuva_info_initialized =
+ paint_image.IsYuv(&yuva_size_info, plane_indices);
DCHECK(yuva_info_initialized);
}
SkISize supported_size =
@@ -298,7 +303,7 @@ bool DrawAndScaleImage(const DrawImage& draw_image,
SetYuvPixmapsFromSizeInfo(pixmap_y, pixmap_u, pixmap_v, yuva_size_info,
planes, info, pixmap.writable_addr());
return paint_image.DecodeYuv(planes, draw_image.frame_index(), client_id,
- yuva_size_info);
+ yuva_size_info, plane_indices);
}
return paint_image.Decode(pixmap.writable_addr(), &info, color_space,
draw_image.frame_index(), client_id);
@@ -346,11 +351,12 @@ bool DrawAndScaleImage(const DrawImage& draw_image,
yuva_size_info.computePlanes(decode_pixmap.writable_addr(), planes);
}
bool initial_decode_failed =
- do_yuv_decode ? !paint_image.DecodeYuv(planes, draw_image.frame_index(),
- client_id, yuva_size_info)
- : !paint_image.Decode(decode_pixmap.writable_addr(),
- &decode_info, color_space,
- draw_image.frame_index(), client_id);
+ do_yuv_decode
+ ? !paint_image.DecodeYuv(planes, draw_image.frame_index(), client_id,
+ yuva_size_info, plane_indices)
+ : !paint_image.Decode(decode_pixmap.writable_addr(), &decode_info,
+ color_space, draw_image.frame_index(),
+ client_id);
if (initial_decode_failed)
return false;
@@ -611,6 +617,11 @@ class ImageUploadTaskImpl : public TileTask {
void RunOnWorkerThread() override {
TRACE_EVENT2("cc", "ImageUploadTaskImpl::RunOnWorkerThread", "mode", "gpu",
"source_prepare_tiles_id", tracing_info_.prepare_tiles_id);
+ const auto* image_metadata = image_.paint_image().GetImageHeaderMetadata();
+ const ImageType image_type =
+ image_metadata ? image_metadata->image_type : ImageType::kInvalid;
+ devtools_instrumentation::ScopedImageUploadTask image_upload_task(
+ &image_.paint_image(), ImageDecodeCache::ToScopedImageType(image_type));
cache_->UploadImageInTask(image_);
}
@@ -675,8 +686,10 @@ int GpuImageDecodeCache::ImageDataBase::UsageState() const {
GpuImageDecodeCache::DecodedImageData::DecodedImageData(
bool is_bitmap_backed,
+ bool can_do_hardware_accelerated_decode,
bool do_hardware_accelerated_decode)
: is_bitmap_backed_(is_bitmap_backed),
+ can_do_hardware_accelerated_decode_(can_do_hardware_accelerated_decode),
do_hardware_accelerated_decode_(do_hardware_accelerated_decode) {}
GpuImageDecodeCache::DecodedImageData::~DecodedImageData() {
ResetData();
@@ -869,6 +882,7 @@ GpuImageDecodeCache::ImageData::ImageData(
int upload_scale_mip_level,
bool needs_mips,
bool is_bitmap_backed,
+ bool can_do_hardware_accelerated_decode,
bool do_hardware_accelerated_decode,
bool is_yuv_format,
SkYUVColorSpace yuv_cs)
@@ -881,7 +895,9 @@ GpuImageDecodeCache::ImageData::ImageData(
needs_mips(needs_mips),
is_bitmap_backed(is_bitmap_backed),
is_yuv(is_yuv_format),
- decode(is_bitmap_backed, do_hardware_accelerated_decode) {
+ decode(is_bitmap_backed,
+ can_do_hardware_accelerated_decode,
+ do_hardware_accelerated_decode) {
// Only fill out the base::Optional |yuv_color_space| if doing YUV decoding.
// Otherwise it was filled out with a default "identity" value by the decoder.
if (is_yuv) {
@@ -1022,8 +1038,10 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
TRACE_EVENT0(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"GpuImageDecodeCache::GetTaskForImageAndRef");
- if (SkipImage(draw_image))
- return TaskResult(false);
+ if (SkipImage(draw_image)) {
+ return TaskResult(false /* need_unref */, false /* is_at_raster_decode */,
+ false /* can_do_hardware_accelerated_decode */);
+ }
base::AutoLock lock(lock_);
const InUseCacheKey cache_key = InUseCacheKey::FromDrawImage(draw_image);
@@ -1041,26 +1059,31 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
image_data = new_data.get();
} else if (image_data->decode.decode_failure) {
// We have already tried and failed to decode this image, so just return.
- return TaskResult(false);
+ return TaskResult(false /* need_unref */, false /* is_at_raster_decode */,
+ image_data->decode.can_do_hardware_accelerated_decode());
} else if (task_type == DecodeTaskType::kPartOfUploadTask &&
image_data->upload.task) {
// We had an existing upload task, ref the image and return the task.
image_data->ValidateBudgeted();
RefImage(draw_image, cache_key);
- return TaskResult(image_data->upload.task);
+ return TaskResult(image_data->upload.task,
+ image_data->decode.can_do_hardware_accelerated_decode());
} else if (task_type == DecodeTaskType::kStandAloneDecodeTask &&
image_data->decode.stand_alone_task) {
// We had an existing out of raster task, ref the image and return the task.
image_data->ValidateBudgeted();
RefImage(draw_image, cache_key);
- return TaskResult(image_data->decode.stand_alone_task);
+ DCHECK(!image_data->decode.can_do_hardware_accelerated_decode());
+ return TaskResult(image_data->decode.stand_alone_task,
+ false /* can_do_hardware_accelerated_decode */);
}
// Ensure that the image we're about to decode/upload will fit in memory, if
// not already budgeted.
if (!image_data->is_budgeted && !EnsureCapacity(image_data->size)) {
// Image will not fit, do an at-raster decode.
- return TaskResult(false);
+ return TaskResult(false /* need_unref */, true /* is_at_raster_decode */,
+ image_data->decode.can_do_hardware_accelerated_decode());
}
// If we had to create new image data, add it to our map now that we know it
@@ -1077,7 +1100,8 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
DCHECK(image_data->is_budgeted);
if (image_data->HasUploadedData() &&
TryLockImage(HaveContextLock::kNo, draw_image, image_data)) {
- return TaskResult(true);
+ return TaskResult(true /* need_unref */, false /* is_at_raster_decode */,
+ image_data->decode.can_do_hardware_accelerated_decode());
}
scoped_refptr<TileTask> task;
@@ -1094,7 +1118,8 @@ ImageDecodeCache::TaskResult GpuImageDecodeCache::GetTaskForImageAndRefInternal(
task = GetImageDecodeTaskAndRef(draw_image, tracing_info, task_type);
}
- return TaskResult(task);
+ return TaskResult(task,
+ image_data->decode.can_do_hardware_accelerated_decode());
}
void GpuImageDecodeCache::UnrefImage(const DrawImage& draw_image) {
@@ -2015,8 +2040,7 @@ void GpuImageDecodeCache::UploadImageIfNecessary(const DrawImage& draw_image,
ClientImageTransferCacheEntry::GetNextId();
const gpu::SyncToken decode_sync_token =
context_->RasterInterface()->ScheduleImageDecode(
- base::make_span<const uint8_t>(encoded_data->bytes(),
- encoded_data->size()),
+ base::make_span(encoded_data->bytes(), encoded_data->size()),
output_size, transfer_cache_id,
color_space ? gfx::ColorSpace(*color_space) : gfx::ColorSpace(),
image_data->needs_mips);
@@ -2269,6 +2293,7 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
// gives us the result in the GPU process. Figure out what to do.
const ImageHeaderMetadata* image_metadata =
draw_image.paint_image().GetImageHeaderMetadata();
+ bool can_do_hardware_accelerated_decode = false;
bool do_hardware_accelerated_decode = false;
if (allow_hardware_decode && mode == DecodedDataMode::kTransferCache &&
upload_scale_mip_level == 0 &&
@@ -2281,6 +2306,7 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
DCHECK_EQ(image_metadata->image_size.height(),
draw_image.paint_image().height());
+ can_do_hardware_accelerated_decode = true;
const bool is_jpeg = (image_metadata->image_type == ImageType::kJPEG);
const bool is_webp = (image_metadata->image_type == ImageType::kWEBP);
do_hardware_accelerated_decode =
@@ -2301,7 +2327,6 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
mode != DecodedDataMode::kCpu && !image_larger_than_max_texture;
// TODO(crbug.com/910276): Change after alpha support.
if (is_yuv) {
- size_t y_size_bytes = image_info.width() * image_info.height();
const gfx::Size target_raster_size(image_info.width(), image_info.height());
gfx::Size unscaled_u_size(
target_yuva_size_info.fSizes[SkYUVAIndex::kU_Index].width(),
@@ -2314,17 +2339,25 @@ GpuImageDecodeCache::CreateImageData(const DrawImage& draw_image,
ComputeMippedUVPlaneSizes(target_raster_size, unscaled_u_size,
unscaled_v_size, draw_image, &scaled_u_size,
&scaled_v_size);
- size_t u_size_bytes = base::checked_cast<size_t>(scaled_u_size.GetArea());
- size_t v_size_bytes = base::checked_cast<size_t>(scaled_v_size.GetArea());
+
+ size_t y_size_bytes =
+ target_yuva_size_info.fWidthBytes[SkYUVAIndex::kY_Index] *
+ target_yuva_size_info.fSizes[SkYUVAIndex::kY_Index].height();
+ size_t u_size_bytes =
+ target_yuva_size_info.fWidthBytes[SkYUVAIndex::kU_Index] *
+ target_yuva_size_info.fSizes[SkYUVAIndex::kU_Index].height();
+ size_t v_size_bytes =
+ target_yuva_size_info.fWidthBytes[SkYUVAIndex::kV_Index] *
+ target_yuva_size_info.fSizes[SkYUVAIndex::kV_Index].height();
data_size = y_size_bytes + u_size_bytes + v_size_bytes;
}
- return base::WrapRefCounted(
- new ImageData(draw_image.paint_image().stable_id(), mode, data_size,
- draw_image.target_color_space(),
- CalculateDesiredFilterQuality(draw_image),
- upload_scale_mip_level, needs_mips, is_bitmap_backed,
- do_hardware_accelerated_decode, is_yuv, yuv_color_space));
+ return base::WrapRefCounted(new ImageData(
+ draw_image.paint_image().stable_id(), mode, data_size,
+ draw_image.target_color_space(),
+ CalculateDesiredFilterQuality(draw_image), upload_scale_mip_level,
+ needs_mips, is_bitmap_backed, can_do_hardware_accelerated_decode,
+ do_hardware_accelerated_decode, is_yuv, yuv_color_space));
}
void GpuImageDecodeCache::WillAddCacheEntry(const DrawImage& draw_image) {
diff --git a/chromium/cc/tiles/gpu_image_decode_cache.h b/chromium/cc/tiles/gpu_image_decode_cache.h
index fdfd11497a1..4ee3ae8054e 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache.h
+++ b/chromium/cc/tiles/gpu_image_decode_cache.h
@@ -249,6 +249,7 @@ class CC_EXPORT GpuImageDecodeCache
// Stores the CPU-side decoded bits of an image and supporting fields.
struct DecodedImageData : public ImageDataBase {
explicit DecodedImageData(bool is_bitmap_backed,
+ bool can_do_hardware_accelerated_decode,
bool do_hardware_accelerated_decode);
~DecodedImageData();
@@ -288,6 +289,10 @@ class CC_EXPORT GpuImageDecodeCache
bool is_yuv() const { return image_yuv_planes_.has_value(); }
+ bool can_do_hardware_accelerated_decode() const {
+ return can_do_hardware_accelerated_decode_;
+ }
+
bool do_hardware_accelerated_decode() const {
return do_hardware_accelerated_decode_;
}
@@ -319,6 +324,11 @@ class CC_EXPORT GpuImageDecodeCache
// decoder.
base::Optional<YUVSkImages> image_yuv_planes_;
+ // Keeps tracks of images that could go through hardware decode acceleration
+ // though they're possibly prevented from doing so because of a disabled
+ // feature flag.
+ bool can_do_hardware_accelerated_decode_;
+
// |do_hardware_accelerated_decode_| keeps track of images that should go
// through hardware decode acceleration. Currently, this path is intended
// only for Chrome OS and only for some JPEG images (see
@@ -493,6 +503,7 @@ class CC_EXPORT GpuImageDecodeCache
int upload_scale_mip_level,
bool needs_mips,
bool is_bitmap_backed,
+ bool can_do_hardware_accelerated_decode,
bool do_hardware_accelerated_decode,
bool is_yuv_format,
SkYUVColorSpace yuv_cs);
diff --git a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
index 329edf9d239..fd008a698af 100644
--- a/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
+++ b/chromium/cc/tiles/gpu_image_decode_cache_unittest.cc
@@ -184,7 +184,13 @@ class FakeGPUImageDecodeTestGLES2Interface : public viz::TestGLES2Interface,
bool CanDecodeWithHardwareAcceleration(
const ImageHeaderMetadata* image_metadata) const override {
- return advertise_accelerated_decoding_;
+ // Only advertise hardware accelerated decoding for the current use cases
+ // (JPEG and WebP).
+ if (image_metadata && (image_metadata->image_type == ImageType::kJPEG ||
+ image_metadata->image_type == ImageType::kWEBP)) {
+ return advertise_accelerated_decoding_;
+ }
+ return false;
}
std::pair<TransferCacheEntryType, uint32_t> MakeEntryKey(uint32_t type,
@@ -362,10 +368,11 @@ class GpuImageDecodeCacheTest
do_yuv_decode_ = std::get<2>(GetParam());
}
- std::unique_ptr<GpuImageDecodeCache> CreateCache() {
+ std::unique_ptr<GpuImageDecodeCache> CreateCache(
+ size_t memory_limit_bytes = kGpuMemoryLimitBytes) {
return std::make_unique<GpuImageDecodeCache>(
context_provider_.get(), use_transfer_cache_, color_type_,
- kGpuMemoryLimitBytes, max_texture_size_,
+ memory_limit_bytes, max_texture_size_,
PaintImage::kDefaultGeneratorClientId);
}
@@ -2998,6 +3005,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
ASSERT_TRUE(result.task);
+ EXPECT_TRUE(result.can_do_hardware_accelerated_decode);
// Accelerated decodes should not produce decode tasks.
ASSERT_TRUE(result.task->dependencies().empty());
@@ -3032,6 +3040,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
ASSERT_TRUE(result.task);
+ EXPECT_TRUE(result.can_do_hardware_accelerated_decode);
// Accelerated decodes should not produce decode tasks.
ASSERT_TRUE(result.task->dependencies().empty());
@@ -3069,6 +3078,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
ASSERT_TRUE(result.task);
+ EXPECT_TRUE(result.can_do_hardware_accelerated_decode);
// Accelerated decodes should not produce decode tasks.
ASSERT_TRUE(result.task->dependencies().empty());
@@ -3083,6 +3093,14 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
.Times(1);
TestTileTaskRunner::ProcessTask(result.task.get());
+ // Attempting to get another task for the image should result in no task
+ // because the decode is considered to have failed before.
+ ImageDecodeCache::TaskResult result_after_run =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_FALSE(result_after_run.need_unref);
+ EXPECT_FALSE(result_after_run.task);
+ EXPECT_TRUE(result_after_run.can_do_hardware_accelerated_decode);
+
// Must hold context lock before calling GetDecodedImageForDraw /
// DrawWithImageFinished.
viz::ContextProvider::ScopedContextLock context_lock(context_provider());
@@ -3107,6 +3125,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->GetOutOfRasterDecodeTaskForImageAndRef(draw_image);
EXPECT_TRUE(result.need_unref);
ASSERT_TRUE(result.task);
+ EXPECT_FALSE(result.can_do_hardware_accelerated_decode);
// A non-accelerated standalone decode should produce only a decode task.
ASSERT_TRUE(result.task->dependencies().empty());
@@ -3128,6 +3147,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
ASSERT_TRUE(result.task);
+ EXPECT_FALSE(result.can_do_hardware_accelerated_decode);
// A non-accelerated normal decode should produce a decode dependency.
ASSERT_EQ(result.task->dependencies().size(), 1u);
@@ -3151,6 +3171,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(result.need_unref);
ASSERT_TRUE(result.task);
+ EXPECT_TRUE(result.can_do_hardware_accelerated_decode);
// Accelerated decodes should not produce decode tasks.
ASSERT_TRUE(result.task->dependencies().empty());
@@ -3164,6 +3185,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(another_result.need_unref);
ASSERT_TRUE(another_result.task);
+ EXPECT_TRUE(another_result.can_do_hardware_accelerated_decode);
EXPECT_EQ(another_result.task->dependencies().size(), 0u);
ASSERT_TRUE(image.GetImageHeaderMetadata());
EXPECT_CALL(*raster_implementation(),
@@ -3183,6 +3205,37 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
cache->UnrefImage(draw_image);
}
+TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesTest,
+ RequestAcceleratedDecodeSuccessfullyAtRasterTime) {
+ // We force at-raster decodes by setting the cache memory limit to 0 bytes.
+ auto cache = CreateCache(0u /* memory_limit_bytes */);
+ const gfx::ColorSpace target_color_space = gfx::ColorSpace::CreateSRGB();
+ ASSERT_TRUE(target_color_space.IsValid());
+ const PaintImage image = CreatePaintImageForDecodeAcceleration();
+ const SkFilterQuality quality = kHigh_SkFilterQuality;
+ DrawImage draw_image(image, SkIRect::MakeWH(image.width(), image.height()),
+ quality, CreateMatrix(SkSize::Make(0.75f, 0.75f)),
+ PaintImage::kDefaultFrameIndex, target_color_space);
+ ImageDecodeCache::TaskResult result =
+ cache->GetTaskForImageAndRef(draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_FALSE(result.need_unref);
+ EXPECT_FALSE(result.task);
+ EXPECT_TRUE(result.is_at_raster_decode);
+ EXPECT_TRUE(result.can_do_hardware_accelerated_decode);
+
+ // Must hold context lock before calling GetDecodedImageForDraw /
+ // DrawWithImageFinished.
+ EXPECT_CALL(*raster_implementation(),
+ DoScheduleImageDecode(image.GetImageHeaderMetadata()->image_size,
+ _, gfx::ColorSpace(), _))
+ .Times(1);
+ viz::ContextProvider::ScopedContextLock context_lock(context_provider());
+ const DecodedDrawImage decoded_draw_image =
+ cache->GetDecodedImageForDraw(draw_image);
+ EXPECT_TRUE(decoded_draw_image.transfer_cache_entry_id().has_value());
+ cache->DrawWithImageFinished(draw_image, decoded_draw_image);
+}
+
INSTANTIATE_TEST_SUITE_P(
GpuImageDecodeCacheTestsOOPR,
GpuImageDecodeCacheWithAcceleratedDecodesTest,
@@ -3222,6 +3275,8 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
// task without a decode dependency since the decode will be done in the GPU
// process. In the alternative path (software decoding), the upload task
// depends on a decode task that runs in the renderer.
+ EXPECT_EQ(advertise_accelerated_decoding_,
+ jpeg_task.can_do_hardware_accelerated_decode);
if (advertise_accelerated_decoding_ && allow_accelerated_jpeg_decoding_) {
ASSERT_TRUE(jpeg_task.task->dependencies().empty());
ASSERT_TRUE(jpeg_image.GetImageHeaderMetadata());
@@ -3235,8 +3290,31 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
ASSERT_TRUE(jpeg_task.task->dependencies()[0]);
TestTileTaskRunner::ProcessTask(jpeg_task.task->dependencies()[0].get());
}
- TestTileTaskRunner::ProcessTask(jpeg_task.task.get());
+ TestTileTaskRunner::ScheduleTask(jpeg_task.task.get());
+
+ // After scheduling the task, trying to get another task for the image should
+ // result in the original task.
+ ImageDecodeCache::TaskResult jpeg_task_again = cache->GetTaskForImageAndRef(
+ jpeg_draw_image, ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(jpeg_task_again.need_unref);
+ EXPECT_EQ(jpeg_task_again.task.get(), jpeg_task.task.get());
+ EXPECT_EQ(advertise_accelerated_decoding_,
+ jpeg_task_again.can_do_hardware_accelerated_decode);
+
+ TestTileTaskRunner::RunTask(jpeg_task.task.get());
+ TestTileTaskRunner::CompleteTask(jpeg_task.task.get());
testing::Mock::VerifyAndClearExpectations(raster_implementation());
+
+ // After running the tasks, trying to get another task for the image should
+ // result in no task.
+ jpeg_task = cache->GetTaskForImageAndRef(jpeg_draw_image,
+ ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(jpeg_task.need_unref);
+ EXPECT_FALSE(jpeg_task.task);
+ EXPECT_EQ(advertise_accelerated_decoding_,
+ jpeg_task.can_do_hardware_accelerated_decode);
+ cache->UnrefImage(jpeg_draw_image);
+ cache->UnrefImage(jpeg_draw_image);
cache->UnrefImage(jpeg_draw_image);
// Try a WebP image.
@@ -3250,6 +3328,8 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
webp_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(webp_task.need_unref);
ASSERT_TRUE(webp_task.task);
+ EXPECT_EQ(advertise_accelerated_decoding_,
+ webp_task.can_do_hardware_accelerated_decode);
if (advertise_accelerated_decoding_ && allow_accelerated_webp_decoding_) {
ASSERT_TRUE(webp_task.task->dependencies().empty());
ASSERT_TRUE(webp_image.GetImageHeaderMetadata());
@@ -3265,6 +3345,15 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
}
TestTileTaskRunner::ProcessTask(webp_task.task.get());
testing::Mock::VerifyAndClearExpectations(raster_implementation());
+
+ // The image should have been cached.
+ webp_task = cache->GetTaskForImageAndRef(webp_draw_image,
+ ImageDecodeCache::TracingInfo());
+ EXPECT_TRUE(webp_task.need_unref);
+ EXPECT_FALSE(webp_task.task);
+ EXPECT_EQ(advertise_accelerated_decoding_,
+ webp_task.can_do_hardware_accelerated_decode);
+ cache->UnrefImage(webp_draw_image);
cache->UnrefImage(webp_draw_image);
// Try a PNG image (which should not be hardware accelerated).
@@ -3278,6 +3367,7 @@ TEST_P(GpuImageDecodeCacheWithAcceleratedDecodesFlagsTest,
png_draw_image, ImageDecodeCache::TracingInfo());
EXPECT_TRUE(png_task.need_unref);
ASSERT_TRUE(png_task.task);
+ EXPECT_FALSE(png_task.can_do_hardware_accelerated_decode);
ASSERT_EQ(png_task.task->dependencies().size(), 1u);
ASSERT_TRUE(png_task.task->dependencies()[0]);
TestTileTaskRunner::ProcessTask(png_task.task->dependencies()[0].get());
diff --git a/chromium/cc/tiles/image_controller.cc b/chromium/cc/tiles/image_controller.cc
index 9f600462eb8..0fe837a669a 100644
--- a/chromium/cc/tiles/image_controller.cc
+++ b/chromium/cc/tiles/image_controller.cc
@@ -150,9 +150,13 @@ void ImageController::ConvertImagesToTasks(
std::vector<DrawImage>* sync_decoded_images,
std::vector<scoped_refptr<TileTask>>* tasks,
bool* has_at_raster_images,
+ bool* has_hardware_accelerated_jpeg_candidates,
+ bool* has_hardware_accelerated_webp_candidates,
const ImageDecodeCache::TracingInfo& tracing_info) {
DCHECK(cache_);
*has_at_raster_images = false;
+ *has_hardware_accelerated_jpeg_candidates = false;
+ *has_hardware_accelerated_webp_candidates = false;
for (auto it = sync_decoded_images->begin();
it != sync_decoded_images->end();) {
// PaintWorklet images should not be included in this set; they have already
@@ -161,7 +165,19 @@ void ImageController::ConvertImagesToTasks(
ImageDecodeCache::TaskResult result =
cache_->GetTaskForImageAndRef(*it, tracing_info);
- *has_at_raster_images |= result.IsAtRaster();
+ *has_at_raster_images |= result.is_at_raster_decode;
+
+ ImageType image_type =
+ it->paint_image().GetImageHeaderMetadata()
+ ? it->paint_image().GetImageHeaderMetadata()->image_type
+ : ImageType::kInvalid;
+ *has_hardware_accelerated_jpeg_candidates |=
+ (result.can_do_hardware_accelerated_decode &&
+ image_type == ImageType::kJPEG);
+ *has_hardware_accelerated_webp_candidates |=
+ (result.can_do_hardware_accelerated_decode &&
+ image_type == ImageType::kWEBP);
+
if (result.task)
tasks->push_back(std::move(result.task));
if (result.need_unref)
@@ -185,9 +201,16 @@ std::vector<scoped_refptr<TileTask>> ImageController::SetPredecodeImages(
std::vector<DrawImage> images,
const ImageDecodeCache::TracingInfo& tracing_info) {
std::vector<scoped_refptr<TileTask>> new_tasks;
+ // The images here are in a pre-decode area: we decode them in advance, but
+ // they're not dependencies for raster tasks. If these images do end up
+ // getting rasterized, we will still have a chance to record the raster
+ // scheduling delay UMAs when we create and run the raster task.
bool has_at_raster_images = false;
+ bool has_hardware_accelerated_jpeg_candidates = false;
+ bool has_hardware_accelerated_webp_candidates = false;
ConvertImagesToTasks(&images, &new_tasks, &has_at_raster_images,
- tracing_info);
+ &has_hardware_accelerated_jpeg_candidates,
+ &has_hardware_accelerated_webp_candidates, tracing_info);
UnrefImages(predecode_locked_images_);
predecode_locked_images_ = std::move(images);
return new_tasks;
@@ -206,7 +229,10 @@ ImageController::ImageDecodeRequestId ImageController::QueueImageDecode(
bool is_image_lazy = draw_image.paint_image().IsLazyGenerated();
// Get the tasks for this decode.
- ImageDecodeCache::TaskResult result(false);
+ ImageDecodeCache::TaskResult result(
+ /*need_unref=*/false,
+ /*is_at_raster_decode=*/false,
+ /*can_do_hardware_accelerated_decode=*/false);
if (is_image_lazy)
result = cache_->GetOutOfRasterDecodeTaskForImageAndRef(draw_image);
// If we don't need to unref this, we don't actually have a task.
diff --git a/chromium/cc/tiles/image_controller.h b/chromium/cc/tiles/image_controller.h
index 1ec832d13c1..560226c00fd 100644
--- a/chromium/cc/tiles/image_controller.h
+++ b/chromium/cc/tiles/image_controller.h
@@ -44,10 +44,16 @@ class CC_EXPORT ImageController {
// vector under certain conditions.
// |tasks| is an output, which are the built tile tasks.
// |has_at_raster_images| is an output parameter.
+ // |has_hardware_accelerated_jpeg_candidates| and
+ // |has_hardware_accelerated_webp_candidates| are output parameters that
+ // indicate if there are images in |sync_decoded_images| that could be decoded
+ // using hardware decode acceleration.
// |tracing_info| is used in tracing or UMA only.
void ConvertImagesToTasks(std::vector<DrawImage>* sync_decoded_images,
std::vector<scoped_refptr<TileTask>>* tasks,
bool* has_at_raster_images,
+ bool* has_hardware_accelerated_jpeg_candidates,
+ bool* has_hardware_accelerated_webp_candidates,
const ImageDecodeCache::TracingInfo& tracing_info);
void UnrefImages(const std::vector<DrawImage>& images);
void ReduceMemoryUsage();
diff --git a/chromium/cc/tiles/image_controller_unittest.cc b/chromium/cc/tiles/image_controller_unittest.cc
index 17b20018fb2..fbe924af6fd 100644
--- a/chromium/cc/tiles/image_controller_unittest.cc
+++ b/chromium/cc/tiles/image_controller_unittest.cc
@@ -107,11 +107,16 @@ class TestableCache : public StubDecodeCache {
if (image.paint_image() &&
image.paint_image().width() * image.paint_image().height() >=
1000 * 1000) {
- return TaskResult(false);
+ return TaskResult(/*need_unref=*/false, /*is_at_raster_decode=*/true,
+ /*can_do_hardware_accelerated_decode=*/false);
}
++number_of_refs_;
- return TaskResult(task_to_use_);
+ if (task_to_use_)
+ return TaskResult(task_to_use_,
+ /*can_do_hardware_accelerated_decode=*/false);
+ return TaskResult(/*need_unref=*/true, /*is_at_raster_decode=*/false,
+ /*can_do_hardware_accelerated_decode=*/false);
}
TaskResult GetOutOfRasterDecodeTaskForImageAndRef(
const DrawImage& image) override {
diff --git a/chromium/cc/tiles/image_decode_cache.cc b/chromium/cc/tiles/image_decode_cache.cc
index 9c68e3cc26c..0b085cc2335 100644
--- a/chromium/cc/tiles/image_decode_cache.cc
+++ b/chromium/cc/tiles/image_decode_cache.cc
@@ -8,11 +8,23 @@
namespace cc {
-ImageDecodeCache::TaskResult::TaskResult(bool need_unref)
- : need_unref(need_unref) {}
-
-ImageDecodeCache::TaskResult::TaskResult(scoped_refptr<TileTask> task)
- : task(std::move(task)), need_unref(true) {}
+ImageDecodeCache::TaskResult::TaskResult(
+ bool need_unref,
+ bool is_at_raster_decode,
+ bool can_do_hardware_accelerated_decode)
+ : need_unref(need_unref),
+ is_at_raster_decode(is_at_raster_decode),
+ can_do_hardware_accelerated_decode(can_do_hardware_accelerated_decode) {}
+
+ImageDecodeCache::TaskResult::TaskResult(
+ scoped_refptr<TileTask> task,
+ bool can_do_hardware_accelerated_decode)
+ : task(std::move(task)),
+ need_unref(true),
+ is_at_raster_decode(false),
+ can_do_hardware_accelerated_decode(can_do_hardware_accelerated_decode) {
+ DCHECK(this->task);
+}
ImageDecodeCache::TaskResult::TaskResult(const TaskResult& result) = default;
diff --git a/chromium/cc/tiles/image_decode_cache.h b/chromium/cc/tiles/image_decode_cache.h
index f2451ca7e5a..6366a6276f6 100644
--- a/chromium/cc/tiles/image_decode_cache.h
+++ b/chromium/cc/tiles/image_decode_cache.h
@@ -87,15 +87,18 @@ class CC_EXPORT ImageDecodeCache {
virtual ~ImageDecodeCache() {}
struct CC_EXPORT TaskResult {
- explicit TaskResult(bool need_unref);
- explicit TaskResult(scoped_refptr<TileTask> task);
+ explicit TaskResult(bool need_unref,
+ bool is_at_raster_decode,
+ bool can_do_hardware_accelerated_decode);
+ explicit TaskResult(scoped_refptr<TileTask> task,
+ bool can_do_hardware_accelerated_decode);
TaskResult(const TaskResult& result);
~TaskResult();
- bool IsAtRaster() const { return !task && !need_unref; }
-
scoped_refptr<TileTask> task;
bool need_unref = false;
+ bool is_at_raster_decode = false;
+ bool can_do_hardware_accelerated_decode = false;
};
// Fill in an TileTask which will decode the given image when run. In
// case the image is already cached, fills in nullptr. Returns true if the
diff --git a/chromium/cc/tiles/software_image_decode_cache.cc b/chromium/cc/tiles/software_image_decode_cache.cc
index cbe8511f196..a0077ff4e3d 100644
--- a/chromium/cc/tiles/software_image_decode_cache.cc
+++ b/chromium/cc/tiles/software_image_decode_cache.cc
@@ -6,6 +6,10 @@
#include <stdint.h>
+#include <algorithm>
+#include <string>
+#include <utility>
+
#include "base/bind.h"
#include "base/format_macros.h"
#include "base/metrics/histogram_macros.h"
@@ -205,10 +209,12 @@ SoftwareImageDecodeCache::GetTaskForImageAndRefInternal(
// If the target size is empty, we can skip this image during draw (and thus
// we don't need to decode it or ref it).
if (key.target_size().IsEmpty())
- return TaskResult(false);
+ return TaskResult(/*need_unref=*/false, /*is_at_raster_decode=*/false,
+ /*can_do_hardware_accelerated_decode=*/false);
if (!UseCacheForDrawImage(image))
- return TaskResult(false);
+ return TaskResult(/*need_unref=*/false, /*is_at_raster_decode=*/false,
+ /*can_do_hardware_accelerated_decode=*/false);
base::AutoLock lock(lock_);
@@ -221,7 +227,8 @@ SoftwareImageDecodeCache::GetTaskForImageAndRefInternal(
if (decoded_it == decoded_images_.end()) {
// There is no reason to create a new entry if we know it won't fit anyway.
if (!new_image_fits_in_memory)
- return TaskResult(false);
+ return TaskResult(/*need_unref=*/false, /*is_at_raster_decode=*/true,
+ /*can_do_hardware_accelerated_decode=*/false);
cache_entry = AddCacheEntry(key);
if (task_type == DecodeTaskType::USE_OUT_OF_RASTER_TASKS)
cache_entry->mark_out_of_raster();
@@ -234,7 +241,8 @@ SoftwareImageDecodeCache::GetTaskForImageAndRefInternal(
if (!new_image_fits_in_memory) {
// We don't need to ref anything here because this image will be at
// raster.
- return TaskResult(false);
+ return TaskResult(/*need_unref=*/false, /*is_at_raster_decode=*/true,
+ /*can_do_hardware_accelerated_decode=*/false);
}
AddBudgetForImage(key, cache_entry);
}
@@ -247,7 +255,8 @@ SoftwareImageDecodeCache::GetTaskForImageAndRefInternal(
// If we already have a locked entry, then we can just use that. Otherwise
// we'll have to create a task.
if (cache_entry->is_locked)
- return TaskResult(true);
+ return TaskResult(/*need_unref=*/true, /*is_at_raster_decode=*/false,
+ /*can_do_hardware_accelerated_decode=*/false);
scoped_refptr<TileTask>& task =
task_type == DecodeTaskType::USE_IN_RASTER_TASKS
@@ -259,7 +268,7 @@ SoftwareImageDecodeCache::GetTaskForImageAndRefInternal(
task = base::MakeRefCounted<SoftwareImageDecodeTaskImpl>(
this, key, image.paint_image(), task_type, tracing_info);
}
- return TaskResult(task);
+ return TaskResult(task, /*can_do_hardware_accelerated_decode=*/false);
}
void SoftwareImageDecodeCache::AddBudgetForImage(const CacheKey& key,
@@ -267,7 +276,6 @@ void SoftwareImageDecodeCache::AddBudgetForImage(const CacheKey& key,
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"SoftwareImageDecodeCache::AddBudgetForImage", "key",
key.ToString());
- lock_.AssertAcquired();
DCHECK(!entry->is_budgeted);
DCHECK_GE(locked_images_budget_.AvailableMemoryBytes(), key.locked_bytes());
@@ -280,7 +288,6 @@ void SoftwareImageDecodeCache::RemoveBudgetForImage(const CacheKey& key,
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"SoftwareImageDecodeCache::RemoveBudgetForImage", "key",
key.ToString());
- lock_.AssertAcquired();
DCHECK(entry->is_budgeted);
locked_images_budget_.SubtractUsage(key.locked_bytes());
@@ -297,7 +304,6 @@ void SoftwareImageDecodeCache::UnrefImage(const DrawImage& image) {
}
void SoftwareImageDecodeCache::UnrefImage(const CacheKey& key) {
- lock_.AssertAcquired();
auto decoded_image_it = decoded_images_.Peek(key);
DCHECK(decoded_image_it != decoded_images_.end());
auto* entry = decoded_image_it->second.get();
@@ -340,7 +346,6 @@ SoftwareImageDecodeCache::DecodeImageIfNecessary(const CacheKey& key,
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"SoftwareImageDecodeCache::DecodeImageIfNecessary", "key",
key.ToString());
- lock_.AssertAcquired();
DCHECK_GT(entry->ref_count, 0);
if (key.target_size().IsEmpty())
@@ -550,7 +555,6 @@ DecodedDrawImage SoftwareImageDecodeCache::GetDecodedImageForDrawInternal(
"SoftwareImageDecodeCache::GetDecodedImageForDrawInternal",
"key", key.ToString());
- lock_.AssertAcquired();
auto decoded_it = decoded_images_.Get(key);
CacheEntry* cache_entry = nullptr;
if (decoded_it == decoded_images_.end())
@@ -695,13 +699,17 @@ void SoftwareImageDecodeCache::OnMemoryPressure(
SoftwareImageDecodeCache::CacheEntry* SoftwareImageDecodeCache::AddCacheEntry(
const CacheKey& key) {
- lock_.AssertAcquired();
frame_key_to_image_keys_[key.frame_key()].push_back(key);
auto it = decoded_images_.Put(key, std::make_unique<CacheEntry>());
it->second.get()->mark_cached();
return it->second.get();
}
+size_t SoftwareImageDecodeCache::GetNumCacheEntriesForTesting() {
+ base::AutoLock lock(lock_);
+ return decoded_images_.size();
+}
+
// MemoryBudget ----------------------------------------------------------------
SoftwareImageDecodeCache::MemoryBudget::MemoryBudget(size_t limit_bytes)
: limit_bytes_(limit_bytes), current_usage_bytes_(0u) {}
diff --git a/chromium/cc/tiles/software_image_decode_cache.h b/chromium/cc/tiles/software_image_decode_cache.h
index 994194b9fcb..274528d95db 100644
--- a/chromium/cc/tiles/software_image_decode_cache.h
+++ b/chromium/cc/tiles/software_image_decode_cache.h
@@ -9,11 +9,13 @@
#include <memory>
#include <unordered_map>
+#include <vector>
#include "base/containers/mru_cache.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/memory/ref_counted.h"
#include "base/numerics/safe_math.h"
+#include "base/thread_annotations.h"
#include "base/trace_event/memory_dump_provider.h"
#include "cc/cc_export.h"
#include "cc/paint/draw_image.h"
@@ -72,7 +74,7 @@ class CC_EXPORT SoftwareImageDecodeCache
bool OnMemoryDump(const base::trace_event::MemoryDumpArgs& args,
base::trace_event::ProcessMemoryDump* pmd) override;
- size_t GetNumCacheEntriesForTesting() const { return decoded_images_.size(); }
+ size_t GetNumCacheEntriesForTesting();
private:
using CacheEntry = Utils::CacheEntry;
@@ -98,69 +100,67 @@ class CC_EXPORT SoftwareImageDecodeCache
using ImageMRUCache = base::
HashingMRUCache<CacheKey, std::unique_ptr<CacheEntry>, CacheKeyHash>;
- // Actually decode the image. Note that this function can (and should) be
- // called with no lock acquired, since it can do a lot of work. Note that it
- // can also return nullptr to indicate the decode failed.
- std::unique_ptr<CacheEntry> DecodeImageInternal(const CacheKey& key,
- const DrawImage& draw_image);
-
// Get the decoded draw image for the given key and paint_image. Note that
- // this function has to be called with no lock acquired, since it will acquire
- // its own locks and might call DecodeImageInternal above. Note that
// when used internally, we still require that DrawWithImageFinished() is
// called afterwards.
- DecodedDrawImage GetDecodedImageForDrawInternal(
- const CacheKey& key,
- const PaintImage& paint_image);
+ DecodedDrawImage GetDecodedImageForDrawInternal(const CacheKey& key,
+ const PaintImage& paint_image)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
// Removes unlocked decoded images until the number of decoded images is
// reduced within the given limit.
- void ReduceCacheUsageUntilWithinLimit(size_t limit);
+ void ReduceCacheUsageUntilWithinLimit(size_t limit)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
- void OnMemoryPressure(
- base::MemoryPressureListener::MemoryPressureLevel level);
+ void OnMemoryPressure(base::MemoryPressureListener::MemoryPressureLevel level)
+ LOCKS_EXCLUDED(lock_);
// Helper method to get the different tasks. Note that this should be used as
// if it was public (ie, all of the locks need to be properly acquired).
TaskResult GetTaskForImageAndRefInternal(const DrawImage& image,
const TracingInfo& tracing_info,
- DecodeTaskType type);
+ DecodeTaskType type)
+ LOCKS_EXCLUDED(lock_);
- CacheEntry* AddCacheEntry(const CacheKey& key);
+ CacheEntry* AddCacheEntry(const CacheKey& key)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
TaskProcessingResult DecodeImageIfNecessary(const CacheKey& key,
const PaintImage& paint_image,
- CacheEntry* cache_entry);
- void AddBudgetForImage(const CacheKey& key, CacheEntry* entry);
- void RemoveBudgetForImage(const CacheKey& key, CacheEntry* entry);
- base::Optional<CacheKey> FindCachedCandidate(const CacheKey& key);
+ CacheEntry* cache_entry)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ void AddBudgetForImage(const CacheKey& key, CacheEntry* entry)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ void RemoveBudgetForImage(const CacheKey& key, CacheEntry* entry)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
+ base::Optional<CacheKey> FindCachedCandidate(const CacheKey& key)
+ EXCLUSIVE_LOCKS_REQUIRED(lock_);
- void UnrefImage(const CacheKey& key);
+ void UnrefImage(const CacheKey& key) EXCLUSIVE_LOCKS_REQUIRED(lock_);
- // The members below this comment can only be accessed if the lock is held to
- // ensure that they are safe to access on multiple threads.
- // The exception is accessing |locked_images_budget_.total_limit_bytes()|,
- // which is const and thread safe.
base::Lock lock_;
-
// Decoded images and ref counts (predecode path).
- ImageMRUCache decoded_images_;
+ ImageMRUCache decoded_images_ GUARDED_BY(lock_);
- std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
+ std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_
+ GUARDED_BY(lock_);
// A map of PaintImage::FrameKey to the ImageKeys for cached decodes of this
// PaintImage.
std::unordered_map<PaintImage::FrameKey,
std::vector<CacheKey>,
PaintImage::FrameKeyHash>
- frame_key_to_image_keys_;
+ frame_key_to_image_keys_ GUARDED_BY(lock_);
+ // Should be GUARDED_BY(lock_), except that accessing
+ // |locked_images_budget_.total_limit_bytes()| is fine without the lock, as
+ // it is const and thread safe.
MemoryBudget locked_images_budget_;
const SkColorType color_type_;
const PaintImage::GeneratorClientId generator_client_id_;
- size_t max_items_in_cache_;
+ const size_t max_items_in_cache_;
};
} // namespace cc
diff --git a/chromium/cc/tiles/tile_manager.cc b/chromium/cc/tiles/tile_manager.cc
index 5ec8b2642fe..3fd32784f08 100644
--- a/chromium/cc/tiles/tile_manager.cc
+++ b/chromium/cc/tiles/tile_manager.cc
@@ -845,12 +845,6 @@ TileManager::PrioritizedWorkToSchedule TileManager::AssignGpuMemoryToTiles() {
}
}
- if (had_enough_memory_to_schedule_tiles_needed_now) {
- int64_t tiles_gpu_memory_kb = memory_usage.memory_bytes() / 1024;
- UMA_HISTOGRAM_MEMORY_KB("TileManager.TilesGPUMemoryUsage2",
- tiles_gpu_memory_kb);
- }
-
UMA_HISTOGRAM_BOOLEAN("TileManager.ExceededMemoryBudget",
!had_enough_memory_to_schedule_tiles_needed_now);
did_oom_on_last_assign_ = !had_enough_memory_to_schedule_tiles_needed_now;
@@ -1135,11 +1129,14 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
"TileManager::CreateRasterTask", "Tile", tile->id());
+ const int msaa_sample_count = client_->GetMSAASampleCountForRaster(
+ prioritized_tile.raster_source()->GetDisplayItemList());
+
// Get the resource.
ResourcePool::InUsePoolResource resource;
uint64_t resource_content_id = 0;
gfx::Rect invalidated_rect = tile->invalidated_content_rect();
- if (UsePartialRaster() && tile->invalidated_id()) {
+ if (UsePartialRaster(msaa_sample_count) && tile->invalidated_id()) {
resource = resource_pool_->TryAcquireResourceForPartialRaster(
tile->id(), tile->invalidated_content_rect(), tile->invalidated_id(),
&invalidated_rect);
@@ -1162,6 +1159,7 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
const bool skip_images =
prioritized_tile.priority().resolution == LOW_RESOLUTION;
playback_settings.use_lcd_text = tile->can_use_lcd_text();
+ playback_settings.msaa_sample_count = msaa_sample_count;
// Create and queue all image decode tasks that this tile depends on. Note
// that we need to store the images for decode tasks in
@@ -1185,8 +1183,12 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
prepare_tiles_count_, prioritized_tile.priority().priority_bin,
ImageDecodeCache::TaskType::kInRaster);
bool has_at_raster_images = false;
- image_controller_.ConvertImagesToTasks(&sync_decoded_images, &decode_tasks,
- &has_at_raster_images, tracing_info);
+ bool has_hardware_accelerated_jpeg_candidates = false;
+ bool has_hardware_accelerated_webp_candidates = false;
+ image_controller_.ConvertImagesToTasks(
+ &sync_decoded_images, &decode_tasks, &has_at_raster_images,
+ &has_hardware_accelerated_jpeg_candidates,
+ &has_hardware_accelerated_webp_candidates, tracing_info);
// Notify |decoded_image_tracker_| after |image_controller_| to ensure we've
// taken new refs on the images before releasing the predecode API refs.
decoded_image_tracker_.OnImagesUsedInDraw(sync_decoded_images);
@@ -1227,7 +1229,9 @@ scoped_refptr<TileTask> TileManager::CreateRasterTask(
std::unique_ptr<RasterBuffer> raster_buffer =
raster_buffer_provider_->AcquireBufferForRaster(
- resource, resource_content_id, tile->invalidated_id());
+ resource, resource_content_id, tile->invalidated_id(),
+ has_at_raster_images, has_hardware_accelerated_jpeg_candidates,
+ has_hardware_accelerated_webp_candidates);
base::Optional<PlaybackImageProvider::Settings> settings;
if (!skip_images) {
@@ -1611,9 +1615,13 @@ TileManager::ScheduledTasksStateAsValue() const {
return std::move(state);
}
-bool TileManager::UsePartialRaster() const {
+bool TileManager::UsePartialRaster(int msaa_sample_count) const {
+ // Partial raster doesn't support MSAA, as the MSAA resolve is unaware of clip
+ // rects.
+ // TODO(crbug.com/629683): See if we can work around this limitation.
return tile_manager_settings_.use_partial_raster &&
- raster_buffer_provider_->CanPartialRasterIntoProvidedResource();
+ raster_buffer_provider_->CanPartialRasterIntoProvidedResource() &&
+ msaa_sample_count == 0;
}
void TileManager::CheckPendingGpuWorkAndIssueSignals() {
diff --git a/chromium/cc/tiles/tile_manager.h b/chromium/cc/tiles/tile_manager.h
index afa7d42ef37..c41a1355440 100644
--- a/chromium/cc/tiles/tile_manager.h
+++ b/chromium/cc/tiles/tile_manager.h
@@ -87,9 +87,14 @@ class CC_EXPORT TileManagerClient {
// rasterized with missing images need to be invalidated.
virtual void RequestImplSideInvalidationForCheckerImagedTiles() = 0;
+ // Returns the frame index to display for the given image on the given tree.
virtual size_t GetFrameIndexForImage(const PaintImage& paint_image,
WhichTree tree) const = 0;
+ // Returns the sample count to use if MSAA is enabled for a tile.
+ virtual int GetMSAASampleCountForRaster(
+ const scoped_refptr<DisplayItemList>& display_list) = 0;
+
protected:
virtual ~TileManagerClient() {}
};
@@ -202,7 +207,11 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
tiles[i]->desired_texture_size(),
raster_buffer_provider_->GetResourceFormat(),
client_->GetRasterColorSpace());
- raster_buffer_provider_->AcquireBufferForRaster(resource, 0, 0);
+ raster_buffer_provider_->AcquireBufferForRaster(
+ resource, 0, 0,
+ /*depends_on_at_raster_decodes=*/false,
+ /*depends_on_hardware_accelerated_jpeg_candidates=*/false,
+ /*depends_on_hardware_accelerated_webp_candidates=*/false);
// The raster here never really happened, cuz tests. So just add an
// arbitrary sync token.
if (resource.gpu_backing()) {
@@ -399,7 +408,7 @@ class CC_EXPORT TileManager : CheckerImageTrackerClient {
std::unique_ptr<base::trace_event::ConvertableToTraceFormat>
ScheduledTasksStateAsValue() const;
- bool UsePartialRaster() const;
+ bool UsePartialRaster(int msaa_sample_count) const;
void FlushAndIssueSignals();
void CheckPendingGpuWorkAndIssueSignals();
diff --git a/chromium/cc/tiles/tile_manager_unittest.cc b/chromium/cc/tiles/tile_manager_unittest.cc
index 56410fea4fc..dc0be3ff8fc 100644
--- a/chromium/cc/tiles/tile_manager_unittest.cc
+++ b/chromium/cc/tiles/tile_manager_unittest.cc
@@ -1531,7 +1531,10 @@ class TestSoftwareRasterBufferProvider : public FakeRasterBufferProviderImpl {
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override {
if (!resource.software_backing()) {
auto backing = std::make_unique<TestSoftwareBacking>();
backing->shared_bitmap_id = viz::SharedBitmap::GenerateId();
@@ -1969,7 +1972,10 @@ class VerifyResourceContentIdRasterBufferProvider
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override {
EXPECT_EQ(expected_content_id_, resource_content_id);
return nullptr;
}
@@ -2167,7 +2173,10 @@ class InvalidResourceRasterBufferProvider
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override {
if (!resource.gpu_backing()) {
auto backing = std::make_unique<StubGpuBacking>();
// Don't set a mailbox to signal invalid resource.
@@ -2263,7 +2272,10 @@ class MockReadyToDrawRasterBufferProviderImpl
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override {
if (!resource.software_backing())
resource.set_software_backing(std::make_unique<TestSoftwareBacking>());
return std::make_unique<FakeRasterBuffer>();
@@ -3251,7 +3263,10 @@ class VerifyImageProviderRasterBufferProvider
std::unique_ptr<RasterBuffer> AcquireBufferForRaster(
const ResourcePool::InUsePoolResource& resource,
uint64_t resource_content_id,
- uint64_t previous_content_id) override {
+ uint64_t previous_content_id,
+ bool depends_on_at_raster_decodes,
+ bool depends_on_hardware_accelerated_jpeg_candidates,
+ bool depends_on_hardware_accelerated_webp_candidates) override {
buffer_count_++;
return std::make_unique<VerifyImageProviderRasterBuffer>();
}
diff --git a/chromium/cc/tiles/tile_priority.cc b/chromium/cc/tiles/tile_priority.cc
index 7898163053e..606a8c64e0b 100644
--- a/chromium/cc/tiles/tile_priority.cc
+++ b/chromium/cc/tiles/tile_priority.cc
@@ -86,6 +86,21 @@ std::string TreePriorityToString(TreePriority prio) {
}
}
+perfetto::protos::pbzero::ChromeCompositorStateMachine::MinorState::TreePriority
+TreePriorityToProtozeroEnum(TreePriority priority) {
+ using pbzeroMinorState =
+ perfetto::protos::pbzero::ChromeCompositorStateMachine::MinorState;
+ switch (priority) {
+ case TreePriority::SAME_PRIORITY_FOR_BOTH_TREES:
+ return pbzeroMinorState::TREE_PRIORITY_SAME_PRIORITY_FOR_BOTH_TREES;
+ case TreePriority::SMOOTHNESS_TAKES_PRIORITY:
+ return pbzeroMinorState::TREE_PRIORITY_SMOOTHNESS_TAKES_PRIORITY;
+ case TreePriority::NEW_CONTENT_TAKES_PRIORITY:
+ return pbzeroMinorState::TREE_PRIORITY_NEW_CONTENT_TAKES_PRIORITY;
+ }
+ return pbzeroMinorState::TREE_PRIORITY_UNSPECIFIED;
+}
+
void GlobalStateThatImpactsTilePriority::AsValueInto(
base::trace_event::TracedValue* state) const {
state->SetString("memory_limit_policy",
diff --git a/chromium/cc/tiles/tile_priority.h b/chromium/cc/tiles/tile_priority.h
index 6b0628aac30..34cd3bc0c5d 100644
--- a/chromium/cc/tiles/tile_priority.h
+++ b/chromium/cc/tiles/tile_priority.h
@@ -14,6 +14,7 @@
#include "base/trace_event/traced_value.h"
#include "cc/cc_export.h"
+#include "third_party/perfetto/protos/perfetto/trace/track_event/chrome_compositor_scheduler_state.pbzero.h"
namespace base {
class Value;
@@ -90,7 +91,11 @@ enum TreePriority {
LAST_TREE_PRIORITY = NEW_CONTENT_TAKES_PRIORITY
// Be sure to update TreePriorityAsValue when adding new fields.
};
+// TODO(nuskos): remove TreePriorityToString once we have a utility function to
+// take protozero to strings.
std::string TreePriorityToString(TreePriority prio);
+perfetto::protos::pbzero::ChromeCompositorStateMachine::MinorState::TreePriority
+TreePriorityToProtozeroEnum(TreePriority priority);
class GlobalStateThatImpactsTilePriority {
public:
diff --git a/chromium/cc/trees/browser_controls_params.cc b/chromium/cc/trees/browser_controls_params.cc
new file mode 100644
index 00000000000..4c762b335b2
--- /dev/null
+++ b/chromium/cc/trees/browser_controls_params.cc
@@ -0,0 +1,26 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "cc/trees/browser_controls_params.h"
+
+namespace cc {
+
+bool BrowserControlsParams::operator==(
+ const BrowserControlsParams& other) const {
+ return top_controls_height == other.top_controls_height &&
+ top_controls_min_height == other.top_controls_min_height &&
+ bottom_controls_height == other.bottom_controls_height &&
+ bottom_controls_min_height == other.bottom_controls_min_height &&
+ animate_browser_controls_height_changes ==
+ other.animate_browser_controls_height_changes &&
+ browser_controls_shrink_blink_size ==
+ other.browser_controls_shrink_blink_size;
+}
+
+bool BrowserControlsParams::operator!=(
+ const BrowserControlsParams& other) const {
+ return !(*this == other);
+}
+
+} // namespace cc
diff --git a/chromium/cc/trees/browser_controls_params.h b/chromium/cc/trees/browser_controls_params.h
new file mode 100644
index 00000000000..7ef5326c9b7
--- /dev/null
+++ b/chromium/cc/trees/browser_controls_params.h
@@ -0,0 +1,44 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef CC_TREES_BROWSER_CONTROLS_PARAMS_H_
+#define CC_TREES_BROWSER_CONTROLS_PARAMS_H_
+
+#include "cc/cc_export.h"
+
+namespace cc {
+
+struct CC_EXPORT BrowserControlsParams {
+ BrowserControlsParams() = default;
+ BrowserControlsParams(const BrowserControlsParams& other) = default;
+ ~BrowserControlsParams() = default;
+
+ // The height of the top controls (always 0 on platforms where URL-bar hiding
+ // isn't supported).
+ float top_controls_height = 0.f;
+
+ // The minimum visible height of the top controls.
+ float top_controls_min_height = 0.f;
+
+ // The height of the bottom controls.
+ float bottom_controls_height = 0.f;
+
+ // The minimum visible height of the bottom controls.
+ float bottom_controls_min_height = 0.f;
+
+ // Whether or not the changes to the browser controls heights should be
+ // animated.
+ bool animate_browser_controls_height_changes = false;
+
+ // Whether or not Blink's viewport size should be shrunk by the height of the
+ // URL-bar (always false on platforms where URL-bar hiding isn't supported).
+ bool browser_controls_shrink_blink_size = false;
+
+ bool operator==(const BrowserControlsParams& other) const;
+ bool operator!=(const BrowserControlsParams& other) const;
+};
+
+} // namespace cc
+
+#endif // CC_TREES_BROWSER_CONTROLS_PARAMS_H_
diff --git a/chromium/cc/trees/damage_tracker_unittest.cc b/chromium/cc/trees/damage_tracker_unittest.cc
index d2636625dfb..42d0fe8a76c 100644
--- a/chromium/cc/trees/damage_tracker_unittest.cc
+++ b/chromium/cc/trees/damage_tracker_unittest.cc
@@ -63,6 +63,7 @@ void ClearDamageForAllSurfaces(LayerImpl* root) {
for (auto* layer : *root->layer_tree_impl()) {
if (GetRenderSurface(layer))
GetRenderSurface(layer)->damage_tracker()->DidDrawDamagedArea();
+ layer->ResetChangeTracking();
}
}
@@ -254,7 +255,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
// CASE 1: Setting the update rect should cause the corresponding damage to
// the surface.
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
+ child->UnionUpdateRect(gfx::Rect(10, 11, 12, 13));
EmulateDrawingOneFrame(root);
// Damage position on the surface should be: position of update_rect (10, 11)
@@ -268,7 +269,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
// CASE 2: The same update rect twice in a row still produces the same
// damage.
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
+ child->UnionUpdateRect(gfx::Rect(10, 11, 12, 13));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
&root_damage_rect));
@@ -278,7 +279,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForUpdateRects) {
// CASE 3: Setting a different update rect should cause damage on the new
// update region, but no additional exposed old region.
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(20, 25, 1, 2));
+ child->UnionUpdateRect(gfx::Rect(20, 25, 1, 2));
EmulateDrawingOneFrame(root);
// Damage position on the surface should be: position of update_rect (20, 25)
@@ -355,7 +356,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
// corresponding damage to the surface.
ClearDamageForAllSurfaces(root);
child->AddDamageRect(gfx::Rect(5, 6, 12, 13));
- child->SetUpdateRect(gfx::Rect(15, 16, 14, 10));
+ child->UnionUpdateRect(gfx::Rect(15, 16, 14, 10));
EmulateDrawingOneFrame(root);
// Damage position on the surface should be: position of unified layer
@@ -370,7 +371,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
// produces the same damage.
ClearDamageForAllSurfaces(root);
child->AddDamageRect(gfx::Rect(10, 11, 12, 13));
- child->SetUpdateRect(gfx::Rect(10, 11, 14, 15));
+ child->UnionUpdateRect(gfx::Rect(10, 11, 14, 15));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
&root_damage_rect));
@@ -380,7 +381,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForLayerUpdateAndDamageRects) {
// damage on the new damaged region, but no additional exposed old region.
ClearDamageForAllSurfaces(root);
child->AddDamageRect(gfx::Rect(20, 25, 2, 3));
- child->SetUpdateRect(gfx::Rect(5, 10, 7, 8));
+ child->UnionUpdateRect(gfx::Rect(5, 10, 7, 8));
EmulateDrawingOneFrame(root);
// Damage position on the surface should be: position of unified layer damage
@@ -402,7 +403,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForPropertyChanges) {
CreateEffectNode(child).render_surface_reason = RenderSurfaceReason::kTest;
EmulateDrawingOneFrame(root);
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
+ child->UnionUpdateRect(gfx::Rect(10, 11, 12, 13));
root->layer_tree_impl()->SetOpacityMutated(child->element_id(), 0.5f);
EmulateDrawingOneFrame(root);
@@ -560,7 +561,7 @@ TEST_F(DamageTrackerTest,
child1_->SetDrawsContent(true);
ClearDamageForAllSurfaces(root);
child1_->AddDamageRect(gfx::Rect(105, 106, 12, 15));
- child1_->SetUpdateRect(gfx::Rect(115, 116, 12, 15));
+ child1_->UnionUpdateRect(gfx::Rect(115, 116, 12, 15));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)
->damage_tracker()
@@ -573,7 +574,7 @@ TEST_F(DamageTrackerTest,
// corresponding damage to the surface.
ClearDamageForAllSurfaces(root);
child2_->AddDamageRect(gfx::Rect(11, 11, 12, 15));
- child2_->SetUpdateRect(gfx::Rect(12, 12, 12, 15));
+ child2_->UnionUpdateRect(gfx::Rect(12, 12, 12, 15));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)
->damage_tracker()
@@ -586,7 +587,7 @@ TEST_F(DamageTrackerTest,
// the corresponding damage to the surface.
ClearDamageForAllSurfaces(root);
grand_child1_->AddDamageRect(gfx::Rect(1, 0, 2, 5));
- grand_child1_->SetUpdateRect(gfx::Rect(2, 1, 2, 5));
+ grand_child1_->UnionUpdateRect(gfx::Rect(2, 1, 2, 5));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)
->damage_tracker()
@@ -762,7 +763,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBlurredSurface) {
// Setting the update rect should cause the corresponding damage to the
// surface, blurred based on the size of the blur filter.
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(1, 2, 3, 4));
+ child->UnionUpdateRect(gfx::Rect(1, 2, 3, 4));
EmulateDrawingOneFrame(root);
// Damage position on the surface should be: position of update_rect (1, 2)
@@ -822,7 +823,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForImageFilter) {
// CASE 1: Setting the update rect should damage the whole surface (for now)
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(1, 1));
+ child->UnionUpdateRect(gfx::Rect(1, 1));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -911,7 +912,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForTransformedImageFilter) {
// Setting the update rect should damage the whole surface (for now)
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(30, 30));
+ child->UnionUpdateRect(gfx::Rect(30, 30));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -970,7 +971,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForHighDPIImageFilter) {
// Setting the update rect should damage only the affected area (original,
// outset by 3 * blur sigma * DSF).
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(30, 30));
+ child->UnionUpdateRect(gfx::Rect(30, 30));
EmulateDrawingOneFrame(root, device_scale_factor);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -1002,7 +1003,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
// blur filter. Note that child1_'s render surface has a size of
// 206x208 due to contributions from grand_child1_ and grand_child2_.
ClearDamageForAllSurfaces(root);
- root->SetUpdateRect(gfx::Rect(297, 297, 2, 2));
+ root->UnionUpdateRect(gfx::Rect(297, 297, 2, 2));
EmulateDrawingOneFrame(root);
gfx::Rect root_damage_rect;
@@ -1022,7 +1023,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
// blur filter. Since the damage extends to the right/bottom outside
// of the blurred layer, only the left/top should end up expanded.
ClearDamageForAllSurfaces(root);
- root->SetUpdateRect(gfx::Rect(297, 297, 30, 30));
+ root->UnionUpdateRect(gfx::Rect(297, 297, 30, 30));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -1039,7 +1040,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
// CASE 3: Setting this update rect outside the blurred content_bounds of the
// blurred child1_ will not cause it to be expanded.
ClearDamageForAllSurfaces(root);
- root->SetUpdateRect(gfx::Rect(30, 30, 2, 2));
+ root->UnionUpdateRect(gfx::Rect(30, 30, 2, 2));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -1054,7 +1055,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
// outside the original content_bounds of the blurred child1_ will
// cause it to be expanded.
ClearDamageForAllSurfaces(root);
- root->SetUpdateRect(gfx::Rect(99, 99, 1, 1));
+ root->UnionUpdateRect(gfx::Rect(99, 99, 1, 1));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -1070,7 +1071,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
// CASE 5: Setting the update rect on child2_, which is above child1_, will
// not get blurred by child1_, so it does not need to get expanded.
ClearDamageForAllSurfaces(root);
- child2_->SetUpdateRect(gfx::Rect(1, 1));
+ child2_->UnionUpdateRect(gfx::Rect(1, 1));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -1085,7 +1086,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForBackdropBlurredChild) {
// that any pixels needed for the blur are redrawn in the current
// frame.
ClearDamageForAllSurfaces(root);
- child1_->SetUpdateRect(gfx::Rect(1, 1));
+ child1_->UnionUpdateRect(gfx::Rect(1, 1));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -1235,8 +1236,8 @@ TEST_F(DamageTrackerTest, VerifyDamageForMultipleLayers) {
// - child1_ update rect in surface space: gfx::Rect(100, 100, 1, 2);
// - child2_ update rect in surface space: gfx::Rect(400, 380, 3, 4);
ClearDamageForAllSurfaces(root);
- child1->SetUpdateRect(gfx::Rect(1, 2));
- child2->SetUpdateRect(gfx::Rect(3, 4));
+ child1->UnionUpdateRect(gfx::Rect(1, 2));
+ child2->UnionUpdateRect(gfx::Rect(3, 4));
EmulateDrawingOneFrame(root);
gfx::Rect root_damage_rect;
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
@@ -1536,7 +1537,7 @@ TEST_F(DamageTrackerTest, VerifyNoDamageForUpdateRectThatDoesNotDrawContent) {
// In our specific tree, the update rect of child1_ should not cause any
// damage to any surface because it does not actually draw content.
ClearDamageForAllSurfaces(root);
- child1_->SetUpdateRect(gfx::Rect(1, 2));
+ child1_->UnionUpdateRect(gfx::Rect(1, 2));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(child1_)->damage_tracker()->GetDamageRectIfValid(
&child_damage_rect));
@@ -1589,7 +1590,7 @@ TEST_F(DamageTrackerTest, VerifyDamageForMask) {
// CASE 1: the update_rect on a mask layer should damage the rect.
ClearDamageForAllSurfaces(root);
- mask_layer->SetUpdateRect(gfx::Rect(1, 2, 3, 4));
+ mask_layer->UnionUpdateRect(gfx::Rect(1, 2, 3, 4));
EmulateDrawingOneFrame(root);
gfx::Rect child_damage_rect;
EXPECT_TRUE(GetRenderSurface(child)->damage_tracker()->GetDamageRectIfValid(
@@ -1676,7 +1677,7 @@ TEST_F(DamageTrackerTest, DamageWhenAddedExternally) {
// it is included with any other partial damage.
//
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(10, 11, 12, 13));
+ child->UnionUpdateRect(gfx::Rect(10, 11, 12, 13));
GetRenderSurface(root)->damage_tracker()->AddDamageNextUpdate(
gfx::Rect(15, 16, 32, 33));
EmulateDrawingOneFrame(root);
@@ -1732,7 +1733,7 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) {
LayerImpl* child = child_layers_[0];
ClearDamageForAllSurfaces(root);
- child->SetUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f));
+ child->UnionUpdateRect(gfx::Rect(10.f, 11.f, 1.f, 2.f));
EmulateDrawingOneFrame(root);
// Sanity check damage after the first frame; this isnt the actual test yet.
@@ -1746,7 +1747,7 @@ TEST_F(DamageTrackerTest, VerifyDamageAccumulatesUntilReset) {
// New damage, without having cleared the previous damage, should be unioned
// to the previous one.
- child->SetUpdateRect(gfx::Rect(20, 25, 1, 2));
+ child->UnionUpdateRect(gfx::Rect(20, 25, 1, 2));
EmulateDrawingOneFrame(root);
EXPECT_TRUE(GetRenderSurface(root)->damage_tracker()->GetDamageRectIfValid(
&root_damage_rect));
diff --git a/chromium/cc/trees/debug_rect_history.cc b/chromium/cc/trees/debug_rect_history.cc
index ca985285ffb..2fee9221061 100644
--- a/chromium/cc/trees/debug_rect_history.cc
+++ b/chromium/cc/trees/debug_rect_history.cc
@@ -50,6 +50,9 @@ void DebugRectHistory::SaveDebugRectsForCurrentFrame(
if (debug_state.show_non_fast_scrollable_rects)
SaveNonFastScrollableRects(tree_impl);
+ if (debug_state.show_main_thread_scrolling_reason_rects)
+ SaveMainThreadScrollingReasonRects(tree_impl);
+
if (debug_state.show_layout_shift_regions)
SaveLayoutShiftRects(hud_layer);
@@ -205,4 +208,23 @@ void DebugRectHistory::SaveNonFastScrollableRectsCallback(LayerImpl* layer) {
}
}
+void DebugRectHistory::SaveMainThreadScrollingReasonRects(
+ LayerTreeImpl* tree_impl) {
+ const auto& scroll_tree = tree_impl->property_trees()->scroll_tree;
+ for (auto* layer : *tree_impl) {
+ if (layer->scrollable()) {
+ if (const auto* scroll_node =
+ scroll_tree.Node(layer->scroll_tree_index())) {
+ if (auto reasons = scroll_node->main_thread_scrolling_reasons) {
+ debug_rects_.push_back(DebugRect(
+ MAIN_THREAD_SCROLLING_REASON_RECT_TYPE,
+ MathUtil::MapEnclosingClippedRect(layer->ScreenSpaceTransform(),
+ gfx::Rect(layer->bounds())),
+ kTouchActionNone, reasons));
+ }
+ }
+ }
+ }
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/debug_rect_history.h b/chromium/cc/trees/debug_rect_history.h
index d9b6da071b9..a24b5d8ee88 100644
--- a/chromium/cc/trees/debug_rect_history.h
+++ b/chromium/cc/trees/debug_rect_history.h
@@ -46,6 +46,7 @@ enum DebugRectType {
WHEEL_EVENT_HANDLER_RECT_TYPE,
SCROLL_EVENT_HANDLER_RECT_TYPE,
NON_FAST_SCROLLABLE_RECT_TYPE,
+ MAIN_THREAD_SCROLLING_REASON_RECT_TYPE,
ANIMATION_BOUNDS_RECT_TYPE,
LAYOUT_SHIFT_RECT_TYPE,
};
@@ -53,19 +54,24 @@ enum DebugRectType {
struct DebugRect {
DebugRect(DebugRectType new_type,
const gfx::Rect& new_rect,
- TouchAction new_touch_action)
- : type(new_type), rect(new_rect), touch_action(new_touch_action) {
+ TouchAction new_touch_action = kTouchActionNone,
+ uint32_t main_thread_scrolling_reasons = 0)
+ : type(new_type),
+ rect(new_rect),
+ touch_action(new_touch_action),
+ main_thread_scrolling_reasons(main_thread_scrolling_reasons) {
if (type != TOUCH_EVENT_HANDLER_RECT_TYPE)
DCHECK_EQ(touch_action, kTouchActionNone);
+ if (type != MAIN_THREAD_SCROLLING_REASON_RECT_TYPE)
+ DCHECK(!main_thread_scrolling_reasons);
}
- DebugRect(DebugRectType new_type, const gfx::Rect& new_rect)
- : DebugRect(new_type, new_rect, kTouchActionNone) {}
-
DebugRectType type;
gfx::Rect rect;
// Valid when |type| is |TOUCH_EVENT_HANDLER_RECT_TYPE|, otherwise default to
// |kTouchActionNone|.
TouchAction touch_action;
+ // Valid when |type| is |MAIN_THREAD_SCROLLING_REASON_RECT_TYPE|, otherwise 0.
+ uint32_t main_thread_scrolling_reasons;
};
// This class maintains a history of rects of various types that can be used
@@ -105,6 +111,7 @@ class DebugRectHistory {
void SaveScrollEventHandlerRectsCallback(LayerImpl* layer);
void SaveNonFastScrollableRects(LayerTreeImpl* layer);
void SaveNonFastScrollableRectsCallback(LayerImpl* layer);
+ void SaveMainThreadScrollingReasonRects(LayerTreeImpl*);
std::vector<DebugRect> debug_rects_;
};
diff --git a/chromium/cc/trees/draw_properties_unittest.cc b/chromium/cc/trees/draw_properties_unittest.cc
index 93acf2883ce..070ef175267 100644
--- a/chromium/cc/trees/draw_properties_unittest.cc
+++ b/chromium/cc/trees/draw_properties_unittest.cc
@@ -21,7 +21,6 @@
#include "cc/layers/content_layer_client.h"
#include "cc/layers/effect_tree_layer_list_iterator.h"
#include "cc/layers/layer.h"
-#include "cc/layers/layer_client.h"
#include "cc/layers/layer_impl.h"
#include "cc/layers/render_surface_impl.h"
#include "cc/test/animation_test_common.h"
@@ -6160,8 +6159,7 @@ TEST_F(DrawPropertiesTest, ViewportBoundsDeltaAffectVisibleContentRect) {
LayerTreeImpl* active_tree = host_impl()->active_tree();
active_tree->SetDeviceViewportRect(device_viewport_rect);
- active_tree->set_browser_controls_shrink_blink_size(true);
- active_tree->SetTopControlsHeight(50);
+ active_tree->SetBrowserControlsParams({50, 0, 0, 0, false, true});
active_tree->PushPageScaleFromMainThread(1.0f, 1.0f, 1.0f);
LayerImpl* root = root_layer();
@@ -6171,12 +6169,12 @@ TEST_F(DrawPropertiesTest, ViewportBoundsDeltaAffectVisibleContentRect) {
LayerImpl* scroll_layer = InnerViewportScrollLayer();
scroll_layer->SetDrawsContent(true);
- active_tree->SetCurrentBrowserControlsShownRatio(1.0f);
+ active_tree->SetCurrentBrowserControlsShownRatio(1.0f, 1.0f);
active_tree->UpdateViewportContainerSizes();
UpdateActiveTreeDrawProperties();
EXPECT_EQ(gfx::Rect(container_size), scroll_layer->visible_layer_rect());
- active_tree->SetCurrentBrowserControlsShownRatio(0.0f);
+ active_tree->SetCurrentBrowserControlsShownRatio(0.0f, 0.0f);
active_tree->UpdateViewportContainerSizes();
UpdateActiveTreeDrawProperties();
diff --git a/chromium/cc/trees/layer_tree_host.cc b/chromium/cc/trees/layer_tree_host.cc
index 09cd244629c..55391d95054 100644
--- a/chromium/cc/trees/layer_tree_host.cc
+++ b/chromium/cc/trees/layer_tree_host.cc
@@ -43,7 +43,6 @@
#include "cc/layers/painted_scrollbar_layer.h"
#include "cc/paint/paint_worklet_layer_painter.h"
#include "cc/resources/ui_resource_manager.h"
-#include "cc/tiles/frame_viewer_instrumentation.h"
#include "cc/trees/clip_node.h"
#include "cc/trees/draw_property_utils.h"
#include "cc/trees/effect_node.h"
@@ -69,7 +68,7 @@
namespace {
static base::AtomicSequenceNumber s_layer_tree_host_sequence_number;
static base::AtomicSequenceNumber s_image_decode_sequence_number;
-}
+} // namespace
namespace cc {
namespace {
@@ -301,8 +300,7 @@ void LayerTreeHost::RequestMainFrameUpdate(bool report_cc_metrics) {
// code that is logically a main thread operation, e.g. deletion of a Layer,
// should be delayed until the LayerTreeHost::CommitComplete, which will run
// after the commit, but on the main thread.
-void LayerTreeHost::FinishCommitOnImplThread(
- LayerTreeHostImpl* host_impl) {
+void LayerTreeHost::FinishCommitOnImplThread(LayerTreeHostImpl* host_impl) {
DCHECK(task_runner_provider_->IsImplThread());
TRACE_EVENT0("cc,benchmark", "LayerTreeHost::FinishCommitOnImplThread");
@@ -458,22 +456,6 @@ void LayerTreeHost::PushPropertyTreesTo(LayerTreeImpl* tree_impl) {
void LayerTreeHost::WillCommit() {
swap_promise_manager_.WillCommit();
client_->WillCommit();
-
- if (frame_viewer_instrumentation::IsTracingLayerTreeSnapshots()) {
- bool is_new_trace;
- TRACE_EVENT_IS_NEW_TRACE(&is_new_trace);
- if (is_new_trace) {
- // We'll be dumping layer trees as part of trace, so make sure
- // PushPropertiesTo() propagates layer debug info to the impl side --
- // otherwise this won't happen for the layers that remain unchanged since
- // tracing started.
- for (auto* layer : *this)
- layer->SetNeedsPushProperties();
- }
-
- for (Layer* layer : LayersThatShouldPushProperties())
- layer->UpdateDebugInfo();
- }
}
void LayerTreeHost::UpdateDeferMainFrameUpdateInternal() {
@@ -533,8 +515,7 @@ void LayerTreeHost::DidFailToInitializeLayerTreeFrameSink() {
client_->DidFailToInitializeLayerTreeFrameSink();
}
-std::unique_ptr<LayerTreeHostImpl>
-LayerTreeHost::CreateLayerTreeHostImpl(
+std::unique_ptr<LayerTreeHostImpl> LayerTreeHost::CreateLayerTreeHostImpl(
LayerTreeHostImplClient* client) {
DCHECK(task_runner_provider_->IsImplThread());
@@ -557,8 +538,6 @@ LayerTreeHost::CreateLayerTreeHostImpl(
ukm_recorder_factory_.reset();
}
- host_impl->SetContentHasSlowPaths(content_has_slow_paths_);
- host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_);
task_graph_runner_ = nullptr;
input_handler_weak_ptr_ = host_impl->AsWeakPtr();
return host_impl;
@@ -649,8 +628,7 @@ void LayerTreeHost::SetNeedsCommitWithForcedRedraw() {
proxy_->SetNeedsCommit();
}
-void LayerTreeHost::SetAnimationEvents(
- std::unique_ptr<MutatorEvents> events) {
+void LayerTreeHost::SetAnimationEvents(std::unique_ptr<MutatorEvents> events) {
DCHECK(task_runner_provider_->IsMainThread());
mutator_host_->SetAnimationEvents(std::move(events));
@@ -661,8 +639,7 @@ void LayerTreeHost::SetAnimationEvents(
SetNeedsAnimate();
}
-void LayerTreeHost::SetDebugState(
- const LayerTreeDebugState& debug_state) {
+void LayerTreeHost::SetDebugState(const LayerTreeDebugState& debug_state) {
LayerTreeDebugState new_debug_state =
LayerTreeDebugState::Unite(settings_.initial_debug_state, debug_state);
@@ -677,8 +654,7 @@ void LayerTreeHost::SetDebugState(
SetNeedsCommit();
}
-void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(
- float page_scale_delta) {
+void LayerTreeHost::ApplyPageScaleDeltaFromImplSide(float page_scale_delta) {
DCHECK(CommitRequested());
if (page_scale_delta == 1.f)
return;
@@ -778,13 +754,6 @@ void LayerTreeHost::RecordGpuRasterizationHistogram(
// mostly used for debugging purposes.
UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationEnabled",
gpu_rasterization_enabled);
- if (gpu_rasterization_enabled) {
- UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSuitableContent",
- !content_has_slow_paths_);
- UMA_HISTOGRAM_BOOLEAN("Renderer4.GpuRasterizationSlowPathsWithNonAAPaint",
- content_has_slow_paths_ && content_has_non_aa_paint_);
- }
-
gpu_rasterization_histogram_recorded_ = true;
}
@@ -862,31 +831,7 @@ bool LayerTreeHost::DoUpdateLayers() {
LayerList update_layer_list;
draw_property_utils::FindLayersThatNeedUpdates(this, &update_layer_list);
-
- bool painted_content_has_slow_paths = false;
- bool painted_content_has_non_aa_paint = false;
- bool did_paint_content =
- PaintContent(update_layer_list, &painted_content_has_slow_paths,
- &painted_content_has_non_aa_paint);
-
- // |painted_content_has_non_aa_paint| is a correctness (not performance)
- // modifier, if it changes we immediately update. To prevent churn, this flag
- // is sticky.
- content_has_non_aa_paint_ |= painted_content_has_non_aa_paint;
-
- // If no slow-path content has appeared for a required number of frames,
- // update the flag.
- if (!painted_content_has_slow_paths) {
- ++num_consecutive_frames_without_slow_paths_;
- if (num_consecutive_frames_without_slow_paths_ >=
- kNumFramesToConsiderBeforeRemovingSlowPathFlag) {
- content_has_slow_paths_ = false;
- }
- } else {
- num_consecutive_frames_without_slow_paths_ = 0;
- content_has_slow_paths_ = true;
- }
-
+ bool did_paint_content = PaintContent(update_layer_list);
return did_paint_content;
}
@@ -897,6 +842,7 @@ void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) {
if (inner_viewport_scroll_delta.IsZero() && info.page_scale_delta == 1.f &&
info.elastic_overscroll_delta.IsZero() && !info.top_controls_delta &&
+ !info.bottom_controls_delta &&
!info.browser_controls_constraint_changed &&
!info.scroll_gesture_did_end &&
info.is_pinch_gesture_active == is_pinch_gesture_active_from_impl_) {
@@ -914,6 +860,14 @@ void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) {
inner_scroll_layer->CurrentScrollOffset() +
inner_viewport_scroll_delta);
}
+ if (IsUsingLayerLists()) {
+ auto& scroll_tree = property_trees()->scroll_tree;
+ scroll_tree.NotifyDidScroll(
+ inner_scroll->element_id,
+ scroll_tree.current_scroll_offset(inner_scroll->element_id) +
+ inner_viewport_scroll_delta,
+ info.inner_viewport_scroll.snap_target_element_ids);
+ }
}
ApplyPageScaleDeltaFromImplSide(info.page_scale_delta);
@@ -924,8 +878,8 @@ void LayerTreeHost::ApplyViewportChanges(const ScrollAndScaleSet& info) {
client_->ApplyViewportChanges(
{inner_viewport_scroll_delta, info.elastic_overscroll_delta,
info.page_scale_delta, info.is_pinch_gesture_active,
- info.top_controls_delta, info.browser_controls_constraint,
- info.scroll_gesture_did_end});
+ info.top_controls_delta, info.bottom_controls_delta,
+ info.browser_controls_constraint, info.scroll_gesture_did_end});
SetNeedsUpdateLayers();
}
@@ -949,6 +903,7 @@ void LayerTreeHost::SendOverscrollAndScrollEndEventsFromImplSide(
void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
DCHECK(info);
+ TRACE_EVENT0("cc", "LayerTreeHost::ApplyScrollAndScale");
for (auto& swap_promise : info->swap_promises) {
TRACE_EVENT_WITH_FLOW1("input,benchmark", "LatencyInfo.Flow",
TRACE_ID_DONT_MANGLE(swap_promise->TraceId()),
@@ -958,19 +913,28 @@ void LayerTreeHost::ApplyScrollAndScale(ScrollAndScaleSet* info) {
}
if (root_layer_) {
- for (size_t i = 0; i < info->scrolls.size(); ++i) {
- Layer* layer = LayerByElementId(info->scrolls[i].element_id);
- if (!layer)
- continue;
- layer->SetScrollOffsetFromImplSide(layer->CurrentScrollOffset() +
- info->scrolls[i].scroll_delta);
- SetNeedsUpdateLayers();
+ auto& scroll_tree = property_trees()->scroll_tree;
+ for (auto& scroll : info->scrolls) {
+ if (Layer* layer = LayerByElementId(scroll.element_id)) {
+ layer->SetScrollOffsetFromImplSide(layer->CurrentScrollOffset() +
+ scroll.scroll_delta);
+ SetNeedsUpdateLayers();
+ }
+ if (IsUsingLayerLists()) {
+ TRACE_EVENT_INSTANT2(
+ "cc", "NotifyDidScroll", TRACE_EVENT_SCOPE_THREAD, "cur_y",
+ scroll_tree.current_scroll_offset(scroll.element_id).y(), "delta",
+ scroll.scroll_delta.y());
+ scroll_tree.NotifyDidScroll(
+ scroll.element_id,
+ scroll_tree.current_scroll_offset(scroll.element_id) +
+ scroll.scroll_delta,
+ scroll.snap_target_element_ids);
+ }
}
- for (size_t i = 0; i < info->scrollbars.size(); ++i) {
- Layer* layer = LayerByElementId(info->scrollbars[i].element_id);
- if (!layer)
- continue;
- layer->SetScrollbarsHiddenFromImplSide(info->scrollbars[i].hidden);
+ for (auto& scrollbar : info->scrollbars) {
+ scroll_tree.NotifyDidChangeScrollbarsHidden(scrollbar.element_id,
+ scrollbar.hidden);
}
}
@@ -992,15 +956,13 @@ void LayerTreeHost::RecordEndOfFrameMetrics(base::TimeTicks frame_begin_time) {
client_->RecordEndOfFrameMetrics(frame_begin_time);
}
-const base::WeakPtr<InputHandler>& LayerTreeHost::GetInputHandler()
- const {
+const base::WeakPtr<InputHandler>& LayerTreeHost::GetInputHandler() const {
return input_handler_weak_ptr_;
}
-void LayerTreeHost::UpdateBrowserControlsState(
- BrowserControlsState constraints,
- BrowserControlsState current,
- bool animate) {
+void LayerTreeHost::UpdateBrowserControlsState(BrowserControlsState constraints,
+ BrowserControlsState current,
+ bool animate) {
// Browser controls are only used in threaded mode but Blink layout tests may
// call into this. The single threaded version is a no-op.
proxy_->UpdateBrowserControlsState(constraints, current, animate);
@@ -1094,8 +1056,6 @@ void LayerTreeHost::SetRootLayer(scoped_refptr<Layer> root_layer) {
// Reset gpu rasterization tracking.
// This flag is sticky until a new tree comes along.
- content_has_slow_paths_ = false;
- content_has_non_aa_paint_ = false;
gpu_rasterization_histogram_recorded_ = false;
force_use_property_tree_builder_ = false;
@@ -1244,25 +1204,23 @@ void LayerTreeHost::SetViewportVisibleRect(const gfx::Rect& visible_rect) {
viewport_visible_rect_ = visible_rect;
}
-void LayerTreeHost::SetBrowserControlsHeight(float top_height,
- float bottom_height,
- bool shrink) {
- if (top_controls_height_ == top_height &&
- bottom_controls_height_ == bottom_height &&
- browser_controls_shrink_blink_size_ == shrink)
+void LayerTreeHost::SetBrowserControlsParams(
+ const BrowserControlsParams& params) {
+ if (browser_controls_params_ == params)
return;
- top_controls_height_ = top_height;
- bottom_controls_height_ = bottom_height;
- browser_controls_shrink_blink_size_ = shrink;
+ browser_controls_params_ = params;
SetNeedsCommit();
}
-void LayerTreeHost::SetBrowserControlsShownRatio(float ratio) {
- if (top_controls_shown_ratio_ == ratio)
+void LayerTreeHost::SetBrowserControlsShownRatio(float top_ratio,
+ float bottom_ratio) {
+ if (top_controls_shown_ratio_ == top_ratio &&
+ bottom_controls_shown_ratio_ == bottom_ratio)
return;
- top_controls_shown_ratio_ = ratio;
+ top_controls_shown_ratio_ = top_ratio;
+ bottom_controls_shown_ratio_ = bottom_ratio;
SetNeedsCommit();
}
@@ -1438,15 +1396,11 @@ Layer* LayerTreeHost::LayerById(int id) const {
return iter != layer_id_map_.end() ? iter->second : nullptr;
}
-bool LayerTreeHost::PaintContent(const LayerList& update_layer_list,
- bool* content_has_slow_paths,
- bool* content_has_non_aa_paint) {
+bool LayerTreeHost::PaintContent(const LayerList& update_layer_list) {
base::AutoReset<bool> painting(&in_paint_layer_contents_, true);
bool did_paint_content = false;
for (const auto& layer : update_layer_list) {
did_paint_content |= layer->Update();
- *content_has_slow_paths |= layer->HasSlowPaths();
- *content_has_non_aa_paint |= layer->HasNonAAPaint();
}
return did_paint_content;
}
@@ -1519,6 +1473,10 @@ void LayerTreeHost::UpdateHudLayer(bool show_hud_info) {
}
}
+bool LayerTreeHost::is_hud_layer(const Layer* layer) const {
+ return hud_layer() == layer;
+}
+
void LayerTreeHost::SetNeedsFullTreeSync() {
needs_full_tree_sync_ = true;
property_trees_.needs_rebuild = true;
@@ -1560,12 +1518,10 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
tree_impl->PushPageScaleFromMainThread(
page_scale_factor_, min_page_scale_factor_, max_page_scale_factor_);
- tree_impl->set_browser_controls_shrink_blink_size(
- browser_controls_shrink_blink_size_);
- tree_impl->SetTopControlsHeight(top_controls_height_);
- tree_impl->SetBottomControlsHeight(bottom_controls_height_);
+ tree_impl->SetBrowserControlsParams(browser_controls_params_);
tree_impl->set_overscroll_behavior(overscroll_behavior_);
- tree_impl->PushBrowserControlsFromMainThread(top_controls_shown_ratio_);
+ tree_impl->PushBrowserControlsFromMainThread(top_controls_shown_ratio_,
+ bottom_controls_shown_ratio_);
tree_impl->elastic_overscroll()->PushMainToPending(elastic_overscroll_);
if (tree_impl->IsActiveTree())
tree_impl->elastic_overscroll()->PushPendingToActive();
@@ -1602,6 +1558,8 @@ void LayerTreeHost::PushLayerTreePropertiesTo(LayerTreeImpl* tree_impl) {
if (top_controls_shown_ratio_ > 0.0f && top_controls_shown_ratio_ < 1.0f) {
tree_impl->UpdateViewportContainerSizes();
}
+
+ tree_impl->set_display_transform_hint(display_transform_hint_);
}
void LayerTreeHost::PushSurfaceRangesTo(LayerTreeImpl* tree_impl) {
@@ -1615,8 +1573,6 @@ void LayerTreeHost::PushSurfaceRangesTo(LayerTreeImpl* tree_impl) {
void LayerTreeHost::PushLayerTreeHostPropertiesTo(
LayerTreeHostImpl* host_impl) {
- host_impl->SetContentHasSlowPaths(content_has_slow_paths_);
- host_impl->SetContentHasNonAAPaint(content_has_non_aa_paint_);
host_impl->set_external_pinch_gesture_active(
is_external_pinch_gesture_active_);
RecordGpuRasterizationHistogram(host_impl);
diff --git a/chromium/cc/trees/layer_tree_host.h b/chromium/cc/trees/layer_tree_host.h
index 104cc541e97..64df3a33fc8 100644
--- a/chromium/cc/trees/layer_tree_host.h
+++ b/chromium/cc/trees/layer_tree_host.h
@@ -35,6 +35,7 @@
#include "cc/layers/layer_list_iterator.h"
#include "cc/metrics/begin_main_frame_metrics.h"
#include "cc/paint/node_id.h"
+#include "cc/trees/browser_controls_params.h"
#include "cc/trees/compositor_mode.h"
#include "cc/trees/layer_tree_frame_sink.h"
#include "cc/trees/layer_tree_host_client.h"
@@ -49,6 +50,7 @@
#include "components/viz/common/surfaces/local_surface_id_allocation.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "ui/gfx/geometry/rect.h"
+#include "ui/gfx/overlay_transform.h"
namespace gfx {
struct PresentationFeedback;
@@ -333,7 +335,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
};
// Sets the collection of viewport property ids, defined to allow viewport
- // pinch-zoom etc. on the compositor thread.
+ // pinch-zoom etc. on the compositor thread. This is set only on the
+ // main-frame's compositor, i.e., will be unset in OOPIF and UI compositors.
void RegisterViewportPropertyIds(const ViewportPropertyIds&);
LayerTreeHost::ViewportPropertyIds ViewportPropertyIdsForTesting() const {
@@ -382,10 +385,8 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
gfx::Rect device_viewport_rect() const { return device_viewport_rect_; }
- void SetBrowserControlsHeight(float top_height,
- float bottom_height,
- bool shrink);
- void SetBrowserControlsShownRatio(float ratio);
+ void SetBrowserControlsParams(const BrowserControlsParams& params);
+ void SetBrowserControlsShownRatio(float top_ratio, float bottom_ratio);
void SetOverscrollBehavior(const OverscrollBehavior& overscroll_behavior);
const OverscrollBehavior& overscroll_behavior() const {
@@ -402,6 +403,13 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void set_background_color(SkColor color) { background_color_ = color; }
SkColor background_color() const { return background_color_; }
+ void set_display_transform_hint(gfx::OverlayTransform hint) {
+ display_transform_hint_ = hint;
+ }
+ gfx::OverlayTransform display_transform_hint() const {
+ return display_transform_hint_;
+ }
+
void StartPageScaleAnimation(const gfx::Vector2d& target_offset,
bool use_anchor,
float scale,
@@ -478,9 +486,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
void UnregisterLayer(Layer* layer);
Layer* LayerById(int id) const;
- bool PaintContent(const LayerList& update_layer_list,
- bool* content_has_slow_paths,
- bool* content_has_non_aa_paint);
+ bool PaintContent(const LayerList& update_layer_list);
bool in_paint_layer_contents() const { return in_paint_layer_contents_; }
void SetHasCopyRequest(bool has_copy_request);
@@ -510,6 +516,7 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// position. If a HUD layer exists but is no longer needed, it is destroyed.
void UpdateHudLayer(bool show_hud_info);
HeadsUpDisplayLayer* hud_layer() const { return hud_layer_.get(); }
+ bool is_hud_layer(const Layer*) const;
virtual void SetNeedsFullTreeSync();
bool needs_full_tree_sync() const { return needs_full_tree_sync_; }
@@ -671,6 +678,10 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
// NodeId in |content| and return true, otherwise return false.
bool CaptureContent(std::vector<NodeId>* content);
+ std::unique_ptr<BeginMainFrameMetrics> begin_main_frame_metrics() {
+ return std::move(begin_main_frame_metrics_);
+ }
+
protected:
LayerTreeHost(InitParams params, CompositorMode mode);
@@ -750,8 +761,6 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
bool visible_ = false;
- bool content_has_slow_paths_ = false;
- bool content_has_non_aa_paint_ = false;
bool gpu_rasterization_histogram_recorded_ = false;
// If set, then page scale animation has completed, but the client hasn't been
@@ -773,12 +782,11 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
ViewportPropertyIds viewport_property_ids_;
- float top_controls_height_ = 0.f;
- float top_controls_shown_ratio_ = 0.f;
- bool browser_controls_shrink_blink_size_ = false;
OverscrollBehavior overscroll_behavior_;
- float bottom_controls_height_ = 0.f;
+ BrowserControlsParams browser_controls_params_;
+ float top_controls_shown_ratio_ = 0.f;
+ float bottom_controls_shown_ratio_ = 0.f;
float device_scale_factor_ = 1.f;
float painted_device_scale_factor_ = 1.f;
@@ -803,6 +811,9 @@ class CC_EXPORT LayerTreeHost : public MutatorHostClient {
SkColor background_color_ = SK_ColorWHITE;
+ // Display transform hint to tag generated compositor frames.
+ gfx::OverlayTransform display_transform_hint_ = gfx::OVERLAY_TRANSFORM_NONE;
+
LayerSelection selection_;
gfx::Rect device_viewport_rect_;
diff --git a/chromium/cc/trees/layer_tree_host_client.h b/chromium/cc/trees/layer_tree_host_client.h
index 8cf1a5682a0..b6298911142 100644
--- a/chromium/cc/trees/layer_tree_host_client.h
+++ b/chromium/cc/trees/layer_tree_host_client.h
@@ -41,9 +41,13 @@ struct ApplyViewportChangesArgs {
// subframe compositors to throttle their re-rastering during the gesture.
bool is_pinch_gesture_active;
- // How much the browser controls have been shown or hidden. The ratio runs
+ // How much the top controls have been shown or hidden. The ratio runs
// between 0 (hidden) and 1 (full-shown). This is additive.
- float browser_controls_delta;
+ float top_controls_delta;
+
+ // How much the bottom controls have been shown or hidden. The ratio runs
+ // between 0 (hidden) and 1 (full-shown). This is additive.
+ float bottom_controls_delta;
// Whether the browser controls have been locked to fully hidden or shown or
// whether they can be freely moved.
diff --git a/chromium/cc/trees/layer_tree_host_impl.cc b/chromium/cc/trees/layer_tree_host_impl.cc
index 0dd3041f319..18ae9c1f1af 100644
--- a/chromium/cc/trees/layer_tree_host_impl.cc
+++ b/chromium/cc/trees/layer_tree_host_impl.cc
@@ -313,7 +313,7 @@ LayerTreeHostImpl::LayerTreeHostImpl(
// LTHI always has an active tree.
active_tree_ = std::make_unique<LayerTreeImpl>(
this, new SyncedProperty<ScaleGroup>, new SyncedBrowserControls,
- new SyncedElasticOverscroll);
+ new SyncedBrowserControls, new SyncedElasticOverscroll);
active_tree_->property_trees()->is_active = true;
viewport_ = Viewport::Create(this);
@@ -823,7 +823,7 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingViewport() const {
auto* node = CurrentlyScrollingNode();
if (!node)
return false;
- return node == viewport()->MainScrollNode();
+ return viewport().ShouldScroll(*node);
}
bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt(
@@ -850,12 +850,6 @@ bool LayerTreeHostImpl::IsCurrentlyScrollingLayerAt(
if (scrolling_node == test_scroll_node)
return true;
- // For active scrolling state treat the inner/outer viewports interchangeably.
- if (scrolling_node->scrolls_inner_viewport ||
- scrolling_node->scrolls_outer_viewport) {
- return test_scroll_node == OuterViewportScrollNode();
- }
-
return false;
}
@@ -1697,10 +1691,11 @@ void LayerTreeHostImpl::BlockImplSideInvalidationRequestsForTesting(
void LayerTreeHostImpl::ResetTreesForTesting() {
if (active_tree_)
active_tree_->DetachLayers();
- active_tree_ =
- std::make_unique<LayerTreeImpl>(this, active_tree()->page_scale_factor(),
- active_tree()->top_controls_shown_ratio(),
- active_tree()->elastic_overscroll());
+ active_tree_ = std::make_unique<LayerTreeImpl>(
+ this, active_tree()->page_scale_factor(),
+ active_tree()->top_controls_shown_ratio(),
+ active_tree()->bottom_controls_shown_ratio(),
+ active_tree()->elastic_overscroll());
active_tree_->property_trees()->is_active = true;
active_tree_->property_trees()->clear();
if (pending_tree_)
@@ -1861,6 +1856,21 @@ size_t LayerTreeHostImpl::GetFrameIndexForImage(const PaintImage& paint_image,
paint_image.stable_id(), tree);
}
+int LayerTreeHostImpl::GetMSAASampleCountForRaster(
+ const scoped_refptr<DisplayItemList>& display_list) {
+ constexpr int kMinNumberOfSlowPathsForMSAA = 6;
+ if (display_list->NumSlowPaths() < kMinNumberOfSlowPathsForMSAA)
+ return 0;
+
+ if (!can_use_msaa_)
+ return 0;
+
+ if (display_list->HasNonAAPaint() && !supports_disable_msaa_)
+ return 0;
+
+ return RequestedMSAASampleCount();
+}
+
void LayerTreeHostImpl::NotifyReadyToActivate() {
// The TileManager may call this method while the pending tree is still being
// painted, as it isn't aware of the ongoing paint. We shouldn't tell the
@@ -2058,6 +2068,10 @@ void LayerTreeHostImpl::OnDraw(const gfx::Transform& transform,
// external viewport to be set otherwise.
DCHECK(active_tree_->internal_device_viewport().origin().IsOrigin());
+#if DCHECK_IS_ON()
+ base::AutoReset<bool> reset_sync_draw(&doing_sync_draw_, true);
+#endif
+
if (skip_draw) {
client_->OnDrawForLayerTreeFrameSink(resourceless_software_draw_, true);
return;
@@ -2135,10 +2149,11 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
- metadata.top_controls_height =
- browser_controls_offset_manager_->TopControlsHeight();
- metadata.top_controls_shown_ratio =
- browser_controls_offset_manager_->TopControlsShownRatio();
+ if (browser_controls_offset_manager_->TopControlsHeight() > 0) {
+ metadata.top_controls_visible_height.emplace(
+ browser_controls_offset_manager_->TopControlsHeight() *
+ browser_controls_offset_manager_->TopControlsShownRatio());
+ }
metadata.local_surface_id_allocation_time =
child_local_surface_id_allocator_.GetCurrentLocalSurfaceIdAllocation()
@@ -2150,6 +2165,8 @@ viz::CompositorFrameMetadata LayerTreeHostImpl::MakeCompositorFrameMetadata() {
gfx::ScrollOffsetToVector2dF(active_tree_->TotalScrollOffset());
}
+ metadata.display_transform_hint = active_tree_->display_transform_hint();
+
return metadata;
}
@@ -2184,19 +2201,43 @@ RenderFrameMetadata LayerTreeHostImpl::MakeRenderFrameMetadata(
metadata.min_page_scale_factor = active_tree_->min_page_scale_factor();
metadata.max_page_scale_factor = active_tree_->max_page_scale_factor();
metadata.root_layer_size = active_tree_->ScrollableSize();
- if (const auto* outer_viewport_scroll_node = OuterViewportScrollNode()) {
+ if (InnerViewportScrollNode()) {
+ DCHECK(OuterViewportScrollNode());
metadata.root_overflow_y_hidden =
- !outer_viewport_scroll_node->user_scrollable_vertical;
- }
- const auto* inner_viewport_scroll_node = InnerViewportScrollNode();
- if (inner_viewport_scroll_node) {
- metadata.root_overflow_y_hidden |=
- !inner_viewport_scroll_node->user_scrollable_vertical;
+ !OuterViewportScrollNode()->user_scrollable_vertical ||
+ !InnerViewportScrollNode()->user_scrollable_vertical;
}
metadata.has_transparent_background =
frame->render_passes.back()->has_transparent_background;
#endif
+ if (last_draw_render_frame_metadata_) {
+ const float last_root_scroll_offset_y =
+ last_draw_render_frame_metadata_->root_scroll_offset
+ .value_or(gfx::Vector2dF())
+ .y();
+
+ const float new_root_scroll_offset_y =
+ metadata.root_scroll_offset.value().y();
+
+ if (!MathUtil::IsWithinEpsilon(last_root_scroll_offset_y,
+ new_root_scroll_offset_y)) {
+ viz::VerticalScrollDirection new_vertical_scroll_direction =
+ (last_root_scroll_offset_y < new_root_scroll_offset_y)
+ ? viz::VerticalScrollDirection::kDown
+ : viz::VerticalScrollDirection::kUp;
+
+ // Changes in vertical scroll direction happen instantaneously. This being
+ // the case, a new vertical scroll direction should only be present in the
+ // singular metadata for the render frame in which the direction change
+ // occurred. If the vertical scroll direction detected here matches that
+ // which we've previously cached, then this frame is not the instant in
+ // which the direction change occurred and is therefore not propagated.
+ if (last_vertical_scroll_direction_ != new_vertical_scroll_direction)
+ metadata.new_vertical_scroll_direction = new_vertical_scroll_direction;
+ }
+ }
+
bool allocate_new_local_surface_id =
#if !defined(OS_ANDROID)
last_draw_render_frame_metadata_ &&
@@ -2241,6 +2282,7 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
frame_trackers_.NotifyImplFrameCausedNoDamage(frame->begin_frame_ack);
TRACE_EVENT_INSTANT0("cc", "EarlyOut_NoDamage", TRACE_EVENT_SCOPE_THREAD);
active_tree()->BreakSwapPromises(SwapPromise::SWAP_FAILS);
+ active_tree()->ResetAllChangeTracking();
return false;
}
@@ -2253,6 +2295,21 @@ bool LayerTreeHostImpl::DrawLayers(FrameData* frame) {
std::move(compositor_frame),
/*hit_test_data_changed=*/false, debug_state_.show_hit_test_borders);
+#if DCHECK_IS_ON()
+ if (!doing_sync_draw_) {
+ // The throughput computation (in |FrameSequenceTracker|) depends on the
+ // compositor-frame submission to happen while a BeginFrameArgs is 'active'
+ // (i.e. between calls to WillBeginImplFrame() and DidFinishImplFrame()).
+ // Verify that this is the case.
+ // No begin-frame is available when doing sync draws, so avoid doing this
+ // check in that case.
+ const auto& bfargs = current_begin_frame_tracker_.Current();
+ const auto& ack = compositor_frame.metadata.begin_frame_ack;
+ DCHECK_EQ(bfargs.source_id, ack.source_id);
+ DCHECK_EQ(bfargs.sequence_number, ack.sequence_number);
+ }
+#endif
+
frame_trackers_.NotifySubmitFrame(
compositor_frame.metadata.frame_token, frame->has_missing_content,
frame->begin_frame_ack, frame->origin_begin_main_frame_args);
@@ -2357,6 +2414,17 @@ viz::CompositorFrame LayerTreeHostImpl::GenerateCompositorFrame(
if (render_frame_metadata_observer_) {
last_draw_render_frame_metadata_ = MakeRenderFrameMetadata(frame);
+
+ // We cache the value of any new vertical scroll direction so that we can
+ // accurately determine when the next change in vertical scroll direction
+ // occurs. Note that |kNull| is only used to indicate the absence of a
+ // vertical scroll direction and should therefore be ignored.
+ if (last_draw_render_frame_metadata_->new_vertical_scroll_direction !=
+ viz::VerticalScrollDirection::kNull) {
+ last_vertical_scroll_direction_ =
+ last_draw_render_frame_metadata_->new_vertical_scroll_direction;
+ }
+
render_frame_metadata_observer_->OnRenderFrameSubmission(
*last_draw_render_frame_metadata_, &metadata,
active_tree()->TakeForceSendMetadataRequest());
@@ -2430,20 +2498,6 @@ int LayerTreeHostImpl::RequestedMSAASampleCount() const {
return settings_.gpu_rasterization_msaa_sample_count;
}
-void LayerTreeHostImpl::SetContentHasSlowPaths(bool flag) {
- if (content_has_slow_paths_ != flag) {
- content_has_slow_paths_ = flag;
- need_update_gpu_rasterization_status_ = true;
- }
-}
-
-void LayerTreeHostImpl::SetContentHasNonAAPaint(bool flag) {
- if (content_has_non_aa_paint_ != flag) {
- content_has_non_aa_paint_ = flag;
- need_update_gpu_rasterization_status_ = true;
- }
-}
-
void LayerTreeHostImpl::GetGpuRasterizationCapabilities(
bool* gpu_rasterization_enabled,
bool* gpu_rasterization_supported,
@@ -2534,23 +2588,14 @@ bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() {
&max_msaa_samples, &supports_disable_msaa);
bool use_gpu = false;
- bool use_msaa = false;
- bool using_msaa_for_slow_paths =
- requested_msaa_samples > 0 &&
- max_msaa_samples >= requested_msaa_samples &&
- (!content_has_non_aa_paint_ || supports_disable_msaa);
+ bool can_use_msaa =
+ requested_msaa_samples > 0 && max_msaa_samples >= requested_msaa_samples;
+
if (settings_.gpu_rasterization_forced) {
use_gpu = true;
gpu_rasterization_status_ = GpuRasterizationStatus::ON_FORCED;
- use_msaa = content_has_slow_paths_ && using_msaa_for_slow_paths;
- if (use_msaa) {
- gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT;
- }
} else if (!gpu_rasterization_enabled) {
gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE;
- } else if (content_has_slow_paths_ && using_msaa_for_slow_paths) {
- use_gpu = use_msaa = true;
- gpu_rasterization_status_ = GpuRasterizationStatus::MSAA_CONTENT;
} else {
use_gpu = true;
gpu_rasterization_status_ = GpuRasterizationStatus::ON;
@@ -2562,18 +2607,24 @@ bool LayerTreeHostImpl::UpdateGpuRasterizationStatus() {
// be created due to losing the GL context, force use of software
// raster.
use_gpu = false;
- use_msaa = false;
+ can_use_msaa_ = false;
+ supports_disable_msaa_ = false;
gpu_rasterization_status_ = GpuRasterizationStatus::OFF_DEVICE;
}
}
- if (use_gpu == use_gpu_rasterization_ && use_msaa == use_msaa_)
+ // Changes in MSAA settings require that we re-raster resources for the
+ // settings to take effect. But we don't need to trigger any raster
+ // invalidation in this case since these settings change only if the context
+ // changed. In this case we already re-allocate and re-raster all resources.
+ if (use_gpu == use_gpu_rasterization_ && can_use_msaa == can_use_msaa_ &&
+ supports_disable_msaa == supports_disable_msaa_) {
return false;
+ }
- // Note that this must happen first, in case the rest of the calls want to
- // query the new state of |use_gpu_rasterization_|.
use_gpu_rasterization_ = use_gpu;
- use_msaa_ = use_msaa;
+ can_use_msaa_ = can_use_msaa;
+ supports_disable_msaa_ = supports_disable_msaa;
return true;
}
@@ -2728,9 +2779,6 @@ static void PopulateHitTestRegion(viz::HitTestRegion* hit_test_region,
base::Optional<viz::HitTestRegionList> LayerTreeHostImpl::BuildHitTestData() {
TRACE_EVENT0("cc", "LayerTreeHostImpl::BuildHitTestData");
- if (!settings_.build_hit_test_data)
- return {};
-
base::Optional<viz::HitTestRegionList> hit_test_region_list(base::in_place);
hit_test_region_list->flags = viz::HitTestRegionFlags::kHitTestMine |
viz::HitTestRegionFlags::kHitTestMouse |
@@ -2875,7 +2923,7 @@ bool LayerTreeHostImpl::IsActivelyScrolling() const {
// are actually animating. So assume there are none.
if (settings_.ignore_root_layer_flings && IsCurrentlyScrollingViewport())
return false;
- return did_lock_scrolling_layer_;
+ return true;
}
void LayerTreeHostImpl::CreatePendingTree() {
@@ -2886,6 +2934,7 @@ void LayerTreeHostImpl::CreatePendingTree() {
pending_tree_ = std::make_unique<LayerTreeImpl>(
this, active_tree()->page_scale_factor(),
active_tree()->top_controls_shown_ratio(),
+ active_tree()->bottom_controls_shown_ratio(),
active_tree()->elastic_overscroll());
}
pending_tree_fully_painted_ = false;
@@ -2971,6 +3020,10 @@ void LayerTreeHostImpl::ActivateSyncTree() {
active_tree_->lifecycle().AdvanceTo(LayerTreeLifecycle::kNotSyncing);
+ // The previous scrolling node no longer exists in the new tree.
+ if (!active_tree_->CurrentlyScrollingNode())
+ ClearCurrentlyScrollingNode();
+
// Now that we've synced everything from the pending tree to the active
// tree, rename the pending tree the recycle tree so we can reuse it on the
// next sync.
@@ -3002,8 +3055,8 @@ void LayerTreeHostImpl::ActivateSyncTree() {
if (InnerViewportScrollNode()) {
active_tree_->property_trees()->scroll_tree.ClampScrollToMaxScrollOffset(
InnerViewportScrollNode(), active_tree_.get());
- }
- if (OuterViewportScrollNode()) {
+
+ DCHECK(OuterViewportScrollNode());
active_tree_->property_trees()->scroll_tree.ClampScrollToMaxScrollOffset(
OuterViewportScrollNode(), active_tree_.get());
}
@@ -3236,11 +3289,10 @@ LayerTreeHostImpl::CreateRasterBufferProvider() {
if (use_gpu_rasterization_) {
DCHECK(worker_context_provider);
- int msaa_sample_count = use_msaa_ ? RequestedMSAASampleCount() : 0;
return std::make_unique<GpuRasterBufferProvider>(
compositor_context_provider, worker_context_provider,
settings_.resource_settings.use_gpu_memory_buffer_resources,
- msaa_sample_count, tile_format, settings_.max_gpu_raster_tile_size,
+ tile_format, settings_.max_gpu_raster_tile_size,
settings_.unpremultiply_and_dither_low_bit_depth_tiles,
use_oop_rasterization_);
}
@@ -3280,10 +3332,6 @@ void LayerTreeHostImpl::SetPaintWorkletLayerPainter(
paint_worklet_painter_ = std::move(painter);
}
-ScrollNode* LayerTreeHostImpl::ViewportMainScrollNode() {
- return viewport()->MainScrollNode();
-}
-
void LayerTreeHostImpl::QueueImageDecode(int request_id,
const PaintImage& image) {
TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("cc.debug"),
@@ -3471,9 +3519,9 @@ bool LayerTreeHostImpl::InitializeFrameSink(
use_oop_rasterization_ = false;
}
- // 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.
+ // Since the new context may support GPU raster or be capable of MSAA, update
+ // status here. We don't need to check the return value since we are
+ // recreating all resources already.
SetNeedUpdateGpuRasterizationStatus();
UpdateGpuRasterizationStatus();
@@ -3528,17 +3576,32 @@ float LayerTreeHostImpl::TopControlsHeight() const {
return active_tree_->top_controls_height();
}
+float LayerTreeHostImpl::TopControlsMinHeight() const {
+ return active_tree_->top_controls_min_height();
+}
+
float LayerTreeHostImpl::BottomControlsHeight() const {
return active_tree_->bottom_controls_height();
}
-void LayerTreeHostImpl::SetCurrentBrowserControlsShownRatio(float ratio) {
- if (active_tree_->SetCurrentBrowserControlsShownRatio(ratio))
+float LayerTreeHostImpl::BottomControlsMinHeight() const {
+ return active_tree_->bottom_controls_min_height();
+}
+
+void LayerTreeHostImpl::SetCurrentBrowserControlsShownRatio(
+ float top_ratio,
+ float bottom_ratio) {
+ if (active_tree_->SetCurrentBrowserControlsShownRatio(top_ratio,
+ bottom_ratio))
DidChangeBrowserControlsPosition();
}
-float LayerTreeHostImpl::CurrentBrowserControlsShownRatio() const {
- return active_tree_->CurrentBrowserControlsShownRatio();
+float LayerTreeHostImpl::CurrentTopControlsShownRatio() const {
+ return active_tree_->CurrentTopControlsShownRatio();
+}
+
+float LayerTreeHostImpl::CurrentBottomControlsShownRatio() const {
+ return active_tree_->CurrentBottomControlsShownRatio();
}
void LayerTreeHostImpl::BindToClient(InputHandlerClient* client) {
@@ -3599,13 +3662,13 @@ InputHandler::ScrollStatus LayerTreeHostImpl::TryScroll(
return scroll_status;
}
- // The outer viewport should be scrolled even if it has no scroll extent
+ // The a viewport node should be scrolled even if it has no scroll extent
// since it'll scroll using the Viewport class which will generate browser
// controls movement and overscroll delta.
gfx::ScrollOffset max_scroll_offset =
scroll_tree.MaxScrollOffset(scroll_node->id);
if (max_scroll_offset.x() <= 0 && max_scroll_offset.y() <= 0 &&
- !scroll_node->scrolls_outer_viewport) {
+ !viewport().ShouldScroll(*scroll_node)) {
TRACE_EVENT0("cc",
"LayerImpl::tryScroll: Ignored. Technically scrollable,"
" but has no affordance in either direction.");
@@ -3713,32 +3776,7 @@ ScrollNode* LayerTreeHostImpl::FindScrollNodeForDeviceViewportPoint(
if (!impl_scroll_node)
return nullptr;
- // Blink has a notion of a "root scroller", which is the scroller in a page
- // that is considered to host the main content. Typically this will be the
- // document/LayoutView contents; however, in some situations Blink may choose
- // a sub-scroller (div, iframe) that should scroll with "viewport" behavior.
- // The "root scroller" is the node designated as the outer viewport in CC.
- // See third_party/blink/renderer/core/page/scrolling/README.md for details.
- //
- // "Viewport" scrolling ensures generation of overscroll events, top controls
- // movement, as well as correct multi-viewport panning in pinch-zoom and
- // other scenarios. We use the viewport's outer scroll node to represent the
- // viewport in the scroll chain and apply scroll delta using CC's Viewport
- // class.
- //
- // Scrolling from position: fixed layers will chain directly up to the inner
- // viewport. Whether that should use the outer viewport (and thus the
- // Viewport class) to scroll or not depends on the root scroller scenario
- // because we don't want setting a root scroller to change the scroll chain
- // order. The |prevent_viewport_scrolling_from_inner| bit is used to
- // communicate that context.
- DCHECK(!impl_scroll_node->prevent_viewport_scrolling_from_inner ||
- impl_scroll_node->scrolls_inner_viewport);
- bool should_use_viewport =
- OuterViewportScrollNode() && impl_scroll_node->scrolls_inner_viewport &&
- !impl_scroll_node->prevent_viewport_scrolling_from_inner;
- if (should_use_viewport)
- impl_scroll_node = OuterViewportScrollNode();
+ impl_scroll_node = GetNodeToScroll(impl_scroll_node);
// Ensure that final scroll node scrolls on impl thread (crbug.com/625100)
ScrollStatus status =
@@ -3788,16 +3826,14 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode ScrollBeginImpl",
TRACE_EVENT_SCOPE_THREAD, "isNull",
scrolling_node ? false : true);
- active_tree_->SetCurrentlyScrollingNode(scrolling_node);
// TODO(majidvp): get rid of touch_scrolling_ and set is_direct_manipulation
// in input_handler_proxy instead.
touch_scrolling_ = type == InputHandler::TOUCHSCREEN;
wheel_scrolling_ = type == InputHandler::WHEEL;
middle_click_autoscrolling_ = type == InputHandler::AUTOSCROLL;
scroll_state->set_is_direct_manipulation(touch_scrolling_);
- // Invoke |DistributeScrollDelta| even with zero delta and velocity to ensure
- // scroll customization callbacks are invoked.
- DistributeScrollDelta(scroll_state);
+
+ LatchToScroller(scroll_state, scrolling_node);
// If the CurrentlyScrollingNode doesn't exist after distributing scroll
// delta, no scroller can scroll in the given delta hint direction(s).
@@ -3813,9 +3849,11 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBeginImpl(
// If the viewport is scrolling and it cannot consume any delta hints, the
// scroll event will need to get bubbled if the viewport is for a guest or
// oopif.
- if (active_tree_->CurrentlyScrollingNode() == ViewportMainScrollNode() &&
- !viewport()->CanScroll(*scroll_state)) {
- scroll_status.bubble = true;
+ if (ScrollNode* node = active_tree_->CurrentlyScrollingNode()) {
+ if (viewport().ShouldScroll(*node) &&
+ !viewport().CanScroll(*node, *scroll_state)) {
+ scroll_status.bubble = true;
+ }
}
frame_trackers_.StartSequence(wheel_scrolling_
@@ -3868,6 +3906,9 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
ScrollNode* scrolling_node = nullptr;
bool scroll_on_main_thread = false;
+ // TODO(bokan): This appears Mac-specific - from
+ // https://codereview.chromium.org/2486673008 Suspect it is unnecessary - a
+ // fling should just produce GSUs without an intermediate GSB and GSE.
if (scroll_state->is_in_inertial_phase())
scrolling_node = CurrentlyScrollingNode();
@@ -3908,11 +3949,10 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollBegin(
ElementId current_native_scrolling_element =
scroll_state->data()->current_native_scrolling_element();
- if (current_native_scrolling_element.GetStableId() != 0) {
+ if (current_native_scrolling_element) {
auto& scroll_tree = active_tree_->property_trees()->scroll_tree;
scrolling_node =
scroll_tree.FindNodeFromElementId(current_native_scrolling_element);
- did_lock_scrolling_layer_ = true;
} else {
scrolling_node = FindScrollNodeForDeviceViewportPoint(
device_viewport_point, layer_impl, &scroll_on_main_thread,
@@ -3942,6 +3982,38 @@ bool LayerTreeHostImpl::IsTouchDraggingScrollbar(
type == InputHandler::TOUCHSCREEN;
}
+ScrollNode* LayerTreeHostImpl::GetNodeToScroll(ScrollNode* node) const {
+ // Blink has a notion of a "root scroller", which is the scroller in a page
+ // that is considered to host the main content. Typically this will be the
+ // document/LayoutView contents; however, in some situations Blink may choose
+ // a sub-scroller (div, iframe) that should scroll with "viewport" behavior.
+ // The "root scroller" is the node designated as the outer viewport in CC.
+ // See third_party/blink/renderer/core/page/scrolling/README.md for details.
+ //
+ // "Viewport" scrolling ensures generation of overscroll events, top controls
+ // movement, as well as correct multi-viewport panning in pinch-zoom and
+ // other scenarios. We use the viewport's outer scroll node to represent the
+ // viewport in the scroll chain and apply scroll delta using CC's Viewport
+ // class.
+ //
+ // Scrolling from position: fixed layers will chain directly up to the inner
+ // viewport. Whether that should use the outer viewport (and thus the
+ // Viewport class) to scroll or not depends on the root scroller scenario
+ // because we don't want setting a root scroller to change the scroll chain
+ // order. The |prevent_viewport_scrolling_from_inner| bit is used to
+ // communicate that context.
+ DCHECK(!node->prevent_viewport_scrolling_from_inner ||
+ node->scrolls_inner_viewport);
+
+ if (node->scrolls_inner_viewport &&
+ !node->prevent_viewport_scrolling_from_inner) {
+ DCHECK(OuterViewportScrollNode());
+ return OuterViewportScrollNode();
+ }
+
+ return node;
+}
+
// Initial scroll hit testing can be unreliable in the presence of squashed
// layers. In this case, we fall back to main thread scrolling. This function
// compares |layer_impl| returned from a regular hit test to the layer
@@ -3954,9 +4026,8 @@ bool LayerTreeHostImpl::IsTouchDraggingScrollbar(
// (since they don't scroll with the outer viewport), however, scrolls from the
// fixed layer still chain to the outer viewport. It's also possible for a node
// to have the inner viewport as its ancestor without going through the outer
-// viewport; however, it will still scroll using the viewport(). Hence, this
-// method needs to use the same scroll chaining logic we use in ApplyScroll by
-// looking at Viewport::ShouldScroll.
+// viewport; however, it may still scroll using the viewport(). Hence, this
+// method must use the same scroll chaining logic we use in ApplyScroll.
bool LayerTreeHostImpl::IsInitialScrollHitTestReliable(
LayerImpl* layer_impl,
LayerImpl* first_scrolling_layer_or_scrollbar) {
@@ -3975,13 +4046,7 @@ bool LayerTreeHostImpl::IsInitialScrollHitTestReliable(
for (; scroll_tree.parent(scroll_node);
scroll_node = scroll_tree.parent(scroll_node)) {
if (scroll_node->scrollable) {
- // Ensure we use scroll chaining behavior for the inner viewport node.
- if (scroll_node->scrolls_inner_viewport &&
- !scroll_node->prevent_viewport_scrolling_from_inner) {
- closest_scroll_node = viewport()->MainScrollNode();
- } else {
- closest_scroll_node = scroll_node;
- }
+ closest_scroll_node = GetNodeToScroll(scroll_node);
break;
}
}
@@ -4009,7 +4074,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
InputHandler::ScrollStatus scroll_status;
scroll_status.main_thread_scrolling_reasons =
MainThreadScrollingReason::kNotScrollingOnMain;
- deferred_scroll_end_state_.reset();
+ deferred_scroll_end_ = false;
ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
if (scroll_node) {
@@ -4035,10 +4100,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimatedBegin(
if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
scroll_animating_latched_element_id_ = ElementId();
scroll_animating_overscroll_target_element_id_ = ElementId();
- ScrollStateData scroll_state_end_data;
- scroll_state_end_data.is_ending = true;
- ScrollState scroll_state_end(scroll_state_end_data);
- ScrollEndImpl(&scroll_state_end);
+ ScrollEndImpl();
}
return scroll_status;
}
@@ -4207,9 +4269,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
continue;
}
- bool scrolls_main_viewport_scroll_layer =
- scroll_node == viewport()->MainScrollNode();
- if (scrolls_main_viewport_scroll_layer) {
+ if (viewport().ShouldScroll(*scroll_node)) {
// Flash the overlay scrollbar even if the scroll dalta is 0.
if (settings_.scrollbar_flash_after_any_scroll_update) {
FlashAllScrollbars(false);
@@ -4219,9 +4279,11 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
if (animation_controller)
animation_controller->WillUpdateScroll();
}
+ }
+ if (scroll_node->scrolls_outer_viewport) {
gfx::Vector2dF scrolled =
- viewport()->ScrollAnimated(pending_delta, delayed_by);
+ viewport().ScrollAnimated(pending_delta, delayed_by);
// Viewport::ScrollAnimated returns pending_delta as long as it starts
// an animation.
did_scroll_x_for_scroll_gesture_ |= scrolled.x() != 0;
@@ -4285,8 +4347,7 @@ InputHandler::ScrollStatus LayerTreeHostImpl::ScrollAnimated(
client_->SetNeedsCommitOnImplThread();
}
- scroll_state.set_is_ending(true);
- ScrollEndImpl(&scroll_state);
+ ScrollEndImpl();
if (scroll_status.thread == SCROLL_ON_IMPL_THREAD) {
// Update scroll_status.thread to SCROLL_IGNORED when there is no ongoing
// scroll animation, we can scroll on impl thread and yet, we couldn't
@@ -4362,6 +4423,10 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta(
return gfx::Vector2dF();
}
+ bool scrolls_outer_viewport = scroll_node->scrolls_outer_viewport;
+ TRACE_EVENT2("cc", "ScrollNodeWithViewportSpaceDelta", "delta_y",
+ local_scroll_delta.y(), "is_outer", scrolls_outer_viewport);
+
// Apply the scroll delta.
gfx::ScrollOffset previous_offset =
scroll_tree->current_scroll_offset(scroll_node->element_id);
@@ -4370,6 +4435,9 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollNodeWithViewportSpaceDelta(
scroll_tree->current_scroll_offset(scroll_node->element_id) -
previous_offset;
+ TRACE_EVENT_INSTANT1("cc", "ConsumedDelta", TRACE_EVENT_SCOPE_THREAD, "y",
+ scrolled.y());
+
// Get the end point in the layer's content space so we can apply its
// ScreenSpaceTransform.
gfx::PointF actual_local_end_point =
@@ -4397,6 +4465,10 @@ static gfx::Vector2dF ScrollNodeWithLocalDelta(
const gfx::Vector2dF& local_delta,
float page_scale_factor,
LayerTreeImpl* layer_tree_impl) {
+ bool scrolls_outer_viewport = scroll_node->scrolls_outer_viewport;
+ TRACE_EVENT2("cc", "ScrollNodeWithLocalDelta", "delta_y", local_delta.y(),
+ "is_outer", scrolls_outer_viewport);
+
ScrollTree& scroll_tree = layer_tree_impl->property_trees()->scroll_tree;
gfx::ScrollOffset previous_offset =
scroll_tree.current_scroll_offset(scroll_node->element_id);
@@ -4408,6 +4480,8 @@ static gfx::Vector2dF ScrollNodeWithLocalDelta(
previous_offset;
gfx::Vector2dF consumed_scroll(scrolled.x(), scrolled.y());
consumed_scroll.Scale(page_scale_factor);
+ TRACE_EVENT_INSTANT1("cc", "ConsumedDelta", TRACE_EVENT_SCOPE_THREAD, "y",
+ consumed_scroll.y());
return consumed_scroll;
}
@@ -4440,38 +4514,39 @@ gfx::Vector2dF LayerTreeHostImpl::ScrollSingleNode(
active_tree());
}
-void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node,
- ScrollState* scroll_state) {
- DCHECK(scroll_node && scroll_state);
+void LayerTreeHostImpl::ScrollLatchedScroller(ScrollState* scroll_state) {
+ DCHECK(CurrentlyScrollingNode() && scroll_state);
+ ScrollNode* scroll_node = CurrentlyScrollingNode();
gfx::Point viewport_point(scroll_state->position_x(),
scroll_state->position_y());
const gfx::Vector2dF delta(scroll_state->delta_x(), scroll_state->delta_y());
+ TRACE_EVENT2("cc", "LayerTreeHostImpl::ScrollLatchedScroller", "delta_x",
+ delta.x(), "delta_y", 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;
- if (viewport()->ShouldScroll(*scroll_node)) {
- // |scroll_outer_vieiwport| will only ever be false if the scroll chains up
- // to the viewport without going through the outer viewport scroll node.
+ if (viewport().ShouldScroll(*scroll_node)) {
+ // |scrolls_outer_vieiwport| will only ever be false if the scroll chains
+ // up to the viewport without going through the outer viewport scroll node.
// This is because we normally terminate the scroll chain at the outer
// viewport node. For example, if we start scrolling from an element
// that's not a descendant of the root scroller. In these cases we want to
// scroll *only* the inner viewport -- to allow panning while zoomed -- but
// still use Viewport::ScrollBy to also move browser controls if needed.
- bool scroll_outer_viewport = scroll_node->scrolls_outer_viewport;
- Viewport::ScrollResult result = viewport()->ScrollBy(
+ Viewport::ScrollResult result = viewport().ScrollBy(
delta, viewport_point, scroll_state->is_direct_manipulation(),
- !wheel_scrolling_, scroll_outer_viewport);
+ !wheel_scrolling_, scroll_node->scrolls_outer_viewport);
applied_delta = result.consumed_delta;
delta_applied_to_content = result.content_scrolled_delta;
} else {
- applied_delta = ScrollSingleNode(
- scroll_node, delta, viewport_point,
- scroll_state->is_direct_manipulation(),
- &scroll_state->layer_tree_impl()->property_trees()->scroll_tree);
+ applied_delta =
+ ScrollSingleNode(scroll_node, delta, viewport_point,
+ scroll_state->is_direct_manipulation(),
+ &active_tree_->property_trees()->scroll_tree);
}
// If the layer wasn't able to move, try the next one in the hierarchy.
@@ -4486,7 +4561,7 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node,
return;
}
- if (!viewport()->ShouldScroll(*scroll_node)) {
+ if (!viewport().ShouldScroll(*scroll_node)) {
// 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.
@@ -4510,45 +4585,38 @@ void LayerTreeHostImpl::ApplyScroll(ScrollNode* scroll_node,
scroll_state->set_current_native_scrolling_node(scroll_node);
}
-void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) {
- // TODO(majidvp): in Blink we compute scroll chain only at scroll begin which
- // is not the case here. We eventually want to have the same behaviour on both
- // sides but it may become a non issue if we get rid of scroll chaining (see
- // crbug.com/526462)
+void LayerTreeHostImpl::LatchToScroller(ScrollState* scroll_state,
+ ScrollNode* starting_node) {
std::list<ScrollNode*> current_scroll_chain;
ScrollTree& scroll_tree = active_tree_->property_trees()->scroll_tree;
- ScrollNode* scroll_node = scroll_tree.CurrentlyScrollingNode();
- ScrollNode* viewport_scroll_node = ViewportMainScrollNode();
- if (did_lock_scrolling_layer_) {
- DCHECK(scroll_node);
+ ScrollNode* scroll_node = nullptr;
+ if (scroll_state->data()->current_native_scrolling_element()) {
+ DCHECK(starting_node);
+ DCHECK_EQ(starting_node->element_id,
+ scroll_state->data()->current_native_scrolling_element());
// Needed for non-animated scrolls.
- current_scroll_chain.push_front(scroll_node);
- } else 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 == 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_scroll_node);
- current_scroll_chain.push_front(viewport_scroll_node);
+ scroll_node = starting_node;
+ } else {
+ for (ScrollNode* cur_node = starting_node; cur_node;
+ cur_node = scroll_tree.parent(cur_node)) {
+ if (viewport().ShouldScroll(*cur_node)) {
+ // Don't chain scrolls past a viewport node. Once we reach that, we
+ // should scroll using the appropriate viewport node which may not be
+ // |cur_node|.
+ scroll_node = GetNodeToScroll(cur_node);
break;
}
- if (!scroll_node->scrollable)
+ if (!cur_node->scrollable)
continue;
- if (middle_click_autoscrolling_) {
- current_scroll_chain.push_front(scroll_node);
+ if (middle_click_autoscrolling_ ||
+ CanConsumeDelta(*cur_node, *scroll_state)) {
+ scroll_node = cur_node;
break;
}
- if (CanConsumeDelta(*scroll_node, *scroll_state))
- current_scroll_chain.push_front(scroll_node);
-
float delta_x = scroll_state->is_beginning()
? scroll_state->delta_x_hint()
: scroll_state->delta_x();
@@ -4556,28 +4624,23 @@ void LayerTreeHostImpl::DistributeScrollDelta(ScrollState* scroll_state) {
? scroll_state->delta_y_hint()
: scroll_state->delta_y();
- if (!CanPropagate(scroll_node, delta_x, delta_y)) {
- // We should add the first node with non-auto overscroll-behavior to
- // the scroll chain regardlessly, as it's the only node we can latch to.
- if (current_scroll_chain.empty() ||
- current_scroll_chain.front() != scroll_node) {
- current_scroll_chain.push_front(scroll_node);
- }
+ if (!CanPropagate(cur_node, delta_x, delta_y)) {
+ // If we reach a node with non-auto overscroll-behavior and we still
+ // haven't latched, we must latch to it. Consider a fully scrolled node
+ // with non-auto overscroll-behavior: we are not allowed to further
+ // chain scroll delta passed to it in the current direction but if we
+ // reverse direction we should scroll it so we must be latched to it.
+ scroll_node = cur_node;
scroll_state->set_is_scroll_chain_cut(true);
break;
}
}
}
- scroll_node =
- current_scroll_chain.empty() ? nullptr : current_scroll_chain.back();
- TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode DistributeScrollDelta",
+ TRACE_EVENT_INSTANT1("cc", "SetCurrentlyScrollingNode LatchToScroller",
TRACE_EVENT_SCOPE_THREAD, "isNull",
scroll_node ? false : true);
active_tree_->SetCurrentlyScrollingNode(scroll_node);
- scroll_state->set_scroll_chain_and_layer_tree(current_scroll_chain,
- active_tree());
- scroll_state->DistributeToScrollChainDescendant();
}
bool LayerTreeHostImpl::CanConsumeDelta(const ScrollNode& scroll_node,
@@ -4671,12 +4734,10 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
float initial_top_controls_offset =
browser_controls_offset_manager_->ControlsTopOffset();
- scroll_state->set_delta_consumed_for_scroll_sequence(
- did_lock_scrolling_layer_);
scroll_state->set_is_direct_manipulation(touch_scrolling_);
scroll_state->set_current_native_scrolling_node(scroll_node);
- DistributeScrollDelta(scroll_state);
+ ScrollLatchedScroller(scroll_state);
ScrollNode* current_scrolling_node =
scroll_state->current_native_scrolling_node();
@@ -4684,8 +4745,6 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
TRACE_EVENT_SCOPE_THREAD, "isNull",
current_scrolling_node ? false : true);
active_tree_->SetCurrentlyScrollingNode(current_scrolling_node);
- did_lock_scrolling_layer_ =
- scroll_state->delta_consumed_for_scroll_sequence();
bool did_scroll_x = scroll_state->caused_scroll_x();
bool did_scroll_y = scroll_state->caused_scroll_y();
@@ -4712,7 +4771,7 @@ InputHandlerScrollResult LayerTreeHostImpl::ScrollBy(
gfx::Vector2dF unused_root_delta;
if (current_scrolling_node &&
- current_scrolling_node == ViewportMainScrollNode()) {
+ viewport().ShouldScroll(*current_scrolling_node)) {
unused_root_delta =
gfx::Vector2dF(scroll_state->delta_x(), scroll_state->delta_y());
}
@@ -4779,15 +4838,15 @@ void LayerTreeHostImpl::SetSynchronousInputHandlerRootScrollOffset(
"offset_x", root_content_offset.x(), "offset_y", root_content_offset.y());
gfx::Vector2dF physical_delta = ContentToPhysical(
- root_content_offset.DeltaFrom(viewport()->TotalScrollOffset()),
+ root_content_offset.DeltaFrom(viewport().TotalScrollOffset()),
active_tree()->page_scale_factor_for_scroll());
bool changed = !viewport()
- ->ScrollBy(physical_delta,
- /*viewport_point=*/gfx::Point(),
- /*is_direct_manipulation=*/false,
- /*affect_browser_controls=*/false,
- /*scroll_outer_viewport=*/true)
+ .ScrollBy(physical_delta,
+ /*viewport_point=*/gfx::Point(),
+ /*is_direct_manipulation=*/false,
+ /*affect_browser_controls=*/false,
+ /*scroll_outer_viewport=*/true)
.consumed_delta.IsZero();
if (!changed)
return;
@@ -4806,7 +4865,6 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
if (!scroll_node || !scroll_node->snap_container_data.has_value())
return false;
- const SnapContainerData& data = scroll_node->snap_container_data.value();
gfx::ScrollOffset current_position = GetVisualScrollOffset(*scroll_node);
std::unique_ptr<SnapSelectionStrategy> strategy =
@@ -4814,16 +4872,10 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
current_position, did_scroll_x_for_scroll_gesture_,
did_scroll_y_for_scroll_gesture_);
gfx::ScrollOffset snap_position;
- if (!data.FindSnapPosition(*strategy, &snap_position))
+ if (!FindSnapPositionAndSetTarget(scroll_node, *strategy, &snap_position))
return false;
- gfx::Vector2dF delta =
- ScrollOffsetToVector2dF(snap_position - current_position);
- bool scrolls_main_viewport_scroll_layer =
- scroll_node == ViewportMainScrollNode();
-
- bool did_animate = false;
- if (scrolls_main_viewport_scroll_layer) {
+ if (viewport().ShouldScroll(*scroll_node)) {
// Flash the overlay scrollbar even if the scroll dalta is 0.
if (settings_.scrollbar_flash_after_any_scroll_update) {
FlashAllScrollbars(false);
@@ -4833,10 +4885,16 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
if (animation_controller)
animation_controller->WillUpdateScroll();
}
+ }
+
+ gfx::Vector2dF delta =
+ ScrollOffsetToVector2dF(snap_position - current_position);
+ bool did_animate = false;
+ if (scroll_node->scrolls_outer_viewport) {
gfx::Vector2dF scaled_delta(delta);
scaled_delta.Scale(active_tree()->page_scale_factor_for_scroll());
gfx::Vector2dF consumed_delta =
- viewport()->ScrollAnimated(scaled_delta, base::TimeDelta());
+ viewport().ScrollAnimated(scaled_delta, base::TimeDelta());
did_animate = !consumed_delta.IsZero();
} else {
did_animate = ScrollAnimationCreate(scroll_node, delta, base::TimeDelta());
@@ -4846,23 +4904,42 @@ bool LayerTreeHostImpl::SnapAtScrollEnd() {
return did_animate;
}
+bool LayerTreeHostImpl::FindSnapPositionAndSetTarget(
+ ScrollNode* scroll_node,
+ const SnapSelectionStrategy& strategy,
+ gfx::ScrollOffset* snap_position) const {
+ SnapContainerData& data = scroll_node->snap_container_data.value();
+
+ TargetSnapAreaElementIds snap_targets;
+ bool did_find_target =
+ data.FindSnapPosition(strategy, snap_position, &snap_targets);
+
+ // Even if a target was not found we still need to invalidate the target snap
+ // area element ids.
+ if (data.SetTargetSnapAreaElementIds(
+ did_find_target ? snap_targets : TargetSnapAreaElementIds())) {
+ client_->SetNeedsCommitOnImplThread();
+ }
+
+ return did_find_target;
+}
+
gfx::ScrollOffset LayerTreeHostImpl::GetVisualScrollOffset(
const ScrollNode& scroll_node) const {
- if (&scroll_node == viewport()->MainScrollNode())
- return viewport()->TotalScrollOffset();
+ if (scroll_node.scrolls_outer_viewport)
+ return viewport().TotalScrollOffset();
return active_tree()->property_trees()->scroll_tree.current_scroll_offset(
scroll_node.element_id);
}
-bool LayerTreeHostImpl::GetSnapFlingInfo(
+bool LayerTreeHostImpl::GetSnapFlingInfoAndSetSnapTarget(
const gfx::Vector2dF& natural_displacement_in_viewport,
gfx::Vector2dF* out_initial_position,
- gfx::Vector2dF* out_target_position) const {
- const ScrollNode* scroll_node = CurrentlyScrollingNode();
+ gfx::Vector2dF* out_target_position) {
+ ScrollNode* scroll_node = CurrentlyScrollingNode();
if (!scroll_node || !scroll_node->snap_container_data.has_value())
return false;
- const SnapContainerData& data = scroll_node->snap_container_data.value();
float scale_factor = active_tree()->page_scale_factor_for_scroll();
gfx::Vector2dF natural_displacement_in_content =
gfx::ScaleVector2d(natural_displacement_in_viewport, 1.f / scale_factor);
@@ -4874,7 +4951,7 @@ bool LayerTreeHostImpl::GetSnapFlingInfo(
std::unique_ptr<SnapSelectionStrategy> strategy =
SnapSelectionStrategy::CreateForEndAndDirection(
current_offset, gfx::ScrollOffset(natural_displacement_in_content));
- if (!data.FindSnapPosition(*strategy, &snap_offset))
+ if (!FindSnapPositionAndSetTarget(scroll_node, *strategy, &snap_offset))
return false;
*out_target_position = ScrollOffsetToVector2dF(snap_offset);
@@ -4886,7 +4963,6 @@ bool LayerTreeHostImpl::GetSnapFlingInfo(
void LayerTreeHostImpl::ClearCurrentlyScrollingNode() {
TRACE_EVENT0("cc", "LayerTreeHostImpl::ClearCurrentlyScrollingNode");
active_tree_->ClearCurrentlyScrollingNode();
- did_lock_scrolling_layer_ = false;
scroll_affects_scroll_handler_ = false;
accumulated_root_overscroll_ = gfx::Vector2dF();
did_scroll_x_for_scroll_gesture_ = false;
@@ -4894,10 +4970,7 @@ void LayerTreeHostImpl::ClearCurrentlyScrollingNode() {
is_animating_for_snap_ = false;
}
-void LayerTreeHostImpl::ScrollEndImpl(ScrollState* scroll_state) {
- DCHECK(scroll_state);
- DCHECK(scroll_state->delta_x() == 0 && scroll_state->delta_y() == 0);
-
+void LayerTreeHostImpl::ScrollEndImpl() {
// In smooth-scrolling path when the GSE arrives after scroll animation
// completion, CurrentlyScrollingNode() is already cleared due to
// ScrollEndImpl call inside ScrollOffsetAnimationFinished. In this case
@@ -4906,7 +4979,6 @@ void LayerTreeHostImpl::ScrollEndImpl(ScrollState* scroll_state) {
if (!last_scroller_element_id_ && CurrentlyScrollingNode())
last_scroller_element_id_ = CurrentlyScrollingNode()->element_id;
- DistributeScrollDelta(scroll_state);
browser_controls_offset_manager_->ScrollEnd();
ClearCurrentlyScrollingNode();
frame_trackers_.StopSequence(wheel_scrolling_
@@ -4914,15 +4986,15 @@ void LayerTreeHostImpl::ScrollEndImpl(ScrollState* scroll_state) {
: FrameSequenceTrackerType::kTouchScroll);
}
-void LayerTreeHostImpl::ScrollEnd(ScrollState* scroll_state, bool should_snap) {
+void LayerTreeHostImpl::ScrollEnd(bool should_snap) {
if ((should_snap && SnapAtScrollEnd()) ||
mutator_host_->IsImplOnlyScrollAnimating()) {
- DCHECK(!deferred_scroll_end_state_.has_value());
- deferred_scroll_end_state_ = *scroll_state;
+ DCHECK(!deferred_scroll_end_);
+ deferred_scroll_end_ = true;
return;
}
- ScrollEndImpl(scroll_state);
- deferred_scroll_end_state_.reset();
+ ScrollEndImpl();
+ deferred_scroll_end_ = false;
scroll_gesture_did_end_ = true;
client_->SetNeedsCommitOnImplThread();
}
@@ -5003,9 +5075,11 @@ InputHandlerPointerResult LayerTreeHostImpl::MouseMoveAt(
scroll_element_id = scroll_node->element_id;
// Scrollbars for the viewport are registered with the outer viewport layer.
- if (InnerViewportScrollNode() && OuterViewportScrollNode() &&
- scroll_element_id == InnerViewportScrollNode()->element_id)
+ if (InnerViewportScrollNode() &&
+ scroll_element_id == InnerViewportScrollNode()->element_id) {
+ DCHECK(OuterViewportScrollNode());
scroll_element_id = OuterViewportScrollNode()->element_id;
+ }
}
ScrollbarAnimationController* new_animation_controller =
@@ -5058,7 +5132,7 @@ void LayerTreeHostImpl::PinchGestureUpdate(float magnify_delta,
if (!InnerViewportScrollNode())
return;
has_pinch_zoomed_ = true;
- viewport()->PinchUpdate(magnify_delta, anchor);
+ viewport().PinchUpdate(magnify_delta, anchor);
client_->SetNeedsCommitOnImplThread();
SetNeedsRedraw();
client_->RenewTreePriority();
@@ -5074,7 +5148,7 @@ void LayerTreeHostImpl::PinchGestureEnd(const gfx::Point& anchor,
pinch_gesture_end_should_clear_scrolling_node_ = false;
ClearCurrentlyScrollingNode();
}
- viewport()->PinchEnd(anchor, snap_to_min);
+ viewport().PinchEnd(anchor, snap_to_min);
browser_controls_offset_manager_->PinchEnd();
client_->SetNeedsCommitOnImplThread();
// When a pinch ends, we may be displaying content cached at incorrect scales,
@@ -5123,6 +5197,8 @@ std::unique_ptr<ScrollAndScaleSet> LayerTreeHostImpl::ProcessScrollDeltas() {
scroll_info->page_scale_delta == 1.f);
scroll_info->top_controls_delta =
active_tree()->top_controls_shown_ratio()->PullDeltaForMainThread();
+ scroll_info->bottom_controls_delta =
+ active_tree()->bottom_controls_shown_ratio()->PullDeltaForMainThread();
scroll_info->elastic_overscroll_delta =
active_tree_->elastic_overscroll()->PullDeltaForMainThread();
scroll_info->swap_promises.swap(swap_promises_for_main_thread_scroll_update_);
@@ -5207,8 +5283,7 @@ bool LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) {
gfx::ScrollOffset next_scroll = gfx::ScrollOffset(
page_scale_animation_->ScrollOffsetAtTime(monotonic_time));
- DCHECK(viewport());
- viewport()->ScrollByInnerFirst(next_scroll.DeltaFrom(scroll_total));
+ viewport().ScrollByInnerFirst(next_scroll.DeltaFrom(scroll_total));
if (page_scale_animation_->IsAnimationCompleteAtTime(monotonic_time)) {
page_scale_animation_ = nullptr;
@@ -5222,12 +5297,12 @@ bool LayerTreeHostImpl::AnimatePageScale(base::TimeTicks monotonic_time) {
}
bool LayerTreeHostImpl::AnimateBrowserControls(base::TimeTicks time) {
- if (!browser_controls_offset_manager_->has_animation())
+ if (!browser_controls_offset_manager_->HasAnimation())
return false;
gfx::Vector2dF scroll_delta = browser_controls_offset_manager_->Animate(time);
- if (browser_controls_offset_manager_->has_animation())
+ if (browser_controls_offset_manager_->HasAnimation())
SetNeedsOneBeginImplFrame();
if (active_tree_->TotalScrollOffset().y() == 0.f)
@@ -5236,12 +5311,11 @@ bool LayerTreeHostImpl::AnimateBrowserControls(base::TimeTicks time) {
if (scroll_delta.IsZero())
return false;
- DCHECK(viewport());
- viewport()->ScrollBy(scroll_delta,
- /*viewport_point=*/gfx::Point(),
- /*is_wheel_scroll=*/false,
- /*affect_browser_controls=*/false,
- /*scroll_outer_viewport=*/true);
+ viewport().ScrollBy(scroll_delta,
+ /*viewport_point=*/gfx::Point(),
+ /*is_wheel_scroll=*/false,
+ /*affect_browser_controls=*/false,
+ /*scroll_outer_viewport=*/true);
client_->SetNeedsCommitOnImplThread();
client_->RenewTreePriority();
return true;
@@ -5320,9 +5394,10 @@ void LayerTreeHostImpl::RegisterScrollbarAnimationController(
scrollbar_opacity);
}
-void LayerTreeHostImpl::UnregisterScrollbarAnimationController(
+void LayerTreeHostImpl::DidUnregisterScrollbarLayer(
ElementId scroll_element_id) {
scrollbar_animation_controllers_.erase(scroll_element_id);
+ scrollbar_controller_->DidUnregisterScrollbar(scroll_element_id);
}
ScrollbarAnimationController*
@@ -5331,7 +5406,8 @@ LayerTreeHostImpl::ScrollbarAnimationControllerForElementId(
// The viewport layers have only one set of scrollbars. On Android, these are
// registered with the inner viewport, otherwise they're registered with the
// outer viewport. If a controller for one exists, the other shouldn't.
- if (InnerViewportScrollNode() && OuterViewportScrollNode()) {
+ if (InnerViewportScrollNode()) {
+ DCHECK(OuterViewportScrollNode());
if (scroll_element_id == InnerViewportScrollNode()->element_id ||
scroll_element_id == OuterViewportScrollNode()->element_id) {
auto itr = scrollbar_animation_controllers_.find(
@@ -6020,15 +6096,12 @@ void LayerTreeHostImpl::ScrollOffsetAnimationFinished() {
// Call scrollEnd with the deferred scroll end state when the scroll animation
// completes after GSE arrival.
- if (deferred_scroll_end_state_.has_value()) {
- ScrollEnd(&deferred_scroll_end_state_.value(), false);
+ if (deferred_scroll_end_) {
+ ScrollEnd(/*should_snap=*/false);
return;
}
- // TODO(majidvp): We should pass in the original starting scroll position here
- ScrollStateData scroll_state_data;
- ScrollState scroll_state(scroll_state_data);
- ScrollEndImpl(&scroll_state);
+ ScrollEndImpl();
}
void LayerTreeHostImpl::NotifyAnimationWorkletStateChange(
@@ -6130,6 +6203,7 @@ void LayerTreeHostImpl::InitializeUkm(
std::unique_ptr<ukm::UkmRecorder> recorder) {
DCHECK(!ukm_manager_);
ukm_manager_ = std::make_unique<UkmManager>(std::move(recorder));
+ frame_trackers_.SetUkmManager(ukm_manager_.get());
}
void LayerTreeHostImpl::SetActiveURL(const GURL& url, ukm::SourceId source_id) {
diff --git a/chromium/cc/trees/layer_tree_host_impl.h b/chromium/cc/trees/layer_tree_host_impl.h
index 4242cd1e415..930a307f785 100644
--- a/chromium/cc/trees/layer_tree_host_impl.h
+++ b/chromium/cc/trees/layer_tree_host_impl.h
@@ -106,7 +106,6 @@ enum class GpuRasterizationStatus {
ON,
ON_FORCED,
OFF_DEVICE,
- MSAA_CONTENT,
};
enum class ImplThreadPhase {
@@ -271,12 +270,11 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
const gfx::Point& viewport_point,
const gfx::Vector2dF& scroll_delta,
base::TimeDelta delayed_by = base::TimeDelta()) override;
- void ApplyScroll(ScrollNode* scroll_node, ScrollState* scroll_state);
InputHandlerScrollResult ScrollBy(ScrollState* scroll_state) override;
void RequestUpdateForSynchronousInputHandler() override;
void SetSynchronousInputHandlerRootScrollOffset(
const gfx::ScrollOffset& root_content_offset) override;
- void ScrollEnd(ScrollState* scroll_state, bool should_snap = false) override;
+ void ScrollEnd(bool should_snap = false) override;
InputHandlerPointerResult MouseDown(const gfx::PointF& viewport_point,
bool shift_modifier) override;
@@ -316,9 +314,13 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// BrowserControlsOffsetManagerClient implementation.
float TopControlsHeight() const override;
+ float TopControlsMinHeight() const override;
float BottomControlsHeight() const override;
- void SetCurrentBrowserControlsShownRatio(float offset) override;
- float CurrentBrowserControlsShownRatio() const override;
+ float BottomControlsMinHeight() const override;
+ void SetCurrentBrowserControlsShownRatio(float top_ratio,
+ float bottom_ratio) override;
+ float CurrentTopControlsShownRatio() const override;
+ float CurrentBottomControlsShownRatio() const override;
void DidChangeBrowserControlsPosition() override;
bool HaveRootScrollNode() const override;
void SetNeedsCommit() override;
@@ -448,7 +450,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
void RegisterScrollbarAnimationController(ElementId scroll_element_id,
float initial_opacity);
- void UnregisterScrollbarAnimationController(ElementId scroll_element_id);
+ void DidUnregisterScrollbarLayer(ElementId scroll_element_id);
ScrollbarAnimationController* ScrollbarAnimationControllerForElementId(
ElementId scroll_element_id) const;
void FlashAllScrollbars(bool did_scroll);
@@ -472,6 +474,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
void RequestImplSideInvalidationForCheckerImagedTiles() override;
size_t GetFrameIndexForImage(const PaintImage& paint_image,
WhichTree tree) const override;
+ int GetMSAASampleCountForRaster(
+ const scoped_refptr<DisplayItemList>& display_list) override;
// ScrollbarAnimationControllerClient implementation.
void PostDelayedScrollbarAnimationTask(base::OnceClosure task,
@@ -522,15 +526,12 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
virtual bool InitializeFrameSink(LayerTreeFrameSink* layer_tree_frame_sink);
TileManager* tile_manager() { return &tile_manager_; }
- void SetContentHasSlowPaths(bool flag);
- void SetContentHasNonAAPaint(bool flag);
void GetGpuRasterizationCapabilities(bool* gpu_rasterization_enabled,
bool* gpu_rasterization_supported,
int* max_msaa_samples,
bool* supports_disable_msaa);
bool use_gpu_rasterization() const { return use_gpu_rasterization_; }
bool use_oop_rasterization() const { return use_oop_rasterization_; }
- bool use_msaa() const { return use_msaa_; }
GpuRasterizationStatus gpu_rasterization_status() const {
return gpu_rasterization_status_;
@@ -678,9 +679,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// visual and layout offsets of the viewport.
gfx::ScrollOffset GetVisualScrollOffset(const ScrollNode& scroll_node) const;
- bool GetSnapFlingInfo(const gfx::Vector2dF& natural_displacement_in_viewport,
- gfx::Vector2dF* out_initial_position,
- gfx::Vector2dF* out_target_position) const override;
+ bool GetSnapFlingInfoAndSetSnapTarget(
+ const gfx::Vector2dF& natural_displacement_in_viewport,
+ gfx::Vector2dF* out_initial_position,
+ gfx::Vector2dF* out_target_position) override;
// Returns the amount of delta that can be applied to scroll_node, taking
// page scale into account.
@@ -763,13 +765,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
return paint_worklet_painter_.get();
}
- // The viewport has two scroll nodes, corresponding to the visual and layout
- // viewports. However, when we compute the scroll chain we include only one
- // of these -- we call that the "main" scroll node. When scrolling it, we
- // scroll using the Viewport class which knows how to distribute scroll
- // between the two.
- ScrollNode* ViewportMainScrollNode();
-
void QueueImageDecode(int request_id, const PaintImage& image);
std::vector<std::pair<int, bool>> TakeCompletedImageDecodeRequests();
@@ -804,6 +799,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
return paint_worklet_tracker_;
}
+ bool can_use_msaa() const { return can_use_msaa_; }
+
protected:
LayerTreeHostImpl(
const LayerTreeSettings& settings,
@@ -842,6 +839,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
void CollectScrollDeltas(ScrollAndScaleSet* scroll_info) const;
void CollectScrollbarUpdates(ScrollAndScaleSet* scroll_info) const;
+ // Returns the ScrollNode we should use to scroll, accounting for viewport
+ // scroll chaining rules.
+ ScrollNode* GetNodeToScroll(ScrollNode* node) const;
+
// Transforms viewport start point and scroll delta to local start point and
// local delta, respectively. If the transformation of either the start or end
// point of a scroll is clipped, the function returns false.
@@ -891,7 +892,7 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
bool UpdateGpuRasterizationStatus();
void UpdateTreeResourcesForGpuRasterizationIfNeeded();
- Viewport* viewport() const { return viewport_.get(); }
+ Viewport& viewport() const { return *viewport_.get(); }
InputHandler::ScrollStatus ScrollBeginImpl(
ScrollState* scroll_state,
@@ -903,7 +904,8 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
bool IsInitialScrollHitTestReliable(
LayerImpl* layer,
LayerImpl* first_scrolling_layer_or_drawn_scrollbar);
- void DistributeScrollDelta(ScrollState* scroll_state);
+ void LatchToScroller(ScrollState* scroll_state, ScrollNode* starting_node);
+ void ScrollLatchedScroller(ScrollState* scroll_state);
bool AnimatePageScale(base::TimeTicks monotonic_time);
bool AnimateScrollbars(base::TimeTicks monotonic_time);
@@ -956,12 +958,19 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
const gfx::Vector2dF& scroll_delta,
base::TimeDelta delayed_by);
- void ScrollEndImpl(ScrollState* scroll_state);
+ void ScrollEndImpl();
// Creates an animation curve and returns true if we need to update the
// scroll position to a snap point. Otherwise returns false.
bool SnapAtScrollEnd();
+ // Returns true if a target snap position was found.
+ // Updates the scrolling node's snap container data's target snap points
+ // accordingly to the found target.
+ bool FindSnapPositionAndSetTarget(ScrollNode* scroll_node,
+ const SnapSelectionStrategy& strategy,
+ gfx::ScrollOffset* snap_position) const;
+
void SetContextVisibility(bool is_visible);
void ImageDecodeFinished(int request_id, bool decode_succeeded);
@@ -1035,12 +1044,12 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
std::unique_ptr<viz::ContextCacheController::ScopedVisibility>
worker_context_visibility_;
+ bool can_use_msaa_ = false;
+ bool supports_disable_msaa_ = false;
+
bool need_update_gpu_rasterization_status_ = false;
- bool content_has_slow_paths_ = false;
- bool content_has_non_aa_paint_ = false;
bool use_gpu_rasterization_ = false;
bool use_oop_rasterization_ = false;
- bool use_msaa_ = false;
GpuRasterizationStatus gpu_rasterization_status_ =
GpuRasterizationStatus::OFF_DEVICE;
std::unique_ptr<RasterBufferProvider> raster_buffer_provider_;
@@ -1061,7 +1070,6 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
std::unique_ptr<LayerTreeImpl> recycle_tree_;
InputHandlerClient* input_handler_client_ = nullptr;
- bool did_lock_scrolling_layer_ = false;
bool touch_scrolling_ = false;
bool wheel_scrolling_ = false;
bool middle_click_autoscrolling_ = false;
@@ -1237,6 +1245,12 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
base::Optional<RenderFrameMetadata> last_draw_render_frame_metadata_;
viz::ChildLocalSurfaceIdAllocator child_local_surface_id_allocator_;
+ // Indicates the direction of the last vertical scroll of the root layer.
+ // Until the first vertical scroll occurs, this value is |kNull|. Note that
+ // once this value is updated, it will never return to |kNull|.
+ viz::VerticalScrollDirection last_vertical_scroll_direction_ =
+ viz::VerticalScrollDirection::kNull;
+
std::unique_ptr<base::MemoryPressureListener> memory_pressure_listener_;
PresentationTimeCallbackBuffer presentation_time_callbacks_;
@@ -1259,10 +1273,10 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
ElementId last_scroller_element_id_;
// Scroll animation can finish either before or after GSE arrival.
- // deferred_scroll_end_state_ is set when the GSE has arrvied before scroll
- // animation completion. ScrollEnd will get called with this deferred state
- // once the animation is over.
- base::Optional<ScrollState> deferred_scroll_end_state_;
+ // deferred_scroll_end_ is set when the GSE has arrvied before scroll
+ // animation completion. ScrollEnd will get called once the animation is
+ // over.
+ bool deferred_scroll_end_ = false;
// PaintWorklet painting is controlled from the LayerTreeHostImpl, dispatched
// to the worklet thread via |paint_worklet_painter_|.
@@ -1273,6 +1287,11 @@ class CC_EXPORT LayerTreeHostImpl : public InputHandler,
// not we are in that state.
bool pending_tree_fully_painted_ = false;
+#if DCHECK_IS_ON()
+ // Use to track when doing a synchronous draw.
+ bool doing_sync_draw_ = false;
+#endif
+
// Provides support for PaintWorklets which depend on input properties that
// are being animated by the compositor (aka 'animated' PaintWorklets).
// Responsible for storing animated custom property values and for
diff --git a/chromium/cc/trees/layer_tree_host_impl_unittest.cc b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
index 986eca85577..2d897103570 100644
--- a/chromium/cc/trees/layer_tree_host_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_impl_unittest.cc
@@ -279,7 +279,7 @@ class LayerTreeHostImplTest : public testing::Test,
host_impl_->SetVisible(true);
bool init = host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get());
host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10));
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 1);
host_impl_->active_tree()->SetLocalSurfaceIdAllocationFromParent(
viz::LocalSurfaceIdAllocation(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)),
@@ -451,9 +451,10 @@ class LayerTreeHostImplTest : public testing::Test,
gfx::Size scroll_content_size = gfx::Size(345, 3800);
gfx::Size scrollbar_size = gfx::Size(15, 600);
- LayerImpl* root = SetupRootLayer<LayerImpl>(layer_tree_impl, content_size);
+ SetupViewportLayersNoScrolls(content_size);
+ LayerImpl* outer_scroll = OuterViewportScrollLayer();
LayerImpl* scroll =
- AddScrollableLayer(root, content_size, scroll_content_size);
+ AddScrollableLayer(outer_scroll, content_size, scroll_content_size);
auto* squash2 = AddLayer<LayerImpl>(layer_tree_impl);
squash2->SetBounds(gfx::Size(140, 300));
@@ -470,7 +471,7 @@ class LayerTreeHostImplTest : public testing::Test,
auto* squash1 = AddLayer<LayerImpl>(layer_tree_impl);
squash1->SetBounds(gfx::Size(140, 300));
- CopyProperties(root, squash1);
+ CopyProperties(outer_scroll, squash1);
squash1->SetOffsetToTransformParent(gfx::Vector2dF(220, 0));
if (transparent_layer) {
CreateEffectNode(squash1).opacity = 0.0f;
@@ -488,22 +489,25 @@ class LayerTreeHostImplTest : public testing::Test,
// The point hits squash1 layer and also scroll layer, because scroll layer
// is not an ancestor of squash1 layer, we cannot scroll on impl thread.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(230, 150)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(230, 150), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
ASSERT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest,
status.main_thread_scrolling_reasons);
// The point hits squash1 layer and also scrollbar layer.
- status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(),
- InputHandler::WHEEL);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(350, 150), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
ASSERT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
ASSERT_EQ(MainThreadScrollingReason::kFailedHitTest,
status.main_thread_scrolling_reasons);
// The point hits squash2 layer and also scroll layer, because scroll layer
// is an ancestor of squash2 layer, we should scroll on impl.
- status = host_impl_->ScrollBegin(BeginState(gfx::Point(230, 450)).get(),
- InputHandler::WHEEL);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(230, 450), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
}
@@ -549,7 +553,7 @@ class LayerTreeHostImplTest : public testing::Test,
scrollbar->SetElementId(LayerIdToElementIdForTesting(scrollbar->id()));
SetupScrollbarLayerCommon(scroll_layer, scrollbar);
auto& effect = CreateEffectNode(scrollbar);
- effect.opacity = 0.f;
+ effect.opacity = 0;
effect.has_potential_opacity_animation = true;
}
@@ -557,7 +561,7 @@ class LayerTreeHostImplTest : public testing::Test,
PaintedScrollbarLayerImpl* scrollbar) {
SetupScrollbarLayerCommon(scroll_layer, scrollbar);
scrollbar->SetHitTestable(true);
- CreateEffectNode(scrollbar).opacity = 1.f;
+ CreateEffectNode(scrollbar).opacity = 1;
}
LayerImpl* InnerViewportScrollLayer() {
@@ -567,11 +571,14 @@ class LayerTreeHostImplTest : public testing::Test,
return host_impl_->active_tree()->OuterViewportScrollLayerForTesting();
}
- std::unique_ptr<ScrollState> BeginState(const gfx::Point& point) {
+ std::unique_ptr<ScrollState> BeginState(const gfx::Point& point,
+ const gfx::Vector2dF& delta_hint) {
ScrollStateData scroll_state_data;
scroll_state_data.is_beginning = true;
scroll_state_data.position_x = point.x();
scroll_state_data.position_y = point.y();
+ scroll_state_data.delta_x_hint = delta_hint.x();
+ scroll_state_data.delta_y_hint = delta_hint.y();
std::unique_ptr<ScrollState> scroll_state(
new ScrollState(scroll_state_data));
return scroll_state;
@@ -589,20 +596,16 @@ class LayerTreeHostImplTest : public testing::Test,
return scroll_state;
}
- std::unique_ptr<ScrollState> EndState() {
- ScrollStateData scroll_state_data;
- scroll_state_data.is_ending = true;
- std::unique_ptr<ScrollState> scroll_state(
- new ScrollState(scroll_state_data));
- return scroll_state;
- }
-
void DrawFrame() {
PrepareForUpdateDrawProperties(host_impl_->active_tree());
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
RenderFrameMetadata StartDrawAndProduceRenderFrameMetadata() {
@@ -701,7 +704,7 @@ class LayerTreeHostImplTest : public testing::Test,
ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
gfx::RectF(0, 0, 200, 200), gfx::ScrollOffset(300, 300));
SnapAreaData area_data(ScrollSnapAlign(SnapAlignment::kStart),
- gfx::RectF(50, 50, 100, 100), false);
+ gfx::RectF(50, 50, 100, 100), false, ElementId(10));
container_data.AddSnapAreaData(area_data);
GetScrollNode(overflow)->snap_container_data.emplace(container_data);
DrawFrame();
@@ -709,6 +712,11 @@ class LayerTreeHostImplTest : public testing::Test,
return overflow;
}
+ base::Optional<SnapContainerData> GetSnapContainerData(LayerImpl* layer) {
+ return GetScrollNode(layer) ? GetScrollNode(layer)->snap_container_data
+ : base::nullopt;
+ }
+
void ClearLayersAndPropertyTrees(LayerTreeImpl* layer_tree_impl) {
layer_tree_impl->SetRootLayerForTesting(nullptr);
layer_tree_impl->DetachLayers();
@@ -815,9 +823,9 @@ class LayerTreeHostImplTimelinesTest : public LayerTreeHostImplTest {
class TestInputHandlerClient : public InputHandlerClient {
public:
TestInputHandlerClient()
- : page_scale_factor_(0.f),
- min_page_scale_factor_(-1.f),
- max_page_scale_factor_(-1.f) {}
+ : page_scale_factor_(0),
+ min_page_scale_factor_(-1),
+ max_page_scale_factor_(-1) {}
~TestInputHandlerClient() override = default;
// InputHandlerClient implementation.
@@ -1041,13 +1049,15 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest,
TEST_F(LayerTreeHostImplTest, ScrollBeforeRootLayerAttached) {
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 1)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
status.main_thread_scrolling_reasons);
- status = host_impl_->RootScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::WHEEL);
+ status = host_impl_->RootScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 1)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
status.main_thread_scrolling_reasons);
@@ -1058,7 +1068,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
DrawFrame();
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -1066,7 +1077,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootCallsCommitAndRedraw) {
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, 10)));
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
@@ -1077,22 +1088,24 @@ TEST_F(LayerTreeHostImplTest, ScrollActiveOnlyAfterScrollMovement) {
DrawFrame();
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- EXPECT_FALSE(host_impl_->IsActivelyScrolling());
+ EXPECT_TRUE(host_impl_->IsActivelyScrolling());
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
EXPECT_TRUE(host_impl_->IsActivelyScrolling());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->IsActivelyScrolling());
}
TEST_F(LayerTreeHostImplTest, ScrollWithoutRootLayer) {
// We should not crash when trying to scroll an empty layer tree.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
status.main_thread_scrolling_reasons);
@@ -1113,7 +1126,8 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutRenderer) {
// We should not crash when trying to scroll after the renderer initialization
// fails.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -1124,10 +1138,14 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
DrawFrame();
// We should not crash if the tree is replaced while we are scrolling.
+ gfx::ScrollOffset scroll_delta(0, 10);
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(gfx::Point(),
+ gfx::ScrollOffsetToVector2dF(scroll_delta))
+ .get(),
+ InputHandler::WHEEL)
.thread);
ClearLayersAndPropertyTrees(host_impl_->active_tree());
@@ -1136,17 +1154,43 @@ TEST_F(LayerTreeHostImplTest, ReplaceTreeWhileScrolling) {
// We should still be scrolling, because the scrolled layer also exists in the
// new tree.
- gfx::ScrollOffset scroll_delta(0, 10);
host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta))
.get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
scroll_delta));
}
+TEST_F(LayerTreeHostImplTest, ActivateTreeScrollingNodeDisappeared) {
+ SetupViewportLayersOuterScrolls(gfx::Size(100, 100), gfx::Size(1000, 1000));
+
+ auto status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(30, 30), gfx::Vector2d(0, 10)).get(),
+ InputHandler::WHEEL);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
+ EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
+ status.main_thread_scrolling_reasons);
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
+ EXPECT_TRUE(host_impl_->active_tree()->CurrentlyScrollingNode());
+ EXPECT_TRUE(host_impl_->IsActivelyScrolling());
+
+ // Create the pending tree containing only the root layer.
+ CreatePendingTree();
+ PropertyTrees pending_property_trees;
+ pending_property_trees.sequence_number =
+ host_impl_->active_tree()->property_trees()->sequence_number + 1;
+ host_impl_->pending_tree()->SetPropertyTrees(&pending_property_trees);
+ SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), gfx::Size(100, 100));
+ host_impl_->ActivateSyncTree();
+
+ // The scroll should stop.
+ EXPECT_FALSE(host_impl_->active_tree()->CurrentlyScrollingNode());
+ EXPECT_FALSE(host_impl_->IsActivelyScrolling());
+}
+
TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
auto* scroll = InnerViewportScrollLayer();
@@ -1167,11 +1211,12 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnWheelEventHandlers) {
// But they don't influence the actual handling of the scroll gestures.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2d(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) {
@@ -1199,11 +1244,12 @@ TEST_F(LayerTreeHostImplTest, ScrollBlocksOnTouchEventHandlers) {
// But they don't influence the actual handling of the scroll gestures.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
+ BeginState(gfx::Point(), gfx::Vector2d(0, 10)).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_EQ(InputHandler::TouchStartOrMoveEventListenerType::HANDLER,
host_impl_->EventListenerTypeForTouchStartOrMoveAt(
@@ -1229,13 +1275,15 @@ TEST_F(LayerTreeHostImplTest, ShouldScrollOnMainThread) {
DrawFrame();
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2d(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
status.main_thread_scrolling_reasons);
- status = host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2d(0, 10)).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
status.main_thread_scrolling_reasons);
@@ -1256,9 +1304,9 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) {
gfx::Size scroll_content_size = gfx::Size(345, 3800);
gfx::Size scrollbar_size = gfx::Size(15, 600);
- LayerImpl* root = SetupDefaultRootLayer(content_size);
- LayerImpl* scroll =
- AddScrollableLayer(root, content_size, scroll_content_size);
+ SetupViewportLayersNoScrolls(content_size);
+ LayerImpl* scroll = AddScrollableLayer(OuterViewportScrollLayer(),
+ content_size, scroll_content_size);
auto* drawn_scrollbar = AddLayer<PaintedScrollbarLayerImpl>(
layer_tree_impl, VERTICAL, false, true);
@@ -1278,16 +1326,18 @@ TEST_F(LayerTreeHostImplTest, ScrolledOverlappingDrawnScrollbarLayer) {
// The point hits squash layer and also scrollbar layer, but because the
// scrollbar layer is a drawn scrollbar, we cannot scroll on the impl thread.
- auto status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 150)).get(),
- InputHandler::WHEEL);
+ auto status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(350, 150), gfx::Vector2d(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
status.main_thread_scrolling_reasons);
// The point hits the drawn scrollbar layer completely and should scroll on
// the impl thread.
- status = host_impl_->ScrollBegin(BeginState(gfx::Point(350, 500)).get(),
- InputHandler::WHEEL);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(350, 500), gfx::Vector2d(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -1303,22 +1353,25 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
// All scroll types inside the non-fast scrollable region should fail.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(25, 25)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(25, 25), gfx::Vector2d(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
status.main_thread_scrolling_reasons);
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25)));
- status = host_impl_->ScrollBegin(BeginState(gfx::Point(25, 25)).get(),
- InputHandler::TOUCHSCREEN);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(25, 25), gfx::Vector2d(0, 10)).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
status.main_thread_scrolling_reasons);
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25)));
// All scroll types outside this region should succeed.
- status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
- InputHandler::WHEEL);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(75, 75), gfx::Vector2d(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -1326,17 +1379,18 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionBasic) {
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(25, 25)));
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
- status = host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
- InputHandler::TOUCHSCREEN);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(75, 75), gfx::Vector2d(0, 10)).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(75, 75)));
}
@@ -1345,7 +1399,7 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
LayerImpl* outer_scroll = OuterViewportScrollLayer();
outer_scroll->SetNonFastScrollableRegion(gfx::Rect(0, 0, 50, 50));
- SetPostTranslation(outer_scroll, gfx::Vector2dF(-25.f, 0.f));
+ SetPostTranslation(outer_scroll, gfx::Vector2dF(-25, 0));
outer_scroll->SetDrawsContent(true);
DrawFrame();
@@ -1353,18 +1407,20 @@ TEST_F(LayerTreeHostImplTest, NonFastScrollableRegionWithOffset) {
// This point would fall into the non-fast scrollable region except that we've
// moved the layer left by 25 pixels.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(40, 10)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(40, 10), gfx::Vector2d(0, 1)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(40, 10)));
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 1)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// This point is still inside the non-fast region.
- status = host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
- InputHandler::WHEEL);
+ status = host_impl_->ScrollBegin(
+ BeginState(gfx::Point(10, 10), gfx::Vector2d(0, 1)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
status.main_thread_scrolling_reasons);
@@ -1376,10 +1432,10 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerNotPresent) {
DrawFrame();
EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2d(0, 10)).get(),
InputHandler::TOUCHSCREEN);
EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
}
@@ -1389,10 +1445,10 @@ TEST_F(LayerTreeHostImplTest, ScrollHandlerPresent) {
DrawFrame();
EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2d(0, 10)).get(),
InputHandler::TOUCHSCREEN);
EXPECT_TRUE(host_impl_->scroll_affects_scroll_handler());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->scroll_affects_scroll_handler());
}
@@ -1401,7 +1457,8 @@ TEST_F(LayerTreeHostImplTest, ScrollByReturnsCorrectValue) {
DrawFrame();
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::TOUCHSCREEN);
+ BeginState(gfx::Point(), gfx::Vector2d(-10, 0)).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -1475,19 +1532,26 @@ TEST_F(LayerTreeHostImplTest, ScrollSnapOnX) {
LayerImpl* overflow = CreateLayerForSnapping();
gfx::Point pointer_position(10, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ gfx::Vector2dF x_delta(20, 0);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
- gfx::Vector2dF x_delta(20, 0);
host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get());
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
- host_impl_->ScrollEnd(EndState().get(), true);
+ host_impl_->ScrollEnd(true);
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
+
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
BeginImplFrameAndAnimate(begin_frame_args, start_time);
@@ -1497,25 +1561,33 @@ TEST_F(LayerTreeHostImplTest, ScrollSnapOnX) {
begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(1000));
EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), overflow->CurrentScrollOffset());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
}
TEST_F(LayerTreeHostImplTest, ScrollSnapOnY) {
LayerImpl* overflow = CreateLayerForSnapping();
gfx::Point pointer_position(10, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ gfx::Vector2dF y_delta(0, 20);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, y_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
- gfx::Vector2dF y_delta(0, 20);
host_impl_->ScrollBy(UpdateState(pointer_position, y_delta).get());
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
- host_impl_->ScrollEnd(EndState().get(), true);
+ host_impl_->ScrollEnd(true);
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(), ElementId(10)),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
BeginImplFrameAndAnimate(begin_frame_args, start_time);
@@ -1525,25 +1597,33 @@ TEST_F(LayerTreeHostImplTest, ScrollSnapOnY) {
begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(1000));
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 50), overflow->CurrentScrollOffset());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(), ElementId(10)),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
}
TEST_F(LayerTreeHostImplTest, ScrollSnapOnBoth) {
LayerImpl* overflow = CreateLayerForSnapping();
gfx::Point pointer_position(10, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ gfx::Vector2dF delta(20, 20);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
- gfx::Vector2dF delta(20, 20);
host_impl_->ScrollBy(UpdateState(pointer_position, delta).get());
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
- host_impl_->ScrollEnd(EndState().get(), true);
+ host_impl_->ScrollEnd(true);
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
BeginImplFrameAndAnimate(begin_frame_args, start_time);
@@ -1553,6 +1633,8 @@ TEST_F(LayerTreeHostImplTest, ScrollSnapOnBoth) {
begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(1000));
EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50), overflow->CurrentScrollOffset());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
}
TEST_F(LayerTreeHostImplTest, ScrollSnapAfterAnimatedScroll) {
@@ -1567,6 +1649,9 @@ TEST_F(LayerTreeHostImplTest, ScrollSnapAfterAnimatedScroll) {
EXPECT_EQ(overflow->scroll_tree_index(),
host_impl_->CurrentlyScrollingNode()->id);
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
+
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
viz::BeginFrameArgs begin_frame_args =
@@ -1582,37 +1667,44 @@ TEST_F(LayerTreeHostImplTest, ScrollSnapAfterAnimatedScroll) {
EXPECT_GT(20, current_offset.x());
EXPECT_LT(0, current_offset.y());
EXPECT_GT(20, current_offset.y());
+ EXPECT_EQ(TargetSnapAreaElementIds(),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
- // Animating for the snap.
+ // The scroll animation is finished, so the snap target should be set now and
+ // the snap animation should begin.
BeginImplFrameAndAnimate(
begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(1000));
EXPECT_TRUE(host_impl_->is_animating_for_snap_for_testing());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
// Finish the animation.
BeginImplFrameAndAnimate(
begin_frame_args, start_time + base::TimeDelta::FromMilliseconds(1500));
EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50), overflow->CurrentScrollOffset());
EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
}
TEST_F(LayerTreeHostImplTest, SnapAnimationCancelledByScroll) {
LayerImpl* overflow = CreateLayerForSnapping();
gfx::Point pointer_position(10, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ gfx::Vector2dF x_delta(20, 0);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
- gfx::Vector2dF x_delta(20, 0);
host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get());
EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing());
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
- host_impl_->ScrollEnd(EndState().get(), true);
+ host_impl_->ScrollEnd(true);
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
BeginImplFrameAndAnimate(begin_frame_args, start_time);
@@ -1626,12 +1718,12 @@ TEST_F(LayerTreeHostImplTest, SnapAnimationCancelledByScroll) {
EXPECT_LT(20, current_offset.x());
EXPECT_EQ(0, current_offset.y());
- // Interrup the snap animation with ScrollBegin.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ // Interrupt the snap animation with ScrollBegin.
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing());
BeginImplFrameAndAnimate(begin_frame_args,
start_time + base::TimeDelta::FromMilliseconds(150));
@@ -1644,21 +1736,21 @@ TEST_F(LayerTreeHostImplTest,
LayerImpl* overflow = CreateLayerForSnapping();
gfx::Point pointer_position(10, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ gfx::Vector2dF x_delta(50, 0);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
// There is a snap target at 50, scroll to it directly.
- gfx::Vector2dF x_delta(50, 0);
host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get());
EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing());
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
- host_impl_->ScrollEnd(EndState().get(), true);
+ host_impl_->ScrollEnd(true);
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromMilliseconds(100);
BeginImplFrameAndAnimate(begin_frame_args, start_time);
@@ -1672,34 +1764,38 @@ TEST_F(LayerTreeHostImplTest,
start_time + base::TimeDelta::FromMilliseconds(100));
EXPECT_FALSE(host_impl_->is_animating_for_snap_for_testing());
EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 0), overflow->CurrentScrollOffset());
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId()),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
}
-TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoWhenZoomed) {
+TEST_F(LayerTreeHostImplTest, GetSnapFlingInfoAndSetSnapTargetWhenZoomed) {
LayerImpl* overflow = CreateLayerForSnapping();
// Scales the page to its 1/5.
- host_impl_->active_tree()->PushPageScaleFromMainThread(0.2f, 0.1f, 5.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(0.2f, 0.1f, 5);
// Should be (10, 10) in the scroller's coordinate.
gfx::Point pointer_position(2, 2);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ gfx::Vector2dF delta(4, 4);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
// Should be (20, 20) in the scroller's coordinate.
- gfx::Vector2dF delta(4, 4);
InputHandlerScrollResult result =
host_impl_->ScrollBy(UpdateState(pointer_position, delta).get());
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 20), overflow->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(4, 4), result.current_visual_offset);
gfx::Vector2dF initial_offset, target_offset;
- EXPECT_TRUE(host_impl_->GetSnapFlingInfo(gfx::Vector2dF(10, 10),
- &initial_offset, &target_offset));
+ EXPECT_TRUE(host_impl_->GetSnapFlingInfoAndSetSnapTarget(
+ gfx::Vector2dF(10, 10), &initial_offset, &target_offset));
EXPECT_VECTOR_EQ(gfx::Vector2dF(4, 4), initial_offset);
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), target_offset);
+ EXPECT_EQ(TargetSnapAreaElementIds(ElementId(10), ElementId(10)),
+ GetSnapContainerData(overflow)->GetTargetSnapAreaElementIds());
}
TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
@@ -1716,21 +1812,21 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
DrawFrame();
gfx::Point pointer_position(50, 50);
+ gfx::Vector2dF x_delta(-10, 0);
+ gfx::Vector2dF y_delta(0, -10);
+ gfx::Vector2dF diagonal_delta(-10, -10);
// OverscrollBehaviorTypeAuto shouldn't prevent scroll propagation.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(30, 30), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->CurrentScrollOffset());
- gfx::Vector2dF x_delta(-10, 0);
- gfx::Vector2dF y_delta(0, -10);
- gfx::Vector2dF diagonal_delta(-10, -10);
host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 30), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
@@ -1742,31 +1838,31 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
// OverscrollBehaviorContain on x should prevent propagations of scroll
// on x.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 30), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 30), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
// OverscrollBehaviorContain on x shouldn't prevent propagations of
// scroll on y.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, y_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 30), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(pointer_position, y_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
@@ -1775,13 +1871,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(pointer_position, diagonal_delta).get(),
+ InputHandler::WHEEL)
.thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(pointer_position, diagonal_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
@@ -1794,31 +1891,31 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
// OverscrollBehaviorContain on y shouldn't prevent propagations of
// scroll on x.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(20, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(pointer_position, x_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
// OverscrollBehaviorContain on y should prevent propagations of scroll
// on y.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, y_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(pointer_position, y_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
@@ -1827,13 +1924,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(pointer_position, diagonal_delta).get(),
+ InputHandler::WHEEL)
.thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(pointer_position, diagonal_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
@@ -1845,11 +1943,11 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
DrawFrame();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(pointer_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(pointer_position, x_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), overflow->CurrentScrollOffset());
@@ -1857,7 +1955,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollBehaviorPreventsPropagation) {
host_impl_->ScrollBy(UpdateState(pointer_position, -x_delta).get());
host_impl_->ScrollBy(UpdateState(pointer_position, y_delta).get());
host_impl_->ScrollBy(UpdateState(pointer_position, -y_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset());
}
@@ -1875,18 +1973,18 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
DrawFrame();
gfx::Point scroll_position(10, 10);
+ gfx::Vector2dF scroll_delta(10, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(scroll_position, scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(), overflow->CurrentScrollOffset());
- gfx::Vector2dF scroll_delta(10, 10);
host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset());
@@ -1894,32 +1992,32 @@ TEST_F(LayerTreeHostImplTest, ScrollWithUserUnscrollableLayers) {
DrawFrame();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(scroll_position, scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
GetScrollNode(overflow)->user_scrollable_vertical = false;
DrawFrame();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(scroll_position).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(scroll_position, scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(scroll_position, scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 10), scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(10, 20), overflow->CurrentScrollOffset());
}
@@ -1933,7 +2031,8 @@ TEST_F(LayerTreeHostImplTest, ForceMainThreadScrollWithoutScrollLayer) {
DrawFrame();
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(25, 25)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(25, 25), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNonFastScrollableRegion,
status.main_thread_scrolling_reasons);
@@ -2008,9 +2107,9 @@ TEST_F(CommitToPendingTreeLayerTreeHostImplTest,
// Add a translate from 6,7 to 8,9.
TransformOperations start;
- start.AppendTranslate(6.f, 7.f, 0.f);
+ start.AppendTranslate(6, 7, 0);
TransformOperations end;
- end.AppendTranslate(8.f, 9.f, 0.f);
+ end.AppendTranslate(8, 9, 0);
AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(),
4.0, start, end);
UpdateDrawProperties(host_impl_->active_tree());
@@ -2101,9 +2200,9 @@ TEST_F(LayerTreeHostImplTest, AnimationSchedulingOnLayerDestruction) {
// Add a translate animation.
TransformOperations start;
- start.AppendTranslate(6.f, 7.f, 0.f);
+ start.AppendTranslate(6, 7, 0);
TransformOperations end;
- end.AppendTranslate(8.f, 9.f, 0.f);
+ end.AppendTranslate(8, 9, 0);
AddAnimatedTransformToElementWithAnimation(child->element_id(), timeline(),
4.0, start, end);
UpdateDrawProperties(host_impl_->active_tree());
@@ -2174,8 +2273,8 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
LayerImpl* scroll_layer = InnerViewportScrollLayer();
EXPECT_EQ(gfx::Size(50, 50), root_layer()->bounds());
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 1.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 1;
// The impl-based pinch zoom should adjust the max scroll position.
{
@@ -2184,14 +2283,18 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
- float page_scale_delta = 2.f;
+ float page_scale_delta = 2;
- host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
- InputHandler::TOUCHSCREEN);
+ // TODO(bokan): What are the delta_hints for a GSB that's sent for a pinch
+ // gesture that doesn't cause (initial) scrolling?
+ // https://crbug.com/1030262
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(50, 50), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
host_impl_->PinchGestureEnd(gfx::Point(50, 50), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(did_request_next_frame_);
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
@@ -2213,22 +2316,23 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoom) {
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
- float page_scale_delta = 2.f;
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ float page_scale_delta = 2;
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
gfx::Vector2d scroll_delta(0, 10);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -2260,7 +2364,7 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollbarGeometry) {
// Setup
LayerTreeImpl* active_tree = host_impl_->active_tree();
- active_tree->PushPageScaleFromMainThread(1.f, minimum_scale, 4.f);
+ active_tree->PushPageScaleFromMainThread(1, minimum_scale, 4);
// When Chrome on Android loads a non-mobile page, it resizes the main
// frame (outer viewport) such that it matches the width of the content,
@@ -2285,7 +2389,7 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollbarGeometry) {
host_impl_->active_tree()->DidBecomeActive();
// Zoom out to the minimum scale. The scrollbars shoud not be scrollable.
- host_impl_->active_tree()->SetPageScaleOnActiveTree(0.f);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(0);
EXPECT_FALSE(v_scrollbar->CanScrollOrientation());
EXPECT_FALSE(h_scrollbar->CanScrollOrientation());
@@ -2298,7 +2402,7 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollbarGeometry) {
TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) {
LayerTreeSettings settings = DefaultSettings();
CreateHostImpl(settings, CreateLayerTreeFrameSink());
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.25f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.25f, 4);
const gfx::Size content_size(1000, 1000);
const gfx::Size viewport_size(500, 500);
@@ -2313,12 +2417,13 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) {
EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500),
outer_scroll_layer->MaxScrollOffset());
- host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(250, 250), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
- host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
+ host_impl_->PinchGestureUpdate(2, gfx::Point(0, 0));
host_impl_->PinchGestureEnd(gfx::Point(0, 0), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Sanity check - we're zoomed in, starting from the origin.
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
@@ -2327,11 +2432,12 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) {
inner_scroll_layer->CurrentScrollOffset());
// Scroll down - only the inner viewport should scroll.
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
inner_scroll_layer->CurrentScrollOffset());
@@ -2340,11 +2446,12 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) {
// Scroll down - outer viewport should start scrolling after the inner is at
// its maximum.
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(250, 250),
inner_scroll_layer->CurrentScrollOffset());
@@ -2355,7 +2462,7 @@ TEST_F(LayerTreeHostImplTest, ViewportScrollOrder) {
// Make sure scrolls smaller than a unit applied to the viewport don't get
// dropped. crbug.com/539334.
TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) {
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 2);
const gfx::Size content_size(1000, 1000);
const gfx::Size viewport_size(500, 500);
@@ -2374,28 +2481,30 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) {
EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll_layer->CurrentScrollOffset());
// Scroll only the layout viewport.
- host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(250, 250), gfx::Vector2dF(0.125f, 0.125f)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
UpdateState(gfx::Point(250, 250), gfx::Vector2dF(0.125f, 0.125f)).get());
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.125f, 0.125f),
outer_scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0, 0),
inner_scroll_layer->CurrentScrollOffset());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
- host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2, 1, 2);
// Now that we zoomed in, the scroll should be applied to the inner viewport.
- host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(250, 250), gfx::Vector2dF(0.5f, 0.5f)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
UpdateState(gfx::Point(250, 250), gfx::Vector2dF(0.5f, 0.5f)).get());
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.125f, 0.125f),
outer_scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.25f, 0.25f),
inner_scroll_layer->CurrentScrollOffset());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
// Tests that scrolls during a pinch gesture (i.e. "two-finger" scrolls) work
@@ -2404,7 +2513,7 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportWithFractionalAmounts) {
TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) {
LayerTreeSettings settings = DefaultSettings();
CreateHostImpl(settings, CreateLayerTreeFrameSink());
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 2);
const gfx::Size content_size(1000, 1000);
const gfx::Size viewport_size(500, 500);
@@ -2419,8 +2528,9 @@ TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) {
EXPECT_VECTOR_EQ(gfx::Vector2dF(500, 500),
outer_scroll_layer->MaxScrollOffset());
- host_impl_->ScrollBegin(BeginState(gfx::Point(250, 250)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(250, 250), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(2, gfx::Point(250, 250));
@@ -2433,7 +2543,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) {
DrawFrame();
host_impl_->ScrollBy(
- UpdateState(gfx::Point(250, 250), gfx::Vector2dF(10.f, 10.f)).get());
+ UpdateState(gfx::Point(250, 250), gfx::Vector2dF(10, 10)).get());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
outer_scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(130, 130),
@@ -2442,14 +2552,14 @@ TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) {
DrawFrame();
host_impl_->ScrollBy(
- UpdateState(gfx::Point(250, 250), gfx::Vector2dF(400.f, 400.f)).get());
+ UpdateState(gfx::Point(250, 250), gfx::Vector2dF(400, 400)).get());
EXPECT_VECTOR_EQ(gfx::Vector2dF(80, 80),
outer_scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(250, 250),
inner_scroll_layer->CurrentScrollOffset());
host_impl_->PinchGestureEnd(gfx::Point(250, 250), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
// Tests the "snapping" of pinch-zoom gestures to the screen edge. That is, when
@@ -2458,7 +2568,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDuringPinchGesture) {
TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) {
LayerTreeSettings settings = DefaultSettings();
CreateHostImpl(settings, CreateLayerTreeFrameSink());
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 2);
const gfx::Size content_size(1000, 1000);
const gfx::Size viewport_size(500, 500);
@@ -2470,51 +2580,54 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) {
// Pinch in within the margins. The scroll should stay exactly locked to the
// bottom and right.
- host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(BeginState(anchor, gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(2, anchor);
host_impl_->PinchGestureEnd(anchor, true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(250, 250),
InnerViewportScrollLayer()->CurrentScrollOffset());
// Reset.
- host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(1);
SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d());
SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d());
// Pinch in within the margins. The scroll should stay exactly locked to the
// top and left.
anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
- host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(BeginState(anchor, gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(2, anchor);
host_impl_->PinchGestureEnd(anchor, true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
InnerViewportScrollLayer()->CurrentScrollOffset());
// Reset.
- host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(1);
SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d());
SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d());
// Pinch in just outside the margin. There should be no snapping.
offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
anchor = gfx::Point(offsetFromEdge, offsetFromEdge);
- host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(BeginState(anchor, gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(2, anchor);
host_impl_->PinchGestureEnd(anchor, true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
InnerViewportScrollLayer()->CurrentScrollOffset());
// Reset.
- host_impl_->active_tree()->SetPageScaleOnActiveTree(1.f);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(1);
SetScrollOffsetDelta(InnerViewportScrollLayer(), gfx::Vector2d());
SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2d());
@@ -2522,11 +2635,12 @@ TEST_F(LayerTreeHostImplTest, PinchZoomSnapsToScreenEdge) {
offsetFromEdge = Viewport::kPinchZoomSnapMarginDips;
anchor = gfx::Point(viewport_size.width() - offsetFromEdge,
viewport_size.height() - offsetFromEdge);
- host_impl_->ScrollBegin(BeginState(anchor).get(), InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(BeginState(anchor, gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(2, anchor);
host_impl_->PinchGestureEnd(anchor, true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(200, 200),
InnerViewportScrollLayer()->CurrentScrollOffset());
@@ -2541,19 +2655,20 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
LayerImpl* inner_scroll_layer = InnerViewportScrollLayer();
// Zoom into the page by a 2X factor
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 2.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 2;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
// Scroll by a small amount, there should be no bubbling to the outer
// viewport.
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(10, 20)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(10.f, 20.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(10, 20)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 10),
inner_scroll_layer->CurrentScrollOffset());
@@ -2561,11 +2676,12 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
// Scroll by the inner viewport's max scroll extent, the remainder
// should bubble up to the outer viewport.
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
inner_scroll_layer->CurrentScrollOffset());
@@ -2574,11 +2690,12 @@ TEST_F(LayerTreeHostImplTest, ImplPinchZoomWheelBubbleBetweenViewports) {
// Scroll by the outer viewport's max scroll extent, it should all go to the
// outer viewport.
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(190, 180)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(190.f, 180.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(190, 180)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(100, 100),
outer_scroll_layer->CurrentScrollOffset());
@@ -2594,15 +2711,16 @@ TEST_F(LayerTreeHostImplTest, ScrollWithSwapPromises) {
new LatencyInfoSwapPromise(latency_info));
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2d(0, 10)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
host_impl_->QueueSwapPromiseForMainThreadScrollUpdate(
std::move(swap_promise));
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -2634,13 +2752,14 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) {
DrawFrame();
{
- host_impl_->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(21, 21), gfx::Vector2d(5, 5)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
UpdateState(gfx::Point(21, 21), gfx::Vector2d(5, 5)).get());
host_impl_->ScrollBy(
UpdateState(gfx::Point(21, 21), gfx::Vector2d(100, 100)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The child should be fully scrolled by the first ScrollBy.
EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5), scroll_child->CurrentScrollOffset());
@@ -2657,8 +2776,9 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) {
}
{
- host_impl_->ScrollBegin(BeginState(gfx::Point(21, 21)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(21, 21), gfx::Vector2d(3, 4)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
UpdateState(gfx::Point(21, 21), gfx::Vector2d(3, 4)).get());
host_impl_->ScrollBy(
@@ -2667,7 +2787,7 @@ TEST_F(LayerTreeHostImplTest, ScrollDoesntBubble) {
UpdateState(gfx::Point(21, 21), gfx::Vector2d(2, 1)).get());
host_impl_->ScrollBy(
UpdateState(gfx::Point(21, 21), gfx::Vector2d(2, 1)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The ScrollBy's should scroll the parent to its extent.
EXPECT_VECTOR_EQ(gfx::Vector2dF(5, 5),
@@ -2688,22 +2808,23 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
LayerImpl* scroll_layer = InnerViewportScrollLayer();
DCHECK(scroll_layer);
- float min_page_scale = 1.f;
- float max_page_scale = 4.f;
+ float min_page_scale = 1;
+ float max_page_scale = 4;
// Basic pinch zoom in gesture
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
- float page_scale_delta = 2.f;
- host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
- InputHandler::TOUCHSCREEN);
+ float page_scale_delta = 2;
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(50, 50), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
host_impl_->PinchGestureEnd(gfx::Point(50, 50), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(did_request_next_frame_);
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
@@ -2715,17 +2836,18 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Zoom-in clamping
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
- float page_scale_delta = 10.f;
+ float page_scale_delta = 10;
- host_impl_->ScrollBegin(BeginState(gfx::Point(50, 50)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(50, 50), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(50, 50));
host_impl_->PinchGestureEnd(gfx::Point(50, 50), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -2734,7 +2856,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Zoom-out clamping
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
scroll_layer->layer_tree_impl()
@@ -2746,12 +2868,12 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
scroll_layer->element_id(), gfx::ScrollOffset(50, 50));
float page_scale_delta = 0.1f;
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -2762,7 +2884,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Two-finger panning should not happen based on pinch events only
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
scroll_layer->layer_tree_impl()
@@ -2773,14 +2895,15 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
->scroll_tree.UpdateScrollOffsetBaseForTesting(
scroll_layer->element_id(), gfx::ScrollOffset(20, 20));
- float page_scale_delta = 1.f;
- host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
- InputHandler::TOUCHSCREEN);
+ float page_scale_delta = 1;
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(10, 10), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
host_impl_->PinchGestureEnd(gfx::Point(20, 20), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -2790,7 +2913,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Two-finger panning should work with interleaved scroll events
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
scroll_layer->layer_tree_impl()
@@ -2801,16 +2924,17 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
->scroll_tree.UpdateScrollOffsetBaseForTesting(
scroll_layer->element_id(), gfx::ScrollOffset(20, 20));
- float page_scale_delta = 1.f;
- host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
- InputHandler::TOUCHSCREEN);
+ float page_scale_delta = 1;
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(10, 10), gfx::Vector2dF(-10, -10)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
host_impl_->ScrollBy(
UpdateState(gfx::Point(10, 10), gfx::Vector2d(-10, -10)).get());
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(20, 20));
host_impl_->PinchGestureEnd(gfx::Point(20, 20), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -2821,7 +2945,7 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
// Two-finger panning should work when starting fully zoomed out.
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(0.5f, 0.5f, 4);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
scroll_layer->layer_tree_impl()
->property_trees()
@@ -2831,24 +2955,25 @@ TEST_F(LayerTreeHostImplTest, PinchGesture) {
->scroll_tree.UpdateScrollOffsetBaseForTesting(
scroll_layer->element_id(), gfx::ScrollOffset(0, 0));
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
- host_impl_->PinchGestureUpdate(2.f, gfx::Point(0, 0));
- host_impl_->PinchGestureUpdate(1.f, gfx::Point(0, 0));
+ host_impl_->PinchGestureUpdate(2, gfx::Point(0, 0));
+ host_impl_->PinchGestureUpdate(1, gfx::Point(0, 0));
// Needed so layer transform includes page scale.
DrawFrame();
host_impl_->ScrollBy(
UpdateState(gfx::Point(0, 0), gfx::Vector2d(10, 10)).get());
- host_impl_->PinchGestureUpdate(1.f, gfx::Point(10, 10));
+ host_impl_->PinchGestureUpdate(1, gfx::Point(10, 10));
host_impl_->PinchGestureEnd(gfx::Point(10, 10), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
- EXPECT_EQ(scroll_info->page_scale_delta, 2.f);
+ EXPECT_EQ(scroll_info->page_scale_delta, 2);
EXPECT_TRUE(ScrollInfoContains(*scroll_info, scroll_layer->element_id(),
gfx::ScrollOffset(10, 10)));
}
@@ -2861,10 +2986,10 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) {
LayerImpl* scroll_layer = InnerViewportScrollLayer();
DCHECK(scroll_layer);
- float min_page_scale = 1.f;
- float max_page_scale = 4.f;
+ float min_page_scale = 1;
+ float max_page_scale = 4;
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
scroll_layer->layer_tree_impl()
@@ -2875,16 +3000,17 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) {
->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
gfx::ScrollOffset(0, 20));
- float page_scale_delta = 1.f;
- host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
- InputHandler::TOUCHSCREEN);
+ float page_scale_delta = 1;
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(10, 10), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 10));
host_impl_->ScrollBy(
UpdateState(gfx::Point(10, 10), gfx::Vector2dF(0, -1.001f)).get());
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point(10, 9));
host_impl_->PinchGestureEnd(gfx::Point(10, 9), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -2896,7 +3022,7 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollDelta) {
// scroll layer.
draw_property_utils::ComputeTransforms(
&scroll_layer->layer_tree_impl()->property_trees()->transform_tree);
- EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, -19.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0, -19),
scroll_layer->ScreenSpaceTransform().To2dTranslation());
}
@@ -2916,11 +3042,12 @@ TEST_F(LayerTreeHostImplTest, SyncSubpixelScrollFromFractionalActiveBase) {
->scroll_tree.UpdateScrollOffsetBaseForTesting(
scroll_layer->element_id(), gfx::ScrollOffset(0, 20.5f));
- host_impl_->ScrollBegin(BeginState(gfx::Point(10, 10)).get(),
- InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(10, 10), gfx::Vector2dF(0, -1)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(
UpdateState(gfx::Point(10, 10), gfx::Vector2dF(0, -1)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
gfx::ScrollOffset active_base =
host_impl_->active_tree()
@@ -2939,8 +3066,8 @@ TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
DrawFrame();
- float min_page_scale = 1.f;
- float max_page_scale = 4.f;
+ float min_page_scale = 1;
+ float max_page_scale = 4;
float page_scale_delta = 1.04f;
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromSeconds(1);
@@ -2953,7 +3080,7 @@ TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) {
// Zoom animation if page_scale is < 1.05 * min_page_scale.
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
did_request_redraw_ = false;
@@ -2998,7 +3125,7 @@ TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) {
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
- EXPECT_EQ(scroll_info->page_scale_delta, 1.f);
+ EXPECT_EQ(scroll_info->page_scale_delta, 1);
}
start_time += base::TimeDelta::FromSeconds(10);
@@ -3008,7 +3135,7 @@ TEST_F(LayerTreeHostImplTest, PinchZoomTriggersPageScaleAnimation) {
// No zoom animation if page_scale is >= 1.05 * min_page_scale.
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
did_request_redraw_ = false;
@@ -3065,7 +3192,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
DCHECK(scroll_layer);
float min_page_scale = 0.5f;
- float max_page_scale = 4.f;
+ float max_page_scale = 4;
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromSeconds(1);
base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
@@ -3077,7 +3204,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
// Non-anchor zoom-in
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
scroll_layer->layer_tree_impl()
->property_trees()
@@ -3088,7 +3215,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
did_request_next_frame_ = false;
host_impl_->active_tree()->SetPendingPageScaleAnimation(
std::unique_ptr<PendingPageScaleAnimation>(
- new PendingPageScaleAnimation(gfx::Vector2d(), false, 2.f,
+ new PendingPageScaleAnimation(gfx::Vector2d(), false, 2,
duration)));
host_impl_->ActivateSyncTree();
EXPECT_FALSE(did_request_redraw_);
@@ -3138,7 +3265,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimation) {
// Anchor zoom-out
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
scroll_layer->layer_tree_impl()
->property_trees()
@@ -3194,7 +3321,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
DCHECK(scroll_layer);
float min_page_scale = 0.5f;
- float max_page_scale = 4.f;
+ float max_page_scale = 4;
base::TimeTicks start_time =
base::TimeTicks() + base::TimeDelta::FromSeconds(1);
base::TimeDelta duration = base::TimeDelta::FromMilliseconds(100);
@@ -3206,7 +3333,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
// Anchor zoom with unchanged page scale should not change scroll or scale.
{
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
scroll_layer->layer_tree_impl()
->property_trees()
@@ -3215,8 +3342,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
host_impl_->active_tree()->SetPendingPageScaleAnimation(
std::unique_ptr<PendingPageScaleAnimation>(
- new PendingPageScaleAnimation(gfx::Vector2d(), true, 1.f,
- duration)));
+ new PendingPageScaleAnimation(gfx::Vector2d(), true, 1, duration)));
host_impl_->ActivateSyncTree();
begin_frame_args.frame_time = start_time;
begin_frame_args.sequence_number++;
@@ -3247,7 +3373,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationNoOp) {
TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
CreatePendingTree();
- host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 1);
SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50),
gfx::Size(100, 100), gfx::Size(100, 100));
host_impl_->ActivateSyncTree();
@@ -3257,8 +3383,8 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
DCHECK(scroll_layer);
float min_page_scale = 0.5f;
- float max_page_scale = 4.f;
- host_impl_->sync_tree()->PushPageScaleFromMainThread(1.f, min_page_scale,
+ float max_page_scale = 4;
+ host_impl_->sync_tree()->PushPageScaleFromMainThread(1, min_page_scale,
max_page_scale);
host_impl_->ActivateSyncTree();
@@ -3268,7 +3394,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationTransferedOnSyncTreeActivate) {
base::TimeTicks third_through_animation = start_time + duration / 3;
base::TimeTicks halfway_through_animation = start_time + duration / 2;
base::TimeTicks end_time = start_time + duration;
- float target_scale = 2.f;
+ float target_scale = 2;
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
@@ -3385,7 +3511,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
scroll_layer->layer_tree_impl()
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
@@ -3393,8 +3519,8 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
did_complete_page_scale_animation_ = false;
host_impl_->active_tree()->SetPendingPageScaleAnimation(
- std::unique_ptr<PendingPageScaleAnimation>(new PendingPageScaleAnimation(
- gfx::Vector2d(), false, 2.f, duration)));
+ std::unique_ptr<PendingPageScaleAnimation>(
+ new PendingPageScaleAnimation(gfx::Vector2d(), false, 2, duration)));
host_impl_->ActivateSyncTree();
begin_frame_args.frame_time = start_time;
begin_frame_args.sequence_number++;
@@ -3420,7 +3546,7 @@ TEST_F(LayerTreeHostImplTest, PageScaleAnimationCompletedNotification) {
TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
DrawFrame();
LayerImpl* inner_scroll = InnerViewportScrollLayer();
@@ -3428,10 +3554,8 @@ TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) {
EXPECT_EQ(gfx::ScrollOffset(50, 50), inner_scroll->MaxScrollOffset());
PropertyTrees* property_trees = host_impl_->active_tree()->property_trees();
- property_trees->SetInnerViewportContainerBoundsDelta(
- gfx::Vector2dF(15.f, 15.f));
- property_trees->SetOuterViewportContainerBoundsDelta(
- gfx::Vector2dF(7.f, 7.f));
+ property_trees->SetInnerViewportContainerBoundsDelta(gfx::Vector2dF(15, 15));
+ property_trees->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(7, 7));
EXPECT_EQ(gfx::ScrollOffset(42, 42), inner_scroll->MaxScrollOffset());
property_trees->SetInnerViewportContainerBoundsDelta(gfx::Vector2dF());
@@ -3440,8 +3564,7 @@ TEST_F(LayerTreeHostImplTest, MaxScrollOffsetAffectedByViewportBoundsDelta) {
GetScrollNode(inner_scroll)->bounds = inner_scroll->bounds();
DrawFrame();
- property_trees->SetOuterViewportContainerBoundsDelta(
- gfx::Vector2dF(60.f, 60.f));
+ property_trees->SetOuterViewportContainerBoundsDelta(gfx::Vector2dF(60, 60));
EXPECT_EQ(gfx::ScrollOffset(10, 10), inner_scroll->MaxScrollOffset());
}
@@ -3495,7 +3618,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
host_impl_->InitializeFrameSink(layer_tree_frame_sink_.get());
SetupViewportLayersInnerScrolls(viewport_size, content_size);
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 4);
auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>(
host_impl_->active_tree(), VERTICAL, 10, 0, false);
@@ -3544,9 +3667,9 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
}
// If no scroll happened during a scroll gesture, it should have no effect.
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::WHEEL);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
EXPECT_EQ(base::TimeDelta(), requested_animation_delay_);
@@ -3554,10 +3677,10 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
// For Aura Overlay Scrollbar, if no scroll happened during a scroll
// gesture, shows scrollbars and schedules a delay fade out.
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 0)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
if (animator == LayerTreeSettings::AURA_OVERLAY) {
@@ -3586,8 +3709,9 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
// After a scroll, a scrollbar animation should be scheduled about 20ms from
// now.
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 5)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get());
EXPECT_FALSE(did_request_next_frame_);
EXPECT_TRUE(did_request_redraw_);
@@ -3601,7 +3725,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
EXPECT_TRUE(animation_task_.is_null());
}
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
if (expecting_animations) {
@@ -3662,7 +3786,7 @@ class LayerTreeHostImplTestScrollbarAnimation : public LayerTreeHostImplTest {
EXPECT_TRUE(animation_task_.is_null());
// Changing page scale triggers scrollbar animation.
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 4);
host_impl_->active_tree()->SetPageScaleOnActiveTree(1.1f);
EXPECT_FALSE(did_request_next_frame_);
EXPECT_FALSE(did_request_redraw_);
@@ -3716,7 +3840,7 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest {
SetupScrollbarLayer(scroll, scrollbar);
scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(90, 0));
- host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 1);
UpdateDrawProperties(host_impl_->pending_tree());
host_impl_->ActivateSyncTree();
@@ -3734,10 +3858,11 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest {
EXPECT_EQ(nullptr, host_impl_->ScrollbarAnimationControllerForElementId(
scroll->element_id()));
}
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 5)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 5)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
CreatePendingTree();
// To test the case where the effect tree index of scrollbar layer changes,
@@ -3756,22 +3881,22 @@ class LayerTreeHostImplTestScrollbarOpacity : public LayerTreeHostImplTest {
EffectNode* pending_tree_node = GetEffectNode(pending_scrollbar_layer);
if (expecting_animations) {
- EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity);
- EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity());
+ EXPECT_FLOAT_EQ(1, active_tree_node->opacity);
+ EXPECT_FLOAT_EQ(1, active_scrollbar_layer->Opacity());
} else {
- EXPECT_FLOAT_EQ(0.f, active_tree_node->opacity);
- EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity());
+ EXPECT_FLOAT_EQ(0, active_tree_node->opacity);
+ EXPECT_FLOAT_EQ(0, active_scrollbar_layer->Opacity());
}
- EXPECT_FLOAT_EQ(0.f, pending_tree_node->opacity);
+ EXPECT_FLOAT_EQ(0, pending_tree_node->opacity);
host_impl_->ActivateSyncTree();
active_tree_node = GetEffectNode(active_scrollbar_layer);
if (expecting_animations) {
- EXPECT_FLOAT_EQ(1.f, active_tree_node->opacity);
- EXPECT_FLOAT_EQ(1.f, active_scrollbar_layer->Opacity());
+ EXPECT_FLOAT_EQ(1, active_tree_node->opacity);
+ EXPECT_FLOAT_EQ(1, active_scrollbar_layer->Opacity());
} else {
- EXPECT_FLOAT_EQ(0.f, active_tree_node->opacity);
- EXPECT_FLOAT_EQ(0.f, active_scrollbar_layer->Opacity());
+ EXPECT_FLOAT_EQ(0, active_tree_node->opacity);
+ EXPECT_FLOAT_EQ(0, active_scrollbar_layer->Opacity());
}
}
};
@@ -3832,8 +3957,8 @@ class LayerTreeHostImplTestMultiScrollable : public LayerTreeHostImplTest {
}
void ResetScrollbars() {
- GetEffectNode(scrollbar_1_)->opacity = 0.f;
- GetEffectNode(scrollbar_2_)->opacity = 0.f;
+ GetEffectNode(scrollbar_1_)->opacity = 0;
+ GetEffectNode(scrollbar_2_)->opacity = 0;
UpdateDrawProperties(host_impl_->active_tree());
if (is_aura_scrollbar_)
@@ -3855,15 +3980,16 @@ TEST_F(LayerTreeHostImplTestMultiScrollable,
SetUpLayers(settings);
- EXPECT_EQ(scrollbar_1_->Opacity(), 0.f);
- EXPECT_EQ(scrollbar_2_->Opacity(), 0.f);
+ EXPECT_EQ(scrollbar_1_->Opacity(), 0);
+ EXPECT_EQ(scrollbar_2_->Opacity(), 0);
// Scroll on root should flash all scrollbars.
- host_impl_->RootScrollBegin(BeginState(gfx::Point(20, 20)).get(),
- InputHandler::WHEEL);
+ host_impl_->RootScrollBegin(
+ BeginState(gfx::Point(20, 20), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(
UpdateState(gfx::Point(20, 20), gfx::Vector2d(0, 10)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_TRUE(scrollbar_1_->Opacity());
EXPECT_TRUE(scrollbar_2_->Opacity());
@@ -3872,9 +3998,10 @@ TEST_F(LayerTreeHostImplTestMultiScrollable,
ResetScrollbars();
// Scroll on child should flash all scrollbars.
- host_impl_->ScrollAnimatedBegin(BeginState(gfx::Point(70, 70)).get());
+ host_impl_->ScrollAnimatedBegin(
+ BeginState(gfx::Point(70, 70), gfx::Vector2dF(0, 100)).get());
host_impl_->ScrollAnimated(gfx::Point(70, 70), gfx::Vector2d(0, 100));
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_TRUE(scrollbar_1_->Opacity());
EXPECT_TRUE(scrollbar_2_->Opacity());
@@ -3891,8 +4018,8 @@ TEST_F(LayerTreeHostImplTestMultiScrollable, ScrollbarFlashWhenMouseEnter) {
SetUpLayers(settings);
- EXPECT_EQ(scrollbar_1_->Opacity(), 0.f);
- EXPECT_EQ(scrollbar_2_->Opacity(), 0.f);
+ EXPECT_EQ(scrollbar_1_->Opacity(), 0);
+ EXPECT_EQ(scrollbar_2_->Opacity(), 0);
// Scroll should flash when mouse enter.
host_impl_->MouseMoveAt(gfx::Point(1, 1));
@@ -3951,14 +4078,16 @@ TEST_F(LayerTreeHostImplTest, ScrollHitTestOnScrollbar) {
// Wheel scroll on root scrollbar should process on impl thread.
{
InputHandler::ScrollStatus status = host_impl_->RootScrollBegin(
- BeginState(gfx::Point(1, 1)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(1, 1), gfx::Vector2dF()).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
}
// Touch scroll on root scrollbar should process on main thread.
{
InputHandler::ScrollStatus status = host_impl_->RootScrollBegin(
- BeginState(gfx::Point(1, 1)).get(), InputHandler::TOUCHSCREEN);
+ BeginState(gfx::Point(1, 1), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kScrollbarScrolling,
status.main_thread_scrolling_reasons);
@@ -3967,7 +4096,8 @@ TEST_F(LayerTreeHostImplTest, ScrollHitTestOnScrollbar) {
// Wheel scroll on scrollbar should process on impl thread.
{
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(51, 51)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(51, 51), gfx::Vector2dF()).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNotScrollingOnMain,
status.main_thread_scrolling_reasons);
@@ -3976,7 +4106,8 @@ TEST_F(LayerTreeHostImplTest, ScrollHitTestOnScrollbar) {
// Touch scroll on scrollbar should process on main thread.
{
InputHandler::ScrollStatus status = host_impl_->RootScrollBegin(
- BeginState(gfx::Point(51, 51)).get(), InputHandler::TOUCHSCREEN);
+ BeginState(gfx::Point(51, 51), gfx::Vector2dF()).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kScrollbarScrolling,
status.main_thread_scrolling_reasons);
@@ -4002,7 +4133,7 @@ TEST_F(LayerTreeHostImplTest, ScrollbarVisibilityChangeCausesRedrawAndCommit) {
SetupScrollbarLayer(scroll, scrollbar);
scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(90, 0));
- host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 1);
host_impl_->ActivateSyncTree();
ScrollbarAnimationController* scrollbar_controller =
@@ -4121,9 +4252,11 @@ TEST_F(LayerTreeHostImplTest, ScrollbarRegistration) {
// Scrolling the viewport should result in a scrollbar animation update.
animation_task_.Reset();
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(10, 10)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(10, 10)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(animation_task_.is_null());
animation_task_.Reset();
@@ -4203,18 +4336,22 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeMouseMove) {
EXPECT_FALSE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL));
// Scroll the page down which moves the thumb down.
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 100)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 100)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Move the mouse near the thumb in the top position.
host_impl_->MouseMoveAt(near_thumb_at_top);
EXPECT_FALSE(scrollbar_controller->MouseIsNearScrollbarThumb(VERTICAL));
// Scroll the page up which moves the thumb back up.
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, -100)).get(),
+ InputHandler::WHEEL);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, -100)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Move the mouse near the thumb in the top position.
host_impl_->MouseMoveAt(near_thumb_at_top);
@@ -4292,11 +4429,11 @@ void LayerTreeHostImplTest::SetupMouseMoveAtWithDeviceScale(
}
TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf1) {
- SetupMouseMoveAtWithDeviceScale(1.f);
+ SetupMouseMoveAtWithDeviceScale(1);
}
TEST_F(LayerTreeHostImplTest, MouseMoveAtWithDeviceScaleOf2) {
- SetupMouseMoveAtWithDeviceScale(2.f);
+ SetupMouseMoveAtWithDeviceScale(2);
}
// This test verifies that only SurfaceLayers in the viewport and have fallbacks
@@ -4323,7 +4460,7 @@ TEST_F(LayerTreeHostImplTest, ActivationDependenciesInMetadata) {
child->SetRange(
viz::SurfaceRange(fallback_surfaces[i], primary_surfaces[i]), 2u);
CopyProperties(root, child);
- child->SetOffsetToTransformParent(gfx::Vector2dF(25.f * i, 0.f));
+ child->SetOffsetToTransformParent(gfx::Vector2dF(25.0f * i, 0));
}
base::flat_set<viz::SurfaceRange> surfaces_set;
@@ -4415,14 +4552,14 @@ TEST_F(LayerTreeHostImplTest, SurfaceReferencesChangeCausesDamage) {
TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
DrawFrame();
{
viz::CompositorFrameMetadata metadata =
host_impl_->MakeCompositorFrameMetadata();
EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
- EXPECT_EQ(1.f, metadata.page_scale_factor);
- EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size);
+ EXPECT_EQ(1, metadata.page_scale_factor);
+ EXPECT_EQ(gfx::SizeF(50, 50), metadata.scrollable_viewport_size);
EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
}
@@ -4430,46 +4567,47 @@ TEST_F(LayerTreeHostImplTest, CompositorFrameMetadata) {
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
{
viz::CompositorFrameMetadata metadata =
host_impl_->MakeCompositorFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
}
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
{
viz::CompositorFrameMetadata metadata =
host_impl_->MakeCompositorFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
}
// Page scale should update metadata correctly (shrinking only the viewport).
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
- host_impl_->PinchGestureUpdate(2.f, gfx::Point());
+ host_impl_->PinchGestureUpdate(2, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
{
viz::CompositorFrameMetadata metadata =
host_impl_->MakeCompositorFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
- EXPECT_EQ(2.f, metadata.page_scale_factor);
- EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
+ EXPECT_EQ(2, metadata.page_scale_factor);
+ EXPECT_EQ(gfx::SizeF(25, 25), metadata.scrollable_viewport_size);
EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
}
// Likewise if set from the main thread.
host_impl_->ProcessScrollDeltas();
- host_impl_->active_tree()->PushPageScaleFromMainThread(4.f, 0.5f, 4.f);
- host_impl_->active_tree()->SetPageScaleOnActiveTree(4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(4, 0.5f, 4);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(4);
{
viz::CompositorFrameMetadata metadata =
host_impl_->MakeCompositorFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
- EXPECT_EQ(4.f, metadata.page_scale_factor);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
+ EXPECT_EQ(4, metadata.page_scale_factor);
EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size);
EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
}
@@ -4549,6 +4687,9 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) {
{
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
EXPECT_FALSE(frame.has_no_damage);
@@ -4559,12 +4700,13 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) {
EXPECT_NE(total_quad_count, 0u);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
// Stops the child layer from drawing. We should have damage from this but
// should not have any quads. This should clear the damaged area.
layer->SetDrawsContent(false);
- GetEffectNode(root)->opacity = 0.f;
+ GetEffectNode(root)->opacity = 0;
UpdateDrawProperties(host_impl_->active_tree());
// The background is default to transparent. If the background is opaque, we
@@ -4574,6 +4716,9 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) {
{
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
EXPECT_FALSE(frame.has_no_damage);
@@ -4584,12 +4729,16 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) {
EXPECT_EQ(total_quad_count, 0u);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
// Now tries to draw again. Nothing changes, so should have no damage, no
// render pass, and no quad.
{
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
EXPECT_TRUE(frame.has_no_damage);
@@ -4600,6 +4749,7 @@ TEST_F(LayerTreeHostImplTest, DamageShouldNotCareAboutContributingLayers) {
EXPECT_EQ(total_quad_count, 0u);
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
}
@@ -4636,7 +4786,7 @@ TEST_F(LayerTreeHostImplTest, DidDrawNotCalledOnHiddenLayer) {
layer->SetBounds(gfx::Size(10, 10));
CopyProperties(root, layer);
// Ensure visible_layer_rect for layer is not empty
- layer->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f));
+ layer->SetOffsetToTransformParent(gfx::Vector2dF(100, 100));
UpdateDrawProperties(host_impl_->active_tree());
EXPECT_FALSE(layer->will_draw_returned_true());
@@ -4893,9 +5043,13 @@ TEST_F(LayerTreeHostImplPrepareToDrawTest, PrepareToDrawSucceedsAndFails) {
host_impl_->SetRequiresHighResToDraw();
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(testcase.expected_result, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
}
@@ -4959,7 +5113,8 @@ TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
// Scroll event is ignored because layer is not scrollable.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
status.main_thread_scrolling_reasons);
@@ -4969,7 +5124,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootIgnored) {
TEST_F(LayerTreeHostImplTest, ClampingAfterActivation) {
CreatePendingTree();
- host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 1);
SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50),
gfx::Size(100, 100), gfx::Size(100, 100));
host_impl_->ActivateSyncTree();
@@ -5005,8 +5160,9 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest {
bool init = LayerTreeHostImplTest::CreateHostImpl(
settings, std::move(layer_tree_frame_sink));
if (init) {
- host_impl_->active_tree()->SetTopControlsHeight(top_controls_height_);
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f);
+ host_impl_->active_tree()->SetBrowserControlsParams(
+ {top_controls_height_, 0, 0, 0, false, false});
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f, 1.f);
host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
}
return init;
@@ -5027,9 +5183,9 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest {
const gfx::Size& inner_viewport_size,
const gfx::Size& outer_viewport_size,
const gfx::Size& scroll_layer_size) {
- tree_impl->set_browser_controls_shrink_blink_size(true);
- tree_impl->SetTopControlsHeight(top_controls_height_);
- tree_impl->SetCurrentBrowserControlsShownRatio(1.f);
+ tree_impl->SetBrowserControlsParams(
+ {top_controls_height_, 0, 0, 0, false, true});
+ tree_impl->SetCurrentBrowserControlsShownRatio(1.f, 1.f);
tree_impl->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
host_impl_->DidChangeBrowserControlsPosition();
@@ -5050,7 +5206,7 @@ class LayerTreeHostImplBrowserControlsTest : public LayerTreeHostImplTest {
auto* tree = host_impl_->active_tree(); \
auto* property_trees = tree->property_trees(); \
EXPECT_EQ(expected_browser_controls_shown_ratio, \
- tree->CurrentBrowserControlsShownRatio()); \
+ tree->CurrentTopControlsShownRatio()); \
EXPECT_EQ( \
tree->top_controls_height() * expected_browser_controls_shown_ratio, \
host_impl_->browser_controls_manager()->ContentTopOffset()); \
@@ -5087,32 +5243,33 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
EXPECT_VIEWPORT_GEOMETRIES(1);
EXPECT_EQ(gfx::SizeF(50, 50), active_tree->ScrollableSize());
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 25)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
host_impl_->browser_controls_manager()->ScrollBegin();
// Hide the browser controls by a bit, the scrollable size should increase but
// the actual content bounds shouldn't.
- host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
+ host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0, 25));
EXPECT_VIEWPORT_GEOMETRIES(0.5f);
EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize());
// Fully hide the browser controls.
- host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
+ host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0, 25));
EXPECT_VIEWPORT_GEOMETRIES(0);
EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
// Scrolling additionally shouldn't have any effect.
- host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
+ host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0, 25));
EXPECT_VIEWPORT_GEOMETRIES(0);
EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
host_impl_->browser_controls_manager()->ScrollEnd();
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
// Ensure that moving the browser controls (i.e. omnibox/url-bar on mobile) on
@@ -5133,7 +5290,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
LayerImpl* content = AddLayer();
content->SetBounds(gfx::Size(100, 100));
CopyProperties(OuterViewportScrollLayer(), content);
- active_tree->PushPageScaleFromMainThread(0.5f, 0.5f, 4.f);
+ active_tree->PushPageScaleFromMainThread(0.5f, 0.5f, 4);
DrawFrame();
@@ -5142,21 +5299,22 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
EXPECT_VIEWPORT_GEOMETRIES(1.0f);
EXPECT_EQ(gfx::SizeF(200, 1000), active_tree->ScrollableSize());
- ASSERT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ ASSERT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 25)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
// Hide the browser controls by 25px. The outer clip should expand by 50px as
// because the outer viewport is sized based on the minimum scale, in this
// case 0.5. Therefore, changes to the outer viewport need to be divided by
// the minimum scale as well.
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0.f, 25.f)).get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(0, 25)).get());
EXPECT_VIEWPORT_GEOMETRIES(0.5f);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
// Tests that browser controls affect the position of horizontal scrollbars.
@@ -5189,18 +5347,19 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds());
EXPECT_EQ(gfx::Rect(20, 0, 10, 3), scrollbar_layer->ComputeThumbQuadRect());
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 25)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
host_impl_->browser_controls_manager()->ScrollBegin();
// Hide the browser controls by a bit, the scrollable size should increase but
// the actual content bounds shouldn't.
{
- host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
+ host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0, 25));
host_impl_->active_tree()->UpdateScrollbarGeometries();
EXPECT_VIEWPORT_GEOMETRIES(0.5f);
EXPECT_EQ(gfx::SizeF(50, 75), active_tree->ScrollableSize());
@@ -5211,7 +5370,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// Fully hide the browser controls.
{
- host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
+ host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0, 25));
host_impl_->active_tree()->UpdateScrollbarGeometries();
EXPECT_VIEWPORT_GEOMETRIES(0);
EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
@@ -5222,7 +5381,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// Additional scrolling shouldn't have any effect.
{
- host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 25.f));
+ host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0, 25));
EXPECT_VIEWPORT_GEOMETRIES(0);
EXPECT_EQ(gfx::SizeF(50, 100), active_tree->ScrollableSize());
EXPECT_EQ(gfx::Size(50, 15), scrollbar_layer->bounds());
@@ -5231,7 +5390,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
}
host_impl_->browser_controls_manager()->ScrollEnd();
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
TEST_F(LayerTreeHostImplBrowserControlsTest,
@@ -5240,21 +5399,22 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
gfx::Size(10, 10), gfx::Size(10, 10), gfx::Size(10, 10));
DrawFrame();
+ gfx::Vector2dF top_controls_scroll_delta(0, 5.25f);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(), top_controls_scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
// 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 browser controls.
- gfx::Vector2dF top_controls_scroll_delta(0.f, 5.25f);
host_impl_->browser_controls_manager()->ScrollBegin();
host_impl_->browser_controls_manager()->ScrollBy(top_controls_scroll_delta);
host_impl_->browser_controls_manager()->ScrollEnd();
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
auto* property_trees = host_impl_->active_tree()->property_trees();
EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(),
property_trees->inner_viewport_container_bounds_delta().y());
@@ -5277,70 +5437,67 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// Need SetDrawsContent so ScrollBegin's hit test finds an actual layer.
outer_scroll->SetDrawsContent(true);
- host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2, 1, 2);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
- host_impl_->ScrollBy(
- UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 50.f)).get());
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 50)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 50)).get());
// 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()->CurrentBrowserControlsShownRatio());
- EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio());
+ EXPECT_EQ(0, inner_scroll->CurrentScrollOffset().y());
EXPECT_EQ(100, inner_scroll->bounds().height());
EXPECT_EQ(100, outer_scroll->bounds().height());
// The inner viewport should be scrollable by 50px * page_scale.
- host_impl_->ScrollBy(
- UpdateState(gfx::Point(), gfx::Vector2dF(0.f, 100.f)).get());
- EXPECT_EQ(50.f, inner_scroll->CurrentScrollOffset().y());
- EXPECT_EQ(0.f, outer_scroll->CurrentScrollOffset().y());
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get());
+ EXPECT_EQ(50, inner_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(0, outer_scroll->CurrentScrollOffset().y());
EXPECT_EQ(gfx::ScrollOffset(), outer_scroll->MaxScrollOffset());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, -50)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
outer_scroll->scroll_tree_index());
- host_impl_->ScrollBy(
- UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50.f)).get());
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, -50)).get());
// 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()->CurrentBrowserControlsShownRatio());
+ EXPECT_EQ(1, host_impl_->active_tree()->CurrentTopControlsShownRatio());
EXPECT_EQ(50, inner_scroll->bounds().height());
EXPECT_EQ(100, outer_scroll->bounds().height());
- EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
- EXPECT_EQ(25.f, inner_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(25, outer_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(25, inner_scroll->CurrentScrollOffset().y());
// Now when we continue scrolling, make sure the outer viewport gets scrolled
// since it wasn't scrollable when the scroll began.
- host_impl_->ScrollBy(
- UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -20.f)).get());
- EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
- EXPECT_EQ(15.f, inner_scroll->CurrentScrollOffset().y());
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, -20)).get());
+ EXPECT_EQ(25, outer_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(15, inner_scroll->CurrentScrollOffset().y());
- host_impl_->ScrollBy(
- UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -30.f)).get());
- EXPECT_EQ(25.f, outer_scroll->CurrentScrollOffset().y());
- EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
+ host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2dF(0, -30)).get());
+ EXPECT_EQ(25, outer_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(0, inner_scroll->CurrentScrollOffset().y());
host_impl_->ScrollBy(
- UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(), gfx::Vector2dF(0.f, -50)).get());
+ host_impl_->ScrollEnd();
- EXPECT_EQ(0.f, outer_scroll->CurrentScrollOffset().y());
- EXPECT_EQ(0.f, inner_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(0, outer_scroll->CurrentScrollOffset().y());
+ EXPECT_EQ(0, inner_scroll->CurrentScrollOffset().y());
}
// Test that the fixed position container delta is appropriately adjusted
@@ -5349,22 +5506,23 @@ 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);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 2);
float page_scale = 1.5f;
// Zoom in, since the fixed container is the outer viewport, the delta should
// not be scaled.
- host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1, 2);
+ gfx::Vector2dF top_controls_scroll_delta(0, 20);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(), top_controls_scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
// 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_->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(),
@@ -5373,7 +5531,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, FixedContainerDelta) {
auto* property_trees = host_impl_->active_tree()->property_trees();
EXPECT_FLOAT_EQ(top_controls_scroll_delta.y(),
property_trees->outer_viewport_container_bounds_delta().y());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Scroll past the maximum extent. The delta shouldn't be greater than the
// browser controls height.
@@ -5381,10 +5539,10 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, FixedContainerDelta) {
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_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, top_controls_height_),
property_trees->outer_viewport_container_bounds_delta());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Scroll in the direction to make the browser controls show.
host_impl_->browser_controls_manager()->ScrollBegin();
@@ -5410,17 +5568,15 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, BrowserControlsPushUnsentRatio) {
LayerImpl* outer_scroll = OuterViewportScrollLayer();
outer_scroll->SetDrawsContent(true);
- host_impl_->active_tree()->PushBrowserControlsFromMainThread(1);
- ASSERT_EQ(1.0f,
- host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
+ host_impl_->active_tree()->PushBrowserControlsFromMainThread(1, 1);
+ ASSERT_EQ(1.0f, 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()->SetCurrentBrowserControlsShownRatio(0.5f, 0.5f);
+ ASSERT_EQ(0.5f, host_impl_->active_tree()->CurrentTopControlsShownRatio());
- host_impl_->active_tree()->PushBrowserControlsFromMainThread(0);
+ host_impl_->active_tree()->PushBrowserControlsFromMainThread(0, 0);
- ASSERT_EQ(0, host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
+ ASSERT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio());
}
// Test that if a scrollable sublayer doesn't consume the scroll,
@@ -5434,7 +5590,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
DrawFrame();
// Show browser controls
- EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
+ EXPECT_EQ(1, host_impl_->active_tree()->CurrentTopControlsShownRatio());
LayerImpl* outer_viewport_scroll_layer = OuterViewportScrollLayer();
LayerImpl* child = AddLayer();
@@ -5451,17 +5607,17 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
UpdateDrawProperties(host_impl_->active_tree());
// Scroll child to the limit.
- SetScrollOffsetDelta(child, gfx::Vector2dF(0, 100.f));
+ SetScrollOffsetDelta(child, gfx::Vector2dF(0, 100));
// Scroll 25px to hide browser controls
- gfx::Vector2dF scroll_delta(0.f, 25.f);
+ gfx::Vector2dF scroll_delta(0, 25);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Browser controls should be hidden
EXPECT_EQ(scroll_delta.y(),
@@ -5478,19 +5634,19 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
layer_size_, layer_size_, layer_size_);
DrawFrame();
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f);
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0, 0);
host_impl_->active_tree()->top_controls_shown_ratio()->PushMainToPending(
- 30.f / top_controls_height_);
+ 30 / top_controls_height_);
host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
- EXPECT_FLOAT_EQ(30.f,
+ EXPECT_FLOAT_EQ(30,
host_impl_->browser_controls_manager()->ContentTopOffset());
- EXPECT_FLOAT_EQ(-20.f,
+ EXPECT_FLOAT_EQ(-20,
host_impl_->browser_controls_manager()->ControlsTopOffset());
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f);
- EXPECT_FLOAT_EQ(0.f,
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0, 0);
+ EXPECT_FLOAT_EQ(0,
host_impl_->browser_controls_manager()->ContentTopOffset());
- EXPECT_FLOAT_EQ(-50.f,
+ EXPECT_FLOAT_EQ(-50,
host_impl_->browser_controls_manager()->ControlsTopOffset());
host_impl_->DidChangeBrowserControlsPosition();
@@ -5511,33 +5667,33 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// Changing SetCurrentBrowserControlsShownRatio is one way to cause the
// pending tree to update it's viewport.
- host_impl_->SetCurrentBrowserControlsShownRatio(0.f);
+ host_impl_->SetCurrentBrowserControlsShownRatio(0, 0);
EXPECT_FLOAT_EQ(top_controls_height_,
host_impl_->pending_tree()
->property_trees()
->inner_viewport_container_bounds_delta()
.y());
- host_impl_->SetCurrentBrowserControlsShownRatio(0.5f);
+ host_impl_->SetCurrentBrowserControlsShownRatio(0.5f, 0.5f);
EXPECT_FLOAT_EQ(0.5f * top_controls_height_,
host_impl_->pending_tree()
->property_trees()
->inner_viewport_container_bounds_delta()
.y());
- host_impl_->SetCurrentBrowserControlsShownRatio(1.f);
- EXPECT_FLOAT_EQ(0.f, host_impl_->pending_tree()
- ->property_trees()
- ->inner_viewport_container_bounds_delta()
- .y());
+ host_impl_->SetCurrentBrowserControlsShownRatio(1, 1);
+ EXPECT_FLOAT_EQ(0, host_impl_->pending_tree()
+ ->property_trees()
+ ->inner_viewport_container_bounds_delta()
+ .y());
// Pushing changes from the main thread is the second way. These values are
- // added to the 1.f set above.
- host_impl_->pending_tree()->PushBrowserControlsFromMainThread(-0.5f);
+ // added to the 1 set above.
+ host_impl_->pending_tree()->PushBrowserControlsFromMainThread(-0.5f, -0.5f);
EXPECT_FLOAT_EQ(0.5f * top_controls_height_,
host_impl_->pending_tree()
->property_trees()
->inner_viewport_container_bounds_delta()
.y());
- host_impl_->pending_tree()->PushBrowserControlsFromMainThread(-1.f);
+ host_impl_->pending_tree()->PushBrowserControlsFromMainThread(-1, -1);
EXPECT_FLOAT_EQ(top_controls_height_,
host_impl_->pending_tree()
->property_trees()
@@ -5554,35 +5710,34 @@ TEST_F(LayerTreeHostImplBrowserControlsTest, ApplyDeltaOnTreeActivation) {
DrawFrame();
host_impl_->active_tree()->top_controls_shown_ratio()->PushMainToPending(
- 20.f / top_controls_height_);
+ 20 / top_controls_height_);
host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(
- 15.f / top_controls_height_);
+ 15 / top_controls_height_, 15 / top_controls_height_);
host_impl_->active_tree()
->top_controls_shown_ratio()
->PullDeltaForMainThread();
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f);
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0, 0);
host_impl_->sync_tree()->PushBrowserControlsFromMainThread(
- 15.f / top_controls_height_);
+ 15 / top_controls_height_, 15 / top_controls_height_);
host_impl_->DidChangeBrowserControlsPosition();
auto* property_trees = host_impl_->active_tree()->property_trees();
- EXPECT_EQ(gfx::Vector2dF(0.f, 50.f),
+ EXPECT_EQ(gfx::Vector2dF(0, 50),
property_trees->inner_viewport_container_bounds_delta());
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset());
+ EXPECT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset());
host_impl_->ActivateSyncTree();
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset());
- EXPECT_EQ(gfx::Vector2dF(0.f, 50.f),
+ EXPECT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset());
+ EXPECT_EQ(gfx::Vector2dF(0, 50),
property_trees->inner_viewport_container_bounds_delta());
EXPECT_FLOAT_EQ(
- -15.f, host_impl_->active_tree()->top_controls_shown_ratio()->Delta() *
- top_controls_height_);
+ -15, host_impl_->active_tree()->top_controls_shown_ratio()->Delta() *
+ top_controls_height_);
EXPECT_FLOAT_EQ(
- 15.f,
- host_impl_->active_tree()->top_controls_shown_ratio()->ActiveBase() *
- top_controls_height_);
+ 15, host_impl_->active_tree()->top_controls_shown_ratio()->ActiveBase() *
+ top_controls_height_);
}
// Test that changing the browser controls layout height is correctly applied to
@@ -5595,22 +5750,23 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
layer_size_, layer_size_, layer_size_);
DrawFrame();
- host_impl_->sync_tree()->PushBrowserControlsFromMainThread(1.f);
- host_impl_->sync_tree()->set_browser_controls_shrink_blink_size(true);
+ host_impl_->sync_tree()->PushBrowserControlsFromMainThread(1, 1);
+ host_impl_->sync_tree()->SetBrowserControlsParams(
+ {top_controls_height_, 0, 0, 0, false, true});
- host_impl_->active_tree()->top_controls_shown_ratio()->PushMainToPending(1.f);
+ host_impl_->active_tree()->top_controls_shown_ratio()->PushMainToPending(1);
host_impl_->active_tree()->top_controls_shown_ratio()->PushPendingToActive();
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0.f);
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(0, 0);
host_impl_->DidChangeBrowserControlsPosition();
auto* property_trees = host_impl_->active_tree()->property_trees();
EXPECT_EQ(gfx::Vector2dF(0, 50),
property_trees->inner_viewport_container_bounds_delta());
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset());
+ EXPECT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset());
host_impl_->ActivateSyncTree();
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset());
+ EXPECT_EQ(0, 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
@@ -5618,13 +5774,12 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
EXPECT_EQ(gfx::Vector2dF(0, 50),
property_trees->inner_viewport_container_bounds_delta());
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f);
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1, 1);
host_impl_->DidChangeBrowserControlsPosition();
- 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_EQ(1, host_impl_->browser_controls_manager()->TopControlsShownRatio());
+ EXPECT_EQ(50, host_impl_->browser_controls_manager()->TopControlsHeight());
+ EXPECT_EQ(50, host_impl_->browser_controls_manager()->ContentTopOffset());
EXPECT_EQ(gfx::Vector2dF(),
property_trees->inner_viewport_container_bounds_delta());
}
@@ -5638,34 +5793,34 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
gfx::Size(100, 100), gfx::Size(200, 200), gfx::Size(200, 400));
DrawFrame();
- EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
+ EXPECT_EQ(1, host_impl_->active_tree()->CurrentTopControlsShownRatio());
LayerImpl* outer_scroll = OuterViewportScrollLayer();
LayerImpl* inner_scroll = InnerViewportScrollLayer();
// Scroll the viewports to max scroll offset.
- SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f));
- SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100.f));
+ SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200));
+ SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100));
gfx::ScrollOffset viewport_offset =
host_impl_->active_tree()->TotalScrollOffset();
EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(), viewport_offset);
// Hide the browser controls by 25px.
- gfx::Vector2dF scroll_delta(0.f, 25.f);
+ gfx::Vector2dF scroll_delta(0, 25);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
// scrolling down at the max extents no longer hides the browser controls
- EXPECT_EQ(1.f, host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
+ EXPECT_EQ(1, host_impl_->active_tree()->CurrentTopControlsShownRatio());
// forcefully hide the browser controls by 25px
host_impl_->browser_controls_manager()->ScrollBy(scroll_delta);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FLOAT_EQ(
scroll_delta.y(),
@@ -5682,21 +5837,21 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
viewport_offset = host_impl_->active_tree()->TotalScrollOffset();
// Bring the browser controls down by 25px.
- scroll_delta = gfx::Vector2dF(0.f, -25.f);
+ scroll_delta = gfx::Vector2dF(0, -25);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The viewport offset shouldn't have changed.
EXPECT_EQ(viewport_offset, host_impl_->active_tree()->TotalScrollOffset());
// Scroll the viewports to max scroll offset.
- SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200.f));
- SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100.f));
+ SetScrollOffsetDelta(outer_scroll, gfx::Vector2dF(0, 200));
+ SetScrollOffsetDelta(inner_scroll, gfx::Vector2dF(100, 100));
EXPECT_EQ(host_impl_->active_tree()->TotalMaxScrollOffset(),
host_impl_->active_tree()->TotalScrollOffset());
}
@@ -5706,20 +5861,20 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
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);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 2);
DrawFrame();
EXPECT_FLOAT_EQ(top_controls_height_,
host_impl_->browser_controls_manager()->ContentTopOffset());
- gfx::Vector2dF scroll_delta(0.f, 25.f);
+ gfx::Vector2dF scroll_delta(0, 25);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FLOAT_EQ(
scroll_delta.y(),
@@ -5750,27 +5905,27 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// Send a gesture scroll that will scroll the outer viewport, make sure the
// browser controls get scrolled.
- gfx::Vector2dF scroll_delta(0.f, 15.f);
+ gfx::Vector2dF scroll_delta(0, 15);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
EXPECT_EQ(OuterViewportScrollLayer()->scroll_tree_index(),
host_impl_->CurrentlyScrollingNode()->id);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FLOAT_EQ(
scroll_delta.y(),
top_controls_height_ -
host_impl_->browser_controls_manager()->ContentTopOffset());
- scroll_delta = gfx::Vector2dF(0.f, 50.f);
+ scroll_delta = gfx::Vector2dF(0, 50);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
@@ -5779,17 +5934,17 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
EXPECT_EQ(OuterViewportScrollLayer()->scroll_tree_index(),
host_impl_->CurrentlyScrollingNode()->id);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Position the viewports such that the inner viewport will be scrolled.
- gfx::Vector2dF inner_viewport_offset(0.f, 25.f);
+ gfx::Vector2dF inner_viewport_offset(0, 25);
SetScrollOffsetDelta(OuterViewportScrollLayer(), gfx::Vector2dF());
SetScrollOffsetDelta(InnerViewportScrollLayer(), inner_viewport_offset);
- scroll_delta = gfx::Vector2dF(0.f, -65.f);
+ scroll_delta = gfx::Vector2dF(0, -65);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
@@ -5800,7 +5955,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
inner_viewport_offset.y() + (scroll_delta.y() + top_controls_height_),
ScrollDelta(InnerViewportScrollLayer()).y());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
TEST_F(LayerTreeHostImplBrowserControlsTest,
@@ -5809,33 +5964,35 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
layer_size_, layer_size_, layer_size_);
DrawFrame();
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 50)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
host_impl_->browser_controls_manager()->ScrollBegin();
- host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0.f, 50.f));
+ host_impl_->browser_controls_manager()->ScrollBy(gfx::Vector2dF(0, 50));
host_impl_->browser_controls_manager()->ScrollEnd();
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ContentTopOffset());
+ EXPECT_EQ(0, host_impl_->browser_controls_manager()->ContentTopOffset());
// Now that browser controls have moved, expect the clip to resize.
auto* property_trees = host_impl_->active_tree()->property_trees();
EXPECT_EQ(gfx::Vector2dF(0, 50),
property_trees->inner_viewport_container_bounds_delta());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, -25)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
- float scroll_increment_y = -25.f;
+ float scroll_increment_y = -25;
host_impl_->browser_controls_manager()->ScrollBegin();
host_impl_->browser_controls_manager()->ScrollBy(
- gfx::Vector2dF(0.f, scroll_increment_y));
+ gfx::Vector2dF(0, scroll_increment_y));
EXPECT_FLOAT_EQ(-scroll_increment_y,
host_impl_->browser_controls_manager()->ContentTopOffset());
// Now that browser controls have moved, expect the clip to resize.
@@ -5843,7 +6000,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
property_trees->inner_viewport_container_bounds_delta());
host_impl_->browser_controls_manager()->ScrollBy(
- gfx::Vector2dF(0.f, scroll_increment_y));
+ gfx::Vector2dF(0, scroll_increment_y));
host_impl_->browser_controls_manager()->ScrollEnd();
EXPECT_FLOAT_EQ(-2 * scroll_increment_y,
host_impl_->browser_controls_manager()->ContentTopOffset());
@@ -5851,16 +6008,17 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
EXPECT_EQ(gfx::Vector2dF(),
property_trees->inner_viewport_container_bounds_delta());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Verify the layer is once-again non-scrollable.
EXPECT_EQ(gfx::ScrollOffset(), InnerViewportScrollLayer()->MaxScrollOffset());
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
}
// Tests that activating a pending tree while there's a bounds_delta on the
@@ -5878,25 +6036,28 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
{
SetupBrowserControlsAndScrollLayerWithVirtualViewport(
inner_viewport_size, outer_viewport_size, content_size);
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 1);
// 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_->active_tree()->SetBrowserControlsParams(
+ {top_controls_height_, 0, 0, 0, false, false});
+ host_impl_->active_tree()->PushBrowserControlsFromMainThread(0, 0);
CreatePendingTree();
SetupBrowserControlsAndScrollLayerWithVirtualViewport(
host_impl_->pending_tree(), inner_viewport_size, outer_viewport_size,
content_size);
- host_impl_->pending_tree()->set_browser_controls_shrink_blink_size(false);
+ host_impl_->pending_tree()->SetBrowserControlsParams(
+ {top_controls_height_, 0, 0, 0, false, false});
UpdateDrawProperties(host_impl_->pending_tree());
// Fully scroll the viewport.
- host_impl_->ScrollBegin(BeginState(gfx::Point(75, 75)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(75, 75), gfx::Vector2dF(0, 2000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::Vector2d(0, 2000)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
LayerImpl* outer_scroll = OuterViewportScrollLayer();
@@ -5968,7 +6129,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
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.
- ASSERT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1.f);
+ ASSERT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1);
}
// Activate the pending tree which should have the same scroll value as the
@@ -5982,7 +6143,7 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
// Make sure we don't accidentally clamp the outer offset based on a bounds
// delta that hasn't yet been updated.
- EXPECT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1.f);
+ EXPECT_NEAR(1050, outer_scroll->CurrentScrollOffset().y(), 1);
}
}
@@ -6008,13 +6169,14 @@ TEST_F(LayerTreeHostImplTest, ScrollNonCompositedRoot) {
DrawFrame();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(5, 5), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
}
@@ -6032,13 +6194,14 @@ TEST_F(LayerTreeHostImplTest, ScrollChildCallsCommitAndRedraw) {
DrawFrame();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(5, 5), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
}
@@ -6053,7 +6216,8 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesChild) {
// Scroll event is ignored because the input coordinate is outside the layer
// boundaries.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(15, 5)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(15, 5), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
status.main_thread_scrolling_reasons);
@@ -6078,7 +6242,8 @@ TEST_F(LayerTreeHostImplTest, ScrollMissesBackfacingChild) {
// Scroll event is ignored because the scrollable layer is not facing the
// viewer and there is nothing scrollable behind it.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(5, 5), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_IGNORED, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kNoScrollingLayer,
status.main_thread_scrolling_reasons);
@@ -6105,7 +6270,8 @@ TEST_F(LayerTreeHostImplTest, ScrollBlockedByContentLayer) {
// Scrolling fails because the content layer is asking to be scrolled on the
// main thread.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(5, 5), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kHasBackgroundAttachmentFixedObjects,
status.main_thread_scrolling_reasons);
@@ -6117,24 +6283,24 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
gfx::Size content_size(80, 80);
SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size,
outer_viewport_size, content_size);
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 2);
DrawFrame();
gfx::Vector2d scroll_delta(0, 10);
gfx::ScrollOffset expected_scroll_delta(scroll_delta);
LayerImpl* outer_scroll = OuterViewportScrollLayer();
gfx::ScrollOffset expected_max_scroll = outer_scroll->MaxScrollOffset();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Set new page scale from main thread.
- float page_scale = 2.f;
- host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f, 2.f);
+ float page_scale = 2;
+ host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1, 2);
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -6147,7 +6313,7 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnMainThread) {
// The page scale delta remains constant because the impl thread did not
// scale.
- EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
+ EXPECT_EQ(1, host_impl_->active_tree()->page_scale_delta());
}
TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
@@ -6156,29 +6322,29 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
gfx::Size content_size(80, 80);
SetupViewportLayers(host_impl_->active_tree(), inner_viewport_size,
outer_viewport_size, content_size);
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 2);
DrawFrame();
gfx::Vector2d scroll_delta(0, 10);
gfx::ScrollOffset expected_scroll_delta(scroll_delta);
LayerImpl* outer_scroll = OuterViewportScrollLayer();
gfx::ScrollOffset expected_max_scroll = outer_scroll->MaxScrollOffset();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Set new page scale on impl thread by pinching.
- float page_scale = 2.f;
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ float page_scale = 2;
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
DrawOneFrame();
@@ -6197,14 +6363,14 @@ TEST_F(LayerTreeHostImplTest, ScrollRootAndChangePageScaleOnImplThread) {
}
TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 2);
gfx::Size viewport_size(5, 5);
gfx::Size surface_size(10, 10);
- float default_page_scale = 1.f;
+ float default_page_scale = 1;
gfx::Transform default_page_scale_matrix;
default_page_scale_matrix.Scale(default_page_scale, default_page_scale);
- float new_page_scale = 2.f;
+ float new_page_scale = 2;
gfx::Transform new_page_scale_matrix;
new_page_scale_matrix.Scale(new_page_scale, new_page_scale);
@@ -6220,20 +6386,20 @@ TEST_F(LayerTreeHostImplTest, PageScaleDeltaAppliedToRootScrollLayerOnly) {
UpdateDrawProperties(host_impl_->active_tree());
// Set new page scale on impl thread by pinching.
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(new_page_scale, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
DrawOneFrame();
// Make sure all the layers are drawn with the page scale delta applied, i.e.,
// the page scale delta on the root layer is applied hierarchically.
DrawFrame();
- EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(0, 0));
- EXPECT_EQ(1.f, root->DrawTransform().matrix().getDouble(1, 1));
+ EXPECT_EQ(1, root->DrawTransform().matrix().getDouble(0, 0));
+ EXPECT_EQ(1, root->DrawTransform().matrix().getDouble(1, 1));
EXPECT_EQ(new_page_scale,
inner_scroll->DrawTransform().matrix().getDouble(0, 0));
EXPECT_EQ(new_page_scale,
@@ -6254,16 +6420,16 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
gfx::Vector2d scroll_delta(0, 10);
gfx::ScrollOffset expected_scroll_delta(scroll_delta);
gfx::ScrollOffset expected_max_scroll(outer_scroll->MaxScrollOffset());
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
- float page_scale = 2.f;
- host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1.f,
+ float page_scale = 2;
+ host_impl_->active_tree()->PushPageScaleFromMainThread(page_scale, 1,
page_scale);
DrawOneFrame();
@@ -6277,7 +6443,7 @@ TEST_F(LayerTreeHostImplTest, ScrollChildAndChangePageScaleOnMainThread) {
// The page scale delta remains constant because the impl thread did not
// scale.
- EXPECT_EQ(1.f, host_impl_->active_tree()->page_scale_delta());
+ EXPECT_EQ(1, host_impl_->active_tree()->page_scale_delta());
}
TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
@@ -6308,13 +6474,13 @@ TEST_F(LayerTreeHostImplTest, ScrollChildBeyondLimit) {
DrawFrame();
{
gfx::Vector2d scroll_delta(-8, -7);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -6445,11 +6611,11 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
gfx::Vector2d scroll_delta(0, -10);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -6464,17 +6630,18 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
// The next time we scroll we should only scroll the parent.
scroll_delta = gfx::Vector2d(0, -3);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
- grand_child_layer->scroll_tree_index());
+ child_layer->scroll_tree_index());
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
child_layer->scroll_tree_index());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
scroll_info = host_impl_->ProcessScrollDeltas();
@@ -6491,17 +6658,18 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
// After scrolling the parent, another scroll on the opposite direction
// should still scroll the child.
scroll_delta = gfx::Vector2d(0, 7);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
grand_child_layer->scroll_tree_index());
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
grand_child_layer->scroll_tree_index());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
scroll_info = host_impl_->ProcessScrollDeltas();
@@ -6516,19 +6684,20 @@ TEST_F(LayerTreeHostImplTest, ScrollWithoutBubbling) {
gfx::ScrollOffset(0, -3)));
// Scrolling should be adjusted from viewport space.
- host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 2.f, 2.f);
- host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2, 2, 2);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(2);
scroll_delta = gfx::Vector2d(0, -2);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(1, 1), scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_EQ(grand_child_layer->scroll_tree_index(),
host_impl_->CurrentlyScrollingNode()->id);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
scroll_info = host_impl_->ProcessScrollDeltas();
@@ -6559,15 +6728,18 @@ TEST_F(LayerTreeHostImplTest, ChildrenOfInnerScrollNodeCanScrollOnThread) {
{
gfx::ScrollOffset scroll_delta(0, 4);
// Scrolling should be able to happen on the compositor thread here.
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5),
+ gfx::ScrollOffsetToVector2dF(scroll_delta))
+ .get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta))
.get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -6597,15 +6769,18 @@ TEST_F(LayerTreeHostImplTest, ScrollEventBubbling) {
DrawFrame();
{
gfx::ScrollOffset scroll_delta(0, 4);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5),
+ gfx::ScrollOffsetToVector2dF(scroll_delta))
+ .get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(scroll_delta))
.get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
std::unique_ptr<ScrollAndScaleSet> scroll_info =
host_impl_->ProcessScrollDeltas();
@@ -6632,11 +6807,12 @@ TEST_F(LayerTreeHostImplTest, ScrollBeforeRedraw) {
SetupViewportLayersNoScrolls(surface_size);
// Scrolling should still work even though we did not draw yet.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(5, 5), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
+ .thread);
}
TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
@@ -6653,13 +6829,14 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
// Scroll to the right in screen coordinates with a gesture.
gfx::Vector2d gesture_scroll_delta(10, 0);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gesture_scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The layer should have scrolled down in its local coordinates.
std::unique_ptr<ScrollAndScaleSet> scroll_info =
@@ -6671,15 +6848,18 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
// Reset and scroll down with the wheel.
SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
gfx::ScrollOffset wheel_scroll_delta(0, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(),
+ gfx::ScrollOffsetToVector2dF(wheel_scroll_delta))
+ .get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(
wheel_scroll_delta))
.get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The layer should have scrolled down in its local coordinates.
scroll_info = host_impl_->ProcessScrollDeltas();
@@ -6690,7 +6870,7 @@ TEST_F(LayerTreeHostImplTest, ScrollAxisAlignedRotatedLayer) {
TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
auto* scroll_layer = InnerViewportScrollLayer();
- float child_layer_angle = -20.f;
+ float child_layer_angle = -20;
// Create a child layer that is rotated to a non-axis-aligned angle.
// Only allow vertical scrolling.
@@ -6709,7 +6889,7 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
// is a different size than the clip, so make sure the clip layer's origin
// lines up over the child.
clip_layer_transform_node.origin = gfx::Point3F(
- clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0.f);
+ clip_layer->bounds().width() * 0.5f, clip_layer->bounds().height(), 0);
clip_layer_transform_node.local = rotate_transform;
LayerImpl* child =
@@ -6723,11 +6903,12 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
gfx::Vector2d gesture_scroll_delta(0, 10);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(1, 1), gesture_scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The child layer should have scrolled down in its local coordinates an
// amount proportional to the angle between it and the input scroll delta.
@@ -6749,11 +6930,12 @@ TEST_F(LayerTreeHostImplTest, ScrollNonAxisAlignedRotatedLayer) {
gfx::Vector2d gesture_scroll_delta(10, 0);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point(1, 1)).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(1, 1), gesture_scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gesture_scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The child layer should have scrolled down in its local coordinates an
// amount proportional to the angle between it and the input scroll delta.
@@ -6790,7 +6972,7 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
// is a different size than the clip, so make sure the clip layer's origin
// lines up over the child.
clip_layer_transform_node.origin = gfx::Point3F(
- clip_layer->bounds().width(), clip_layer->bounds().height(), 0.f);
+ clip_layer->bounds().width(), clip_layer->bounds().height(), 0);
clip_layer_transform_node.local = perspective_transform;
LayerImpl* child = AddScrollableLayer(clip_layer, clip_layer->bounds(),
@@ -6826,8 +7008,11 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
DrawFrame();
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(viewport_point).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(viewport_point, gfx::ScrollOffsetToVector2dF(
+ gesture_scroll_deltas[i]))
+ .get(),
+ InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(
UpdateState(viewport_point,
@@ -6835,7 +7020,7 @@ TEST_F(LayerTreeHostImplTest, ScrollPerspectiveTransformedLayer) {
.get());
viewport_point +=
gfx::ScrollOffsetToFlooredVector2d(gesture_scroll_deltas[i]);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
scroll_info = host_impl_->ProcessScrollDeltas();
EXPECT_TRUE(ScrollInfoContains(*scroll_info.get(), child->element_id(),
@@ -6863,11 +7048,11 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
gfx::Vector2d scroll_delta(0, 10);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The layer should have scrolled down in its local coordinates, but half the
// amount.
@@ -6880,15 +7065,18 @@ TEST_F(LayerTreeHostImplTest, ScrollScaledLayer) {
// Reset and scroll down with the wheel.
SetScrollOffsetDelta(scroll_layer, gfx::Vector2dF());
gfx::ScrollOffset wheel_scroll_delta(0, 10);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(),
+ gfx::ScrollOffsetToVector2dF(wheel_scroll_delta))
+ .get(),
+ InputHandler::WHEEL)
+ .thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::ScrollOffsetToVector2dF(
wheel_scroll_delta))
.get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// It should apply the scale factor to the scroll delta for the wheel event.
scroll_info = host_impl_->ProcessScrollDeltas();
@@ -6905,7 +7093,7 @@ TEST_F(LayerTreeHostImplTest, ScrollViewportRounding) {
UpdateDrawProperties(host_impl_->active_tree());
host_impl_->active_tree()->SetDeviceScaleFactor(scale);
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
LayerImpl* inner_viewport_scroll_layer = InnerViewportScrollLayer();
EXPECT_EQ(gfx::ScrollOffset(0, 0),
@@ -6920,7 +7108,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
host_impl_->BindToClient(&scroll_watcher);
- gfx::Vector2dF initial_scroll_delta(10.f, 10.f);
+ gfx::Vector2dF initial_scroll_delta(10, 10);
scroll_layer->layer_tree_impl()
->property_trees()
->scroll_tree.UpdateScrollOffsetBaseForTesting(scroll_layer->element_id(),
@@ -6938,48 +7126,48 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
// page_scale_factor and {min|max}_page_scale_factor being set.
EXPECT_EQ(gfx::SizeF(100, 100), scroll_watcher.scrollable_size());
EXPECT_EQ(gfx::ScrollOffset(90, 80), scroll_watcher.max_scroll_offset());
- EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
- EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
- EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
+ EXPECT_EQ(1, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(1, scroll_watcher.min_page_scale_factor());
+ EXPECT_EQ(1, scroll_watcher.max_page_scale_factor());
// Put a page scale on the tree.
- host_impl_->active_tree()->PushPageScaleFromMainThread(2.f, 0.5f, 4.f);
- EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
- EXPECT_EQ(1.f, scroll_watcher.min_page_scale_factor());
- EXPECT_EQ(1.f, scroll_watcher.max_page_scale_factor());
+ host_impl_->active_tree()->PushPageScaleFromMainThread(2, 0.5f, 4);
+ EXPECT_EQ(1, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(1, scroll_watcher.min_page_scale_factor());
+ EXPECT_EQ(1, scroll_watcher.max_page_scale_factor());
// Activation will update the delegate.
host_impl_->ActivateSyncTree();
- EXPECT_EQ(2.f, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(2, scroll_watcher.page_scale_factor());
EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
- EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
+ EXPECT_EQ(4, scroll_watcher.max_page_scale_factor());
// Animating page scale can change the root offset, so it should update the
// delegate. Also resets the page scale to 1 for the rest of the test.
host_impl_->LayerTreeHostImpl::StartPageScaleAnimation(
- gfx::Vector2d(0, 0), false, 1.f, base::TimeDelta());
+ gfx::Vector2d(0, 0), false, 1, base::TimeDelta());
host_impl_->Animate();
- EXPECT_EQ(1.f, scroll_watcher.page_scale_factor());
+ EXPECT_EQ(1, scroll_watcher.page_scale_factor());
EXPECT_EQ(.5f, scroll_watcher.min_page_scale_factor());
- EXPECT_EQ(4.f, scroll_watcher.max_page_scale_factor());
+ EXPECT_EQ(4, scroll_watcher.max_page_scale_factor());
// The pinch gesture doesn't put the delegate into a state where the scroll
// offset is outside of the scroll range. (this is verified by DCHECKs in the
// delegate).
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
- host_impl_->PinchGestureUpdate(2.f, gfx::Point());
+ host_impl_->PinchGestureUpdate(2, gfx::Point());
host_impl_->PinchGestureUpdate(.5f, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// Scrolling should be relative to the offset as given by the delegate.
- gfx::Vector2dF scroll_delta(0.f, 10.f);
- gfx::ScrollOffset current_offset(7.f, 8.f);
+ gfx::Vector2dF scroll_delta(0, 10);
+ gfx::ScrollOffset current_offset(7, 8);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
@@ -6988,12 +7176,12 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
EXPECT_EQ(ScrollOffsetWithDelta(current_offset, scroll_delta),
scroll_watcher.last_set_scroll_offset());
- current_offset = gfx::ScrollOffset(42.f, 41.f);
+ current_offset = gfx::ScrollOffset(42, 41);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
EXPECT_EQ(current_offset + gfx::ScrollOffset(scroll_delta),
scroll_watcher.last_set_scroll_offset());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
host_impl_->SetSynchronousInputHandlerRootScrollOffset(gfx::ScrollOffset());
// Forces a full tree synchronization and ensures that the scroll delegate
@@ -7001,7 +7189,7 @@ TEST_F(LayerTreeHostImplTest, RootLayerScrollOffsetDelegation) {
gfx::Size new_viewport_size(21, 12);
gfx::Size new_content_size(42, 24);
CreatePendingTree();
- host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 1.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 1);
SetupViewportLayers(host_impl_->pending_tree(), new_viewport_size,
new_content_size, new_content_size);
host_impl_->ActivateSyncTree();
@@ -7030,20 +7218,24 @@ TEST_F(LayerTreeHostImplTest,
// Draw first frame to clear any pending draws and check scroll.
DrawFrame();
- CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f));
+ CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0, 0));
EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
// Set external scroll delta on delegate and notify LayerTreeHost.
- gfx::ScrollOffset scroll_offset(10.f, 10.f);
+ gfx::ScrollOffset scroll_offset(10, 10);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
- CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0.f, 0.f));
+ CheckLayerScrollDelta(scroll_layer, gfx::Vector2dF(0, 0));
EXPECT_TRUE(host_impl_->active_tree()->needs_update_draw_properties());
// Check scroll delta reflected in layer.
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
EXPECT_FALSE(frame.has_no_damage);
CheckLayerScrollDelta(scroll_layer,
gfx::ScrollOffsetToVector2dF(scroll_offset));
@@ -7070,7 +7262,7 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
// Ensure that the scroll offset is interpreted as a content offset so it
// should be unaffected by the page scale factor. See
// https://crbug.com/973771.
- float page_scale_factor = 2.f;
+ float page_scale_factor = 2;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, page_scale_factor, page_scale_factor);
@@ -7080,7 +7272,7 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
GetScrollNode(inner_scroll)->user_scrollable_vertical = false;
GetScrollNode(inner_scroll)->user_scrollable_horizontal = false;
- gfx::ScrollOffset scroll_offset(25.f, 30.f);
+ gfx::ScrollOffset scroll_offset(25, 30);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
scroll_tree.current_scroll_offset(inner_element_id));
@@ -7102,9 +7294,9 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
GetScrollNode(outer_scroll)->user_scrollable_vertical = false;
GetScrollNode(outer_scroll)->user_scrollable_horizontal = false;
- gfx::ScrollOffset scroll_offset(120.f, 140.f);
+ gfx::ScrollOffset scroll_offset(120, 140);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
- EXPECT_VECTOR_EQ(gfx::ScrollOffset(50.f, 50.f),
+ EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50),
scroll_tree.current_scroll_offset(inner_element_id));
EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
scroll_tree.current_scroll_offset(outer_element_id));
@@ -7126,7 +7318,7 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
GetScrollNode(outer_scroll)->user_scrollable_vertical = false;
GetScrollNode(outer_scroll)->user_scrollable_horizontal = false;
- gfx::ScrollOffset scroll_offset(60.f, 70.f);
+ gfx::ScrollOffset scroll_offset(60, 70);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
scroll_tree.current_scroll_offset(inner_element_id));
@@ -7147,11 +7339,11 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
ASSERT_FALSE(did_request_redraw_);
GetScrollNode(outer_scroll)->user_scrollable_vertical = false;
GetScrollNode(outer_scroll)->user_scrollable_horizontal = false;
- SetScrollOffset(inner_scroll, gfx::ScrollOffset(50.f, 50.f));
+ SetScrollOffset(inner_scroll, gfx::ScrollOffset(50, 50));
- gfx::ScrollOffset scroll_offset(60.f, 70.f);
+ gfx::ScrollOffset scroll_offset(60, 70);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
- EXPECT_VECTOR_EQ(gfx::ScrollOffset(50.f, 50.f),
+ EXPECT_VECTOR_EQ(gfx::ScrollOffset(50, 50),
scroll_tree.current_scroll_offset(inner_element_id));
EXPECT_VECTOR_EQ(gfx::ScrollOffset(),
scroll_tree.current_scroll_offset(outer_element_id));
@@ -7168,7 +7360,7 @@ TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetUserScrollable) {
TEST_F(LayerTreeHostImplTest, SetRootScrollOffsetNoViewportCrash) {
auto* inner_scroll = InnerViewportScrollLayer();
ASSERT_FALSE(inner_scroll);
- gfx::ScrollOffset scroll_offset(25.f, 30.f);
+ gfx::ScrollOffset scroll_offset(25, 30);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(scroll_offset);
}
@@ -7176,7 +7368,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
InputHandlerScrollResult scroll_result;
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
DrawFrame();
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
@@ -7184,7 +7376,8 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
.thread);
scroll_result = host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
@@ -7297,7 +7490,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollRoot) {
EXPECT_EQ(scroll_result.accumulated_root_overscroll,
host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
@@ -7306,18 +7499,14 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
InputHandlerScrollResult scroll_result;
gfx::Size scroll_container_size(5, 5);
gfx::Size surface_size(10, 10);
- LayerImpl* root_clip = SetupDefaultRootLayer(surface_size);
- LayerImpl* root =
- AddScrollableLayer(root_clip, scroll_container_size, surface_size);
+ SetupViewportLayersNoScrolls(surface_size);
+ LayerImpl* root = AddScrollableLayer(OuterViewportScrollLayer(),
+ scroll_container_size, surface_size);
LayerImpl* child_layer =
AddScrollableLayer(root, scroll_container_size, surface_size);
LayerImpl* grand_child_layer =
AddScrollableLayer(child_layer, scroll_container_size, surface_size);
- LayerTreeImpl::ViewportPropertyIds viewport_property_ids;
- viewport_property_ids.inner_scroll = root->scroll_tree_index();
- host_impl_->active_tree()->SetViewportPropertyIds(viewport_property_ids);
-
UpdateDrawProperties(host_impl_->active_tree());
host_impl_->active_tree()->DidBecomeActive();
@@ -7335,33 +7524,38 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
gfx::Vector2d scroll_delta(0, -10);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
scroll_result =
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
+ EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
+ grand_child_layer->scroll_tree_index());
EXPECT_TRUE(scroll_result.did_scroll);
EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// The next time we scroll we should only scroll the parent, but overscroll
// should still not reach the root layer.
scroll_delta = gfx::Vector2d(0, -30);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
- grand_child_layer->scroll_tree_index());
+ child_layer->scroll_tree_index());
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::TOUCHSCREEN)
- .thread);
+ host_impl_->ScrollEnd();
+
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
scroll_result =
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
EXPECT_TRUE(scroll_result.did_scroll);
@@ -7369,16 +7563,17 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
child_layer->scroll_tree_index());
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// After scrolling the parent, another scroll on the opposite direction
// should scroll the child.
scroll_delta = gfx::Vector2d(0, 70);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
grand_child_layer->scroll_tree_index());
scroll_result =
@@ -7388,7 +7583,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildWithoutBubbling) {
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
grand_child_layer->scroll_tree_index());
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
}
@@ -7401,11 +7596,12 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
DrawFrame();
{
gfx::Vector2d scroll_delta(0, 8);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(5, 5)).get(),
- InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(5, 5), scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
scroll_result =
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
EXPECT_TRUE(scroll_result.did_scroll);
@@ -7421,7 +7617,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollChildEventBubbling) {
EXPECT_FALSE(scroll_result.did_scroll);
EXPECT_TRUE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF(0, 14), host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
}
@@ -7433,7 +7629,7 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
SetupViewportLayersNoScrolls(gfx::Size(50, 50));
UpdateDrawProperties(host_impl_->active_tree());
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
DrawFrame();
EXPECT_EQ(gfx::Vector2dF(), host_impl_->accumulated_root_overscroll());
@@ -7441,7 +7637,8 @@ TEST_F(LayerTreeHostImplTest, OverscrollAlways) {
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
.thread);
scroll_result = host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
@@ -7460,11 +7657,13 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
// Edge glow effect should be applicable only upon reaching Edges
// of the content. unnecessary glow effect calls shouldn't be
// called while scrolling up without reaching the edge of the content.
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(0, 100)).get(),
+ InputHandler::WHEEL)
+ .thread);
scroll_result = host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get());
EXPECT_TRUE(scroll_result.did_scroll);
@@ -7477,13 +7676,14 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF().ToString(),
host_impl_->accumulated_root_overscroll().ToString());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// unusedrootDelta should be subtracted from applied delta so that
// unwanted glow effect calls are not called.
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(0, 20)).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
scroll_result = host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::Vector2dF(0, 20)).get());
@@ -7498,13 +7698,15 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_VECTOR2DF_EQ(gfx::Vector2dF(0.000000f, 17.699997f),
host_impl_->accumulated_root_overscroll());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
// TestCase to check kEpsilon, which prevents minute values to trigger
// gloweffect without reaching edge.
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::WHEEL)
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(-0.12f, 0.1f))
+ .get(),
+ InputHandler::WHEEL)
.thread);
scroll_result = host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::Vector2dF(-0.12f, 0.1f)).get());
@@ -7512,7 +7714,7 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollWhenNotAtEdge) {
EXPECT_FALSE(scroll_result.did_overscroll_root);
EXPECT_EQ(gfx::Vector2dF().ToString(),
host_impl_->accumulated_root_overscroll().ToString());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
}
@@ -7532,14 +7734,15 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnNonViewportLayers) {
// Start a scroll gesture, ensure it's scrolling the subscroller.
{
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(100.f, 100.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(100, 100),
scroll_layer->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
outer_scroll_layer->CurrentScrollOffset());
}
@@ -7547,11 +7750,11 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnNonViewportLayers) {
// doesn't consume the delta but it isn't counted as overscroll.
{
InputHandlerScrollResult result = host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(120.f, 140.f)).get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(120, 140)).get());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(200, 200),
scroll_layer->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
outer_scroll_layer->CurrentScrollOffset());
EXPECT_FALSE(result.did_overscroll_root);
}
@@ -7560,16 +7763,16 @@ TEST_F(LayerTreeHostImplTest, NoOverscrollOnNonViewportLayers) {
// doesn't consume the delta but it isn't counted as overscroll.
{
InputHandlerScrollResult result = host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(20.f, 40.f)).get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(20, 40)).get());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(200, 200),
scroll_layer->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
outer_scroll_layer->CurrentScrollOffset());
EXPECT_FALSE(result.did_overscroll_root);
}
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) {
@@ -7592,18 +7795,20 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnMainThread) {
gfx::PointF(0, 60)));
EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, 60)).get(),
- InputHandler::WHEEL)
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, 60), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
.thread);
// Overscroll initiated inside layers will be handled by the main thread.
EXPECT_NE(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
gfx::PointF(0, 0)));
- EXPECT_EQ(
- InputHandler::SCROLL_ON_MAIN_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_MAIN_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
+ .thread);
}
// Test that scrolling the inner viewport directly works, as can happen when the
@@ -7612,8 +7817,9 @@ TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) {
const gfx::Size viewport_size(100, 100);
SetupViewportLayersNoScrolls(viewport_size);
- host_impl_->active_tree()->SetTopControlsHeight(10);
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f);
+ host_impl_->active_tree()->SetBrowserControlsParams(
+ {10, 0, 0, 0, false, false});
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f, 1.f);
LayerImpl* outer_scroll_layer = OuterViewportScrollLayer();
LayerImpl* inner_scroll_layer = InnerViewportScrollLayer();
@@ -7625,23 +7831,23 @@ TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) {
LayerImpl* scroll_layer = AddScrollableLayer(
inner_scroll_layer, viewport_size, gfx::Size(400, 400));
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 2.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 2;
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_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get());
+ host_impl_->ScrollEnd();
- EXPECT_EQ(1.f,
- host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(300.f, 300.f),
+ EXPECT_EQ(1, host_impl_->active_tree()->CurrentTopControlsShownRatio());
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(300, 300),
scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(),
inner_scroll_layer->CurrentScrollOffset());
@@ -7653,23 +7859,22 @@ TEST_F(LayerTreeHostImplTest, ScrollFromOuterViewportSibling) {
// 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_->ScrollBegin(BeginState(gfx::Point(0, 0), scroll_delta).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- EXPECT_EQ(0.f,
- host_impl_->active_tree()->CurrentBrowserControlsShownRatio());
+ EXPECT_EQ(0, host_impl_->active_tree()->CurrentTopControlsShownRatio());
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),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 10),
inner_scroll_layer->CurrentScrollOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(),
outer_scroll_layer->CurrentScrollOffset());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
}
@@ -7705,25 +7910,27 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
// chain to the parent scrolling layer which is now set as the outer
// viewport. The original outer viewport layer shouldn't get any scroll here.
{
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(200, 200)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200, 200)).get());
+ host_impl_->ScrollEnd();
- EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(200, 200),
child_scroll_layer->CurrentScrollOffset());
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(200, 200)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200.f, 200.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(200, 200)).get());
+ host_impl_->ScrollEnd();
- EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
outer_scroll_layer->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(200.f, 200.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(200, 200),
scroll_layer->CurrentScrollOffset());
}
@@ -7731,11 +7938,12 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
// would normally chain up to the "outer viewport" but since we've set the
// scrolling content as the outer viewport, it should stop chaining there.
{
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(),
outer_scroll_layer->CurrentScrollOffset());
@@ -7743,8 +7951,8 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
// Zoom into the page by a 2X factor so that the inner viewport becomes
// scrollable.
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 2.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 2;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
@@ -7757,24 +7965,26 @@ TEST_F(LayerTreeHostImplTest, ScrollChainingWithReplacedOuterViewport) {
// and then chain up to the current outer viewport (i.e. the parent scroll
// layer).
{
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get());
+ host_impl_->ScrollEnd();
- EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
inner_scroll_layer->CurrentScrollOffset());
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get());
+ host_impl_->ScrollEnd();
- EXPECT_VECTOR_EQ(gfx::Vector2dF(0.f, 0.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 0),
outer_scroll_layer->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(50.f, 50.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(50, 50),
scroll_layer->CurrentScrollOffset());
}
}
@@ -7798,10 +8008,13 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
// of the outer viewport scroll layer.
LayerImpl* outer_scroll_layer =
AddScrollableLayer(content_layer, content_size, gfx::Size(1200, 1200));
- GetScrollNode(outer_scroll_layer)->scrolls_outer_viewport = true;
LayerImpl* sibling_scroll_layer = AddScrollableLayer(
content_layer, gfx::Size(600, 600), gfx::Size(1200, 1200));
+ GetScrollNode(InnerViewportScrollLayer())
+ ->prevent_viewport_scrolling_from_inner = true;
+ GetScrollNode(OuterViewportScrollLayer())->scrolls_outer_viewport = false;
+ GetScrollNode(outer_scroll_layer)->scrolls_outer_viewport = true;
auto viewport_property_ids = layer_tree_impl->ViewportPropertyIdsForTesting();
viewport_property_ids.outer_scroll = outer_scroll_layer->scroll_tree_index();
layer_tree_impl->SetViewportPropertyIds(viewport_property_ids);
@@ -7813,33 +8026,35 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
// 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_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get());
+ host_impl_->ScrollEnd();
- EXPECT_VECTOR_EQ(gfx::Vector2dF(600.f, 600.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(600, 600),
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_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000.f, 1000.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(1000, 1000)).get());
+ host_impl_->ScrollEnd();
- EXPECT_VECTOR_EQ(gfx::Vector2dF(600.f, 600.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(600, 600),
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;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 1;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
@@ -7854,9 +8069,9 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
{
// 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;
+ page_scale_factor = 2;
gfx::Point anchor(viewport_size.width() / 2, viewport_size.height() / 2);
- host_impl_->ScrollBegin(BeginState(anchor).get(),
+ host_impl_->ScrollBegin(BeginState(anchor, gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_factor, anchor);
@@ -7867,7 +8082,7 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
host_impl_->ScrollBy(UpdateState(anchor, viewport_size_vec).get());
- EXPECT_VECTOR_EQ(ScaleVector2d(viewport_size_vec, 1.f / page_scale_factor),
+ EXPECT_VECTOR_EQ(ScaleVector2d(viewport_size_vec, 1 / 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.
@@ -7877,7 +8092,7 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
EXPECT_VECTOR_EQ(gfx::Vector2dF(),
sibling_scroll_layer->CurrentScrollOffset());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
// Reset the scroll offsets
@@ -7891,23 +8106,25 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
{
// 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_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(2000, 2000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000.f, 2000.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000, 2000)).get());
+ host_impl_->ScrollEnd();
- EXPECT_VECTOR_EQ(gfx::Vector2dF(600.f, 600.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(600, 600),
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_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(2000, 2000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000.f, 2000.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000, 2000)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(ScaleVector2d(viewport_size_vec, 1 / page_scale_factor),
inner_scroll_layer->CurrentScrollOffset());
@@ -7915,11 +8132,12 @@ TEST_F(LayerTreeHostImplTest, RootScrollerScrollNonDescendant) {
outer_scroll_layer->CurrentScrollOffset());
// No more scrolling should be possible.
- host_impl_->ScrollBegin(BeginState(gfx::Point(0, 0)).get(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(2000, 2000)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000.f, 2000.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(2000, 2000)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(),
outer_scroll_layer->CurrentScrollOffset());
@@ -7949,18 +8167,20 @@ TEST_F(LayerTreeHostImplTest, OverscrollOnImplThread) {
gfx::PointF(0, 60)));
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, 60)).get(),
- InputHandler::WHEEL)
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, 60), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
.thread);
// Overscroll initiated inside layers will be handled by the impl thread.
EXPECT_NE(nullptr, host_impl_->active_tree()->FindLayerThatIsHitByPoint(
gfx::PointF(0, 0)));
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, 0)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
+ .thread);
}
class BlendStateCheckLayer : public LayerImpl {
@@ -8014,10 +8234,10 @@ class BlendStateCheckLayer : public LayerImpl {
auto* test_blending_draw_quad =
render_pass->CreateAndAppendDrawQuad<viz::TileDrawQuad>();
- test_blending_draw_quad->SetNew(
- shared_quad_state, quad_rect_, visible_quad_rect, needs_blending,
- resource_id_, gfx::RectF(0.f, 0.f, 1.f, 1.f), gfx::Size(1, 1), false,
- false, false);
+ test_blending_draw_quad->SetNew(shared_quad_state, quad_rect_,
+ visible_quad_rect, needs_blending,
+ resource_id_, gfx::RectF(0, 0, 1, 1),
+ gfx::Size(1, 1), false, false, false);
EXPECT_EQ(blend_, test_blending_draw_quad->ShouldDrawWithBlending());
EXPECT_EQ(has_render_surface_,
@@ -8060,20 +8280,20 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
auto* layer1 = AddLayer<BlendStateCheckLayer>(
host_impl_->active_tree(), host_impl_->resource_provider());
CopyProperties(root, layer1);
- CreateTransformNode(layer1).post_translation = gfx::Vector2dF(2.f, 2.f);
+ CreateTransformNode(layer1).post_translation = gfx::Vector2dF(2, 2);
CreateEffectNode(layer1);
// Opaque layer, drawn without blending.
layer1->SetContentsOpaque(true);
layer1->SetExpectation(false, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
// Layer with translucent content and painting, so drawn with blending.
layer1->SetContentsOpaque(false);
layer1->SetExpectation(true, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
@@ -8081,7 +8301,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
SetOpacity(layer1, 0.5f);
layer1->SetExpectation(true, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
@@ -8089,25 +8309,25 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetContentsOpaque(true);
SetOpacity(layer1, 0.5f);
layer1->SetExpectation(true, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
auto* layer2 = AddLayer<BlendStateCheckLayer>(
host_impl_->active_tree(), host_impl_->resource_provider());
CopyProperties(layer1, layer2);
- CreateTransformNode(layer2).post_translation = gfx::Vector2dF(4.f, 4.f);
+ CreateTransformNode(layer2).post_translation = gfx::Vector2dF(4, 4);
CreateEffectNode(layer2);
// 2 opaque layers, drawn without blending.
layer1->SetContentsOpaque(true);
- SetOpacity(layer1, 1.f);
+ SetOpacity(layer1, 1);
layer1->SetExpectation(false, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(true);
- SetOpacity(layer2, 1.f);
+ SetOpacity(layer2, 1);
layer2->SetExpectation(false, false, root);
- layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer2->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -8116,9 +8336,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Child layer with opaque content, drawn without blending.
layer1->SetContentsOpaque(false);
layer1->SetExpectation(true, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetExpectation(false, false, root);
- layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer2->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -8128,9 +8348,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Child layer with opaque content, drawn without blending.
layer1->SetContentsOpaque(true);
layer1->SetExpectation(false, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetExpectation(false, false, root);
- layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer2->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -8144,9 +8364,9 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
SetOpacity(layer1, 0.5f);
GetEffectNode(layer1)->render_surface_reason = RenderSurfaceReason::kTest;
layer1->SetExpectation(false, true, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetExpectation(false, false, layer1);
- layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer2->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -8155,26 +8375,26 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// Draw again, but with child non-opaque, to make sure
// layer1 not culled.
layer1->SetContentsOpaque(true);
- SetOpacity(layer1, 1.f);
+ SetOpacity(layer1, 1);
layer1->SetExpectation(false, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(true);
SetOpacity(layer2, 0.5f);
layer2->SetExpectation(true, false, layer1);
- layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer2->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
// A second way of making the child non-opaque.
layer1->SetContentsOpaque(true);
- SetOpacity(layer1, 1.f);
+ SetOpacity(layer1, 1);
layer1->SetExpectation(false, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(false);
- SetOpacity(layer2, 1.f);
+ SetOpacity(layer2, 1);
layer2->SetExpectation(true, false, root);
- layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer2->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -8182,13 +8402,13 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
// And when the layer says its not opaque but is painted opaque, it is not
// blended.
layer1->SetContentsOpaque(true);
- SetOpacity(layer1, 1.f);
+ SetOpacity(layer1, 1);
layer1->SetExpectation(false, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
layer2->SetContentsOpaque(true);
- SetOpacity(layer2, 1.f);
+ SetOpacity(layer2, 1);
layer2->SetExpectation(false, false, root);
- layer2->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer2->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
EXPECT_TRUE(layer2->quads_appended());
@@ -8199,7 +8419,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
@@ -8209,7 +8429,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 5, 2));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
@@ -8219,7 +8439,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(7, 5, 3, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(true, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
@@ -8230,7 +8450,7 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
layer1->SetQuadVisibleRect(gfx::Rect(5, 5, 2, 5));
layer1->SetOpaqueContentRect(gfx::Rect(5, 5, 2, 5));
layer1->SetExpectation(false, false, root);
- layer1->SetUpdateRect(gfx::Rect(layer1->bounds()));
+ layer1->UnionUpdateRect(gfx::Rect(layer1->bounds()));
DrawFrame();
EXPECT_TRUE(layer1->quads_appended());
}
@@ -8238,9 +8458,13 @@ TEST_F(LayerTreeHostImplTest, BlendingOffWhenDrawingOpaqueLayers) {
static bool MayContainVideoBitSetOnFrameData(LayerTreeHostImpl* host_impl) {
host_impl->active_tree()->set_needs_update_draw_properties();
TestFrameData frame;
+ host_impl->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame));
host_impl->DrawLayers(&frame);
host_impl->DidDrawAllLayers(frame);
+ host_impl->DidFinishImplFrame();
return frame.may_contain_video;
}
@@ -8273,11 +8497,11 @@ TEST_F(LayerTreeHostImplTest, MayContainVideo) {
EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
// Move the video layer so it goes beyond the root.
- video_layer->SetOffsetToTransformParent(gfx::Vector2dF(100.f, 100.f));
+ video_layer->SetOffsetToTransformParent(gfx::Vector2dF(100, 100));
UpdateDrawProperties(host_impl_->active_tree());
EXPECT_FALSE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
- video_layer->SetOffsetToTransformParent(gfx::Vector2dF(0.f, 0.f));
+ video_layer->SetOffsetToTransformParent(gfx::Vector2dF(0, 0));
video_layer->NoteLayerPropertyChanged();
UpdateDrawProperties(host_impl_->active_tree());
EXPECT_TRUE(MayContainVideoBitSetOnFrameData(host_impl_.get()));
@@ -8491,7 +8715,7 @@ TEST_F(LayerTreeHostImplViewportCoveredTest, ViewportCoveredScaled) {
bool software = false;
CreateHostImpl(DefaultSettings(), CreateFakeLayerTreeFrameSink(software));
- host_impl_->active_tree()->SetDeviceScaleFactor(2.f);
+ host_impl_->active_tree()->SetDeviceScaleFactor(2);
SetupActiveTreeLayers();
EXPECT_SCOPED(TestLayerCoversFullViewport());
EXPECT_SCOPED(TestEmptyLayer());
@@ -8577,8 +8801,6 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
nullptr);
layer_tree_host_impl->SetVisible(true);
layer_tree_host_impl->InitializeFrameSink(layer_tree_frame_sink.get());
- layer_tree_host_impl->WillBeginImplFrame(
- viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 2));
LayerImpl* root = SetupRootLayer<LayerImpl>(
layer_tree_host_impl->active_tree(), gfx::Size(500, 500));
@@ -8586,7 +8808,7 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
child->SetBounds(gfx::Size(14, 15));
child->SetDrawsContent(true);
CopyProperties(root, child);
- child->SetOffsetToTransformParent(gfx::Vector2dF(12.f, 13.f));
+ child->SetOffsetToTransformParent(gfx::Vector2dF(12, 13));
layer_tree_host_impl->active_tree()->SetLocalSurfaceIdAllocationFromParent(
viz::LocalSurfaceIdAllocation(
viz::LocalSurfaceId(1, base::UnguessableToken::Deserialize(2u, 3u)),
@@ -8596,9 +8818,13 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
TestFrameData frame;
// First frame, the entire screen should get swapped.
+ layer_tree_host_impl->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
layer_tree_host_impl->DrawLayers(&frame);
layer_tree_host_impl->DidDrawAllLayers(frame);
+ layer_tree_host_impl->DidFinishImplFrame();
gfx::Rect expected_swap_rect(500, 500);
EXPECT_EQ(expected_swap_rect.ToString(),
fake_layer_tree_frame_sink->last_swap_rect().ToString());
@@ -8607,9 +8833,13 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
// the union of old and new child rects: gfx::Rect(26, 28).
child->SetOffsetToTransformParent(gfx::Vector2dF());
child->NoteLayerPropertyChanged();
+ layer_tree_host_impl->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
layer_tree_host_impl->DrawLayers(&frame);
- host_impl_->DidDrawAllLayers(frame);
+ layer_tree_host_impl->DidDrawAllLayers(frame);
+ layer_tree_host_impl->DidFinishImplFrame();
expected_swap_rect = gfx::Rect(26, 28);
EXPECT_EQ(expected_swap_rect.ToString(),
@@ -8618,9 +8848,13 @@ TEST_F(LayerTreeHostImplTest, PartialSwapReceivesDamageRect) {
layer_tree_host_impl->active_tree()->SetDeviceViewportRect(gfx::Rect(10, 10));
// This will damage everything.
root->SetBackgroundColor(SK_ColorBLACK);
+ layer_tree_host_impl->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, layer_tree_host_impl->PrepareToDraw(&frame));
layer_tree_host_impl->DrawLayers(&frame);
- host_impl_->DidDrawAllLayers(frame);
+ layer_tree_host_impl->DidDrawAllLayers(frame);
+ layer_tree_host_impl->DidFinishImplFrame();
expected_swap_rect = gfx::Rect(10, 10);
EXPECT_EQ(expected_swap_rect.ToString(),
@@ -8715,6 +8949,9 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
// Verify one quad is drawn when transparent background set is not set.
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
{
const auto& root_pass = frame.render_passes.back();
@@ -8724,6 +8961,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
}
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
// Cause damage so we would draw something if possible.
host_impl_->SetFullViewportDamage();
@@ -8731,6 +8969,9 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
// Verify no quads are drawn when transparent background is set.
host_impl_->active_tree()->set_background_color(SK_ColorTRANSPARENT);
host_impl_->SetFullViewportDamage();
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
{
const auto& root_pass = frame.render_passes.back();
@@ -8738,6 +8979,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
}
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
// Cause damage so we would draw something if possible.
host_impl_->SetFullViewportDamage();
@@ -8745,6 +8987,9 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
// Verify no quads are drawn when semi-transparent background is set.
host_impl_->active_tree()->set_background_color(SkColorSetARGB(5, 255, 0, 0));
host_impl_->SetFullViewportDamage();
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
{
const auto& root_pass = frame.render_passes.back();
@@ -8752,6 +8997,7 @@ TEST_F(LayerTreeHostImplTest, HasTransparentBackground) {
}
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest {
@@ -8765,6 +9011,9 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest {
bool expect_to_draw = !expected_damage.IsEmpty();
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
if (!expect_to_draw) {
@@ -8794,6 +9043,7 @@ class LayerTreeHostImplTestDrawAndTestDamage : public LayerTreeHostImplTest {
EXPECT_EQ(expect_to_draw, host_impl_->DrawLayers(&frame));
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
};
@@ -8809,7 +9059,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
child->SetDrawsContent(true);
child->SetBackgroundColor(SK_ColorRED);
CopyProperties(root, child);
- child->SetOffsetToTransformParent(gfx::Vector2dF(9.f, 9.f));
+ child->SetOffsetToTransformParent(gfx::Vector2dF(9, 9));
UpdateDrawProperties(host_impl_->active_tree());
@@ -8821,7 +9071,7 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage, FrameIncludesDamageRect) {
// The second frame has damage that doesn't touch the child layer. Its quads
// should still be generated.
gfx::Rect small_damage = gfx::Rect(0, 0, 1, 1);
- root->SetUpdateRect(small_damage);
+ root->UnionUpdateRect(small_damage);
DrawFrameAndTestDamage(small_damage, child);
// The third frame should have no damage, so no quads should be generated.
@@ -8837,12 +9087,11 @@ class GLRendererWithSetupQuadForAntialiasing : public viz::GLRenderer {
TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
// Due to precision issues (especially on Android), sometimes far
// away quads can end up thinking they need AA.
- float device_scale_factor = 4.f / 3.f;
+ float device_scale_factor = 4 / 3;
gfx::Size root_size(2000, 1000);
CreatePendingTree();
host_impl_->pending_tree()->SetDeviceScaleFactor(device_scale_factor);
- host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f / 16.f,
- 16.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1 / 16, 16);
auto* root = SetupRootLayer<LayerImpl>(host_impl_->pending_tree(), root_size);
root->SetNeedsPushProperties();
@@ -8875,6 +9124,9 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
ASSERT_EQ(1u, host_impl_->active_tree()->GetRenderSurfaceList().size());
TestFrameData frame;
+ host_impl_->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl_->PrepareToDraw(&frame));
ASSERT_EQ(1u, frame.render_passes.size());
@@ -8894,6 +9146,7 @@ TEST_F(LayerTreeHostImplTest, FarAwayQuadsDontNeedAA) {
host_impl_->DrawLayers(&frame);
host_impl_->DidDrawAllLayers(frame);
+ host_impl_->DidFinishImplFrame();
}
class CompositorFrameMetadataTest : public LayerTreeHostImplTest {
@@ -9054,12 +9307,16 @@ void ExpectFullDamageAndDraw(LayerTreeHostImpl* host_impl) {
gfx::Rect full_frame_damage(
host_impl->active_tree()->GetDeviceViewport().size());
TestFrameData frame;
+ host_impl->WillBeginImplFrame(viz::CreateBeginFrameArgsForTesting(
+ BEGINFRAME_FROM_HERE, viz::BeginFrameArgs::kManualSourceId, 1,
+ base::TimeTicks() + base::TimeDelta::FromMilliseconds(1)));
EXPECT_EQ(DRAW_SUCCESS, host_impl->PrepareToDraw(&frame));
ASSERT_EQ(1u, frame.render_passes.size());
const viz::RenderPass* root_render_pass = frame.render_passes.back().get();
EXPECT_EQ(full_frame_damage, root_render_pass->damage_rect);
EXPECT_TRUE(host_impl->DrawLayers(&frame));
host_impl->DidDrawAllLayers(frame);
+ host_impl->DidFinishImplFrame();
}
} // namespace
@@ -9098,44 +9355,6 @@ TEST_F(LayerTreeHostImplTestDrawAndTestDamage,
EXPECT_SCOPED(ExpectFullDamageAndDraw(host_impl_.get()));
}
-TEST_F(LayerTreeHostImplTest, RequireHighResAfterMSAAToggles) {
- // Create a host impl with MSAA support and a forced sample count of 4.
- LayerTreeSettings msaaSettings = DefaultSettings();
- msaaSettings.gpu_rasterization_msaa_sample_count = 4;
- EXPECT_TRUE(CreateHostImpl(
- msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
- msaaSettings.gpu_rasterization_msaa_sample_count)));
-
- ASSERT_TRUE(host_impl_->active_tree());
- EXPECT_FALSE(host_impl_->use_msaa());
-
- // RequiresHighResToDraw is set when new output surface is used.
- EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
-
- host_impl_->ResetRequiresHighResToDraw();
-
- host_impl_->SetContentHasSlowPaths(false);
- host_impl_->CommitComplete();
- EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
- host_impl_->NotifyReadyToActivate();
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->CommitComplete();
- EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
- host_impl_->NotifyReadyToActivate();
- host_impl_->SetContentHasSlowPaths(false);
- host_impl_->CommitComplete();
- EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
- host_impl_->NotifyReadyToActivate();
-
- host_impl_->ResetRequiresHighResToDraw();
-
- EXPECT_FALSE(host_impl_->RequiresHighResToDraw());
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->CommitComplete();
- EXPECT_TRUE(host_impl_->RequiresHighResToDraw());
- host_impl_->NotifyReadyToActivate();
-}
-
class LayerTreeHostImplTestPrepareTiles : public LayerTreeHostImplTest {
public:
void SetUp() override {
@@ -9227,41 +9446,6 @@ TEST_F(LayerTreeHostImplTest, CreateETC1UIResource) {
EXPECT_NE(0u, id1);
}
-TEST_F(LayerTreeHostImplTest,
- GpuRasterizationStatusChangeDoesNotEvictUIResources) {
- // Create a host impl with MSAA support and a forced sample count of 4.
- LayerTreeSettings msaaSettings = DefaultSettings();
- msaaSettings.gpu_rasterization_msaa_sample_count = 4;
- EXPECT_TRUE(CreateHostImpl(
- msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
- msaaSettings.gpu_rasterization_msaa_sample_count)));
-
- host_impl_->SetContentHasSlowPaths(false);
- 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());
-
- UIResourceId ui_resource_id = 1;
- UIResourceBitmap bitmap(gfx::Size(1, 1), false /* is_opaque */);
- host_impl_->CreateUIResource(ui_resource_id, bitmap);
- viz::ResourceId resource_id =
- host_impl_->ResourceIdForUIResource(ui_resource_id);
- EXPECT_NE(viz::kInvalidResourceId, resource_id);
- EXPECT_FALSE(host_impl_->EvictedUIResourcesExist());
-
- host_impl_->SetContentHasSlowPaths(true);
- 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());
-
- resource_id = host_impl_->ResourceIdForUIResource(ui_resource_id);
- EXPECT_NE(viz::kInvalidResourceId, resource_id);
- EXPECT_FALSE(host_impl_->EvictedUIResourcesExist());
-}
-
TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) {
LayerTreeSettings msaaSettings = DefaultSettings();
msaaSettings.gpu_rasterization_msaa_sample_count = 4;
@@ -9273,15 +9457,7 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) {
msaaSettings,
FakeLayerTreeFrameSink::Create3dForGpuRasterization(
msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->CommitComplete();
-
- EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
- host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_gpu_rasterization());
- EXPECT_FALSE(host_impl_->use_oop_rasterization());
- EXPECT_TRUE(host_impl_->use_msaa());
+ EXPECT_TRUE(host_impl_->can_use_msaa());
}
// gpu raster, msaa off
@@ -9291,15 +9467,7 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) {
msaaSettings,
FakeLayerTreeFrameSink::Create3dForGpuRasterization(
msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
- host_impl_->SetContentHasSlowPaths(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_oop_rasterization());
- EXPECT_FALSE(host_impl_->use_msaa());
+ EXPECT_FALSE(host_impl_->can_use_msaa());
}
// oop raster, msaa on
@@ -9309,15 +9477,7 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) {
msaaSettings,
FakeLayerTreeFrameSink::Create3dForOopRasterization(
msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
- host_impl_->SetContentHasSlowPaths(true);
- 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_oop_rasterization());
- EXPECT_TRUE(host_impl_->use_msaa());
+ EXPECT_TRUE(host_impl_->can_use_msaa());
}
// oop raster, msaa off
@@ -9327,15 +9487,7 @@ TEST_F(LayerTreeHostImplTest, ObeyMSAACaps) {
msaaSettings,
FakeLayerTreeFrameSink::Create3dForOopRasterization(
msaaSettings.gpu_rasterization_msaa_sample_count, msaa_is_slow)));
-
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->CommitComplete();
-
- EXPECT_EQ(GpuRasterizationStatus::ON,
- host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_gpu_rasterization());
- EXPECT_TRUE(host_impl_->use_oop_rasterization());
- EXPECT_FALSE(host_impl_->use_msaa());
+ EXPECT_FALSE(host_impl_->can_use_msaa());
}
}
@@ -9379,7 +9531,7 @@ class LayerTreeHostImplTestWithRenderer
RendererType renderer_type() const { return GetParam(); }
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostImplTestWithRenderer,
::testing::Values(RENDERER_GL, RENDERER_SKIA));
@@ -9457,7 +9609,8 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownNotOnAncestorChain) {
DrawFrame();
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
status.main_thread_scrolling_reasons);
@@ -9478,19 +9631,20 @@ TEST_F(LayerTreeHostImplTest, ScrollUnknownScrollAncestorMismatch) {
LayerImpl* child_scroll =
AddScrollableLayer(child_scroll_clip, viewport_size, content_size);
- child_scroll->SetOffsetToTransformParent(gfx::Vector2dF(10.f, 10.f));
+ child_scroll->SetOffsetToTransformParent(gfx::Vector2dF(10, 10));
LayerImpl* occluder_layer = AddLayer();
occluder_layer->SetDrawsContent(true);
occluder_layer->SetHitTestable(true);
occluder_layer->SetBounds(content_size);
CopyProperties(child_scroll, occluder_layer);
- occluder_layer->SetOffsetToTransformParent(gfx::Vector2dF(-10.f, -10.f));
+ occluder_layer->SetOffsetToTransformParent(gfx::Vector2dF(-10, -10));
DrawFrame();
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point()).get(), InputHandler::WHEEL);
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_UNKNOWN, status.thread);
EXPECT_EQ(MainThreadScrollingReason::kFailedHitTest,
status.main_thread_scrolling_reasons);
@@ -9513,7 +9667,8 @@ TEST_F(LayerTreeHostImplTest, ScrollInvisibleScroller) {
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
.thread);
EXPECT_EQ(child_scroll->scroll_tree_index(),
@@ -9558,13 +9713,13 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
UpdateDrawProperties(host_impl_->active_tree());
// Plumb the layer-local selection bounds.
- gfx::Point selection_top(5, 0);
- gfx::Point selection_bottom(5, 5);
+ gfx::Point selection_start(5, 0);
+ gfx::Point selection_end(5, 5);
LayerSelection selection;
selection.start.type = gfx::SelectionBound::CENTER;
selection.start.layer_id = root->id();
- selection.start.edge_bottom = selection_bottom;
- selection.start.edge_top = selection_top;
+ selection.start.edge_end = selection_end;
+ selection.start.edge_start = selection_start;
selection.end = selection.start;
host_impl_->active_tree()->RegisterSelection(selection);
@@ -9576,8 +9731,8 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToCompositorFrameMetadata) {
metadata.selection;
EXPECT_EQ(selection.start.type, selection_after.start.type());
EXPECT_EQ(selection.end.type, selection_after.end.type());
- EXPECT_EQ(gfx::PointF(selection_bottom), selection_after.start.edge_bottom());
- EXPECT_EQ(gfx::PointF(selection_top), selection_after.start.edge_top());
+ EXPECT_EQ(gfx::PointF(selection_end), selection_after.start.edge_end());
+ EXPECT_EQ(gfx::PointF(selection_start), selection_after.start.edge_start());
EXPECT_TRUE(selection_after.start.visible());
EXPECT_TRUE(selection_after.end.visible());
}
@@ -9588,8 +9743,8 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) {
UpdateDrawProperties(host_impl_->active_tree());
// Plumb the layer-local selection bounds.
- gfx::Point selection_top(5, 0);
- gfx::Point selection_bottom(5, 5);
+ gfx::Point selection_start(5, 0);
+ gfx::Point selection_end(5, 5);
LayerSelection selection;
// Mark the start as hidden.
@@ -9597,8 +9752,8 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) {
selection.start.type = gfx::SelectionBound::CENTER;
selection.start.layer_id = root->id();
- selection.start.edge_bottom = selection_bottom;
- selection.start.edge_top = selection_top;
+ selection.start.edge_end = selection_end;
+ selection.start.edge_start = selection_start;
selection.end = selection.start;
host_impl_->active_tree()->RegisterSelection(selection);
@@ -9610,8 +9765,8 @@ TEST_F(LayerTreeHostImplTest, HiddenSelectionBoundsStayHidden) {
metadata.selection;
EXPECT_EQ(selection.start.type, selection_after.start.type());
EXPECT_EQ(selection.end.type, selection_after.end.type());
- EXPECT_EQ(gfx::PointF(selection_bottom), selection_after.start.edge_bottom());
- EXPECT_EQ(gfx::PointF(selection_top), selection_after.start.edge_top());
+ EXPECT_EQ(gfx::PointF(selection_end), selection_after.start.edge_end());
+ EXPECT_EQ(gfx::PointF(selection_start), selection_after.start.edge_start());
EXPECT_FALSE(selection_after.start.visible());
EXPECT_FALSE(selection_after.end.visible());
}
@@ -9695,16 +9850,17 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
// Scrolling normally should not trigger any forwarding.
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_TRUE(
host_impl_
->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
.did_scroll);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_EQ(0, set_needs_commit_count);
EXPECT_EQ(1, set_needs_redraw_count);
@@ -9712,16 +9868,17 @@ TEST_F(LayerTreeHostImplTest, SimpleSwapPromiseMonitor) {
// Scrolling with a scroll handler should defer the swap to the main
// thread.
host_impl_->active_tree()->set_have_scroll_event_handlers(true);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_TRUE(
host_impl_
->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get())
.did_scroll);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_EQ(0, set_needs_commit_count);
EXPECT_EQ(2, set_needs_redraw_count);
@@ -9734,8 +9891,9 @@ class LayerTreeHostImplWithBrowserControlsTest : public LayerTreeHostImplTest {
LayerTreeSettings settings = DefaultSettings();
settings.commit_to_active_tree = false;
CreateHostImpl(settings, CreateLayerTreeFrameSink());
- host_impl_->active_tree()->SetTopControlsHeight(top_controls_height_);
- host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f);
+ host_impl_->active_tree()->SetBrowserControlsParams(
+ {top_controls_height_, 0, 0, 0, false, false});
+ host_impl_->active_tree()->SetCurrentBrowserControlsShownRatio(1.f, 1.f);
}
protected:
@@ -9764,7 +9922,8 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
EXPECT_FALSE(did_request_redraw_);
CreatePendingTree();
- host_impl_->sync_tree()->SetTopControlsHeight(100);
+ host_impl_->sync_tree()->SetBrowserControlsParams(
+ {100, 0, 0, 0, false, false});
host_impl_->ActivateSyncTree();
EXPECT_EQ(100, host_impl_->browser_controls_manager()->TopControlsHeight());
}
@@ -9772,17 +9931,18 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
TEST_F(LayerTreeHostImplWithBrowserControlsTest,
BrowserControlsStayFullyVisibleOnHeightChange) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset());
+ EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
CreatePendingTree();
- host_impl_->sync_tree()->SetTopControlsHeight(0);
+ host_impl_->sync_tree()->SetBrowserControlsParams({0, 0, 0, 0, false, false});
host_impl_->ActivateSyncTree();
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset());
+ EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
CreatePendingTree();
- host_impl_->sync_tree()->SetTopControlsHeight(50);
+ host_impl_->sync_tree()->SetBrowserControlsParams(
+ {50, 0, 0, 0, false, false});
host_impl_->ActivateSyncTree();
- EXPECT_EQ(0.f, host_impl_->browser_controls_manager()->ControlsTopOffset());
+ EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
}
TEST_F(LayerTreeHostImplWithBrowserControlsTest,
@@ -9809,18 +9969,20 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
BrowserControlsState::kBoth, BrowserControlsState::kShown, false);
DrawFrame();
+ // First, scroll just the browser controls and verify that the scroll
+ // succeeds.
+ const float residue = 10;
+ float offset = top_controls_height_ - residue;
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, offset)).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
EXPECT_EQ(gfx::Vector2dF().ToString(),
scroll_layer->CurrentScrollOffset().ToString());
- // 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(
UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get());
EXPECT_EQ(result.unused_scroll_delta, gfx::Vector2d(0, 0));
@@ -9872,30 +10034,32 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
EXPECT_EQ(gfx::Vector2dF().ToString(),
scroll_layer->CurrentScrollOffset().ToString());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
TEST_F(LayerTreeHostImplWithBrowserControlsTest,
WheelUnhandledByBrowserControls) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 100), gfx::Size(100, 200));
- host_impl_->active_tree()->set_browser_controls_shrink_blink_size(true);
+ host_impl_->active_tree()->SetBrowserControlsParams(
+ {top_controls_height_, 0, 0, 0, false, true});
host_impl_->browser_controls_manager()->UpdateBrowserControlsState(
BrowserControlsState::kBoth, BrowserControlsState::kShown, false);
DrawFrame();
LayerImpl* viewport_layer = InnerViewportScrollLayer();
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
- .thread);
+ const float delta = top_controls_height_;
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, delta)).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
EXPECT_VECTOR_EQ(gfx::Vector2dF(), viewport_layer->CurrentScrollOffset());
// 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())
@@ -9925,18 +10089,19 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
BrowserControlsState::kBoth, BrowserControlsState::kShown, false);
DrawFrame();
+ const float residue = 35;
+ float offset = top_controls_height_ - residue;
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, offset)).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
EXPECT_EQ(gfx::Vector2dF().ToString(),
scroll_layer->CurrentScrollOffset().ToString());
// Scroll the browser controls partially.
- const float residue = 35;
- float offset = top_controls_height_ - residue;
EXPECT_TRUE(
host_impl_
->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
@@ -9951,8 +10116,8 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
did_request_commit_ = false;
// End the scroll while the controls are still offset from their limit.
- host_impl_->ScrollEnd(EndState().get());
- ASSERT_TRUE(host_impl_->browser_controls_manager()->has_animation());
+ host_impl_->ScrollEnd();
+ ASSERT_TRUE(host_impl_->browser_controls_manager()->HasAnimation());
EXPECT_TRUE(did_request_next_frame_);
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
@@ -9987,12 +10152,12 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
EXPECT_TRUE(did_request_redraw_);
if (new_offset != 0) {
- EXPECT_TRUE(host_impl_->browser_controls_manager()->has_animation());
+ EXPECT_TRUE(host_impl_->browser_controls_manager()->HasAnimation());
EXPECT_TRUE(did_request_next_frame_);
}
host_impl_->DidFinishImplFrame();
}
- EXPECT_FALSE(host_impl_->browser_controls_manager()->has_animation());
+ EXPECT_FALSE(host_impl_->browser_controls_manager()->HasAnimation());
}
TEST_F(LayerTreeHostImplWithBrowserControlsTest,
@@ -10011,18 +10176,19 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
gfx::ScrollOffset(0, initial_scroll_offset));
DrawFrame();
+ const float residue = 15;
+ float offset = top_controls_height_ - residue;
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, offset)).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
EXPECT_EQ(gfx::Vector2dF(0, initial_scroll_offset).ToString(),
scroll_layer->CurrentScrollOffset().ToString());
// Scroll the browser controls partially.
- const float residue = 15;
- float offset = top_controls_height_ - residue;
EXPECT_TRUE(
host_impl_
->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, offset)).get())
@@ -10037,8 +10203,8 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
did_request_commit_ = false;
// End the scroll while the controls are still offset from the limit.
- host_impl_->ScrollEnd(EndState().get());
- ASSERT_TRUE(host_impl_->browser_controls_manager()->has_animation());
+ host_impl_->ScrollEnd();
+ ASSERT_TRUE(host_impl_->browser_controls_manager()->HasAnimation());
EXPECT_TRUE(did_request_next_frame_);
EXPECT_TRUE(did_request_redraw_);
EXPECT_TRUE(did_request_commit_);
@@ -10068,7 +10234,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
}
host_impl_->DidFinishImplFrame();
}
- EXPECT_FALSE(host_impl_->browser_controls_manager()->has_animation());
+ EXPECT_FALSE(host_impl_->browser_controls_manager()->HasAnimation());
EXPECT_EQ(-top_controls_height_,
host_impl_->browser_controls_manager()->ControlsTopOffset());
}
@@ -10085,14 +10251,15 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
BrowserControlsState::kBoth, BrowserControlsState::kShown, false);
DrawFrame();
+ float offset = 50;
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
+ ->ScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, offset)).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
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())
@@ -10151,7 +10318,7 @@ TEST_F(LayerTreeHostImplWithBrowserControlsTest,
// Browser controls should be fully visible
EXPECT_EQ(0, host_impl_->browser_controls_manager()->ControlsTopOffset());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
// Tests that when we set a child scroller (e.g. a scrolling div) as the outer
@@ -10185,21 +10352,22 @@ TEST_F(LayerTreeHostImplBrowserControlsTest,
layer_tree_impl->SetViewportPropertyIds(viewport_property_ids);
DrawFrame();
- ASSERT_EQ(1.f, layer_tree_impl->CurrentBrowserControlsShownRatio());
+ ASSERT_EQ(1, layer_tree_impl->CurrentTopControlsShownRatio());
// 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(),
- InputHandler::TOUCHSCREEN);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get(),
+ InputHandler::TOUCHSCREEN);
host_impl_->ScrollBy(
- UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100.f, 100.f)).get());
- host_impl_->ScrollEnd(EndState().get());
+ UpdateState(gfx::Point(0, 0), gfx::Vector2dF(100, 100)).get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(), outer_scroll->CurrentScrollOffset());
- EXPECT_VECTOR_EQ(gfx::Vector2dF(100.f, 50.f),
+ EXPECT_VECTOR_EQ(gfx::Vector2dF(100, 50),
scroll_layer->CurrentScrollOffset());
- EXPECT_EQ(0.f, layer_tree_impl->CurrentBrowserControlsShownRatio());
+ EXPECT_EQ(0, layer_tree_impl->CurrentTopControlsShownRatio());
}
}
@@ -10223,18 +10391,16 @@ TEST_F(LayerTreeHostImplVirtualViewportTest, RootScrollBothInnerAndOuterLayer) {
EXPECT_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
EXPECT_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
- gfx::ScrollOffset current_offset(70.f, 100.f);
+ gfx::ScrollOffset current_offset(70, 100);
host_impl_->SetSynchronousInputHandlerRootScrollOffset(current_offset);
- EXPECT_EQ(gfx::ScrollOffset(25.f, 40.f), inner_scroll->MaxScrollOffset());
- EXPECT_EQ(gfx::ScrollOffset(50.f, 80.f), outer_scroll->MaxScrollOffset());
+ EXPECT_EQ(gfx::ScrollOffset(25, 40), inner_scroll->MaxScrollOffset());
+ EXPECT_EQ(gfx::ScrollOffset(50, 80), outer_scroll->MaxScrollOffset());
// Inner viewport scrolls first. Then the rest is applied to the outer
// viewport.
- EXPECT_EQ(gfx::ScrollOffset(25.f, 40.f),
- inner_scroll->CurrentScrollOffset());
- EXPECT_EQ(gfx::ScrollOffset(45.f, 60.f),
- outer_scroll->CurrentScrollOffset());
+ EXPECT_EQ(gfx::ScrollOffset(25, 40), inner_scroll->CurrentScrollOffset());
+ EXPECT_EQ(gfx::ScrollOffset(45, 60), outer_scroll->CurrentScrollOffset());
}
}
@@ -10257,17 +10423,18 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
EXPECT_VECTOR_EQ(outer_expected, outer_scroll->CurrentScrollOffset());
+ gfx::Vector2d scroll_delta(inner_viewport.width() / 2,
+ inner_viewport.height() / 2);
+
// Make sure the scroll goes to the inner viewport first.
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
InputHandler::TOUCHSCREEN)
.thread);
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
// Scroll near the edge of the outer viewport.
- 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 += scroll_delta;
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
@@ -10283,7 +10450,7 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
outer_expected += scroll_delta;
inner_expected += scroll_delta;
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
EXPECT_VECTOR_EQ(inner_expected, inner_scroll->CurrentScrollOffset());
@@ -10309,20 +10476,22 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->RootScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
+ ->RootScrollBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::TOUCHSCREEN)
.thread);
EXPECT_EQ(host_impl_->CurrentlyScrollingNode(),
- host_impl_->ViewportMainScrollNode());
- host_impl_->ScrollEnd(EndState().get());
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ host_impl_->OuterViewportScrollNode());
+ host_impl_->ScrollEnd();
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
EXPECT_EQ(host_impl_->CurrentlyScrollingNode()->id,
child_scroll->scroll_tree_index());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
}
TEST_F(LayerTreeHostImplVirtualViewportTest,
@@ -10342,11 +10511,12 @@ TEST_F(LayerTreeHostImplVirtualViewportTest,
// Ensure inner viewport doesn't react to scrolls (test it's unscrollable).
EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset());
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
- InputHandler::TOUCHSCREEN)
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 100)).get(),
+ InputHandler::TOUCHSCREEN)
+ .thread);
scroll_result = host_impl_->ScrollBy(
UpdateState(gfx::Point(), gfx::Vector2dF(0, 100)).get());
EXPECT_VECTOR_EQ(gfx::Vector2dF(), inner_scroll->CurrentScrollOffset());
@@ -10687,7 +10857,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) {
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));
+ EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1, 1));
gfx::Transform external_transform;
external_transform.Translate(10, 10);
@@ -10702,7 +10872,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) {
resourceless_software_draw, false);
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));
+ EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2, 2));
// Clear the external transform.
external_transform = gfx::Transform();
@@ -10713,7 +10883,7 @@ TEST_F(LayerTreeHostImplTest, ExternalTransformAffectsSublayerScaleFactor) {
resourceless_software_draw, false);
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));
+ EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1, 1));
}
TEST_F(LayerTreeHostImplTest, ScrollAnimated) {
@@ -10829,8 +10999,8 @@ TEST_F(LayerTreeHostImplTest, ScrollAnimatedWhileZoomed) {
// Zoom in to 2X
{
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 2.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 2;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
@@ -10908,8 +11078,7 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) {
// Set up the thumb dimensions.
scrollbar->SetThumbThickness(15);
scrollbar->SetThumbLength(50);
- scrollbar->SetTrackStart(15);
- scrollbar->SetTrackLength(575);
+ scrollbar->SetTrackRect(gfx::Rect(0, 15, 15, 575));
// Set up scrollbar arrows.
scrollbar->SetBackButtonRect(
@@ -10919,8 +11088,9 @@ TEST_F(LayerTreeHostImplTest, SingleGSUForScrollbarThumbDragPerFrame) {
scrollbar->SetOffsetToTransformParent(gfx::Vector2dF(345, 0));
- host_impl_->ScrollBegin(BeginState(gfx::Point(350, 18)).get(),
- InputHandler::SCROLLBAR);
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(350, 18), gfx::Vector2dF()).get(),
+ InputHandler::SCROLLBAR);
TestInputHandlerClient input_handler_client;
host_impl_->BindToClient(&input_handler_client);
@@ -10976,14 +11146,18 @@ TEST_F(LayerTreeHostImplTest, SecondScrollAnimatedBeginNotIgnored) {
const gfx::Size viewport_size(50, 100);
SetupViewportLayersOuterScrolls(viewport_size, content_size);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_->ScrollAnimatedBegin(BeginState(gfx::Point()).get()).thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollAnimatedBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get())
+ .thread);
// The second ScrollAnimatedBegin should not get ignored.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_->ScrollAnimatedBegin(BeginState(gfx::Point()).get()).thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollAnimatedBegin(
+ BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get())
+ .thread);
}
// Verfify that a smooth scroll animation doesn't jump when UpdateTarget gets
@@ -11148,17 +11322,17 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedAborted) {
EXPECT_TRUE(y > 1 && y < 49);
// Perform instant scroll.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point(0, y)).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(
+ BeginState(gfx::Point(0, y), gfx::Vector2dF(0, 50)).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y)));
host_impl_->ScrollBy(
UpdateState(gfx::Point(0, y), gfx::Vector2d(0, 50)).get());
EXPECT_TRUE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point(0, y + 50)));
- std::unique_ptr<ScrollState> scroll_state_end = EndState();
- host_impl_->ScrollEnd(scroll_state_end.get());
+ host_impl_->ScrollEnd();
EXPECT_FALSE(host_impl_->IsCurrentlyScrollingLayerAt(gfx::Point()));
// The instant scroll should have marked the smooth scroll animation as
@@ -11257,8 +11431,8 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) {
LayerImpl* inner_scroll_layer = InnerViewportScrollLayer();
// Zoom into the page by a 2X factor
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 2.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 2;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
@@ -11269,9 +11443,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) {
base::TimeTicks() + base::TimeDelta::FromMilliseconds(250);
viz::BeginFrameArgs begin_frame_args =
viz::CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, 0, 1);
- EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(10.f, 20.f))
- .thread);
+ EXPECT_EQ(
+ InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(10, 20)).thread);
host_impl_->Animate();
host_impl_->UpdateAnimationState(true);
EXPECT_EQ(inner_scroll_layer->scroll_tree_index(),
@@ -11289,8 +11463,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) {
// should bubble up to the outer viewport.
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(100.f, 100.f))
- .thread);
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(100, 100)).thread);
host_impl_->Animate();
host_impl_->UpdateAnimationState(true);
EXPECT_EQ(inner_scroll_layer->scroll_tree_index(),
@@ -11308,8 +11481,7 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) {
// outer viewport.
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(190.f, 180.f))
- .thread);
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(190, 180)).thread);
host_impl_->Animate();
host_impl_->UpdateAnimationState(true);
EXPECT_EQ(outer_scroll_layer->scroll_tree_index(),
@@ -11325,10 +11497,9 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimated) {
// Scroll upwards by the max scroll extent. The inner viewport should animate
// and the remainder should bubble to the outer viewport.
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(-110.f, -120.f))
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_->ScrollAnimated(gfx::Point(), gfx::Vector2d(-110, -120))
+ .thread);
host_impl_->Animate();
host_impl_->UpdateAnimationState(true);
EXPECT_EQ(inner_scroll_layer->scroll_tree_index(),
@@ -11354,8 +11525,8 @@ TEST_F(LayerTreeHostImplTimelinesTest, ImplPinchZoomScrollAnimatedUpdate) {
LayerImpl* inner_scroll_layer = InnerViewportScrollLayer();
// Zoom into the page by a 2X factor
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 2.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 2;
host_impl_->active_tree()->PushPageScaleFromMainThread(
page_scale_factor, min_page_scale, max_page_scale);
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
@@ -11515,8 +11686,6 @@ TEST_F(LayerTreeHostImplTimelinesTest, ScrollAnimatedChangingBounds) {
scrolling_layer->SetBounds(new_content_size);
GetScrollNode(scrolling_layer)->bounds = new_content_size;
- DrawFrame();
-
begin_frame_args.frame_time =
start_time + base::TimeDelta::FromMilliseconds(200);
begin_frame_args.sequence_number++;
@@ -11547,7 +11716,7 @@ TEST_F(LayerTreeHostImplTest, InvalidLayerNotAddedToRasterQueue) {
layer->tilings()->tiling_at(0)->set_resolution(
TileResolution::HIGH_RESOLUTION);
layer->tilings()->tiling_at(0)->CreateAllTilesForTesting();
- layer->tilings()->UpdateTilePriorities(gfx::Rect(gfx::Size(10, 10)), 1.f, 1.0,
+ layer->tilings()->UpdateTilePriorities(gfx::Rect(gfx::Size(10, 10)), 1, 1.0,
Occlusion(), true);
layer->set_has_valid_tile_priorities(true);
@@ -11604,8 +11773,8 @@ TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) {
EXPECT_EQ(scroll_layer, InnerViewportScrollLayer());
- float min_page_scale = 1.f, max_page_scale = 4.f;
- float page_scale_factor = 1.f;
+ float min_page_scale = 1, max_page_scale = 4;
+ float page_scale_factor = 1;
// The scroll deltas should have the page scale factor applied.
{
@@ -11614,24 +11783,24 @@ TEST_F(LayerTreeHostImplTest, WheelScrollWithPageScaleFactorOnInnerLayer) {
host_impl_->active_tree()->SetPageScaleOnActiveTree(page_scale_factor);
SetScrollOffsetDelta(scroll_layer, gfx::Vector2d());
- float page_scale_delta = 2.f;
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ float page_scale_delta = 2;
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
host_impl_->PinchGestureUpdate(page_scale_delta, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
gfx::Vector2dF scroll_delta(0, 5);
- EXPECT_EQ(
- InputHandler::SCROLL_ON_IMPL_THREAD,
- host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
- .thread);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
+ host_impl_
+ ->ScrollBegin(BeginState(gfx::Point(), scroll_delta).get(),
+ InputHandler::WHEEL)
+ .thread);
EXPECT_VECTOR_EQ(gfx::Vector2dF(), scroll_layer->CurrentScrollOffset());
host_impl_->ScrollBy(UpdateState(gfx::Point(), scroll_delta).get());
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
EXPECT_VECTOR_EQ(gfx::Vector2dF(0, 2.5),
scroll_layer->CurrentScrollOffset());
}
@@ -11849,40 +12018,6 @@ TEST_F(LayerTreeHostImplTest, AddVideoFrameControllerOutsideFrame) {
EXPECT_FALSE(controller.did_draw_frame());
}
-// Tests that SetContentHasSlowPaths behaves as expected.
-TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusSlowPaths) {
- LayerTreeSettings msaaSettings = DefaultSettings();
- msaaSettings.gpu_rasterization_msaa_sample_count = 4;
- EXPECT_TRUE(CreateHostImpl(
- msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
- msaaSettings.gpu_rasterization_msaa_sample_count)));
-
- // Set initial state, with slow paths on.
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
- host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_msaa());
- host_impl_->NotifyReadyToActivate();
-
- // Toggle slow paths off.
- host_impl_->SetContentHasSlowPaths(false);
- 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());
- host_impl_->NotifyReadyToActivate();
-
- // And on.
- host_impl_->SetContentHasSlowPaths(true);
- 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());
- host_impl_->NotifyReadyToActivate();
-}
-
// Tests that SetDeviceScaleFactor correctly impacts GPU rasterization.
TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) {
// Create a host impl with MSAA support (4 samples).
@@ -11892,7 +12027,6 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) {
msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(4)));
// Set initial state, before varying scale factor.
- host_impl_->SetContentHasSlowPaths(true);
host_impl_->CommitComplete();
EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
@@ -11902,18 +12036,15 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusDeviceScaleFactor) {
// 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_->can_use_msaa());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
- EXPECT_TRUE(host_impl_->use_msaa());
host_impl_->NotifyReadyToActivate();
// Set device scale factor back to 1.
host_impl_->active_tree()->SetDeviceScaleFactor(1.0f);
host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
+ EXPECT_FALSE(host_impl_->can_use_msaa());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
- EXPECT_FALSE(host_impl_->use_msaa());
host_impl_->NotifyReadyToActivate();
}
@@ -11926,12 +12057,9 @@ TEST_F(LayerTreeHostImplTest, GpuRasterizationStatusExplicitMSAACount) {
msaaSettings, FakeLayerTreeFrameSink::Create3dForGpuRasterization(
msaaSettings.gpu_rasterization_msaa_sample_count)));
- host_impl_->SetContentHasSlowPaths(true);
host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
- host_impl_->gpu_rasterization_status());
+ EXPECT_TRUE(host_impl_->can_use_msaa());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
- EXPECT_TRUE(host_impl_->use_msaa());
}
class GpuRasterizationDisabledLayerTreeHostImplTest
@@ -11942,28 +12070,6 @@ class GpuRasterizationDisabledLayerTreeHostImplTest
}
};
-// Tests that GPU rasterization overrides work as expected.
-TEST_F(GpuRasterizationDisabledLayerTreeHostImplTest,
- GpuRasterizationStatusOverrides) {
- LayerTreeSettings settings = DefaultSettings();
- EXPECT_TRUE(CreateHostImpl(settings, FakeLayerTreeFrameSink::Create3d()));
- host_impl_->SetContentHasSlowPaths(false);
- host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::OFF_DEVICE,
- 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, FakeLayerTreeFrameSink::Create3d()));
-
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::ON_FORCED,
- host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_gpu_rasterization());
-}
-
class MsaaIsSlowLayerTreeHostImplTest : public LayerTreeHostImplTest {
public:
void CreateHostImplWithCaps(bool msaa_is_slow, bool avoid_stencil_buffers) {
@@ -11987,37 +12093,29 @@ TEST_F(MsaaIsSlowLayerTreeHostImplTest, GpuRasterizationStatusMsaaIsSlow) {
// Ensure that without the msaa_is_slow or avoid_stencil_buffers caps
// we raster slow paths with msaa.
CreateHostImplWithCaps(false, false);
- host_impl_->SetContentHasSlowPaths(true);
host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
- host_impl_->gpu_rasterization_status());
+ EXPECT_TRUE(host_impl_->can_use_msaa());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
// Ensure that with either msaa_is_slow or avoid_stencil_buffers caps
// we don't raster slow paths with msaa (we'll still use GPU raster, though).
// msaa_is_slow = true, avoid_stencil_buffers = false
CreateHostImplWithCaps(true, false);
- host_impl_->SetContentHasSlowPaths(true);
host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
+ EXPECT_FALSE(host_impl_->can_use_msaa());
EXPECT_TRUE(host_impl_->use_gpu_rasterization());
- EXPECT_FALSE(host_impl_->use_msaa());
// msaa_is_slow = false, avoid_stencil_buffers = true
CreateHostImplWithCaps(false, true);
- host_impl_->SetContentHasSlowPaths(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());
+ EXPECT_FALSE(host_impl_->can_use_msaa());
// msaa_is_slow = true, avoid_stencil_buffers = true
CreateHostImplWithCaps(true, true);
- host_impl_->SetContentHasSlowPaths(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());
+ EXPECT_FALSE(host_impl_->can_use_msaa());
}
class MsaaCompatibilityLayerTreeHostImplTest : public LayerTreeHostImplTest {
@@ -12041,66 +12139,73 @@ class MsaaCompatibilityLayerTreeHostImplTest : public LayerTreeHostImplTest {
TEST_F(MsaaCompatibilityLayerTreeHostImplTest,
GpuRasterizationStatusNonAAPaint) {
+ // Always use a recording with slow paths so the toggle is dependent on non aa
+ // paint.
+ auto recording_source = FakeRecordingSource::CreateRecordingSource(
+ gfx::Rect(100, 100), gfx::Size(100, 100));
+ recording_source->set_has_slow_paths(true);
+
// Ensure that without non-aa paint and without multisample compatibility, we
// raster slow paths with msaa.
CreateHostImplWithMultisampleCompatibility(false);
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->SetContentHasNonAAPaint(false);
- host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
- host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ recording_source->set_has_non_aa_paint(false);
+ recording_source->Rerecord();
+ EXPECT_TRUE(host_impl_->can_use_msaa());
+ EXPECT_GT(host_impl_->GetMSAASampleCountForRaster(
+ recording_source->GetDisplayItemList()),
+ 0);
// Ensure that without non-aa paint and with multisample compatibility, we
// raster slow paths with msaa.
CreateHostImplWithMultisampleCompatibility(true);
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->SetContentHasNonAAPaint(false);
- host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
- host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ recording_source->set_has_non_aa_paint(false);
+ recording_source->Rerecord();
+ EXPECT_TRUE(host_impl_->can_use_msaa());
+ EXPECT_GT(host_impl_->GetMSAASampleCountForRaster(
+ recording_source->GetDisplayItemList()),
+ 0);
// Ensure that with non-aa paint and without multisample compatibility, we do
// not raster slow paths with msaa.
CreateHostImplWithMultisampleCompatibility(false);
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->SetContentHasNonAAPaint(true);
- host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::ON, host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ recording_source->set_has_non_aa_paint(true);
+ recording_source->Rerecord();
+ EXPECT_TRUE(host_impl_->can_use_msaa());
+ EXPECT_EQ(host_impl_->GetMSAASampleCountForRaster(
+ recording_source->GetDisplayItemList()),
+ 0);
// Ensure that with non-aa paint and with multisample compatibility, we raster
// slow paths with msaa.
CreateHostImplWithMultisampleCompatibility(true);
- host_impl_->SetContentHasSlowPaths(true);
- host_impl_->SetContentHasNonAAPaint(true);
- host_impl_->CommitComplete();
- EXPECT_EQ(GpuRasterizationStatus::MSAA_CONTENT,
- host_impl_->gpu_rasterization_status());
- EXPECT_TRUE(host_impl_->use_gpu_rasterization());
+ recording_source->set_has_non_aa_paint(true);
+ recording_source->Rerecord();
+ EXPECT_TRUE(host_impl_->can_use_msaa());
+ EXPECT_GT(host_impl_->GetMSAASampleCountForRaster(
+ recording_source->GetDisplayItemList()),
+ 0);
}
TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
// Check page scale factor update in property trees when an update is made
// on the active tree.
CreatePendingTree();
- host_impl_->pending_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f);
+ host_impl_->pending_tree()->PushPageScaleFromMainThread(1, 1, 3);
SetupViewportLayers(host_impl_->pending_tree(), gfx::Size(50, 50),
gfx::Size(100, 100), gfx::Size(100, 100));
host_impl_->ActivateSyncTree();
DrawFrame();
CreatePendingTree();
- host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(2);
TransformNode* active_tree_node =
host_impl_->active_tree()->PageScaleTransformNode();
// SetPageScaleOnActiveTree also updates the factors in property trees.
EXPECT_TRUE(active_tree_node->local.IsScale2d());
- EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d());
+ EXPECT_EQ(gfx::Vector2dF(2, 2), active_tree_node->local.Scale2d());
EXPECT_EQ(gfx::Point3F(), active_tree_node->origin);
- EXPECT_EQ(2.f, host_impl_->active_tree()->current_page_scale_factor());
+ EXPECT_EQ(2, host_impl_->active_tree()->current_page_scale_factor());
TransformNode* pending_tree_node =
host_impl_->pending_tree()->PageScaleTransformNode();
@@ -12109,30 +12214,30 @@ TEST_F(LayerTreeHostImplTest, UpdatePageScaleFactorOnActiveTree) {
// shared data between the active and pending trees.
EXPECT_TRUE(pending_tree_node->local.IsIdentity());
EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin);
- EXPECT_EQ(2.f, host_impl_->pending_tree()->current_page_scale_factor());
- EXPECT_EQ(1.f, host_impl_->pending_tree()
- ->property_trees()
- ->transform_tree.page_scale_factor());
+ EXPECT_EQ(2, host_impl_->pending_tree()->current_page_scale_factor());
+ EXPECT_EQ(1, host_impl_->pending_tree()
+ ->property_trees()
+ ->transform_tree.page_scale_factor());
host_impl_->pending_tree()->set_needs_update_draw_properties();
UpdateDrawProperties(host_impl_->pending_tree());
pending_tree_node = host_impl_->pending_tree()->PageScaleTransformNode();
EXPECT_TRUE(pending_tree_node->local.IsScale2d());
- EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), pending_tree_node->local.Scale2d());
+ EXPECT_EQ(gfx::Vector2dF(2, 2), pending_tree_node->local.Scale2d());
EXPECT_EQ(gfx::Point3F(), pending_tree_node->origin);
host_impl_->ActivateSyncTree();
UpdateDrawProperties(host_impl_->active_tree());
active_tree_node = host_impl_->active_tree()->PageScaleTransformNode();
EXPECT_TRUE(active_tree_node->local.IsScale2d());
- EXPECT_EQ(gfx::Vector2dF(2.f, 2.f), active_tree_node->local.Scale2d());
+ EXPECT_EQ(gfx::Vector2dF(2, 2), active_tree_node->local.Scale2d());
EXPECT_EQ(gfx::Point3F(), active_tree_node->origin);
}
TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) {
// Checks that the sublayer scale of a transform node in the subtree of the
// page scale layer is updated without a property tree rebuild.
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 1.f, 3.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 1, 3);
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
LayerImpl* in_subtree_of_page_scale_layer = AddLayer();
CopyProperties(root_layer(), in_subtree_of_page_scale_layer);
@@ -12144,14 +12249,14 @@ TEST_F(LayerTreeHostImplTest, SubLayerScaleForNodeInSubtreeOfPageScaleLayer) {
DrawFrame();
EffectNode* node = GetEffectNode(in_subtree_of_page_scale_layer);
- EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1.f, 1.f));
+ EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(1, 1));
- host_impl_->active_tree()->SetPageScaleOnActiveTree(2.f);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(2);
DrawFrame();
node = GetEffectNode(in_subtree_of_page_scale_layer);
- EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2.f, 2.f));
+ EXPECT_EQ(node->surface_contents_scale, gfx::Vector2dF(2, 2));
}
// Checks that if we lose a GPU raster enabled LayerTreeFrameSink and replace
@@ -12392,7 +12497,7 @@ void LayerTreeHostImplTest::SetupMouseMoveAtTestScrollbarStates(
// scrollbar_2_animation_controller, then mouse up should not cause crash.
host_impl_->MouseMoveAt(gfx::Point(40, 150));
host_impl_->MouseDown(gfx::PointF(40, 150), /*shift_modifier*/ false);
- host_impl_->UnregisterScrollbarAnimationController(root_scroll->element_id());
+ host_impl_->DidUnregisterScrollbarLayer(root_scroll->element_id());
host_impl_->MouseUp(gfx::PointF(40, 150));
}
@@ -12529,7 +12634,7 @@ TEST_F(LayerTreeHostImplTest, UpdatedTilingsForNonDrawingLayers) {
host_impl_->pending_tree()->SetElementIdsForTesting();
gfx::Transform singular;
- singular.Scale3d(6.f, 6.f, 0.f);
+ singular.Scale3d(6, 6, 0);
CopyProperties(root, animated_transform_layer);
CreateTransformNode(animated_transform_layer).local = singular;
@@ -12646,35 +12751,21 @@ TEST_F(LayerTreeHostImplTest, DrawAfterDroppingTileResources) {
DrawFrame();
EXPECT_FALSE(host_impl_->active_tree()->needs_update_draw_properties());
- EXPECT_LT(0.f, layer->raster_page_scale());
+ EXPECT_LT(0, layer->raster_page_scale());
EXPECT_GT(layer->tilings()->num_tilings(), 0u);
const ManagedMemoryPolicy policy = host_impl_->ActualManagedMemoryPolicy();
const ManagedMemoryPolicy zero_policy(0u);
host_impl_->SetMemoryPolicy(zero_policy);
- EXPECT_EQ(0.f, layer->raster_page_scale());
+ EXPECT_EQ(0, layer->raster_page_scale());
EXPECT_EQ(layer->tilings()->num_tilings(), 0u);
host_impl_->SetMemoryPolicy(policy);
DrawFrame();
- EXPECT_LT(0.f, layer->raster_page_scale());
+ EXPECT_LT(0, layer->raster_page_scale());
EXPECT_GT(layer->tilings()->num_tilings(), 0u);
}
-TEST_F(LayerTreeHostImplTest, NeedUpdateGpuRasterization) {
- EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-
- host_impl_->SetContentHasSlowPaths(true);
- EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
- host_impl_->CommitComplete();
- EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-
- host_impl_->SetContentHasNonAAPaint(true);
- EXPECT_TRUE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
- host_impl_->CommitComplete();
- EXPECT_FALSE(host_impl_->NeedUpdateGpuRasterizationStatusForTesting());
-}
-
TEST_F(LayerTreeHostImplTest, WhiteListedTouchActionTest1) {
WhiteListedTouchActionTestHelper(1.0f, 1.0f);
}
@@ -12726,20 +12817,20 @@ class TestRenderFrameMetadataObserver : public RenderFrameMetadataObserver {
TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) {
SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50));
- host_impl_->active_tree()->PushPageScaleFromMainThread(1.f, 0.5f, 4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(1, 0.5f, 4);
{
// Check initial metadata is correct.
RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata();
EXPECT_EQ(gfx::Vector2dF(), metadata.root_scroll_offset);
- EXPECT_EQ(1.f, metadata.page_scale_factor);
+ EXPECT_EQ(1, metadata.page_scale_factor);
#if defined(OS_ANDROID)
- EXPECT_EQ(gfx::SizeF(50.f, 50.f), metadata.scrollable_viewport_size);
+ EXPECT_EQ(gfx::SizeF(50, 50), metadata.scrollable_viewport_size);
EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
- EXPECT_EQ(4.f, metadata.max_page_scale_factor);
- EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
+ EXPECT_EQ(4, metadata.max_page_scale_factor);
+ EXPECT_EQ(gfx::SizeF(100, 100), metadata.root_layer_size);
EXPECT_FALSE(metadata.root_overflow_y_hidden);
#endif
}
@@ -12748,17 +12839,18 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) {
EXPECT_EQ(
InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(), InputHandler::WHEEL)
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::WHEEL)
.thread);
host_impl_->ScrollBy(UpdateState(gfx::Point(), gfx::Vector2d(0, 10)).get());
{
RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
}
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
{
RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
}
#if defined(OS_ANDROID)
@@ -12811,41 +12903,41 @@ TEST_F(LayerTreeHostImplTest, RenderFrameMetadata) {
#endif
// Page scale should update metadata correctly (shrinking only the viewport).
- host_impl_->ScrollBegin(BeginState(gfx::Point()).get(),
+ host_impl_->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN);
host_impl_->PinchGestureBegin();
- host_impl_->PinchGestureUpdate(2.f, gfx::Point());
+ host_impl_->PinchGestureUpdate(2, gfx::Point());
host_impl_->PinchGestureEnd(gfx::Point(), true);
- host_impl_->ScrollEnd(EndState().get());
+ host_impl_->ScrollEnd();
{
RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
- EXPECT_EQ(2.f, metadata.page_scale_factor);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
+ EXPECT_EQ(2, metadata.page_scale_factor);
#if defined(OS_ANDROID)
- EXPECT_EQ(gfx::SizeF(25.f, 25.f), metadata.scrollable_viewport_size);
+ EXPECT_EQ(gfx::SizeF(25, 25), metadata.scrollable_viewport_size);
EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
- EXPECT_EQ(4.f, metadata.max_page_scale_factor);
- EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
+ EXPECT_EQ(4, metadata.max_page_scale_factor);
+ EXPECT_EQ(gfx::SizeF(100, 100), metadata.root_layer_size);
#endif
}
// Likewise if set from the main thread.
host_impl_->ProcessScrollDeltas();
- host_impl_->active_tree()->PushPageScaleFromMainThread(4.f, 0.5f, 4.f);
- host_impl_->active_tree()->SetPageScaleOnActiveTree(4.f);
+ host_impl_->active_tree()->PushPageScaleFromMainThread(4, 0.5f, 4);
+ host_impl_->active_tree()->SetPageScaleOnActiveTree(4);
{
RenderFrameMetadata metadata = StartDrawAndProduceRenderFrameMetadata();
- EXPECT_EQ(gfx::Vector2dF(0.f, 10.f), metadata.root_scroll_offset);
- EXPECT_EQ(4.f, metadata.page_scale_factor);
+ EXPECT_EQ(gfx::Vector2dF(0, 10), metadata.root_scroll_offset);
+ EXPECT_EQ(4, metadata.page_scale_factor);
#if defined(OS_ANDROID)
EXPECT_EQ(gfx::SizeF(12.5f, 12.5f), metadata.scrollable_viewport_size);
EXPECT_EQ(0.5f, metadata.min_page_scale_factor);
- EXPECT_EQ(4.f, metadata.max_page_scale_factor);
- EXPECT_EQ(gfx::SizeF(100.f, 100.f), metadata.root_layer_size);
+ EXPECT_EQ(4, metadata.max_page_scale_factor);
+ EXPECT_EQ(gfx::SizeF(100, 100), metadata.root_layer_size);
#endif
}
}
@@ -12870,19 +12962,19 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) {
observer_ptr->last_metadata()->selection;
EXPECT_EQ(gfx::SelectionBound::EMPTY, selection_1.start.type());
EXPECT_EQ(gfx::SelectionBound::EMPTY, selection_1.end.type());
- EXPECT_EQ(gfx::PointF(), selection_1.start.edge_bottom());
- EXPECT_EQ(gfx::PointF(), selection_1.start.edge_top());
+ EXPECT_EQ(gfx::PointF(), selection_1.start.edge_end());
+ EXPECT_EQ(gfx::PointF(), selection_1.start.edge_start());
EXPECT_FALSE(selection_1.start.visible());
EXPECT_FALSE(selection_1.end.visible());
// Plumb the layer-local selection bounds.
- gfx::Point selection_top(5, 0);
- gfx::Point selection_bottom(5, 5);
+ gfx::Point selection_start(5, 0);
+ gfx::Point selection_end(5, 5);
LayerSelection selection;
selection.start.type = gfx::SelectionBound::CENTER;
selection.start.layer_id = root->id();
- selection.start.edge_bottom = selection_bottom;
- selection.start.edge_top = selection_top;
+ selection.start.edge_end = selection_end;
+ selection.start.edge_start = selection_start;
selection.end = selection.start;
host_impl_->active_tree()->RegisterSelection(selection);
@@ -12896,12 +12988,96 @@ TEST_F(LayerTreeHostImplTest, SelectionBoundsPassedToRenderFrameMetadata) {
observer_ptr->last_metadata()->selection;
EXPECT_EQ(selection.start.type, selection_2.start.type());
EXPECT_EQ(selection.end.type, selection_2.end.type());
- EXPECT_EQ(gfx::PointF(selection_bottom), selection_2.start.edge_bottom());
- EXPECT_EQ(gfx::PointF(selection_top), selection_2.start.edge_top());
+ EXPECT_EQ(gfx::PointF(selection_end), selection_2.start.edge_end());
+ EXPECT_EQ(gfx::PointF(selection_start), selection_2.start.edge_start());
EXPECT_TRUE(selection_2.start.visible());
EXPECT_TRUE(selection_2.end.visible());
}
+TEST_F(LayerTreeHostImplTest,
+ VerticalScrollDirectionChangesPassedToRenderFrameMetadata) {
+ // Set up the viewport.
+ SetupViewportLayersInnerScrolls(gfx::Size(50, 50), gfx::Size(100, 100));
+ host_impl_->active_tree()->SetDeviceViewportRect(gfx::Rect(50, 50));
+
+ // Set up the render frame metadata observer.
+ auto observer = std::make_unique<TestRenderFrameMetadataObserver>(false);
+ auto* observer_ptr = observer.get();
+ host_impl_->SetRenderFrameObserver(std::move(observer));
+ EXPECT_FALSE(observer_ptr->last_metadata());
+
+ // Our test will be comprised of multiple legs, each leg consisting of a
+ // distinct scroll event and an expectation regarding the vertical scroll
+ // direction passed to the render frame metadata.
+ typedef struct {
+ gfx::Vector2d scroll_delta;
+ viz::VerticalScrollDirection expected_vertical_scroll_direction;
+ } TestLeg;
+
+ std::vector<TestLeg> test_legs;
+
+ // Initially, vertical scroll direction should be |kNull| indicating absence.
+ test_legs.push_back({/*scroll_delta=*/gfx::Vector2d(),
+ /*expected_vertical_scroll_direction=*/viz::
+ VerticalScrollDirection::kNull});
+
+ // Scrolling to the right should not affect vertical scroll direction.
+ test_legs.push_back({/*scroll_delta=*/gfx::Vector2d(10, 0),
+ /*expected_vertical_scroll_direction=*/viz::
+ VerticalScrollDirection::kNull});
+
+ // After scrolling down, the vertical scroll direction should be |kDown|.
+ test_legs.push_back({/*scroll_delta=*/gfx::Vector2d(0, 10),
+ /*expected_vertical_scroll_direction=*/viz::
+ VerticalScrollDirection::kDown});
+
+ // If we scroll down again, the vertical scroll direction should be |kNull| as
+ // there was no change in vertical scroll direction.
+ test_legs.push_back({/*scroll_delta=*/gfx::Vector2d(0, 10),
+ /*expected_vertical_scroll_direction=*/viz::
+ VerticalScrollDirection::kNull});
+
+ // Scrolling to the left should not affect last vertical scroll direction.
+ test_legs.push_back({/*scroll_delta=*/gfx::Vector2d(-10, 0),
+ /*expected_vertical_scroll_direction=*/viz::
+ VerticalScrollDirection::kNull});
+
+ // After scrolling up, the vertical scroll direction should be |kUp|.
+ test_legs.push_back({/*scroll_delta=*/gfx::Vector2d(0, -10),
+ /*expected_vertical_scroll_direction=*/viz::
+ VerticalScrollDirection::kUp});
+
+ // If we scroll up again, the vertical scroll direction should be |kNull| as
+ // there was no change in vertical scroll direction.
+ test_legs.push_back({/*scroll_delta=*/gfx::Vector2d(0, -10),
+ /*expected_vertical_scroll_direction=*/viz::
+ VerticalScrollDirection::kNull});
+
+ // Iterate over all legs of our test.
+ for (auto& test_leg : test_legs) {
+ // If the test leg contains a scroll, perform it.
+ if (!test_leg.scroll_delta.IsZero()) {
+ host_impl_->ScrollBegin(
+ BeginState(gfx::Point(), test_leg.scroll_delta).get(),
+ InputHandler::WHEEL);
+ host_impl_->ScrollBy(
+ UpdateState(gfx::Point(), test_leg.scroll_delta).get());
+ }
+
+ // Trigger draw.
+ host_impl_->SetNeedsRedraw();
+ DrawFrame();
+
+ // Assert our expectation regarding the vertical scroll direction.
+ EXPECT_EQ(test_leg.expected_vertical_scroll_direction,
+ observer_ptr->last_metadata()->new_vertical_scroll_direction);
+
+ // If the test leg contains a scroll, end it.
+ if (!test_leg.scroll_delta.IsZero())
+ host_impl_->ScrollEnd();
+ }
+}
+
// Tests ScrollBy() to see if the method sets the scroll tree's currently
// scrolling node and the ScrollState properly.
TEST_F(LayerTreeHostImplTest, ScrollByScrollingNode) {
@@ -12918,7 +13094,7 @@ TEST_F(LayerTreeHostImplTest, ScrollByScrollingNode) {
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD,
host_impl_
- ->ScrollBegin(BeginState(gfx::Point()).get(),
+ ->ScrollBegin(BeginState(gfx::Point(), gfx::Vector2dF()).get(),
InputHandler::TOUCHSCREEN)
.thread);
@@ -12958,37 +13134,11 @@ class HitTestRegionListGeneratingLayerTreeHostImplTest
std::unique_ptr<LayerTreeFrameSink> layer_tree_frame_sink) override {
// Enable hit test data generation with the CompositorFrame.
LayerTreeSettings new_settings = settings;
- new_settings.build_hit_test_data = true;
return LayerTreeHostImplTest::CreateHostImpl(
new_settings, std::move(layer_tree_frame_sink));
}
};
-// When disabled, no HitTestRegionList should be generated.
-// Test to ensure that hit test data is created correctly from the active layer
-// tree.
-TEST_F(LayerTreeHostImplTest, DisabledBuildHitTestData) {
- // Setup surface layers in LayerTreeHostImpl.
- host_impl_->CreatePendingTree();
- host_impl_->ActivateSyncTree();
-
- auto* root = SetupDefaultRootLayer(gfx::Size(1024, 768));
- auto* surface_child = AddLayer<SurfaceLayerImpl>(host_impl_->active_tree());
-
- surface_child->SetBounds(gfx::Size(100, 100));
- surface_child->SetDrawsContent(true);
- surface_child->SetSurfaceHitTestable(true);
-
- CopyProperties(root, surface_child);
- surface_child->SetOffsetToTransformParent(gfx::Vector2dF(50, 50));
-
- UpdateDrawProperties(host_impl_->active_tree());
-
- base::Optional<viz::HitTestRegionList> hit_test_region_list =
- host_impl_->BuildHitTestData();
- EXPECT_FALSE(hit_test_region_list);
-}
-
// Test to ensure that hit test data is created correctly from the active layer
// tree.
TEST_F(HitTestRegionListGeneratingLayerTreeHostImplTest, BuildHitTestData) {
@@ -13361,9 +13511,9 @@ TEST_F(LayerTreeHostImplTest, TouchScrollOnAndroidScrollbar) {
gfx::Size scroll_content_size = gfx::Size(360, 3800);
gfx::Size scrollbar_size = gfx::Size(15, 600);
- LayerImpl* root = SetupDefaultRootLayer(viewport_size);
- LayerImpl* content =
- AddScrollableLayer(root, viewport_size, scroll_content_size);
+ SetupViewportLayersNoScrolls(viewport_size);
+ LayerImpl* content = AddScrollableLayer(OuterViewportScrollLayer(),
+ viewport_size, scroll_content_size);
auto* scrollbar = AddLayer<SolidColorScrollbarLayerImpl>(
layer_tree_impl, VERTICAL, 10, 0, false);
@@ -13378,7 +13528,8 @@ TEST_F(LayerTreeHostImplTest, TouchScrollOnAndroidScrollbar) {
// should result in scrolling the scroll layer on the impl thread as the
// scrollbar should not be hit.
InputHandler::ScrollStatus status = host_impl_->ScrollBegin(
- BeginState(gfx::Point(350, 50)).get(), InputHandler::TOUCHSCREEN);
+ BeginState(gfx::Point(350, 50), gfx::Vector2dF(0, 10)).get(),
+ InputHandler::TOUCHSCREEN);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
}
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
index 4af1f35d30f..aab9ee9f75f 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_filters.cc
@@ -77,7 +77,7 @@ LayerTreeTest::RendererType const kRendererTypes[] = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostFiltersPixelTest,
::testing::ValuesIn(kRendererTypes));
@@ -91,7 +91,7 @@ LayerTreeTest::RendererType const kRendererTypesGpu[] = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostFiltersPixelTestGPU,
::testing::ValuesIn(kRendererTypesGpu));
@@ -221,21 +221,24 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRounded) {
16, 18, 20, 22, 30, 40, 50);
blur->SetBackdropFilterBounds(backdrop_filter_bounds);
-#if defined(OS_WIN) || defined(ARCH_CPU_ARM64)
- // Windows and ARM64 have 436 pixels off by 1: crbug.com/259915
- float percentage_pixels_large_error = 1.09f; // 436px / (200*200)
- float percentage_pixels_small_error = 0.0f;
- float average_error_allowed_in_bad_pixels = 1.f;
- int large_error_allowed = 1;
- int small_error_allowed = 0;
+ // Skia has various algorithms for clipping by a path, depending on the
+ // available hardware, including MSAA techniques. MSAA results vary
+ // substantially by platform; with 4x MSAA, a difference of 1 sample can
+ // cause up to a 25% color difference!
+ // See http://crbug.com/259915
+ int small_error_threshold = 64; // 25% of 255.
+ // Allow for ~1 perimeter of the clip path to have a small error.
+ float percentage_pixels_small_error = 100.f * (100*4) / (200*200);
+ int large_error_limit = 128; // Off by two samples in 4 MSAA.
+ float percentage_pixels_large_or_small_error =
+ 1.01f * percentage_pixels_small_error;
+ // Divide average error by 4 since we blur most of the result.
+ float average_error_allowed_in_bad_pixels = small_error_threshold / 4.f;
pixel_comparator_.reset(new FuzzyPixelComparator(
true, // discard_alpha
- percentage_pixels_large_error, percentage_pixels_small_error,
- average_error_allowed_in_bad_pixels, large_error_allowed,
- small_error_allowed));
-#else
- pixel_comparator_ = std::make_unique<FuzzyPixelOffByOneComparator>(false);
-#endif
+ percentage_pixels_large_or_small_error, percentage_pixels_small_error,
+ average_error_allowed_in_bad_pixels, large_error_limit,
+ small_error_threshold));
RunPixelTest(renderer_type(), background,
(renderer_type() == RENDERER_SOFTWARE)
@@ -246,11 +249,6 @@ TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurRounded) {
}
TEST_P(LayerTreeHostFiltersPixelTest, BackdropFilterBlurOutsets) {
- if (renderer_type() == RENDERER_SKIA_GL ||
- renderer_type() == RENDERER_SKIA_VK) {
- // TODO(973696): Implement bounds clipping in skia_renderer.
- return;
- }
scoped_refptr<SolidColorLayer> background = CreateSolidColorLayer(
gfx::Rect(200, 200), SK_ColorWHITE);
@@ -469,7 +467,7 @@ class LayerTreeHostFiltersScaledPixelTest
float device_scale_factor_;
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostFiltersScaledPixelTest,
::testing::ValuesIn(kRendererTypes));
@@ -1150,7 +1148,7 @@ class BackdropFilterOffsetTest : public LayerTreeHostFiltersPixelTest {
float device_scale_factor_ = 1;
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
BackdropFilterOffsetTest,
::testing::ValuesIn(kRendererTypes));
@@ -1197,7 +1195,7 @@ class BackdropFilterInvertTest : public LayerTreeHostFiltersPixelTest {
float device_scale_factor_ = 1;
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
BackdropFilterInvertTest,
::testing::ValuesIn(kRendererTypes));
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc b/chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc
index ed011f43887..86b14635524 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_mirror.cc
@@ -31,7 +31,7 @@ const LayerTreeTest::RendererType kRendererTypes[] = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostMirrorPixelTest,
::testing::ValuesIn(kRendererTypes));
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
index 345dc9cab6b..416d19d0351 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_readback.cc
@@ -429,7 +429,7 @@ ReadbackTestConfig const kTestConfigs[] = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostReadbackPixelTest,
::testing::ValuesIn(kTestConfigs));
@@ -447,7 +447,7 @@ ReadbackTestConfig const kMaybeVulkanTestConfigs[] = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostReadbackPixelTestMaybeVulkan,
::testing::ValuesIn(kMaybeVulkanTestConfigs));
@@ -531,7 +531,7 @@ TEST_P(LayerTreeHostReadbackDeviceScalePixelTest, ReadbackNonRootLayerSubrect) {
base::FilePath(FILE_PATH_LITERAL("green_small_with_blue_corner.png")));
}
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostReadbackDeviceScalePixelTest,
::testing::ValuesIn(kTestConfigs));
@@ -571,7 +571,7 @@ TEST_P(LayerTreeHostReadbackColorSpacePixelTest, Readback) {
base::FilePath(FILE_PATH_LITERAL("srgb_green_in_p3.png")));
}
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostReadbackColorSpacePixelTest,
::testing::ValuesIn(kTestConfigs));
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
index 4be54575240..d9e1ec67ee4 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_scrollbars.cc
@@ -50,12 +50,14 @@ class PaintedScrollbar : public FakeScrollbar {
set_track_rect(gfx::Rect(size));
}
- void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override {
+ void PaintPart(PaintCanvas* canvas,
+ ScrollbarPart part,
+ const gfx::Rect& rect) override {
PaintFlags flags;
flags.setStyle(PaintFlags::kStroke_Style);
flags.setStrokeWidth(SkIntToScalar(paint_scale_));
flags.setColor(color_);
- gfx::Rect inset_rect = GetPartRect(part);
+ gfx::Rect inset_rect = rect;
while (!inset_rect.IsEmpty()) {
int big = paint_scale_ + 2;
int small = paint_scale_;
@@ -68,6 +70,8 @@ class PaintedScrollbar : public FakeScrollbar {
void set_paint_scale(int scale) { paint_scale_ = scale; }
private:
+ ~PaintedScrollbar() override = default;
+
int paint_scale_ = 4;
SkColor color_ = SK_ColorGREEN;
};
@@ -80,7 +84,7 @@ LayerTreeTest::RendererType const kRendererTypes[] = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostScrollbarsPixelTest,
::testing::ValuesIn(kRendererTypes));
@@ -88,7 +92,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, NoScale) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(200, 200));
+ auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(200, 200));
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
layer->SetIsDrawable(true);
@@ -107,7 +111,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, DeviceScaleFactor) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(100, 100), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100));
+ auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(100, 100));
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
layer->SetIsDrawable(true);
@@ -122,7 +126,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, TransformScale) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(200, 200), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(100, 100));
+ auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(100, 100));
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
layer->SetIsDrawable(true);
@@ -149,7 +153,7 @@ TEST_P(LayerTreeHostScrollbarsPixelTest, MAYBE_HugeTransformScale) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedScrollbar>(gfx::Size(10, 400));
+ auto scrollbar = base::MakeRefCounted<PaintedScrollbar>(gfx::Size(10, 400));
scrollbar->set_paint_scale(1);
scoped_refptr<PaintedScrollbarLayer> layer =
PaintedScrollbarLayer::Create(std::move(scrollbar));
@@ -210,12 +214,13 @@ class PaintedOverlayScrollbar : public FakeScrollbar {
VERTICAL,
/*is_left_side_vertical_scrollbar*/ false,
/*is_overlay*/ true) {
- set_thumb_thickness(15);
- set_thumb_length(50);
+ set_thumb_size(gfx::Size(15, 50));
set_track_rect(gfx::Rect(0, 0, 15, 400));
}
- void PaintPart(PaintCanvas* canvas, ScrollbarPart part) override {
+ void PaintPart(PaintCanvas* canvas,
+ ScrollbarPart part,
+ const gfx::Rect& rect) override {
// The outside of the rect will be painted with a 1 pixel black, red, then
// blue border. The inside will be solid blue. This will allow the test to
// ensure that scaling the thumb doesn't scale the border at all. Note
@@ -226,7 +231,7 @@ class PaintedOverlayScrollbar : public FakeScrollbar {
flags.setStrokeWidth(SkIntToScalar(1));
flags.setColor(SK_ColorBLACK);
- gfx::Rect inset_rect = GetPartRect(part);
+ gfx::Rect inset_rect = rect;
canvas->drawRect(RectToSkRect(inset_rect), flags);
flags.setColor(SK_ColorRED);
@@ -245,9 +250,12 @@ class PaintedOverlayScrollbar : public FakeScrollbar {
gfx::Rect NinePatchThumbAperture() const override {
return gfx::Rect(3, 3, 1, 1);
}
+
+ private:
+ ~PaintedOverlayScrollbar() override = default;
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostOverlayScrollbarsPixelTest,
::testing::ValuesIn(kRendererTypes));
@@ -257,7 +265,7 @@ TEST_P(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledUp) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedOverlayScrollbar>();
+ auto scrollbar = base::MakeRefCounted<PaintedOverlayScrollbar>();
scoped_refptr<PaintedOverlayScrollbarLayer> layer =
PaintedOverlayScrollbarLayer::Create(std::move(scrollbar));
@@ -281,7 +289,7 @@ TEST_P(LayerTreeHostOverlayScrollbarsPixelTest, NinePatchScrollbarScaledDown) {
scoped_refptr<SolidColorLayer> background =
CreateSolidColorLayer(gfx::Rect(400, 400), SK_ColorWHITE);
- auto scrollbar = std::make_unique<PaintedOverlayScrollbar>();
+ auto scrollbar = base::MakeRefCounted<PaintedOverlayScrollbar>();
scoped_refptr<PaintedOverlayScrollbarLayer> layer =
PaintedOverlayScrollbarLayer::Create(std::move(scrollbar));
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
index 7b3f854f7f9..713d41e50d4 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_synchronous.cc
@@ -63,7 +63,7 @@ LayerTreeTest::RendererType const kRendererTypesGpu[] = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostSynchronousPixelTest,
::testing::ValuesIn(kRendererTypesGpu));
diff --git a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
index 8e27a3ef68b..7ddfc099cc5 100644
--- a/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
+++ b/chromium/cc/trees/layer_tree_host_pixeltest_tiles.cc
@@ -186,7 +186,7 @@ std::vector<TilesTestConfig> const kTestCases = {
#endif
};
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostTilesTestPartialInvalidation,
::testing::ValuesIn(kTestCases));
@@ -214,7 +214,7 @@ std::vector<TilesTestConfig> const kTestCasesMultiThread = {
using LayerTreeHostTilesTestPartialInvalidationMultiThread =
LayerTreeHostTilesTestPartialInvalidation;
-INSTANTIATE_TEST_SUITE_P(,
+INSTANTIATE_TEST_SUITE_P(All,
LayerTreeHostTilesTestPartialInvalidationMultiThread,
::testing::ValuesIn(kTestCasesMultiThread));
@@ -244,7 +244,7 @@ using LayerTreeHostTilesTestPartialInvalidationLowBitDepth =
// RGBA4444 format using either SwiftShader or native Vulkan. See
// crbug.com/987278 for details
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostTilesTestPartialInvalidationLowBitDepth,
::testing::Values(
TilesTestConfig{LayerTreeTest::RENDERER_GL, GPU_LOW_BIT_DEPTH},
diff --git a/chromium/cc/trees/layer_tree_host_unittest.cc b/chromium/cc/trees/layer_tree_host_unittest.cc
index 03d02988fce..0c93511d76c 100644
--- a/chromium/cc/trees/layer_tree_host_unittest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest.cc
@@ -1139,7 +1139,6 @@ class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest {
case 3:
EXPECT_FALSE(GetRenderSurface(root_impl)->AncestorPropertyChanged());
EXPECT_TRUE(GetRenderSurface(child_impl)->AncestorPropertyChanged());
- EndTest();
PostSetNeedsCommitToMainThread();
break;
case 4:
@@ -1158,8 +1157,7 @@ class LayerTreeHostTestSurfaceDamage : public LayerTreeHostTest {
scoped_refptr<Layer> grand_child_;
};
-// TODO(crbug.com/1014263): Disable because this test is flaky.
-// SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage);
+SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostTestSurfaceDamage);
class LayerTreeHostTestLayerListSurfaceDamage : public LayerTreeHostTest {
protected:
@@ -6161,19 +6159,13 @@ class LayerTreeHostTestGpuRasterizationDefault : public LayerTreeHostTest {
}
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- EXPECT_FALSE(layer_->HasSlowPaths());
-
EXPECT_FALSE(host_impl->pending_tree()->use_gpu_rasterization());
EXPECT_FALSE(host_impl->use_gpu_rasterization());
- EXPECT_FALSE(host_impl->use_msaa());
}
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- EXPECT_FALSE(layer_->HasSlowPaths());
-
EXPECT_FALSE(host_impl->active_tree()->use_gpu_rasterization());
EXPECT_FALSE(host_impl->use_gpu_rasterization());
- EXPECT_FALSE(host_impl->use_msaa());
EndTest();
}
@@ -6239,17 +6231,19 @@ class LayerTreeHostTestGpuRasterizationEnabled
void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- EXPECT_FALSE(layer_->HasSlowPaths());
+ auto* raster_source = static_cast<PictureLayerImpl*>(
+ host_impl->sync_tree()->LayerById(layer_->id()))
+ ->GetRasterSource();
+ EXPECT_EQ(host_impl->GetMSAASampleCountForRaster(
+ raster_source->GetDisplayItemList()),
+ 0);
EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
EXPECT_TRUE(host_impl->use_gpu_rasterization());
- EXPECT_FALSE(host_impl->use_msaa());
}
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- EXPECT_FALSE(layer_->HasSlowPaths());
EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
EXPECT_TRUE(host_impl->use_gpu_rasterization());
- EXPECT_FALSE(host_impl->use_msaa());
EndTest();
}
};
@@ -6261,7 +6255,7 @@ class LayerTreeHostTestGpuRasterizationEnabledWithMSAA
protected:
void BeginTest() override {
// Content-based MSAA trigger.
- layer_->set_force_content_has_slow_paths(true);
+ layer_client_.set_contains_slow_paths(true);
// MSAA trigger will take effect when layers are updated.
// The results will be verified after commit is completed below.
@@ -6272,125 +6266,20 @@ class LayerTreeHostTestGpuRasterizationEnabledWithMSAA
}
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- // Ensure the slow path bit sticks.
- EXPECT_TRUE(layer_->HasSlowPaths());
-
+ auto* raster_source = static_cast<PictureLayerImpl*>(
+ host_impl->sync_tree()->LayerById(layer_->id()))
+ ->GetRasterSource();
+ EXPECT_GT(host_impl->GetMSAASampleCountForRaster(
+ raster_source->GetDisplayItemList()),
+ 0);
EXPECT_TRUE(host_impl->pending_tree()->use_gpu_rasterization());
EXPECT_TRUE(host_impl->use_gpu_rasterization());
- EXPECT_TRUE(host_impl->use_msaa());
- }
-
- void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- EXPECT_TRUE(layer_->HasSlowPaths());
-
- EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
- EXPECT_TRUE(host_impl->use_gpu_rasterization());
- EXPECT_TRUE(host_impl->use_msaa());
EndTest();
}
};
MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationEnabledWithMSAA);
-class LayerTreeHostTestGpuRasterizationMSAAReenabled
- : public LayerTreeHostWithGpuRasterizationSupportedTest {
- protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->gpu_rasterization_msaa_sample_count = 4;
- }
-
- void BeginTest() override {
- // Content-based MSAA trigger is relevant.
- layer_->set_force_content_has_slow_paths(true);
-
- // MSAA trigger will take effect when layers are updated.
- // The results will be verified after commit is completed below.
- // Since we are manually marking the source as containing slow paths,
- // make sure that the layer gets a chance to update.
- layer_->SetNeedsDisplay();
- PostSetNeedsCommitToMainThread();
- }
-
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- SCOPED_TRACE(base::StringPrintf("commit %d", num_commits_));
- if (expected_use_msaa_) {
- EXPECT_TRUE(host_impl->use_msaa());
- } else {
- EXPECT_FALSE(host_impl->use_msaa());
- }
-
- ++num_commits_;
- switch (num_commits_) {
- case 1:
- layer_->set_force_content_has_slow_paths(false);
- break;
- case 30:
- layer_->set_force_content_has_slow_paths(true);
- break;
- case 31:
- layer_->set_force_content_has_slow_paths(false);
- break;
- case 90:
- expected_use_msaa_ = false;
- break;
- }
- PostSetNeedsCommitToMainThread();
- if (num_commits_ > 100)
- EndTest();
- }
-
- int num_commits_ = 0;
- bool expected_use_msaa_ = true;
-};
-
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationMSAAReenabled);
-
-class LayerTreeHostTestGpuRasterizationNonAASticky
- : public LayerTreeHostWithGpuRasterizationSupportedTest {
- protected:
- void InitializeSettings(LayerTreeSettings* settings) override {
- settings->gpu_rasterization_msaa_sample_count = 4;
- }
-
- void BeginTest() override {
- // Start without slow paths, but no non-aa paint.
- layer_->set_force_content_has_slow_paths(true);
- layer_->set_force_content_has_non_aa_paint(false);
-
- // The results will be verified after commit is completed below.
- layer_->SetNeedsDisplay();
- PostSetNeedsCommitToMainThread();
- }
-
- void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- SCOPED_TRACE(base::StringPrintf("commit %d", num_commits_));
- if (expected_use_msaa_) {
- EXPECT_TRUE(host_impl->use_msaa());
- } else {
- EXPECT_FALSE(host_impl->use_msaa());
- }
-
- ++num_commits_;
- switch (num_commits_) {
- case 30:
- layer_->set_force_content_has_non_aa_paint(true);
- expected_use_msaa_ = false;
- break;
- case 31:
- layer_->set_force_content_has_non_aa_paint(false);
- break;
- }
- PostSetNeedsCommitToMainThread();
- if (num_commits_ > 100)
- EndTest();
- }
-
- int num_commits_ = 0;
- bool expected_use_msaa_ = true;
-};
-
-MULTI_THREAD_TEST_F(LayerTreeHostTestGpuRasterizationNonAASticky);
-
class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
protected:
void InitializeSettings(LayerTreeSettings* settings) override {
@@ -6417,9 +6306,6 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
}
void BeginTest() override {
- // Content-based MSAA trigger is irrelevant as well.
- layer_->set_force_content_has_slow_paths(true);
-
// Veto will take effect when layers are updated.
// The results will be verified after commit is completed below.
// Since we are manually marking the source as containing slow paths,
@@ -6429,16 +6315,11 @@ class LayerTreeHostTestGpuRasterizationForced : public LayerTreeHostTest {
}
void CommitCompleteOnThread(LayerTreeHostImpl* host_impl) override {
- // Ensure the slow-paths bit sticks.
- EXPECT_TRUE(layer_->HasSlowPaths());
-
EXPECT_TRUE(host_impl->sync_tree()->use_gpu_rasterization());
EXPECT_TRUE(host_impl->use_gpu_rasterization());
}
void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
- EXPECT_TRUE(layer_->HasSlowPaths());
-
EXPECT_TRUE(host_impl->active_tree()->use_gpu_rasterization());
EXPECT_TRUE(host_impl->use_gpu_rasterization());
EndTest();
@@ -6844,7 +6725,7 @@ class LayerTreeHostAcceptsDeltasFromImplWithoutRootLayer
void ApplyViewportChanges(const ApplyViewportChangesArgs& args) override {
EXPECT_EQ(info_.page_scale_delta, args.page_scale_delta);
- EXPECT_EQ(info_.top_controls_delta, args.browser_controls_delta);
+ EXPECT_EQ(info_.top_controls_delta, args.top_controls_delta);
EXPECT_EQ(info_.browser_controls_constraint,
args.browser_controls_constraint);
deltas_sent_to_client_ = true;
@@ -8771,9 +8652,11 @@ class LayerTreeHostTopControlsDeltaTriggersViewportUpdate
SetupViewport(root_layer, gfx::Size(50, 50), root_layer->bounds());
layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 1.f, 1.f);
// Set browser controls to be partially shown.
- layer_tree_host()->SetBrowserControlsHeight(kTopControlsHeight, 0.0f,
- true /* shrink */);
- layer_tree_host()->SetBrowserControlsShownRatio(kTopControlsShownRatio);
+ layer_tree_host()->SetBrowserControlsParams(
+ {kTopControlsHeight, 0, kBottomControlsHeight, 0, false /* animate */,
+ true /* shrink */});
+ layer_tree_host()->SetBrowserControlsShownRatio(kTopControlsShownRatio,
+ kBottomControlsShownRatio);
}
void BeginCommitOnThread(LayerTreeHostImpl* impl) override {
@@ -8800,6 +8683,8 @@ class LayerTreeHostTopControlsDeltaTriggersViewportUpdate
static constexpr float kTopControlsHeight = 10.0f;
static constexpr float kTopControlsShownRatio = 0.3f;
+ static constexpr float kBottomControlsHeight = 10.0f;
+ static constexpr float kBottomControlsShownRatio = 1.f;
};
MULTI_THREAD_TEST_F(LayerTreeHostTopControlsDeltaTriggersViewportUpdate);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_animation.cc b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
index a21e88e65bb..8d49e947ff9 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_animation.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_animation.cc
@@ -15,6 +15,7 @@
#include "cc/animation/element_animations.h"
#include "cc/animation/keyframe_effect.h"
#include "cc/animation/scroll_offset_animation_curve.h"
+#include "cc/animation/scroll_offset_animation_curve_factory.h"
#include "cc/animation/scroll_offset_animations.h"
#include "cc/animation/single_keyframe_effect_animation.h"
#include "cc/animation/timing_function.h"
@@ -793,10 +794,9 @@ class LayerTreeHostAnimationTestScrollOffsetChangesArePropagated
switch (layer_tree_host()->SourceFrameNumber()) {
case 1: {
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(500.f, 550.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::
+ CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(500.f, 550.f)));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
keyframe_model->set_needs_synchronized_start_time(true);
@@ -880,7 +880,9 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationTakeover
scoped_refptr<FakePictureLayer> scroll_layer_;
};
-MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationTakeover);
+// TODO(crbug.com/1018213): [BlinkGenPropertyTrees] Scroll Animation should be
+// taken over from cc when scroll is unpromoted.
+// MULTI_THREAD_TEST_F(LayerTreeHostAnimationTestScrollOffsetAnimationTakeover);
// Verifies that an impl-only scroll offset animation gets updated when the
// scroll offset is adjusted on the main thread.
@@ -1005,10 +1007,8 @@ class LayerTreeHostPresentationDuringAnimation
layer_tree_host()->root_layer()->AddChild(scroll_layer_);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(6500.f, 7500.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(6500.f, 7500.f)));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
keyframe_model->set_needs_synchronized_start_time(true);
@@ -1083,10 +1083,8 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationRemoval
layer_tree_host()->root_layer()->AddChild(scroll_layer_);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(6500.f, 7500.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(6500.f, 7500.f)));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
keyframe_model->set_needs_synchronized_start_time(true);
@@ -1211,10 +1209,8 @@ class LayerTreeHostAnimationTestScrollOffsetAnimationCompletion
layer_tree_host()->root_layer()->AddChild(scroll_layer_);
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- final_position_,
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ final_position_));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
keyframe_model->set_needs_synchronized_start_time(true);
@@ -2163,10 +2159,8 @@ class ImplSideInvalidationWithoutCommitTestScroll
void BeginTest() override {
std::unique_ptr<ScrollOffsetAnimationCurve> curve(
- ScrollOffsetAnimationCurve::Create(
- gfx::ScrollOffset(500.f, 550.f),
- CubicBezierTimingFunction::CreatePreset(
- CubicBezierTimingFunction::EaseType::EASE_IN_OUT)));
+ ScrollOffsetAnimationCurveFactory::CreateEaseInOutAnimationForTesting(
+ gfx::ScrollOffset(500.f, 550.f)));
std::unique_ptr<KeyframeModel> keyframe_model(KeyframeModel::Create(
std::move(curve), 1, 0, TargetProperty::SCROLL_OFFSET));
keyframe_model->set_needs_synchronized_start_time(true);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_context.cc b/chromium/cc/trees/layer_tree_host_unittest_context.cc
index f2b8bba821c..118fbff0189 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_context.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_context.cc
@@ -983,8 +983,7 @@ class LayerTreeHostContextTestDontUseLostResources
layer_tree_host()->SetDebugState(debug_state);
scoped_refptr<PaintedScrollbarLayer> scrollbar =
- PaintedScrollbarLayer::Create(
- std::unique_ptr<Scrollbar>(new FakeScrollbar));
+ PaintedScrollbarLayer::Create(base::MakeRefCounted<FakeScrollbar>());
scrollbar->SetScrollElementId(layer->element_id());
scrollbar->SetBounds(gfx::Size(10, 10));
scrollbar->SetIsDrawable(true);
diff --git a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
index 2d3bc04e847..50e7dbe7489 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_copyrequest.cc
@@ -160,7 +160,7 @@ class LayerTreeHostCopyRequestTestMultipleRequests
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestMultipleRequests,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL,
@@ -197,7 +197,7 @@ class LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestMultipleRequestsOutOfOrder,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -259,7 +259,7 @@ class LayerTreeHostCopyRequestCompletionCausesCommit
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestCompletionCausesCommit,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -364,7 +364,7 @@ class LayerTreeHostCopyRequestTestLayerDestroyed
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestLayerDestroyed,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -471,7 +471,7 @@ class LayerTreeHostCopyRequestTestInHiddenSubtree
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestInHiddenSubtree,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -593,7 +593,7 @@ class LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostTestHiddenSurfaceNotAllocatedForSubtreeCopyRequest,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -650,7 +650,7 @@ class LayerTreeHostCopyRequestTestClippedOut
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestClippedOut,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -711,7 +711,7 @@ class LayerTreeHostCopyRequestTestScaledLayer
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestScaledLayer,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -807,7 +807,7 @@ class LayerTreeHostTestAsyncTwoReadbacksWithoutDraw
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostTestAsyncTwoReadbacksWithoutDraw,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -951,7 +951,7 @@ class LayerTreeHostCopyRequestTestDeleteSharedImage
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestDeleteSharedImage,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -1097,7 +1097,7 @@ class LayerTreeHostCopyRequestTestCreatesSharedImage
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestCreatesSharedImage,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -1186,7 +1186,7 @@ class LayerTreeHostCopyRequestTestDestroyBeforeCopy
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestDestroyBeforeCopy,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -1270,7 +1270,7 @@ class LayerTreeHostCopyRequestTestShutdownBeforeCopy
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestShutdownBeforeCopy,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
@@ -1403,7 +1403,7 @@ class LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest
};
INSTANTIATE_TEST_SUITE_P(
- ,
+ All,
LayerTreeHostCopyRequestTestMultipleDrawsHiddenCopyRequest,
CombineWithCompositorModes({LayerTreeTest::RENDERER_GL,
LayerTreeTest::RENDERER_SKIA_GL}));
diff --git a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
index 6f6915ee368..700c29d9af2 100644
--- a/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
+++ b/chromium/cc/trees/layer_tree_host_unittest_scroll.cc
@@ -61,18 +61,11 @@ std::unique_ptr<ScrollState> UpdateState(const gfx::Point& point,
return scroll_state;
}
-std::unique_ptr<ScrollState> EndState() {
- ScrollStateData scroll_state_data;
- scroll_state_data.is_ending = true;
- std::unique_ptr<ScrollState> scroll_state(new ScrollState(scroll_state_data));
- return scroll_state;
-}
-
static ScrollTree* ScrollTreeForLayer(LayerImpl* layer_impl) {
return &layer_impl->layer_tree_impl()->property_trees()->scroll_tree;
}
-class LayerTreeHostScrollTest : public LayerTreeTest {
+class LayerTreeHostScrollTest : public LayerTreeTest, public ScrollCallbacks {
protected:
LayerTreeHostScrollTest() { SetUseLayerLists(); }
@@ -85,29 +78,48 @@ class LayerTreeHostScrollTest : public LayerTreeTest {
root_layer->bounds().height() + 100);
SetupViewport(root_layer, root_layer->bounds(), scroll_layer_bounds);
- layer_tree_host()
- ->OuterViewportScrollLayerForTesting()
- ->set_did_scroll_callback(base::BindRepeating(
- &LayerTreeHostScrollTest::DidScrollOuterViewport,
- base::Unretained(this)));
+ layer_tree_host()->property_trees()->scroll_tree.SetScrollCallbacks(
+ weak_ptr_factory_.GetWeakPtr());
}
- // This is set as did_scroll_callback of scroll layers to automatically
- // synchronize scroll delta from impl-side, which simulates cc client (e.g.
- // Blink) behavior when handling impl-side scrolls.
- void SyncScrollFromImpl(const gfx::ScrollOffset& scroll_offset,
- const ElementId& element_id) {
+ // This is called from DidScroll() to synchronize scroll delta from impl-side,
+ // which simulates cc client (e.g Blink) behavior when handling impl-side
+ // scrolls.
+ void SyncScrollFromImpl(ElementId element_id,
+ const gfx::ScrollOffset& scroll_offset) {
SetScrollOffset(layer_tree_host()->LayerByElementId(element_id),
scroll_offset);
}
- virtual void DidScrollOuterViewport(const gfx::ScrollOffset& scroll_offset,
- const ElementId& element_id) {
- SyncScrollFromImpl(scroll_offset, element_id);
+ // ScrollCallbacks
+ void DidScroll(ElementId element_id,
+ const gfx::ScrollOffset& scroll_offset,
+ const base::Optional<TargetSnapAreaElementIds>&
+ snap_target_ids) override {
+ SyncScrollFromImpl(element_id, scroll_offset);
+ if (element_id ==
+ layer_tree_host()->OuterViewportScrollLayerForTesting()->element_id()) {
+ DidScrollOuterViewport(scroll_offset);
+ }
+ if (snap_target_ids.has_value()) {
+ ScrollNode* scroller_node =
+ layer_tree_host()
+ ->property_trees()
+ ->scroll_tree.FindNodeFromElementId(element_id);
+ scroller_node->snap_container_data.value().SetTargetSnapAreaElementIds(
+ snap_target_ids.value());
+ }
+ }
+ void DidChangeScrollbarsHidden(ElementId, bool) override {}
+
+ virtual void DidScrollOuterViewport(const gfx::ScrollOffset& scroll_offset) {
num_outer_viewport_scrolls_++;
}
int num_outer_viewport_scrolls_ = 0;
+
+ private:
+ base::WeakPtrFactory<LayerTreeHostScrollTest> weak_ptr_factory_{this};
};
class LayerTreeHostScrollTestScrollSimple : public LayerTreeHostScrollTest {
@@ -523,10 +535,6 @@ class LayerTreeHostScrollTestScrollSnapping : public LayerTreeHostScrollTest {
CreateScrollNode(scroll_layer_.get());
layer_tree_host()->root_layer()->AddChild(scroll_layer_);
- scroll_layer_->set_did_scroll_callback(base::BindRepeating(
- &LayerTreeHostScrollTestScrollSnapping::SyncScrollFromImpl,
- base::Unretained(this)));
-
layer_tree_host()->SetPageScaleFactorAndLimits(1.f, 0.1f, 100.f);
}
@@ -585,9 +593,6 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
layer_tree_host()->OuterViewportScrollLayerForTesting();
child_layer_ = Layer::Create();
- child_layer_->set_did_scroll_callback(
- base::BindRepeating(&LayerTreeHostScrollTestCaseWithChild::DidScroll,
- base::Unretained(this)));
child_layer_->SetElementId(
LayerIdToElementIdForTesting(child_layer_->id()));
child_layer_->SetBounds(gfx::Size(110, 110));
@@ -637,11 +642,18 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
}
}
- void DidScroll(const gfx::ScrollOffset& offset, const ElementId& element_id) {
- SyncScrollFromImpl(offset, element_id);
- final_scroll_offset_ = expected_scroll_layer_->CurrentScrollOffset();
- EXPECT_VECTOR_EQ(offset, final_scroll_offset_);
- EXPECT_EQ(element_id, expected_scroll_layer_->element_id());
+ void DidScroll(ElementId element_id,
+ const gfx::ScrollOffset& offset,
+ const base::Optional<TargetSnapAreaElementIds>&
+ snap_target_ids) override {
+ LayerTreeHostScrollTest::DidScroll(element_id, offset, snap_target_ids);
+ if (element_id == expected_scroll_layer_->element_id()) {
+ final_scroll_offset_ = expected_scroll_layer_->CurrentScrollOffset();
+ EXPECT_EQ(offset, final_scroll_offset_);
+ EXPECT_EQ(element_id, expected_scroll_layer_->element_id());
+ } else {
+ EXPECT_TRUE(offset.IsZero());
+ }
}
void UpdateLayerTreeHost() override {
@@ -707,7 +719,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
impl->ScrollBy(UpdateState(gfx::Point(), scroll_amount_).get());
auto* scrolling_node = impl->CurrentlyScrollingNode();
CHECK(scrolling_node);
- impl->ScrollEnd(EndState().get());
+ impl->ScrollEnd();
CHECK(!impl->CurrentlyScrollingNode());
EXPECT_EQ(scrolling_node->id,
impl->active_tree()->LastScrolledScrollNodeIndex());
@@ -730,7 +742,7 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
BeginState(scroll_point).get(), InputHandler::WHEEL);
EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, status.thread);
impl->ScrollBy(UpdateState(gfx::Point(), scroll_amount_).get());
- impl->ScrollEnd(EndState().get());
+ impl->ScrollEnd();
// Check the scroll is applied as a delta.
EXPECT_VECTOR_EQ(javascript_scroll_,
@@ -757,15 +769,10 @@ class LayerTreeHostScrollTestCaseWithChild : public LayerTreeHostScrollTest {
}
void AfterTest() override {
- if (scroll_child_layer_) {
- EXPECT_EQ(0, num_outer_viewport_scrolls_);
- EXPECT_VECTOR_EQ(gfx::ScrollOffsetWithDelta(javascript_scroll_,
- scroll_amount_),
- final_scroll_offset_);
- } else {
- EXPECT_EQ(2, num_outer_viewport_scrolls_);
- EXPECT_VECTOR_EQ(gfx::ScrollOffset(), final_scroll_offset_);
- }
+ EXPECT_EQ(scroll_child_layer_ ? 0 : 2, num_outer_viewport_scrolls_);
+ EXPECT_VECTOR_EQ(
+ gfx::ScrollOffsetWithDelta(javascript_scroll_, scroll_amount_),
+ final_scroll_offset_);
}
protected:
@@ -1106,6 +1113,296 @@ class LayerTreeHostScrollTestImplOnlyScroll : public LayerTreeHostScrollTest {
// This tests scrolling on the impl side which is only possible with a thread.
MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyScroll);
+void DoGestureScroll(LayerTreeHostImpl* host_impl,
+ const scoped_refptr<Layer>& scroller,
+ gfx::Vector2dF offset) {
+ ScrollStateData begin_scroll_state_data;
+ begin_scroll_state_data.set_current_native_scrolling_element(
+ scroller->element_id());
+ std::unique_ptr<ScrollState> begin_scroll_state(
+ new ScrollState(begin_scroll_state_data));
+ auto scroll_status = host_impl->ScrollBegin(begin_scroll_state.get(),
+ InputHandler::TOUCHSCREEN);
+ EXPECT_EQ(InputHandler::SCROLL_ON_IMPL_THREAD, scroll_status.thread);
+ auto* scrolling_node = host_impl->CurrentlyScrollingNode();
+ EXPECT_TRUE(scrolling_node);
+ EXPECT_EQ(scrolling_node->element_id, scroller->element_id());
+
+ ScrollStateData update_scroll_state_data;
+ update_scroll_state_data.set_current_native_scrolling_element(
+ scroller->element_id());
+ update_scroll_state_data.delta_x = offset.x();
+ update_scroll_state_data.delta_y = offset.y();
+ std::unique_ptr<ScrollState> update_scroll_state(
+ new ScrollState(update_scroll_state_data));
+ host_impl->ScrollBy(update_scroll_state.get());
+
+ ScrollStateData end_scroll_state_data;
+ end_scroll_state_data.set_current_native_scrolling_element(
+ scroller->element_id());
+ std::unique_ptr<ScrollState> end_scroll_state(
+ new ScrollState(end_scroll_state_data));
+ host_impl->ScrollEnd(true /* should_snap */);
+}
+
+// This test simulates scrolling on the impl thread such that snapping occurs
+// and ensures that the target snap area element ids are sent back to the main
+// thread.
+class LayerTreeHostScrollTestImplOnlyScrollSnap
+ : public LayerTreeHostScrollTest {
+ public:
+ LayerTreeHostScrollTestImplOnlyScrollSnap()
+ : initial_scroll_(100, 100),
+ impl_thread_scroll_(350, 350),
+ snap_area_id_(ElementId(10)) {}
+
+ void SetupTree() override {
+ LayerTreeHostScrollTest::SetupTree();
+
+ Layer* root = layer_tree_host()->root_layer();
+ container_ = Layer::Create();
+ scroller_ = Layer::Create();
+ scroller_->SetElementId(LayerIdToElementIdForTesting(scroller_->id()));
+
+ container_->SetBounds(gfx::Size(100, 100));
+ CopyProperties(root, container_.get());
+ root->AddChild(container_);
+
+ scroller_->SetBounds(gfx::Size(1000, 1000));
+ scroller_->SetScrollable(container_->bounds());
+ CopyProperties(container_.get(), scroller_.get());
+ CreateTransformNode(scroller_.get());
+
+ // Set up a snap area.
+ snap_area_ = Layer::Create();
+ snap_area_->SetBounds(gfx::Size(50, 50));
+ snap_area_->SetPosition(gfx::PointF(500, 500));
+ CopyProperties(scroller_.get(), snap_area_.get());
+ scroller_->AddChild(snap_area_);
+ SnapAreaData snap_area_data(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(500, 500, 100, 100), false,
+ snap_area_id_);
+
+ // Set up snap container data.
+ SnapContainerData snap_container_data(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
+ snap_container_data.AddSnapAreaData(snap_area_data);
+ CreateScrollNode(scroller_.get()).snap_container_data = snap_container_data;
+
+ root->AddChild(scroller_);
+ }
+
+ void BeginTest() override {
+ SetScrollOffset(scroller_.get(), initial_scroll_);
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void UpdateLayerTreeHost() override {
+ ScrollNode* scroller_node =
+ layer_tree_host()->property_trees()->scroll_tree.Node(
+ scroller_->scroll_tree_index());
+ auto snap_target_ids = scroller_node->snap_container_data.value()
+ .GetTargetSnapAreaElementIds();
+ if (layer_tree_host()->SourceFrameNumber() == 0) {
+ // On the first BeginMainFrame scrolling has not happened yet.
+ // Check that the scroll offset and scroll snap targets are at the initial
+ // values on the main thread.
+ EXPECT_EQ(snap_target_ids, TargetSnapAreaElementIds());
+ EXPECT_VECTOR_EQ(initial_scroll_, scroller_->CurrentScrollOffset());
+ } else {
+ // After a snap target is set on the impl thread, the snap targets should
+ // be pushed to the main thread.
+ EXPECT_EQ(snap_target_ids,
+ TargetSnapAreaElementIds(snap_area_id_, snap_area_id_));
+ EndTest();
+ }
+ }
+
+ void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ // Perform a scroll such that a snap target is found. This will get pushed
+ // to the main thread on the next BeginMainFrame.
+ if (host_impl->active_tree()->source_frame_number() == 0) {
+ LayerImpl* scroller_impl =
+ host_impl->active_tree()->LayerById(scroller_->id());
+
+ DoGestureScroll(host_impl, scroller_, impl_thread_scroll_);
+
+ EXPECT_TRUE(host_impl->is_animating_for_snap_for_testing());
+ EXPECT_VECTOR_EQ(impl_thread_scroll_, ScrollDelta(scroller_impl));
+
+ ScrollNode* scroller_node =
+ host_impl->active_tree()->property_trees()->scroll_tree.Node(
+ scroller_->scroll_tree_index());
+ auto snap_target_ids = scroller_node->snap_container_data.value()
+ .GetTargetSnapAreaElementIds();
+ EXPECT_EQ(snap_target_ids,
+ TargetSnapAreaElementIds(snap_area_id_, snap_area_id_));
+ }
+ PostSetNeedsCommitToMainThread();
+ }
+
+ private:
+ scoped_refptr<Layer> container_;
+ scoped_refptr<Layer> scroller_;
+ scoped_refptr<Layer> snap_area_;
+
+ gfx::ScrollOffset initial_scroll_;
+ gfx::Vector2dF impl_thread_scroll_;
+
+ ElementId snap_area_id_;
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyScrollSnap);
+
+// This test simulates scrolling on the impl thread such that 2 impl-only
+// scrolls occur between main frames. It ensures that the snap target ids will
+// be synced from impl to main for both snapped scrolling nodes.
+class LayerTreeHostScrollTestImplOnlyMultipleScrollSnap
+ : public LayerTreeHostScrollTest {
+ public:
+ LayerTreeHostScrollTestImplOnlyMultipleScrollSnap()
+ : initial_scroll_(100, 100),
+ // Scroll to the boundary so that an animation is not created when
+ // snapping to allow 2 scrolls between main frames.
+ impl_thread_scroll_a_(400, 400),
+ impl_thread_scroll_b_(400, 400),
+ snap_area_a_id_(ElementId(10)),
+ snap_area_b_id_(ElementId(20)) {}
+
+ void SetupTree() override {
+ LayerTreeHostScrollTest::SetupTree();
+
+ Layer* root = layer_tree_host()->root_layer();
+ container_ = Layer::Create();
+ scroller_a_ = Layer::Create();
+ scroller_b_ = Layer::Create();
+ scroller_a_->SetElementId(LayerIdToElementIdForTesting(scroller_a_->id()));
+ scroller_b_->SetElementId(LayerIdToElementIdForTesting(scroller_b_->id()));
+
+ container_->SetBounds(gfx::Size(100, 100));
+ CopyProperties(root, container_.get());
+ root->AddChild(container_);
+
+ scroller_a_->SetBounds(gfx::Size(1000, 1000));
+ scroller_a_->SetScrollable(container_->bounds());
+ CopyProperties(container_.get(), scroller_a_.get());
+ CreateTransformNode(scroller_a_.get());
+ scroller_b_->SetBounds(gfx::Size(1000, 1000));
+ scroller_b_->SetScrollable(container_->bounds());
+ CopyProperties(container_.get(), scroller_b_.get());
+ CreateTransformNode(scroller_b_.get());
+
+ // Set up snap areas.
+ snap_area_a_ = Layer::Create();
+ snap_area_a_->SetBounds(gfx::Size(50, 50));
+ snap_area_a_->SetPosition(gfx::PointF(500, 500));
+ CopyProperties(scroller_a_.get(), snap_area_a_.get());
+ scroller_a_->AddChild(snap_area_a_);
+ SnapAreaData snap_area_data_a(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(500, 500, 100, 100), false,
+ snap_area_a_id_);
+
+ snap_area_b_ = Layer::Create();
+ snap_area_b_->SetBounds(gfx::Size(50, 50));
+ snap_area_b_->SetPosition(gfx::PointF(500, 500));
+ CopyProperties(scroller_b_.get(), snap_area_b_.get());
+ scroller_b_->AddChild(snap_area_b_);
+ SnapAreaData snap_area_data_b(ScrollSnapAlign(SnapAlignment::kStart),
+ gfx::RectF(500, 500, 100, 100), false,
+ snap_area_b_id_);
+
+ // Set up snap container data.
+ SnapContainerData snap_container_data_a(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
+ snap_container_data_a.AddSnapAreaData(snap_area_data_a);
+ CreateScrollNode(scroller_a_.get()).snap_container_data =
+ snap_container_data_a;
+
+ // Set up snap container data.
+ SnapContainerData snap_container_data_b(
+ ScrollSnapType(false, SnapAxis::kBoth, SnapStrictness::kMandatory),
+ gfx::RectF(0, 0, 100, 100), gfx::ScrollOffset(900, 900));
+ snap_container_data_b.AddSnapAreaData(snap_area_data_b);
+ CreateScrollNode(scroller_b_.get()).snap_container_data =
+ snap_container_data_b;
+
+ root->AddChild(scroller_a_);
+ root->AddChild(scroller_b_);
+ }
+
+ void BeginTest() override {
+ SetScrollOffset(scroller_a_.get(), initial_scroll_);
+ SetScrollOffset(scroller_b_.get(), initial_scroll_);
+ PostSetNeedsCommitToMainThread();
+ }
+
+ void UpdateLayerTreeHost() override {
+ ScrollNode* scroller_node_a =
+ layer_tree_host()->property_trees()->scroll_tree.Node(
+ scroller_a_->scroll_tree_index());
+ ScrollNode* scroller_node_b =
+ layer_tree_host()->property_trees()->scroll_tree.Node(
+ scroller_b_->scroll_tree_index());
+ auto snap_target_ids_a = scroller_node_a->snap_container_data.value()
+ .GetTargetSnapAreaElementIds();
+ auto snap_target_ids_b = scroller_node_b->snap_container_data.value()
+ .GetTargetSnapAreaElementIds();
+ if (layer_tree_host()->SourceFrameNumber() == 0) {
+ // On the first BeginMainFrame scrolling has not happened yet.
+ // Check that the scroll offset and scroll snap targets are at the initial
+ // values on the main thread.
+ EXPECT_EQ(snap_target_ids_a, TargetSnapAreaElementIds());
+ EXPECT_EQ(snap_target_ids_b, TargetSnapAreaElementIds());
+ EXPECT_VECTOR_EQ(initial_scroll_, scroller_a_->CurrentScrollOffset());
+ EXPECT_VECTOR_EQ(initial_scroll_, scroller_b_->CurrentScrollOffset());
+ } else {
+ // When scrolling happens on the impl thread, the snap targets of the
+ // scrolled layers should be pushed to the main thread.
+ EXPECT_EQ(snap_target_ids_a,
+ TargetSnapAreaElementIds(snap_area_a_id_, snap_area_a_id_));
+ EXPECT_EQ(snap_target_ids_b,
+ TargetSnapAreaElementIds(snap_area_b_id_, snap_area_b_id_));
+ EndTest();
+ }
+ }
+
+ void DidActivateTreeOnThread(LayerTreeHostImpl* host_impl) override {
+ // Perform scrolls such that a snap target is found. These will get pushed
+ // to the main thread on the next BeginMainFrame.
+ if (host_impl->active_tree()->source_frame_number() == 0) {
+ LayerImpl* scroller_impl_a =
+ host_impl->active_tree()->LayerById(scroller_a_->id());
+ LayerImpl* scroller_impl_b =
+ host_impl->active_tree()->LayerById(scroller_b_->id());
+
+ DoGestureScroll(host_impl, scroller_a_, impl_thread_scroll_a_);
+ DoGestureScroll(host_impl, scroller_b_, impl_thread_scroll_b_);
+
+ EXPECT_VECTOR_EQ(impl_thread_scroll_a_, ScrollDelta(scroller_impl_a));
+ EXPECT_VECTOR_EQ(impl_thread_scroll_b_, ScrollDelta(scroller_impl_b));
+ }
+ PostSetNeedsCommitToMainThread();
+ }
+
+ private:
+ scoped_refptr<Layer> container_;
+ scoped_refptr<Layer> scroller_a_;
+ scoped_refptr<Layer> scroller_b_;
+ scoped_refptr<Layer> snap_area_a_;
+ scoped_refptr<Layer> snap_area_b_;
+
+ gfx::ScrollOffset initial_scroll_;
+ gfx::Vector2dF impl_thread_scroll_a_;
+ gfx::Vector2dF impl_thread_scroll_b_;
+
+ ElementId snap_area_a_id_;
+ ElementId snap_area_b_id_;
+};
+
+MULTI_THREAD_TEST_F(LayerTreeHostScrollTestImplOnlyMultipleScrollSnap);
+
class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
: public LayerTreeHostScrollTest {
public:
@@ -1129,9 +1426,7 @@ class LayerTreeHostScrollTestScrollZeroMaxScrollOffset
layer_tree_host()->root_layer()->AddChild(scroller_.get());
}
- void BeginTest() override {
- PostSetNeedsCommitToMainThread();
- }
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
void UpdateLayerTreeHost() override {
ScrollTree& scroll_tree = layer_tree_host()->property_trees()->scroll_tree;
@@ -1344,12 +1639,9 @@ class LayerTreeHostScrollTestLayerStructureChange
Layer* outer_scroll_layer =
layer_tree_host()->OuterViewportScrollLayerForTesting();
- Layer* root_scroll_layer =
- CreateScrollLayer(outer_scroll_layer, &root_scroll_layer_client_);
- Layer* sibling_scroll_layer =
- CreateScrollLayer(outer_scroll_layer, &sibling_scroll_layer_client_);
- Layer* child_scroll_layer =
- CreateScrollLayer(root_scroll_layer, &child_scroll_layer_client_);
+ Layer* root_scroll_layer = CreateScrollLayer(outer_scroll_layer);
+ Layer* sibling_scroll_layer = CreateScrollLayer(outer_scroll_layer);
+ Layer* child_scroll_layer = CreateScrollLayer(root_scroll_layer);
root_scroll_layer_id_ = root_scroll_layer->id();
sibling_scroll_layer_id_ = sibling_scroll_layer->id();
child_scroll_layer_id_ = child_scroll_layer->id();
@@ -1378,7 +1670,9 @@ class LayerTreeHostScrollTestLayerStructureChange
}
}
- virtual void DidScroll(Layer* layer) {
+ void DidScroll(ElementId element_id,
+ const gfx::ScrollOffset&,
+ const base::Optional<TargetSnapAreaElementIds>&) override {
if (scroll_destroy_whole_tree_) {
layer_tree_host()->SetRootLayer(nullptr);
layer_tree_host()->property_trees()->clear();
@@ -1387,20 +1681,11 @@ class LayerTreeHostScrollTestLayerStructureChange
EndTest();
return;
}
- layer->RemoveFromParent();
+ layer_tree_host()->LayerByElementId(element_id)->RemoveFromParent();
}
protected:
- class FakeLayerScrollClient {
- public:
- void DidScroll(const gfx::ScrollOffset&, const ElementId&) {
- owner_->DidScroll(layer_);
- }
- LayerTreeHostScrollTestLayerStructureChange* owner_;
- Layer* layer_;
- };
-
- Layer* CreateScrollLayer(Layer* parent, FakeLayerScrollClient* client) {
+ Layer* CreateScrollLayer(Layer* parent) {
scoped_refptr<PictureLayer> scroll_layer =
PictureLayer::Create(&fake_content_layer_client_);
scroll_layer->SetIsDrawable(true);
@@ -1410,10 +1695,6 @@ class LayerTreeHostScrollTestLayerStructureChange
LayerIdToElementIdForTesting(scroll_layer->id()));
scroll_layer->SetBounds(gfx::Size(parent->bounds().width() + 100,
parent->bounds().height() + 100));
- scroll_layer->set_did_scroll_callback(base::BindRepeating(
- &FakeLayerScrollClient::DidScroll, base::Unretained(client)));
- client->owner_ = this;
- client->layer_ = scroll_layer.get();
CopyProperties(parent, scroll_layer.get());
CreateTransformNode(scroll_layer.get());
@@ -1433,9 +1714,6 @@ class LayerTreeHostScrollTestLayerStructureChange
layer_impl->element_id());
}
- FakeLayerScrollClient root_scroll_layer_client_;
- FakeLayerScrollClient sibling_scroll_layer_client_;
- FakeLayerScrollClient child_scroll_layer_client_;
int root_scroll_layer_id_;
int sibling_scroll_layer_id_;
int child_scroll_layer_id_;
@@ -2030,13 +2308,10 @@ SINGLE_AND_MULTI_THREAD_TEST_F(LayerTreeHostScrollTestPropertyTreeUpdate);
class LayerTreeHostScrollTestImplSideInvalidation
: public LayerTreeHostScrollTest {
- void BeginTest() override {
- PostSetNeedsCommitToMainThread();
- }
+ void BeginTest() override { PostSetNeedsCommitToMainThread(); }
- void DidScrollOuterViewport(const gfx::ScrollOffset& offset,
- const ElementId& element_id) override {
- LayerTreeHostScrollTest::DidScrollOuterViewport(offset, element_id);
+ void DidScrollOuterViewport(const gfx::ScrollOffset& offset) override {
+ LayerTreeHostScrollTest::DidScrollOuterViewport(offset);
// Defer responding to the main frame until an impl-side pending tree is
// created for the invalidation request.
diff --git a/chromium/cc/trees/layer_tree_impl.cc b/chromium/cc/trees/layer_tree_impl.cc
index 27812c1d31e..aff9ec178c4 100644
--- a/chromium/cc/trees/layer_tree_impl.cc
+++ b/chromium/cc/trees/layer_tree_impl.cc
@@ -17,6 +17,7 @@
#include "base/debug/dump_without_crashing.h"
#include "base/json/json_writer.h"
#include "base/metrics/histogram_macros.h"
+#include "base/numerics/ranges.h"
#include "base/stl_util.h"
#include "base/strings/stringprintf.h"
#include "base/timer/elapsed_timer.h"
@@ -97,6 +98,18 @@ class ViewportAnchor {
LayerTreeImpl* tree_impl_;
gfx::ScrollOffset viewport_in_content_coordinates_;
};
+
+std::pair<gfx::PointF, gfx::PointF> GetVisibleSelectionEndPoints(
+ const gfx::RectF& rect,
+ const gfx::PointF& top,
+ const gfx::PointF& bottom) {
+ gfx::PointF start(base::ClampToRange(top.x(), rect.x(), rect.right()),
+ base::ClampToRange(top.y(), rect.y(), rect.bottom()));
+ gfx::PointF end =
+ start + gfx::Vector2dF(bottom.x() - top.x(), bottom.y() - top.y());
+ return {start, end};
+}
+
} // namespace
void LayerTreeLifecycle::AdvanceTo(LifecycleState next_state) {
@@ -118,6 +131,7 @@ LayerTreeImpl::LayerTreeImpl(
LayerTreeHostImpl* host_impl,
scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,
scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio,
+ scoped_refptr<SyncedBrowserControls> bottom_controls_shown_ratio,
scoped_refptr<SyncedElasticOverscroll> elastic_overscroll)
: host_impl_(host_impl),
source_frame_number_(-1),
@@ -141,10 +155,8 @@ LayerTreeImpl::LayerTreeImpl(
handle_visibility_changed_(false),
have_scroll_event_handlers_(false),
event_listener_properties_(),
- browser_controls_shrink_blink_size_(false),
- top_controls_height_(0),
- bottom_controls_height_(0),
- top_controls_shown_ratio_(top_controls_shown_ratio) {
+ top_controls_shown_ratio_(std::move(top_controls_shown_ratio)),
+ bottom_controls_shown_ratio_(std::move(bottom_controls_shown_ratio)) {
property_trees()->is_main_thread = false;
}
@@ -242,22 +254,23 @@ void LayerTreeImpl::UpdateScrollbarGeometries() {
gfx::SizeF scrolling_size(scroll_node->bounds);
gfx::Size bounds_size(scroll_tree.container_bounds(scroll_node->id));
- bool is_viewport_scrollbar = scroll_node->scrolls_inner_viewport ||
- scroll_node->scrolls_outer_viewport;
+ bool is_viewport_scrollbar = scroll_node == InnerViewportScrollNode() ||
+ scroll_node == OuterViewportScrollNode();
if (is_viewport_scrollbar) {
gfx::SizeF viewport_bounds(bounds_size);
- if (scroll_node->scrolls_inner_viewport) {
+ if (scroll_node == InnerViewportScrollNode()) {
DCHECK_EQ(scroll_node, InnerViewportScrollNode());
- if (auto* outer_scroll_node = OuterViewportScrollNode()) {
- // Add offset and bounds contribution of outer viewport.
- current_offset +=
- scroll_tree.current_scroll_offset(outer_scroll_node->element_id);
- gfx::SizeF outer_viewport_bounds(
- scroll_tree.container_bounds(outer_scroll_node->id));
- viewport_bounds.SetToMin(outer_viewport_bounds);
- // The scrolling size is only determined by the outer viewport.
- scrolling_size = gfx::SizeF(outer_scroll_node->bounds);
- }
+ auto* outer_scroll_node = OuterViewportScrollNode();
+ DCHECK(outer_scroll_node);
+
+ // Add offset and bounds contribution of outer viewport.
+ current_offset +=
+ scroll_tree.current_scroll_offset(outer_scroll_node->element_id);
+ gfx::SizeF outer_viewport_bounds(
+ scroll_tree.container_bounds(outer_scroll_node->id));
+ viewport_bounds.SetToMin(outer_viewport_bounds);
+ // The scrolling size is only determined by the outer viewport.
+ scrolling_size = gfx::SizeF(outer_scroll_node->bounds);
} else {
DCHECK_EQ(scroll_node, OuterViewportScrollNode());
auto* inner_scroll_node = InnerViewportScrollNode();
@@ -352,25 +365,29 @@ void LayerTreeImpl::UpdateViewportContainerSizes() {
if (!InnerViewportScrollNode())
return;
+ DCHECK(OuterViewportScrollNode());
ViewportAnchor anchor(InnerViewportScrollNode(), OuterViewportScrollNode(),
this);
// Top/bottom controls always share the same shown ratio.
- float controls_shown_ratio =
+ float top_controls_shown_ratio =
top_controls_shown_ratio_->Current(IsActiveTree());
+ float bottom_controls_shown_ratio =
+ bottom_controls_shown_ratio_->Current(IsActiveTree());
float top_controls_layout_height =
browser_controls_shrink_blink_size() ? top_controls_height() : 0.f;
- float top_content_offset = top_controls_height_ > 0
- ? top_controls_height_ * controls_shown_ratio
- : 0.0f;
+ float top_content_offset =
+ top_controls_height() > 0
+ ? top_controls_height() * top_controls_shown_ratio
+ : 0.f;
float delta_from_top_controls =
top_controls_layout_height - top_content_offset;
float bottom_controls_layout_height =
browser_controls_shrink_blink_size() ? bottom_controls_height() : 0.f;
float bottom_content_offset =
- bottom_controls_height_ > 0
- ? bottom_controls_height_ * controls_shown_ratio
- : 0.0f;
+ bottom_controls_height() > 0
+ ? bottom_controls_height() * bottom_controls_shown_ratio
+ : 0.f;
delta_from_top_controls +=
bottom_controls_layout_height - bottom_content_offset;
@@ -387,25 +404,24 @@ void LayerTreeImpl::UpdateViewportContainerSizes() {
// Adjust the outer viewport container as well, since adjusting only the
// inner may cause its bounds to exceed those of the outer, causing scroll
// clamping.
- if (auto* outer_scroll = OuterViewportScrollNode()) {
- gfx::Vector2dF scaled_bounds_delta =
- gfx::ScaleVector2d(bounds_delta, 1.f / min_page_scale_factor());
-
- property_trees->SetOuterViewportContainerBoundsDelta(scaled_bounds_delta);
- // outer_viewport_container_bounds_delta and
- // inner_viewport_scroll_bounds_delta are the same thing.
- DCHECK_EQ(scaled_bounds_delta,
- property_trees->inner_viewport_scroll_bounds_delta());
-
- if (auto* outer_clip_node = OuterViewportClipNode()) {
- float adjusted_container_height =
- outer_scroll->container_bounds.height() + scaled_bounds_delta.y();
- outer_clip_node->clip.set_height(adjusted_container_height);
- }
+ gfx::Vector2dF scaled_bounds_delta =
+ gfx::ScaleVector2d(bounds_delta, 1.f / min_page_scale_factor());
+
+ property_trees->SetOuterViewportContainerBoundsDelta(scaled_bounds_delta);
+ // outer_viewport_container_bounds_delta and
+ // inner_viewport_scroll_bounds_delta are the same thing.
+ DCHECK_EQ(scaled_bounds_delta,
+ property_trees->inner_viewport_scroll_bounds_delta());
- anchor.ResetViewportToAnchoredPosition();
+ if (auto* outer_clip_node = OuterViewportClipNode()) {
+ float adjusted_container_height =
+ OuterViewportScrollNode()->container_bounds.height() +
+ scaled_bounds_delta.y();
+ outer_clip_node->clip.set_height(adjusted_container_height);
}
+ anchor.ResetViewportToAnchoredPosition();
+
property_trees->clip_tree.set_needs_update(true);
property_trees->full_tree_damaged = true;
set_needs_update_draw_properties();
@@ -424,11 +440,12 @@ gfx::ScrollOffset LayerTreeImpl::TotalScrollOffset() const {
gfx::ScrollOffset offset;
const auto& scroll_tree = property_trees()->scroll_tree;
- if (auto* inner_scroll = InnerViewportScrollNode())
+ if (auto* inner_scroll = InnerViewportScrollNode()) {
offset += scroll_tree.current_scroll_offset(inner_scroll->element_id);
-
- if (auto* outer_scroll = OuterViewportScrollNode())
- offset += scroll_tree.current_scroll_offset(outer_scroll->element_id);
+ DCHECK(OuterViewportScrollNode());
+ offset += scroll_tree.current_scroll_offset(
+ OuterViewportScrollNode()->element_id);
+ }
return offset;
}
@@ -543,11 +560,8 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
max_page_scale_factor());
target_tree->SetExternalPageScaleFactor(external_page_scale_factor_);
- target_tree->set_browser_controls_shrink_blink_size(
- browser_controls_shrink_blink_size_);
- target_tree->SetTopControlsHeight(top_controls_height_);
- target_tree->SetBottomControlsHeight(bottom_controls_height_);
- target_tree->PushBrowserControls(nullptr);
+ target_tree->SetBrowserControlsParams(browser_controls_params_);
+ target_tree->PushBrowserControls(nullptr, nullptr);
target_tree->set_overscroll_behavior(overscroll_behavior_);
@@ -602,12 +616,12 @@ void LayerTreeImpl::PushPropertiesTo(LayerTreeImpl* target_tree) {
}
void LayerTreeImpl::HandleTickmarksVisibilityChange() {
- if (!host_impl_->ViewportMainScrollNode())
+ if (!host_impl_->OuterViewportScrollNode())
return;
ScrollbarAnimationController* controller =
host_impl_->ScrollbarAnimationControllerForElementId(
- host_impl_->ViewportMainScrollNode()->element_id);
+ host_impl_->OuterViewportScrollNode()->element_id);
if (!controller)
return;
@@ -994,28 +1008,17 @@ void LayerTreeImpl::PushPageScaleFactorAndLimits(const float* page_scale_factor,
UpdatePageScaleNode();
}
-void LayerTreeImpl::set_browser_controls_shrink_blink_size(bool shrink) {
- if (browser_controls_shrink_blink_size_ == shrink)
- return;
-
- browser_controls_shrink_blink_size_ = shrink;
- UpdateViewportContainerSizes();
-}
-
-void LayerTreeImpl::SetTopControlsHeight(float top_controls_height) {
- if (top_controls_height_ == top_controls_height)
+void LayerTreeImpl::SetBrowserControlsParams(
+ const BrowserControlsParams& params) {
+ if (browser_controls_params_ == params)
return;
- top_controls_height_ = top_controls_height;
+ browser_controls_params_ = params;
UpdateViewportContainerSizes();
-}
-
-void LayerTreeImpl::SetBottomControlsHeight(float bottom_controls_height) {
- if (bottom_controls_height_ == bottom_controls_height)
- return;
- bottom_controls_height_ = bottom_controls_height;
- UpdateViewportContainerSizes();
+ if (IsActiveTree())
+ host_impl_->browser_controls_manager()->OnBrowserControlsParamsChanged(
+ params.animate_browser_controls_height_changes);
}
void LayerTreeImpl::set_overscroll_behavior(
@@ -1023,39 +1026,57 @@ void LayerTreeImpl::set_overscroll_behavior(
overscroll_behavior_ = behavior;
}
-bool LayerTreeImpl::ClampBrowserControlsShownRatio() {
+bool LayerTreeImpl::ClampTopControlsShownRatio() {
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);
+ return top_controls_shown_ratio_->SetCurrent(
+ base::ClampToRange(ratio, 0.f, 1.f));
+}
+
+bool LayerTreeImpl::ClampBottomControlsShownRatio() {
+ float ratio = bottom_controls_shown_ratio_->Current(true);
+ return bottom_controls_shown_ratio_->SetCurrent(
+ base::ClampToRange(ratio, 0.f, 1.f));
}
-bool LayerTreeImpl::SetCurrentBrowserControlsShownRatio(float ratio) {
- TRACE_EVENT1("cc", "LayerTreeImpl::SetCurrentBrowserControlsShownRatio",
- "ratio", ratio);
- bool changed = top_controls_shown_ratio_->SetCurrent(ratio);
- changed |= ClampBrowserControlsShownRatio();
+bool LayerTreeImpl::SetCurrentBrowserControlsShownRatio(float top_ratio,
+ float bottom_ratio) {
+ TRACE_EVENT2("cc", "LayerTreeImpl::SetCurrentBrowserControlsShownRatio",
+ "top_ratio", top_ratio, "bottom_ratio", bottom_ratio);
+ bool changed = top_controls_shown_ratio_->SetCurrent(top_ratio);
+ changed |= ClampTopControlsShownRatio();
+ changed |= bottom_controls_shown_ratio_->SetCurrent(bottom_ratio);
+ changed |= ClampBottomControlsShownRatio();
return changed;
}
void LayerTreeImpl::PushBrowserControlsFromMainThread(
- float top_controls_shown_ratio) {
- PushBrowserControls(&top_controls_shown_ratio);
+ float top_controls_shown_ratio,
+ float bottom_controls_shown_ratio) {
+ PushBrowserControls(&top_controls_shown_ratio, &bottom_controls_shown_ratio);
}
-void LayerTreeImpl::PushBrowserControls(const float* top_controls_shown_ratio) {
+void LayerTreeImpl::PushBrowserControls(
+ const float* top_controls_shown_ratio,
+ const float* bottom_controls_shown_ratio) {
+ DCHECK(top_controls_shown_ratio || bottom_controls_shown_ratio ||
+ IsActiveTree());
+ DCHECK(!top_controls_shown_ratio || bottom_controls_shown_ratio);
DCHECK(top_controls_shown_ratio || IsActiveTree());
if (top_controls_shown_ratio) {
DCHECK(!IsActiveTree() || !host_impl_->pending_tree());
bool changed_pending =
top_controls_shown_ratio_->PushMainToPending(*top_controls_shown_ratio);
+ changed_pending |= bottom_controls_shown_ratio_->PushMainToPending(
+ *bottom_controls_shown_ratio);
if (!IsActiveTree() && changed_pending)
UpdateViewportContainerSizes();
}
if (IsActiveTree()) {
bool changed_active = top_controls_shown_ratio_->PushPendingToActive();
- changed_active |= ClampBrowserControlsShownRatio();
+ changed_active |= ClampTopControlsShownRatio();
+ changed_active |= bottom_controls_shown_ratio_->PushPendingToActive();
+ changed_active |= ClampBottomControlsShownRatio();
if (changed_active)
host_impl_->DidChangeBrowserControlsPosition();
}
@@ -1088,7 +1109,7 @@ void LayerTreeImpl::DidUpdatePageScale() {
host_impl_->FlashAllScrollbars(true);
return;
}
- if (auto* scroll_node = host_impl_->ViewportMainScrollNode()) {
+ if (auto* scroll_node = host_impl_->OuterViewportScrollNode()) {
if (ScrollbarAnimationController* controller =
host_impl_->ScrollbarAnimationControllerForElementId(
scroll_node->element_id))
@@ -1186,10 +1207,10 @@ gfx::SizeF LayerTreeImpl::ScrollableViewportSize() const {
gfx::Rect LayerTreeImpl::RootScrollLayerDeviceViewportBounds() const {
const ScrollNode* root_scroll_node = OuterViewportScrollNode();
- if (!root_scroll_node)
- root_scroll_node = InnerViewportScrollNode();
- if (!root_scroll_node)
+ if (!root_scroll_node) {
+ DCHECK(!InnerViewportScrollNode());
return gfx::Rect();
+ }
return MathUtil::MapEnclosingClippedRect(
property_trees()->transform_tree.ToScreen(root_scroll_node->transform_id),
gfx::Rect(root_scroll_node->bounds));
@@ -1419,10 +1440,10 @@ const Region& LayerTreeImpl::UnoccludedScreenSpaceRegion() const {
gfx::SizeF LayerTreeImpl::ScrollableSize() const {
auto* scroll_node = OuterViewportScrollNode();
- if (!scroll_node)
- scroll_node = InnerViewportScrollNode();
- if (!scroll_node)
+ if (!scroll_node) {
+ DCHECK(!InnerViewportScrollNode());
return gfx::SizeF();
+ }
const auto& scroll_tree = property_trees()->scroll_tree;
auto size = scroll_tree.scroll_bounds(scroll_node->id);
size.SetToMax(gfx::SizeF(scroll_tree.container_bounds(scroll_node->id)));
@@ -1918,7 +1939,7 @@ void LayerTreeImpl::UnregisterScrollbar(
scrollbar_ids.vertical == Layer::INVALID_ID) {
element_id_to_scrollbar_layer_ids_.erase(scroll_element_id);
if (IsActiveTree()) {
- host_impl_->UnregisterScrollbarAnimationController(scroll_element_id);
+ host_impl_->DidUnregisterScrollbarLayer(scroll_element_id);
}
}
}
@@ -2258,27 +2279,27 @@ static gfx::SelectionBound ComputeViewportSelectionBound(
if (!layer || layer_bound.type == gfx::SelectionBound::EMPTY)
return viewport_bound;
- auto layer_top = gfx::PointF(layer_bound.edge_top);
- auto layer_bottom = gfx::PointF(layer_bound.edge_bottom);
+ auto layer_start = gfx::PointF(layer_bound.edge_start);
+ auto layer_end = gfx::PointF(layer_bound.edge_end);
gfx::Transform screen_space_transform = layer->ScreenSpaceTransform();
bool clipped = false;
- gfx::PointF screen_top =
- MathUtil::MapPoint(screen_space_transform, layer_top, &clipped);
- gfx::PointF screen_bottom =
- MathUtil::MapPoint(screen_space_transform, layer_bottom, &clipped);
+ gfx::PointF screen_start =
+ MathUtil::MapPoint(screen_space_transform, layer_start, &clipped);
+ gfx::PointF screen_end =
+ MathUtil::MapPoint(screen_space_transform, layer_end, &clipped);
// MapPoint can produce points with NaN components (even when no inputs are
- // NaN). Since consumers of gfx::SelectionBounds may round |edge_top| or
- // |edge_bottom| (and since rounding will crash on NaN), we return an empty
+ // NaN). Since consumers of gfx::SelectionBounds may round |edge_start| or
+ // |edge_end| (and since rounding will crash on NaN), we return an empty
// bound instead.
- if (std::isnan(screen_top.x()) || std::isnan(screen_top.y()) ||
- std::isnan(screen_bottom.x()) || std::isnan(screen_bottom.y()))
+ if (std::isnan(screen_start.x()) || std::isnan(screen_start.y()) ||
+ std::isnan(screen_end.x()) || std::isnan(screen_end.y()))
return gfx::SelectionBound();
const float inv_scale = 1.f / device_scale_factor;
- viewport_bound.SetEdgeTop(gfx::ScalePoint(screen_top, inv_scale));
- viewport_bound.SetEdgeBottom(gfx::ScalePoint(screen_bottom, inv_scale));
+ viewport_bound.SetEdgeStart(gfx::ScalePoint(screen_start, inv_scale));
+ viewport_bound.SetEdgeEnd(gfx::ScalePoint(screen_end, inv_scale));
// If |layer_bound| is already hidden due to being occluded by painted content
// within the layer, it must remain hidden. Otherwise, check whether its
@@ -2291,9 +2312,9 @@ static gfx::SelectionBound ComputeViewportSelectionBound(
// Shifting the visibility point fractionally inward ensures that
// neighboring or logically coincident layers aligned to integral DPI
// coordinates will not spuriously occlude the bound.
- gfx::Vector2dF visibility_offset = layer_top - layer_bottom;
+ gfx::Vector2dF visibility_offset = layer_start - layer_end;
visibility_offset.Scale(device_scale_factor / visibility_offset.Length());
- gfx::PointF visibility_point = layer_bottom + visibility_offset;
+ gfx::PointF visibility_point = layer_end + visibility_offset;
if (visibility_point.x() <= 0)
visibility_point.set_x(visibility_point.x() + device_scale_factor);
visibility_point =
@@ -2304,6 +2325,31 @@ static gfx::SelectionBound ComputeViewportSelectionBound(
PointHitsLayer(layer, visibility_point, &intersect_distance));
}
+ if (viewport_bound.visible()) {
+ viewport_bound.SetVisibleEdge(viewport_bound.edge_start(),
+ viewport_bound.edge_end());
+ } else {
+ // The |layer_start| and |layer_end| might be clipped.
+ gfx::RectF visible_layer_rect(layer->visible_layer_rect());
+ auto visible_layer_start = layer_start;
+ auto visible_layer_end = layer_end;
+ if (!visible_layer_rect.Contains(visible_layer_start) &&
+ !visible_layer_rect.Contains(visible_layer_end))
+ std::tie(visible_layer_start, visible_layer_end) =
+ GetVisibleSelectionEndPoints(visible_layer_rect, layer_start,
+ layer_end);
+
+ gfx::PointF visible_screen_start = MathUtil::MapPoint(
+ screen_space_transform, visible_layer_start, &clipped);
+ gfx::PointF visible_screen_end =
+ MathUtil::MapPoint(screen_space_transform, visible_layer_end, &clipped);
+
+ viewport_bound.SetVisibleEdgeStart(
+ gfx::ScalePoint(visible_screen_start, inv_scale));
+ viewport_bound.SetVisibleEdgeEnd(
+ gfx::ScalePoint(visible_screen_end, inv_scale));
+ }
+
return viewport_bound;
}
@@ -2346,6 +2392,11 @@ bool LayerTreeImpl::IsActivelyScrolling() const {
return host_impl_->IsActivelyScrolling();
}
+int LayerTreeImpl::GetMSAASampleCountForRaster(
+ const scoped_refptr<DisplayItemList>& display_list) {
+ return host_impl_->GetMSAASampleCountForRaster(display_list);
+}
+
void LayerTreeImpl::SetPendingPageScaleAnimation(
std::unique_ptr<PendingPageScaleAnimation> pending_animation) {
pending_page_scale_animation_ = std::move(pending_animation);
diff --git a/chromium/cc/trees/layer_tree_impl.h b/chromium/cc/trees/layer_tree_impl.h
index 7cb74373eba..118f19d1d65 100644
--- a/chromium/cc/trees/layer_tree_impl.h
+++ b/chromium/cc/trees/layer_tree_impl.h
@@ -15,6 +15,7 @@
#include "base/time/time.h"
#include "base/values.h"
#include "cc/base/synced_property.h"
+#include "cc/input/browser_controls_offset_manager.h"
#include "cc/input/event_listener_properties.h"
#include "cc/input/layer_selection_bound.h"
#include "cc/input/overscroll_behavior.h"
@@ -22,11 +23,13 @@
#include "cc/layers/layer_list_iterator.h"
#include "cc/paint/discardable_image_map.h"
#include "cc/resources/ui_resource_client.h"
+#include "cc/trees/browser_controls_params.h"
#include "cc/trees/layer_tree_host.h"
#include "cc/trees/layer_tree_host_impl.h"
#include "cc/trees/property_tree.h"
#include "cc/trees/swap_promise.h"
#include "components/viz/common/frame_sinks/begin_frame_args.h"
+#include "ui/gfx/overlay_transform.h"
namespace base {
namespace trace_event {
@@ -95,10 +98,12 @@ class CC_EXPORT LayerTreeImpl {
// This is the number of times a fixed point has to be hit continuously by a
// layer to consider it as jittering.
enum : int { kFixedPointHitsThreshold = 3 };
- LayerTreeImpl(LayerTreeHostImpl* host_impl,
- scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,
- scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio,
- scoped_refptr<SyncedElasticOverscroll> elastic_overscroll);
+ LayerTreeImpl(
+ LayerTreeHostImpl* host_impl,
+ scoped_refptr<SyncedProperty<ScaleGroup>> page_scale_factor,
+ scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio,
+ scoped_refptr<SyncedBrowserControls> bottom_controls_shown_ratio,
+ scoped_refptr<SyncedElasticOverscroll> elastic_overscroll);
LayerTreeImpl(const LayerTreeImpl&) = delete;
virtual ~LayerTreeImpl();
@@ -149,6 +154,8 @@ class CC_EXPORT LayerTreeImpl {
base::flat_map<PaintImage::Id, PaintImage::DecodingMode>
decoding_mode_map);
bool IsActivelyScrolling() const;
+ int GetMSAASampleCountForRaster(
+ const scoped_refptr<DisplayItemList>& display_list);
// Tree specific methods exposed to layer-impl tree.
// ---------------------------------------------------------------------------
@@ -277,6 +284,9 @@ class CC_EXPORT LayerTreeImpl {
return !presentation_callbacks_.empty();
}
+ // The following viewport related property nodes will only ever be set on the
+ // main-frame's renderer (i.e. OOPIF and UI compositors will not have these
+ // set.
using ViewportPropertyIds = LayerTreeHost::ViewportPropertyIds;
void SetViewportPropertyIds(const ViewportPropertyIds& ids);
@@ -324,6 +334,13 @@ class CC_EXPORT LayerTreeImpl {
SkColor background_color() const { return background_color_; }
void set_background_color(SkColor color) { background_color_ = color; }
+ gfx::OverlayTransform display_transform_hint() const {
+ return display_transform_hint_;
+ }
+ void set_display_transform_hint(gfx::OverlayTransform hint) {
+ display_transform_hint_ = hint;
+ }
+
void UpdatePropertyTreeAnimationFromMainThread();
void SetPageScaleOnActiveTree(float active_page_scale);
@@ -415,6 +432,12 @@ class CC_EXPORT LayerTreeImpl {
const SyncedBrowserControls* top_controls_shown_ratio() const {
return top_controls_shown_ratio_.get();
}
+ SyncedBrowserControls* bottom_controls_shown_ratio() {
+ return bottom_controls_shown_ratio_.get();
+ }
+ const SyncedBrowserControls* bottom_controls_shown_ratio() const {
+ return bottom_controls_shown_ratio_.get();
+ }
gfx::Vector2dF current_elastic_overscroll() const {
return elastic_overscroll()->Current(IsActiveTree());
}
@@ -502,10 +525,6 @@ class CC_EXPORT LayerTreeImpl {
// Used for accessing the task runner and debug assertions.
TaskRunnerProvider* task_runner_provider() const;
- void ApplyScroll(ScrollNode* scroll_node, ScrollState* scroll_state) {
- host_impl_->ApplyScroll(scroll_node, scroll_state);
- }
-
// Call this function when you expect there to be a swap buffer.
// See swap_promise.h for how to use SwapPromise.
//
@@ -586,19 +605,31 @@ class CC_EXPORT LayerTreeImpl {
// the viewport.
void GetViewportSelection(viz::Selection<gfx::SelectionBound>* selection);
- void set_browser_controls_shrink_blink_size(bool shrink);
bool browser_controls_shrink_blink_size() const {
- return browser_controls_shrink_blink_size_;
+ return browser_controls_params_.browser_controls_shrink_blink_size;
}
- bool SetCurrentBrowserControlsShownRatio(float ratio);
- float CurrentBrowserControlsShownRatio() const {
+ bool SetCurrentBrowserControlsShownRatio(float top_ratio, float bottom_ratio);
+ float CurrentTopControlsShownRatio() const {
return top_controls_shown_ratio_->Current(IsActiveTree());
}
- void SetTopControlsHeight(float top_controls_height);
- float top_controls_height() const { return top_controls_height_; }
- void PushBrowserControlsFromMainThread(float top_controls_shown_ratio);
- void SetBottomControlsHeight(float bottom_controls_height);
- float bottom_controls_height() const { return bottom_controls_height_; }
+ float CurrentBottomControlsShownRatio() const {
+ return bottom_controls_shown_ratio_->Current(IsActiveTree());
+ }
+ void SetBrowserControlsParams(const BrowserControlsParams& params);
+ float top_controls_height() const {
+ return browser_controls_params_.top_controls_height;
+ }
+ float top_controls_min_height() const {
+ return browser_controls_params_.top_controls_min_height;
+ }
+ void PushBrowserControlsFromMainThread(float top_controls_shown_ratio,
+ float bottom_controls_shown_ratio);
+ float bottom_controls_height() const {
+ return browser_controls_params_.bottom_controls_height;
+ }
+ float bottom_controls_min_height() const {
+ return browser_controls_params_.bottom_controls_min_height;
+ }
void set_overscroll_behavior(const OverscrollBehavior& behavior);
OverscrollBehavior overscroll_behavior() const {
@@ -681,8 +712,10 @@ class CC_EXPORT LayerTreeImpl {
bool SetPageScaleFactorLimits(float min_page_scale_factor,
float max_page_scale_factor);
void DidUpdatePageScale();
- void PushBrowserControls(const float* top_controls_shown_ratio);
- bool ClampBrowserControlsShownRatio();
+ void PushBrowserControls(const float* top_controls_shown_ratio,
+ const float* bottom_controls_shown_ratio);
+ bool ClampTopControlsShownRatio();
+ bool ClampBottomControlsShownRatio();
private:
friend class LayerTreeHost;
@@ -800,17 +833,14 @@ class CC_EXPORT LayerTreeImpl {
EventListenerProperties event_listener_properties_
[static_cast<size_t>(EventListenerClass::kLast) + 1];
- // Whether or not Blink's viewport size was shrunk by the height of the top
- // controls at the time of the last layout.
- bool browser_controls_shrink_blink_size_;
- float top_controls_height_;
- float bottom_controls_height_;
+ BrowserControlsParams browser_controls_params_;
OverscrollBehavior overscroll_behavior_;
// The amount that the browser controls are shown from 0 (hidden) to 1 (fully
// shown).
scoped_refptr<SyncedBrowserControls> top_controls_shown_ratio_;
+ scoped_refptr<SyncedBrowserControls> bottom_controls_shown_ratio_;
std::unique_ptr<PendingPageScaleAnimation> pending_page_scale_animation_;
@@ -822,6 +852,9 @@ class CC_EXPORT LayerTreeImpl {
// lifecycle states. See: |LayerTreeLifecycle|.
LayerTreeLifecycle lifecycle_;
+ // Display transform hint to tag frames generated from this tree.
+ gfx::OverlayTransform display_transform_hint_ = gfx::OVERLAY_TRANSFORM_NONE;
+
std::vector<LayerTreeHost::PresentationTimeCallback> presentation_callbacks_;
};
diff --git a/chromium/cc/trees/layer_tree_impl_unittest.cc b/chromium/cc/trees/layer_tree_impl_unittest.cc
index bdfe90cb9bc..dcce0e46683 100644
--- a/chromium/cc/trees/layer_tree_impl_unittest.cc
+++ b/chromium/cc/trees/layer_tree_impl_unittest.cc
@@ -4,6 +4,7 @@
#include "cc/trees/layer_tree_impl.h"
+#include "base/numerics/ranges.h"
#include "cc/layers/heads_up_display_layer_impl.h"
#include "cc/test/fake_layer_tree_host_impl.h"
#include "cc/test/fake_raster_source.h"
@@ -18,6 +19,17 @@
namespace cc {
namespace {
+std::pair<gfx::PointF, gfx::PointF> GetVisibleSelectionEndPoints(
+ const gfx::RectF& rect,
+ const gfx::PointF& top,
+ const gfx::PointF& bottom) {
+ gfx::PointF start(base::ClampToRange(top.x(), rect.x(), rect.right()),
+ base::ClampToRange(top.y(), rect.y(), rect.bottom()));
+ gfx::PointF end =
+ start + gfx::Vector2dF(bottom.x() - top.x(), bottom.y() - top.y());
+ return {start, end};
+}
+
class LayerTreeImplTest : public LayerTreeImplTestBase, public testing::Test {
public:
LayerTreeImplTest() = default;
@@ -1751,13 +1763,13 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) {
LayerSelection input;
input.start.type = gfx::SelectionBound::LEFT;
- input.start.edge_top = gfx::Point(10, 10);
- input.start.edge_bottom = gfx::Point(10, 20);
+ input.start.edge_start = gfx::Point(10, 10);
+ input.start.edge_end = gfx::Point(10, 20);
input.start.layer_id = root->id();
input.end.type = gfx::SelectionBound::RIGHT;
- input.end.edge_top = gfx::Point(50, 10);
- input.end.edge_bottom = gfx::Point(50, 30);
+ input.end.edge_start = gfx::Point(50, 10);
+ input.end.edge_end = gfx::Point(50, 30);
input.end.layer_id = root->id();
viz::Selection<gfx::SelectionBound> output;
@@ -1771,28 +1783,65 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForSingleLayer) {
host_impl().active_tree()->RegisterSelection(input);
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_EQ(input.start.type, output.start.type());
- EXPECT_EQ(gfx::PointF(input.start.edge_bottom), output.start.edge_bottom());
- EXPECT_EQ(gfx::PointF(input.start.edge_top), output.start.edge_top());
+ EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.edge_end());
+ EXPECT_EQ(gfx::PointF(input.start.edge_start), output.start.edge_start());
+ EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.visible_edge_end());
+ EXPECT_EQ(gfx::PointF(input.start.edge_start),
+ output.start.visible_edge_start());
+ EXPECT_TRUE(output.start.visible());
+ EXPECT_EQ(input.end.type, output.end.type());
+ EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.edge_end());
+ EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.edge_start());
+ EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.visible_edge_end());
+ EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.visible_edge_start());
+ EXPECT_TRUE(output.end.visible());
+
+ // Selection bounds should produce distinct left and right bounds for the
+ // vertical text.
+ input.start.type = gfx::SelectionBound::LEFT;
+ input.start.edge_start = gfx::Point(20, 10);
+ input.start.edge_end = gfx::Point(10, 10);
+ input.start.layer_id = root->id();
+
+ input.end.type = gfx::SelectionBound::RIGHT;
+ input.end.edge_start = gfx::Point(30, 20);
+ input.end.edge_end = gfx::Point(50, 20);
+ input.end.layer_id = root->id();
+
+ host_impl().active_tree()->RegisterSelection(input);
+ host_impl().active_tree()->GetViewportSelection(&output);
+ EXPECT_EQ(input.start.type, output.start.type());
+ EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.edge_end());
+ EXPECT_EQ(gfx::PointF(input.start.edge_start), output.start.edge_start());
+ EXPECT_EQ(gfx::PointF(input.start.edge_end), output.start.visible_edge_end());
+ EXPECT_EQ(gfx::PointF(input.start.edge_start),
+ output.start.visible_edge_start());
EXPECT_TRUE(output.start.visible());
EXPECT_EQ(input.end.type, output.end.type());
- EXPECT_EQ(gfx::PointF(input.end.edge_bottom), output.end.edge_bottom());
- EXPECT_EQ(gfx::PointF(input.end.edge_top), output.end.edge_top());
+ EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.edge_end());
+ EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.edge_start());
+ EXPECT_EQ(gfx::PointF(input.end.edge_end), output.end.visible_edge_end());
+ EXPECT_EQ(gfx::PointF(input.end.edge_start), output.end.visible_edge_start());
EXPECT_TRUE(output.end.visible());
// Insertion bounds should produce identical left and right bounds.
LayerSelection insertion_input;
insertion_input.start.type = gfx::SelectionBound::CENTER;
- insertion_input.start.edge_top = gfx::Point(15, 10);
- insertion_input.start.edge_bottom = gfx::Point(15, 30);
+ insertion_input.start.edge_start = gfx::Point(15, 10);
+ insertion_input.start.edge_end = gfx::Point(15, 30);
insertion_input.start.layer_id = root->id();
insertion_input.end = insertion_input.start;
host_impl().active_tree()->RegisterSelection(insertion_input);
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_EQ(insertion_input.start.type, output.start.type());
- EXPECT_EQ(gfx::PointF(insertion_input.start.edge_bottom),
- output.start.edge_bottom());
- EXPECT_EQ(gfx::PointF(insertion_input.start.edge_top),
- output.start.edge_top());
+ EXPECT_EQ(gfx::PointF(insertion_input.start.edge_end),
+ output.start.edge_end());
+ EXPECT_EQ(gfx::PointF(insertion_input.start.edge_start),
+ output.start.edge_start());
+ EXPECT_EQ(gfx::PointF(insertion_input.start.edge_end),
+ output.start.visible_edge_end());
+ EXPECT_EQ(gfx::PointF(insertion_input.start.edge_start),
+ output.start.visible_edge_start());
EXPECT_TRUE(output.start.visible());
EXPECT_EQ(output.start, output.end);
}
@@ -1827,52 +1876,117 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForPartialOccludedLayers) {
LayerSelection input;
input.start.type = gfx::SelectionBound::LEFT;
- input.start.edge_top = gfx::Point(25, 10);
- input.start.edge_bottom = gfx::Point(25, 30);
+ input.start.edge_start = gfx::Point(25, 10);
+ input.start.edge_end = gfx::Point(25, 30);
input.start.layer_id = clipped_layer->id();
input.end.type = gfx::SelectionBound::RIGHT;
- input.end.edge_top = gfx::Point(75, 10);
- input.end.edge_bottom = gfx::Point(75, 30);
+ input.end.edge_start = gfx::Point(75, 10);
+ input.end.edge_end = gfx::Point(75, 30);
input.end.layer_id = clipped_layer->id();
host_impl().active_tree()->RegisterSelection(input);
- // The left bound should be occluded by the clip layer.
+ // The right bound should be occluded by the clip layer.
viz::Selection<gfx::SelectionBound> output;
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_EQ(input.start.type, output.start.type());
- auto expected_output_start_top = gfx::PointF(input.start.edge_top);
- auto expected_output_edge_botom = gfx::PointF(input.start.edge_bottom);
- expected_output_start_top.Offset(clipping_offset.x(), clipping_offset.y());
- expected_output_edge_botom.Offset(clipping_offset.x(), clipping_offset.y());
- EXPECT_EQ(expected_output_start_top, output.start.edge_top());
- EXPECT_EQ(expected_output_edge_botom, output.start.edge_bottom());
+ auto expected_output_edge_start = gfx::PointF(input.start.edge_start);
+ auto expected_output_edge_end = gfx::PointF(input.start.edge_end);
+ expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
+ expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
+ EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
+ EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
+ EXPECT_TRUE(output.start.visible());
+ EXPECT_EQ(input.end.type, output.end.type());
+ expected_output_edge_start = gfx::PointF(input.end.edge_start);
+ expected_output_edge_end = gfx::PointF(input.end.edge_end);
+ expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
+ expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
+ EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
+
+ gfx::RectF visible_layer_rect(clipped_layer->visible_layer_rect());
+ gfx::PointF expected_output_visible_edge_start;
+ gfx::PointF expected_output_visible_edge_end;
+ std::tie(expected_output_visible_edge_start,
+ expected_output_visible_edge_end) =
+ GetVisibleSelectionEndPoints(visible_layer_rect,
+ gfx::PointF(input.end.edge_start),
+ gfx::PointF(input.end.edge_end));
+ expected_output_visible_edge_start.Offset(clipping_offset.x(),
+ clipping_offset.y());
+ expected_output_visible_edge_end.Offset(clipping_offset.x(),
+ clipping_offset.y());
+
+ EXPECT_EQ(expected_output_visible_edge_start,
+ output.end.visible_edge_start());
+ EXPECT_EQ(expected_output_visible_edge_end, output.end.visible_edge_end());
+ EXPECT_FALSE(output.end.visible());
+
+ // The right bound should be occluded by the clip layer for the vertical text.
+ input.start.type = gfx::SelectionBound::LEFT;
+ input.start.edge_start = gfx::Point(25, 10);
+ input.start.edge_end = gfx::Point(15, 10);
+ input.start.layer_id = clipped_layer->id();
+
+ input.end.type = gfx::SelectionBound::RIGHT;
+ input.end.edge_start = gfx::Point(75, 30);
+ input.end.edge_end = gfx::Point(85, 30);
+ input.end.layer_id = clipped_layer->id();
+ host_impl().active_tree()->RegisterSelection(input);
+
+ host_impl().active_tree()->GetViewportSelection(&output);
+ EXPECT_EQ(input.start.type, output.start.type());
+ expected_output_edge_start = gfx::PointF(input.start.edge_start);
+ expected_output_edge_end = gfx::PointF(input.start.edge_end);
+ expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
+ expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
+ EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
+ EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
EXPECT_TRUE(output.start.visible());
EXPECT_EQ(input.end.type, output.end.type());
- auto expected_output_end_top = gfx::PointF(input.end.edge_top);
- auto expected_output_end_bottom = gfx::PointF(input.end.edge_bottom);
- expected_output_end_bottom.Offset(clipping_offset.x(), clipping_offset.y());
- expected_output_end_top.Offset(clipping_offset.x(), clipping_offset.y());
- EXPECT_EQ(expected_output_end_top, output.end.edge_top());
- EXPECT_EQ(expected_output_end_bottom, output.end.edge_bottom());
+ expected_output_edge_start = gfx::PointF(input.end.edge_start);
+ expected_output_edge_end = gfx::PointF(input.end.edge_end);
+ expected_output_edge_end.Offset(clipping_offset.x(), clipping_offset.y());
+ expected_output_edge_start.Offset(clipping_offset.x(), clipping_offset.y());
+ EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
+
+ std::tie(expected_output_visible_edge_start,
+ expected_output_visible_edge_end) =
+ GetVisibleSelectionEndPoints(visible_layer_rect,
+ gfx::PointF(input.end.edge_start),
+ gfx::PointF(input.end.edge_end));
+ expected_output_visible_edge_start.Offset(clipping_offset.x(),
+ clipping_offset.y());
+ expected_output_visible_edge_end.Offset(clipping_offset.x(),
+ clipping_offset.y());
+
+ EXPECT_EQ(expected_output_visible_edge_start,
+ output.end.visible_edge_start());
+ EXPECT_EQ(expected_output_visible_edge_end, output.end.visible_edge_end());
EXPECT_FALSE(output.end.visible());
// Handles outside the viewport bounds should be marked invisible.
- input.start.edge_top = gfx::Point(-25, 0);
- input.start.edge_bottom = gfx::Point(-25, 20);
+ input.start.edge_start = gfx::Point(-25, 0);
+ input.start.edge_end = gfx::Point(-25, 20);
host_impl().active_tree()->RegisterSelection(input);
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_FALSE(output.start.visible());
- input.start.edge_top = gfx::Point(0, -25);
- input.start.edge_bottom = gfx::Point(0, -5);
+ input.start.edge_start = gfx::Point(0, -25);
+ input.start.edge_end = gfx::Point(0, -5);
host_impl().active_tree()->RegisterSelection(input);
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_FALSE(output.start.visible());
- // If the handle bottom is partially visible, the handle is marked visible.
- input.start.edge_top = gfx::Point(0, -20);
- input.start.edge_bottom = gfx::Point(0, 1);
+ // If the handle end is partially visible, the handle is marked visible.
+ input.start.edge_start = gfx::Point(0, -20);
+ input.start.edge_end = gfx::Point(0, 1);
host_impl().active_tree()->RegisterSelection(input);
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_TRUE(output.start.visible());
@@ -1921,13 +2035,13 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
LayerSelection input;
input.start.type = gfx::SelectionBound::LEFT;
- input.start.edge_top = gfx::Point(10, 10);
- input.start.edge_bottom = gfx::Point(10, 30);
+ input.start.edge_start = gfx::Point(10, 10);
+ input.start.edge_end = gfx::Point(10, 30);
input.start.layer_id = page_scale_layer->id();
input.end.type = gfx::SelectionBound::RIGHT;
- input.end.edge_top = gfx::Point(0, 0);
- input.end.edge_bottom = gfx::Point(0, 20);
+ input.end.edge_start = gfx::Point(0, 0);
+ input.end.edge_end = gfx::Point(0, 20);
input.end.layer_id = sub_layer->id();
host_impl().active_tree()->RegisterSelection(input);
@@ -1936,23 +2050,27 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForScaledLayers) {
viz::Selection<gfx::SelectionBound> output;
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_EQ(input.start.type, output.start.type());
- auto expected_output_start_top = gfx::PointF(input.start.edge_top);
- auto expected_output_start_bottom = gfx::PointF(input.start.edge_bottom);
- expected_output_start_top.Scale(page_scale_factor);
- expected_output_start_bottom.Scale(page_scale_factor);
- EXPECT_EQ(expected_output_start_top, output.start.edge_top());
- EXPECT_EQ(expected_output_start_bottom, output.start.edge_bottom());
+ auto expected_output_edge_start = gfx::PointF(input.start.edge_start);
+ auto expected_output_edge_end = gfx::PointF(input.start.edge_end);
+ expected_output_edge_start.Scale(page_scale_factor);
+ expected_output_edge_end.Scale(page_scale_factor);
+ EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
+ EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
EXPECT_TRUE(output.start.visible());
EXPECT_EQ(input.end.type, output.end.type());
- auto expected_output_end_top = gfx::PointF(input.end.edge_top);
- auto expected_output_end_bottom = gfx::PointF(input.end.edge_bottom);
- expected_output_end_top.Offset(sub_layer_offset.x(), sub_layer_offset.y());
- expected_output_end_bottom.Offset(sub_layer_offset.x(), sub_layer_offset.y());
- expected_output_end_top.Scale(page_scale_factor);
- expected_output_end_bottom.Scale(page_scale_factor);
- EXPECT_EQ(expected_output_end_top, output.end.edge_top());
- EXPECT_EQ(expected_output_end_bottom, output.end.edge_bottom());
+ expected_output_edge_start = gfx::PointF(input.end.edge_start);
+ expected_output_edge_end = gfx::PointF(input.end.edge_end);
+ expected_output_edge_start.Offset(sub_layer_offset.x(), sub_layer_offset.y());
+ expected_output_edge_end.Offset(sub_layer_offset.x(), sub_layer_offset.y());
+ expected_output_edge_start.Scale(page_scale_factor);
+ expected_output_edge_end.Scale(page_scale_factor);
+ EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
+ EXPECT_EQ(expected_output_edge_start, output.end.visible_edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.end.visible_edge_end());
EXPECT_TRUE(output.end.visible());
}
@@ -1979,13 +2097,13 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForDSFEnabled) {
LayerSelection input;
input.start.type = gfx::SelectionBound::LEFT;
- input.start.edge_top = gfx::Point(10, 10);
- input.start.edge_bottom = gfx::Point(10, 30);
+ input.start.edge_start = gfx::Point(10, 10);
+ input.start.edge_end = gfx::Point(10, 30);
input.start.layer_id = root->id();
input.end.type = gfx::SelectionBound::RIGHT;
- input.end.edge_top = gfx::Point(0, 0);
- input.end.edge_bottom = gfx::Point(0, 20);
+ input.end.edge_start = gfx::Point(0, 0);
+ input.end.edge_end = gfx::Point(0, 20);
input.end.layer_id = sub_layer->id();
host_impl().active_tree()->RegisterSelection(input);
@@ -1994,27 +2112,31 @@ TEST_F(LayerTreeImplTest, SelectionBoundsForDSFEnabled) {
viz::Selection<gfx::SelectionBound> output;
host_impl().active_tree()->GetViewportSelection(&output);
EXPECT_EQ(input.start.type, output.start.type());
- auto expected_output_start_top = gfx::PointF(input.start.edge_top);
- auto expected_output_edge_bottom = gfx::PointF(input.start.edge_bottom);
- expected_output_start_top.Scale(
+ auto expected_output_edge_start = gfx::PointF(input.start.edge_start);
+ auto expected_output_edge_end = gfx::PointF(input.start.edge_end);
+ expected_output_edge_start.Scale(
1.f / (device_scale_factor * painted_device_scale_factor));
- expected_output_edge_bottom.Scale(
+ expected_output_edge_end.Scale(
1.f / (device_scale_factor * painted_device_scale_factor));
- EXPECT_EQ(expected_output_start_top, output.start.edge_top());
- EXPECT_EQ(expected_output_edge_bottom, output.start.edge_bottom());
+ EXPECT_EQ(expected_output_edge_start, output.start.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.edge_end());
+ EXPECT_EQ(expected_output_edge_start, output.start.visible_edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.start.visible_edge_end());
EXPECT_TRUE(output.start.visible());
EXPECT_EQ(input.end.type, output.end.type());
- auto expected_output_end_top = gfx::PointF(input.end.edge_top);
- auto expected_output_end_bottom = gfx::PointF(input.end.edge_bottom);
- expected_output_end_top.Offset(sub_layer_offset.x(), sub_layer_offset.y());
- expected_output_end_bottom.Offset(sub_layer_offset.x(), sub_layer_offset.y());
- expected_output_end_top.Scale(
+ expected_output_edge_start = gfx::PointF(input.end.edge_start);
+ expected_output_edge_end = gfx::PointF(input.end.edge_end);
+ expected_output_edge_start.Offset(sub_layer_offset.x(), sub_layer_offset.y());
+ expected_output_edge_end.Offset(sub_layer_offset.x(), sub_layer_offset.y());
+ expected_output_edge_start.Scale(
1.f / (device_scale_factor * painted_device_scale_factor));
- expected_output_end_bottom.Scale(
+ expected_output_edge_end.Scale(
1.f / (device_scale_factor * painted_device_scale_factor));
- EXPECT_EQ(expected_output_end_top, output.end.edge_top());
- EXPECT_EQ(expected_output_end_bottom, output.end.edge_bottom());
+ EXPECT_EQ(expected_output_edge_start, output.end.edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.end.edge_end());
+ EXPECT_EQ(expected_output_edge_start, output.end.visible_edge_start());
+ EXPECT_EQ(expected_output_edge_end, output.end.visible_edge_end());
EXPECT_TRUE(output.end.visible());
}
@@ -2043,13 +2165,13 @@ TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) {
LayerSelection input;
input.start.type = gfx::SelectionBound::LEFT;
- input.start.edge_top = gfx::Point(10, 10);
- input.start.edge_bottom = gfx::Point(10, 20);
+ input.start.edge_start = gfx::Point(10, 10);
+ input.start.edge_end = gfx::Point(10, 20);
input.start.layer_id = grand_child->id();
input.end.type = gfx::SelectionBound::RIGHT;
- input.end.edge_top = gfx::Point(50, 10);
- input.end.edge_bottom = gfx::Point(50, 30);
+ input.end.edge_start = gfx::Point(50, 10);
+ input.end.edge_end = gfx::Point(50, 30);
input.end.layer_id = grand_child->id();
host_impl().active_tree()->RegisterSelection(input);
@@ -2057,7 +2179,7 @@ TEST_F(LayerTreeImplTest, SelectionBoundsWithLargeTransforms) {
viz::Selection<gfx::SelectionBound> output;
host_impl().active_tree()->GetViewportSelection(&output);
- // edge_bottom and edge_top aren't allowed to have NaNs, so the selection
+ // edge_end and edge_start aren't allowed to have NaNs, so the selection
// should be empty.
EXPECT_EQ(gfx::SelectionBound(), output.start);
EXPECT_EQ(gfx::SelectionBound(), output.end);
diff --git a/chromium/cc/trees/layer_tree_mutator.cc b/chromium/cc/trees/layer_tree_mutator.cc
index 9e285596b4a..ecd0d6671bd 100644
--- a/chromium/cc/trees/layer_tree_mutator.cc
+++ b/chromium/cc/trees/layer_tree_mutator.cc
@@ -36,9 +36,6 @@ bool AnimationWorkletInput::ValidateId(int worklet_id) const {
}) &&
std::all_of(
removed_animations.cbegin(), removed_animations.cend(),
- [worklet_id](auto& it) { return it.worklet_id == worklet_id; }) &&
- std::all_of(
- peeked_animations.cbegin(), peeked_animations.cend(),
[worklet_id](auto& it) { return it.worklet_id == worklet_id; });
}
#endif
@@ -80,12 +77,6 @@ void MutatorInputState::Remove(WorkletAnimationId worklet_animation_id) {
worklet_input.removed_animations.push_back(worklet_animation_id);
}
-void MutatorInputState::Peek(WorkletAnimationId worklet_animation_id) {
- AnimationWorkletInput& worklet_input =
- EnsureWorkletEntry(worklet_animation_id.worklet_id);
- worklet_input.peeked_animations.push_back(worklet_animation_id);
-}
-
std::unique_ptr<AnimationWorkletInput> MutatorInputState::TakeWorkletState(
int worklet_id) {
auto it = inputs_.find(worklet_id);
diff --git a/chromium/cc/trees/layer_tree_mutator.h b/chromium/cc/trees/layer_tree_mutator.h
index ff1c32579c6..dc9ea0f146a 100644
--- a/chromium/cc/trees/layer_tree_mutator.h
+++ b/chromium/cc/trees/layer_tree_mutator.h
@@ -51,10 +51,18 @@ struct CC_EXPORT WorkletAnimationId {
// animation_id is only guaranteed to be unique per animation worklet.
int animation_id;
+ // Initialize with invalid id.
+ WorkletAnimationId() : worklet_id(0), animation_id(0) {}
+ WorkletAnimationId(int worklet_id, int animation_id)
+ : worklet_id(worklet_id), animation_id(animation_id) {}
+
inline bool operator==(const WorkletAnimationId& rhs) const {
return (this->worklet_id == rhs.worklet_id) &&
(this->animation_id == rhs.animation_id);
}
+ // Returns true if the WorkletAnimationId has been initialized with a valid
+ // id.
+ explicit operator bool() const { return !!worklet_id || !!animation_id; }
};
struct CC_EXPORT AnimationWorkletInput {
@@ -87,7 +95,6 @@ struct CC_EXPORT AnimationWorkletInput {
std::vector<AddAndUpdateState> added_and_updated_animations;
std::vector<UpdateState> updated_animations;
std::vector<WorkletAnimationId> removed_animations;
- std::vector<WorkletAnimationId> peeked_animations;
AnimationWorkletInput();
AnimationWorkletInput(const AnimationWorkletInput&) = delete;
@@ -113,12 +120,6 @@ class CC_EXPORT MutatorInputState {
void Add(AnimationWorkletInput::AddAndUpdateState&& state);
void Update(AnimationWorkletInput::UpdateState&& state);
void Remove(WorkletAnimationId worklet_animation_id);
- // |Update| asks for the animation to *animate* given a current time and
- // return the output value while |Peek| only asks for the last output value
- // (if one available) without requiring animate or providing a current time.
- // In particular, composited animations are updated from compositor and peeked
- // from main thread.
- void Peek(WorkletAnimationId worklet_animation_id);
// Returns input for animation worklet with the given |scope_id| and nullptr
// if there is no input.
diff --git a/chromium/cc/trees/layer_tree_settings.h b/chromium/cc/trees/layer_tree_settings.h
index 182eb5f6873..0743417d59c 100644
--- a/chromium/cc/trees/layer_tree_settings.h
+++ b/chromium/cc/trees/layer_tree_settings.h
@@ -73,6 +73,10 @@ class CC_EXPORT LayerTreeSettings {
// If set, indicates the largest tile size we will use for GPU Raster. If not
// set, no limit is enforced.
gfx::Size max_gpu_raster_tile_size;
+ // Even for really wide viewports, at some point GPU raster should use
+ // less than 4 tiles to fill the viewport. This is set to 256 as a
+ // sane minimum for now, but we might want to tune this for low-end.
+ int min_height_for_gpu_raster_tile = 256;
gfx::Size minimum_occlusion_tracking_size;
// 3000 pixels should give sufficient area for prepainting.
// Note this value is specified with an ideal contents scale in mind. That
@@ -150,10 +154,6 @@ class CC_EXPORT LayerTreeSettings {
// the device scale factor.
bool use_painted_device_scale_factor = false;
- // Whether a HitTestRegionList should be built from the active layer tree when
- // submitting a CompositorFrame.
- bool build_hit_test_data = false;
-
// When false, sync tokens are expected to be present, and are verified,
// before transfering gpu resources to the display compositor.
bool delegated_sync_points_required = true;
diff --git a/chromium/cc/trees/property_tree.cc b/chromium/cc/trees/property_tree.cc
index 6b306c718bd..2db1b0a5560 100644
--- a/chromium/cc/trees/property_tree.cc
+++ b/chromium/cc/trees/property_tree.cc
@@ -25,8 +25,7 @@
namespace cc {
template <typename T>
-PropertyTree<T>::PropertyTree()
- : needs_update_(false) {
+PropertyTree<T>::PropertyTree() : needs_update_(false) {
nodes_.push_back(T());
back()->id = kRootNodeId;
back()->parent_id = kInvalidNodeId;
@@ -1148,11 +1147,12 @@ ScrollTree::~ScrollTree() = default;
ScrollTree& ScrollTree::operator=(const ScrollTree& from) {
PropertyTree::operator=(from);
currently_scrolling_node_id_ = kInvalidNodeId;
- // Maps for ScrollOffsets/SyncedScrollOffsets are intentionally ommitted here
+ // Maps for ScrollOffsets/SyncedScrollOffsets are intentionally omitted here
// since we can not directly copy them. Pushing of these updates from main
// currently depends on Layer properties for scroll offset animation changes
// (setting clobber_active_value for scroll offset animations interrupted on
// the main thread) being pushed to impl first.
+ // |callbacks_| is omitted because it's for the main thread only.
return *this;
}
@@ -1161,6 +1161,8 @@ bool ScrollTree::operator==(const ScrollTree& other) const {
return false;
if (synced_scroll_offset_map_ != other.synced_scroll_offset_map_)
return false;
+ if (callbacks_.get() != other.callbacks_.get())
+ return false;
bool is_currently_scrolling_node_equal =
currently_scrolling_node_id_ == other.currently_scrolling_node_id_;
@@ -1173,6 +1175,7 @@ void ScrollTree::CopyCompleteTreeState(const ScrollTree& other) {
currently_scrolling_node_id_ = other.currently_scrolling_node_id_;
scroll_offset_map_ = other.scroll_offset_map_;
synced_scroll_offset_map_ = other.synced_scroll_offset_map_;
+ callbacks_ = other.callbacks_;
}
#endif
@@ -1202,7 +1205,9 @@ void ScrollTree::clear() {
#if DCHECK_IS_ON()
ScrollTree tree;
- if (!property_trees()->is_main_thread) {
+ if (property_trees()->is_main_thread) {
+ tree.callbacks_ = callbacks_;
+ } else {
DCHECK(scroll_offset_map_.empty());
tree.currently_scrolling_node_id_ = currently_scrolling_node_id_;
tree.synced_scroll_offset_map_ = synced_scroll_offset_map_;
@@ -1417,6 +1422,7 @@ void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
ElementId inner_viewport_scroll_element_id,
bool use_fractional_deltas) {
DCHECK(!property_trees()->is_main_thread);
+ TRACE_EVENT0("cc", "ScrollTree::CollectScrollDeltas");
for (auto map_entry : synced_scroll_offset_map_) {
gfx::ScrollOffset scroll_delta =
PullDeltaForMainThread(map_entry.second.get(), use_fractional_deltas);
@@ -1424,12 +1430,25 @@ void ScrollTree::CollectScrollDeltas(ScrollAndScaleSet* scroll_info,
ElementId id = map_entry.first;
if (!scroll_delta.IsZero()) {
+ TRACE_EVENT_INSTANT2("cc", "CollectScrollDeltas",
+ TRACE_EVENT_SCOPE_THREAD, "x", scroll_delta.x(), "y",
+ scroll_delta.y());
+ // The snap targets will change on cc only if the node was scrolled, so it
+ // is safe to update the snap targets only when the scroll delta is not
+ // zero.
+ ScrollNode* scroll_node = FindNodeFromElementId(id);
+ base::Optional<TargetSnapAreaElementIds> snap_target_ids;
+ if (scroll_node && scroll_node->snap_container_data) {
+ snap_target_ids = scroll_node->snap_container_data.value()
+ .GetTargetSnapAreaElementIds();
+ }
+ ScrollAndScaleSet::ScrollUpdateInfo update(id, scroll_delta,
+ snap_target_ids);
if (id == inner_viewport_scroll_element_id) {
// Inner (visual) viewport is stored separately.
- scroll_info->inner_viewport_scroll.element_id = id;
- scroll_info->inner_viewport_scroll.scroll_delta = scroll_delta;
+ scroll_info->inner_viewport_scroll = std::move(update);
} else {
- scroll_info->scrolls.push_back({id, scroll_delta});
+ scroll_info->scrolls.push_back(std::move(update));
}
}
}
@@ -1581,23 +1600,6 @@ const gfx::ScrollOffset ScrollTree::GetScrollOffsetDeltaForTesting(
return gfx::ScrollOffset();
}
-void ScrollTree::DistributeScroll(ScrollNode* scroll_node,
- ScrollState* scroll_state) {
- DCHECK(scroll_node && scroll_state);
- if (scroll_state->FullyConsumed())
- return;
- scroll_state->DistributeToScrollChainDescendant();
-
- // If we're currently scrolling a node other than this one, prevent the scroll
- // from propagating to this node.
- if (scroll_state->delta_consumed_for_scroll_sequence() &&
- scroll_state->current_native_scrolling_node()->id != scroll_node->id) {
- return;
- }
-
- scroll_state->layer_tree_impl()->ApplyScroll(scroll_node, scroll_state);
-}
-
gfx::Vector2dF ScrollTree::ScrollBy(ScrollNode* scroll_node,
const gfx::Vector2dF& scroll,
LayerTreeImpl* layer_tree_impl) {
@@ -1626,6 +1628,27 @@ gfx::ScrollOffset ScrollTree::ClampScrollOffsetToLimits(
return offset;
}
+void ScrollTree::SetScrollCallbacks(base::WeakPtr<ScrollCallbacks> callbacks) {
+ DCHECK(property_trees()->is_main_thread);
+ callbacks_ = std::move(callbacks);
+}
+
+void ScrollTree::NotifyDidScroll(
+ ElementId scroll_element_id,
+ const gfx::ScrollOffset& scroll_offset,
+ const base::Optional<TargetSnapAreaElementIds>& snap_target_ids) {
+ DCHECK(property_trees()->is_main_thread);
+ if (callbacks_)
+ callbacks_->DidScroll(scroll_element_id, scroll_offset, snap_target_ids);
+}
+
+void ScrollTree::NotifyDidChangeScrollbarsHidden(ElementId scroll_element_id,
+ bool hidden) {
+ DCHECK(property_trees()->is_main_thread);
+ if (callbacks_)
+ callbacks_->DidChangeScrollbarsHidden(scroll_element_id, hidden);
+}
+
PropertyTreesCachedData::PropertyTreesCachedData()
: transform_tree_update_number(0) {
animation_scales.clear();
diff --git a/chromium/cc/trees/property_tree.h b/chromium/cc/trees/property_tree.h
index 8370ad169cf..7cde294f85c 100644
--- a/chromium/cc/trees/property_tree.h
+++ b/chromium/cc/trees/property_tree.h
@@ -11,9 +11,12 @@
#include <unordered_map>
#include <vector>
+#include "base/callback.h"
#include "base/containers/flat_map.h"
+#include "base/memory/weak_ptr.h"
#include "cc/base/synced_property.h"
#include "cc/cc_export.h"
+#include "cc/input/scroll_snap_data.h"
#include "cc/paint/element_id.h"
#include "cc/paint/filter_operations.h"
#include "cc/trees/mutator_host_client.h"
@@ -26,7 +29,7 @@ namespace base {
namespace trace_event {
class TracedValue;
}
-}
+} // namespace base
namespace viz {
class CopyOutputRequest;
@@ -36,7 +39,6 @@ namespace cc {
class LayerTreeImpl;
class RenderSurfaceImpl;
-class ScrollState;
struct ClipNode;
struct EffectNode;
struct ScrollAndScaleSet;
@@ -362,6 +364,23 @@ class CC_EXPORT EffectTree final : public PropertyTree<EffectNode> {
std::vector<std::unique_ptr<RenderSurfaceImpl>> render_surfaces_;
};
+// These callbacks are called in the main thread to notify changes of scroll
+// information in the compositor thread during commit.
+class ScrollCallbacks {
+ public:
+ // Called after the composited scroll offset changed.
+ virtual void DidScroll(ElementId scroll_element_id,
+ const gfx::ScrollOffset&,
+ const base::Optional<TargetSnapAreaElementIds>&) = 0;
+ // Called after the hidden status of composited scrollbars changed. Note that
+ // |scroll_element_id| is the element id of the scroll not of the scrollbars.
+ virtual void DidChangeScrollbarsHidden(ElementId scroll_element_id,
+ bool hidden) = 0;
+
+ protected:
+ virtual ~ScrollCallbacks() {}
+};
+
class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
public:
ScrollTree();
@@ -442,7 +461,6 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
const gfx::ScrollOffset GetScrollOffsetDeltaForTesting(ElementId id) const;
void CollectScrollDeltasForTesting();
- void DistributeScroll(ScrollNode* scroll_node, ScrollState* scroll_state);
gfx::Vector2dF ScrollBy(ScrollNode* scroll_node,
const gfx::Vector2dF& scroll,
LayerTreeImpl* layer_tree_impl);
@@ -459,6 +477,15 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
ScrollNode* FindNodeFromElementId(ElementId id);
const ScrollNode* FindNodeFromElementId(ElementId id) const;
+ void SetScrollCallbacks(base::WeakPtr<ScrollCallbacks> callbacks);
+
+ void NotifyDidScroll(
+ ElementId scroll_element_id,
+ const gfx::ScrollOffset& scroll_offset,
+ const base::Optional<TargetSnapAreaElementIds>& snap_target_ids);
+ void NotifyDidChangeScrollbarsHidden(ElementId scroll_element_id,
+ bool hidden);
+
private:
using ScrollOffsetMap = base::flat_map<ElementId, gfx::ScrollOffset>;
using SyncedScrollOffsetMap =
@@ -474,6 +501,8 @@ class CC_EXPORT ScrollTree final : public PropertyTree<ScrollNode> {
ScrollOffsetMap scroll_offset_map_;
SyncedScrollOffsetMap synced_scroll_offset_map_;
+ base::WeakPtr<ScrollCallbacks> callbacks_;
+
SyncedScrollOffset* GetOrCreateSyncedScrollOffset(ElementId id);
gfx::ScrollOffset PullDeltaForMainThread(SyncedScrollOffset* scroll_offset,
bool use_fractional_deltas);
diff --git a/chromium/cc/trees/proxy_impl.cc b/chromium/cc/trees/proxy_impl.cc
index a43c4b40b7d..e35b3cb4999 100644
--- a/chromium/cc/trees/proxy_impl.cc
+++ b/chromium/cc/trees/proxy_impl.cc
@@ -278,7 +278,13 @@ void ProxyImpl::NotifyReadyToCommitOnImpl(
DCHECK(!blocked_main_commit().layer_tree_host);
blocked_main_commit().layer_tree_host = layer_tree_host;
- scheduler_->NotifyReadyToCommit();
+
+ // Extract metrics data from the layer tree host and send them to the
+ // scheduler to pass them to the compositor_timing_history object.
+ std::unique_ptr<BeginMainFrameMetrics> main_frame_metrics =
+ layer_tree_host->begin_main_frame_metrics();
+
+ scheduler_->NotifyReadyToCommit(std::move(main_frame_metrics));
}
void ProxyImpl::DidLoseLayerTreeFrameSinkOnImplThread() {
diff --git a/chromium/cc/trees/render_frame_metadata.cc b/chromium/cc/trees/render_frame_metadata.cc
index b666e9c6633..158f4a63820 100644
--- a/chromium/cc/trees/render_frame_metadata.cc
+++ b/chromium/cc/trees/render_frame_metadata.cc
@@ -45,7 +45,8 @@ bool RenderFrameMetadata::operator==(const RenderFrameMetadata& other) const {
root_layer_size == other.root_layer_size &&
has_transparent_background == other.has_transparent_background &&
#endif
- local_surface_id_allocation == other.local_surface_id_allocation;
+ local_surface_id_allocation == other.local_surface_id_allocation &&
+ new_vertical_scroll_direction == other.new_vertical_scroll_direction;
}
bool RenderFrameMetadata::operator!=(const RenderFrameMetadata& other) const {
diff --git a/chromium/cc/trees/render_frame_metadata.h b/chromium/cc/trees/render_frame_metadata.h
index 400eeaefe0d..8d71c87c394 100644
--- a/chromium/cc/trees/render_frame_metadata.h
+++ b/chromium/cc/trees/render_frame_metadata.h
@@ -11,6 +11,7 @@
#include "cc/cc_export.h"
#include "components/viz/common/quads/selection.h"
#include "components/viz/common/surfaces/local_surface_id_allocation.h"
+#include "components/viz/common/vertical_scroll_direction.h"
#include "third_party/skia/include/core/SkColor.h"
#include "ui/gfx/geometry/size.h"
#include "ui/gfx/geometry/size_f.h"
@@ -75,6 +76,14 @@ class CC_EXPORT RenderFrameMetadata {
float top_controls_height = 0.f;
float top_controls_shown_ratio = 0.f;
+ // Indicates a change in the vertical scroll direction of the root layer since
+ // the last drawn render frame. If no change occurred, this value is |kNull|.
+ // Note that if a scroll in a given direction occurs, the scroll is completed,
+ // and then another scroll in the *same* direction occurs, we will not
+ // consider the second scroll event to have caused a change in direction.
+ viz::VerticalScrollDirection new_vertical_scroll_direction =
+ viz::VerticalScrollDirection::kNull;
+
#if defined(OS_ANDROID)
// Used to position Android bottom bar, whose position is computed by the
// renderer compositor.
diff --git a/chromium/cc/trees/scroll_and_scale_set.cc b/chromium/cc/trees/scroll_and_scale_set.cc
index e2d08c839c1..6049e60b436 100644
--- a/chromium/cc/trees/scroll_and_scale_set.cc
+++ b/chromium/cc/trees/scroll_and_scale_set.cc
@@ -12,6 +12,7 @@ ScrollAndScaleSet::ScrollAndScaleSet()
: page_scale_delta(1.f),
is_pinch_gesture_active(false),
top_controls_delta(0.f),
+ bottom_controls_delta(0.f),
browser_controls_constraint(BrowserControlsState::kBoth),
browser_controls_constraint_changed(false),
scroll_gesture_did_end(false),
@@ -19,4 +20,20 @@ ScrollAndScaleSet::ScrollAndScaleSet()
ScrollAndScaleSet::~ScrollAndScaleSet() = default;
+ScrollAndScaleSet::ScrollUpdateInfo::ScrollUpdateInfo() = default;
+
+ScrollAndScaleSet::ScrollUpdateInfo::ScrollUpdateInfo(
+ ElementId id,
+ gfx::ScrollOffset delta,
+ base::Optional<TargetSnapAreaElementIds> snap_target_ids)
+ : element_id(id),
+ scroll_delta(delta),
+ snap_target_element_ids(snap_target_ids) {}
+
+ScrollAndScaleSet::ScrollUpdateInfo::ScrollUpdateInfo(
+ const ScrollUpdateInfo& other) = default;
+
+ScrollAndScaleSet::ScrollUpdateInfo& ScrollAndScaleSet::ScrollUpdateInfo::
+operator=(const ScrollUpdateInfo& other) = default;
+
} // namespace cc
diff --git a/chromium/cc/trees/scroll_and_scale_set.h b/chromium/cc/trees/scroll_and_scale_set.h
index 41687918fb2..cef0850f33b 100644
--- a/chromium/cc/trees/scroll_and_scale_set.h
+++ b/chromium/cc/trees/scroll_and_scale_set.h
@@ -9,6 +9,7 @@
#include "cc/cc_export.h"
#include "cc/input/browser_controls_state.h"
+#include "cc/input/scroll_snap_data.h"
#include "cc/paint/element_id.h"
#include "cc/trees/layer_tree_host_client.h"
#include "ui/gfx/geometry/scroll_offset.h"
@@ -27,12 +28,24 @@ struct CC_EXPORT ScrollAndScaleSet {
ScrollAndScaleSet& operator=(const ScrollAndScaleSet&) = delete;
struct CC_EXPORT ScrollUpdateInfo {
+ ScrollUpdateInfo();
+ ScrollUpdateInfo(ElementId id,
+ gfx::ScrollOffset delta,
+ base::Optional<TargetSnapAreaElementIds> snap_target_ids);
+ ScrollUpdateInfo(const ScrollUpdateInfo& other);
+ ScrollUpdateInfo& operator=(const ScrollUpdateInfo&);
ElementId element_id;
gfx::ScrollOffset scroll_delta;
+ // The target snap area element ids of the scrolling element.
+ // This will have a value if the scrolled element's scroll node has snap
+ // container data and the scroll delta is non-zero.
+ base::Optional<TargetSnapAreaElementIds> snap_target_element_ids;
+
bool operator==(const ScrollUpdateInfo& other) const {
return element_id == other.element_id &&
- scroll_delta == other.scroll_delta;
+ scroll_delta == other.scroll_delta &&
+ snap_target_element_ids == other.snap_target_element_ids;
}
};
@@ -59,6 +72,7 @@ struct CC_EXPORT ScrollAndScaleSet {
ElementId scroll_latched_element_id;
float top_controls_delta;
+ float bottom_controls_delta;
// Used to communicate scrollbar visibility from Impl thread to Blink.
// Scrollbar input is handled by Blink but the compositor thread animates
diff --git a/chromium/cc/trees/single_thread_proxy.cc b/chromium/cc/trees/single_thread_proxy.cc
index 64cf02bdbf2..2a235b6dd90 100644
--- a/chromium/cc/trees/single_thread_proxy.cc
+++ b/chromium/cc/trees/single_thread_proxy.cc
@@ -195,8 +195,9 @@ void SingleThreadProxy::DoCommit() {
layer_tree_host_->FinishCommitOnImplThread(host_impl_.get());
- if (scheduler_on_impl_thread_)
+ if (scheduler_on_impl_thread_) {
scheduler_on_impl_thread_->DidCommit();
+ }
IssueImageDecodeFinishedCallbacks();
host_impl_->CommitComplete();
@@ -872,8 +873,10 @@ void SingleThreadProxy::DoPainting() {
// TODO(enne): SingleThreadProxy does not support cancelling commits yet,
// search for CommitEarlyOutReason::FINISHED_NO_UPDATES inside
// thread_proxy.cc
- if (scheduler_on_impl_thread_)
- scheduler_on_impl_thread_->NotifyReadyToCommit();
+ if (scheduler_on_impl_thread_) {
+ scheduler_on_impl_thread_->NotifyReadyToCommit(
+ layer_tree_host_->begin_main_frame_metrics());
+ }
}
void SingleThreadProxy::BeginMainFrameAbortedOnImplThread(
diff --git a/chromium/cc/trees/ukm_manager.cc b/chromium/cc/trees/ukm_manager.cc
index 7b8c98100d6..e860874015f 100644
--- a/chromium/cc/trees/ukm_manager.cc
+++ b/chromium/cc/trees/ukm_manager.cc
@@ -90,4 +90,83 @@ void UkmManager::RecordRenderingUkm() {
total_num_of_checkerboarded_images_ = 0;
}
+void UkmManager::RecordThroughputUKM(
+ FrameSequenceTrackerType tracker_type,
+ FrameSequenceTracker::ThreadType thread_type,
+ int64_t throughput) const {
+ ukm::builders::Graphics_Smoothness_Throughput builder(source_id_);
+ switch (thread_type) {
+ case FrameSequenceTracker::ThreadType::kMain: {
+ switch (tracker_type) {
+#define CASE_FOR_MAIN_THREAD_TRACKER(name) \
+ case FrameSequenceTrackerType::k##name: \
+ builder.SetMainThread_##name(throughput); \
+ break;
+ CASE_FOR_MAIN_THREAD_TRACKER(CompositorAnimation);
+ CASE_FOR_MAIN_THREAD_TRACKER(MainThreadAnimation);
+ CASE_FOR_MAIN_THREAD_TRACKER(PinchZoom);
+ CASE_FOR_MAIN_THREAD_TRACKER(RAF);
+ CASE_FOR_MAIN_THREAD_TRACKER(TouchScroll);
+ CASE_FOR_MAIN_THREAD_TRACKER(Universal);
+ CASE_FOR_MAIN_THREAD_TRACKER(Video);
+ CASE_FOR_MAIN_THREAD_TRACKER(WheelScroll);
+#undef CASE_FOR_MAIN_THREAD_TRACKER
+ default:
+ NOTREACHED();
+ break;
+ }
+
+ break;
+ }
+
+ case FrameSequenceTracker::ThreadType::kCompositor: {
+ switch (tracker_type) {
+#define CASE_FOR_COMPOSITOR_THREAD_TRACKER(name) \
+ case FrameSequenceTrackerType::k##name: \
+ builder.SetCompositorThread_##name(throughput); \
+ break;
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(CompositorAnimation);
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(MainThreadAnimation);
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(PinchZoom);
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(RAF);
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(TouchScroll);
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(Universal);
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(Video);
+ CASE_FOR_COMPOSITOR_THREAD_TRACKER(WheelScroll);
+#undef CASE_FOR_COMPOSITOR_THREAD_TRACKER
+ default:
+ NOTREACHED();
+ break;
+ }
+ break;
+ }
+
+ case FrameSequenceTracker::ThreadType::kSlower: {
+ switch (tracker_type) {
+#define CASE_FOR_SLOWER_THREAD_TRACKER(name) \
+ case FrameSequenceTrackerType::k##name: \
+ builder.SetSlowerThread_##name(throughput); \
+ break;
+ CASE_FOR_SLOWER_THREAD_TRACKER(CompositorAnimation);
+ CASE_FOR_SLOWER_THREAD_TRACKER(MainThreadAnimation);
+ CASE_FOR_SLOWER_THREAD_TRACKER(PinchZoom);
+ CASE_FOR_SLOWER_THREAD_TRACKER(RAF);
+ CASE_FOR_SLOWER_THREAD_TRACKER(TouchScroll);
+ CASE_FOR_SLOWER_THREAD_TRACKER(Universal);
+ CASE_FOR_SLOWER_THREAD_TRACKER(Video);
+ CASE_FOR_SLOWER_THREAD_TRACKER(WheelScroll);
+#undef CASE_FOR_SLOWER_THREAD_TRACKER
+ default:
+ NOTREACHED();
+ break;
+ }
+ break;
+ }
+ default:
+ NOTREACHED();
+ break;
+ }
+ builder.Record(recorder_.get());
+}
+
} // namespace cc
diff --git a/chromium/cc/trees/ukm_manager.h b/chromium/cc/trees/ukm_manager.h
index aeeda10cd0a..a67bbb08269 100644
--- a/chromium/cc/trees/ukm_manager.h
+++ b/chromium/cc/trees/ukm_manager.h
@@ -6,6 +6,7 @@
#define CC_TREES_UKM_MANAGER_H_
#include "cc/cc_export.h"
+#include "cc/metrics/frame_sequence_tracker.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "url/gurl.h"
@@ -22,6 +23,7 @@ class CC_EXPORT UkmRecorderFactory {
virtual std::unique_ptr<ukm::UkmRecorder> CreateRecorder() = 0;
};
+// TODO(xidachen): rename the class to CompositorUkmManager.
class CC_EXPORT UkmManager {
public:
explicit UkmManager(std::unique_ptr<ukm::UkmRecorder> recorder);
@@ -38,6 +40,10 @@ class CC_EXPORT UkmManager {
// These metrics are recorded until the source URL changes.
void AddCheckerboardedImages(int num_of_checkerboarded_images);
+ void RecordThroughputUKM(FrameSequenceTrackerType tracker_type,
+ FrameSequenceTracker::ThreadType thread_type,
+ int64_t throughput) const;
+
ukm::UkmRecorder* recorder_for_testing() { return recorder_.get(); }
private:
diff --git a/chromium/cc/typemaps.gni b/chromium/cc/typemaps.gni
new file mode 100644
index 00000000000..b22ff7bb574
--- /dev/null
+++ b/chromium/cc/typemaps.gni
@@ -0,0 +1,5 @@
+# Copyright 2019 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+typemaps = [ "//cc/mojom/touch_action.typemap" ]